Change API so it doesn't return unnecessary info

This commit is contained in:
Julia Friesel
2018-06-30 20:28:48 +02:00
parent a90d393545
commit 1eb3f4a14a
2 changed files with 84 additions and 64 deletions
+73 -32
View File
@@ -2,32 +2,42 @@ function detectTemperatureShift(temperaturesOfCycle) {
// sensiplan rounds temps to the nearest 0.05
const tempValues = temperaturesOfCycle.map(val => rounded(val, 0.05))
return tempValues.reduce((acc, curr) => {
// if we don't yet have 6 lower temps, we just collect
// if no shift has been detected, we collect low temps
// after the shift has been detected, we count them as part
// of the higher temperature phase
if (acc.low.length < 6) {
acc.low.push(curr)
acc.ltl = Math.max(...acc.low)
// TODO these are the same
} else if (curr <= acc.ltl && !acc.potentialHigh && !acc.shiftDetected) {
acc.low.push(curr)
acc.low.shift(curr)
acc.ltl = Math.max(...acc.low)
} else if (!acc.shiftDetected){
if (!acc.potentialHigh) acc.potentialHigh = []
acc.potentialHigh.push(curr)
checkRules(acc, curr)
} else {
acc.high.push(curr)
function getLtl(i) {
const sixTempsBefore = getSixTempsBefore(i)
return Math.max(...sixTempsBefore)
}
function getSixTempsBefore(i) {
return tempValues.slice(0, i).slice(-6)
}
return tempValues.reduce((acc, temp, i) => {
// need at least 6 low temps before we can detect a first high measurement
if (i < 6) return acc
// if we've already detected a shift, we put it with the other high level temps
if(acc.detected) {
acc.high.push(temp)
return acc
}
// is the temp a candidate for a first high measurement?
const ltl = getLtl(i)
if (temp <= ltl) return acc
const checkResult = checkIfFirstHighMeasurement(temp, i, tempValues, ltl)
// if we don't have a winner, keep going
if (!checkResult.isFirstHighMeasurement) return acc
// if we do, remember the details and start collecting the high level temps
acc.detected = true
acc.high = [temp]
acc.rules = checkResult.rules
acc.ltl = ltl
acc.low = getSixTempsBefore(i)
return acc
}, {
low: [],
ltl: null,
shiftDetected: false
detected: false
})
}
@@ -36,20 +46,51 @@ function rounded(val, step) {
return Math.round(val * inverted) / inverted
}
function checkRules(acc, curr) {
function regularRuleApplies() {
// we round the difference because of JS decimal weirdness
return acc.potentialHigh.length === 3 && rounded(curr - acc.ltl, 0.01) >= 0.2
function checkIfFirstHighMeasurement(temp, i, temps, ltl) {
// need at least 3 high temps to form a high temperature level
if (i > temps.length - 3) {
return { isFirstHighMeasurement: false }
}
function firstExceptionRuleApplies() {
return acc.potentialHigh.length === 4 && curr > acc.ltl
const nextTemps = temps.slice(i + 1, i + 4)
if (regularRuleApplies(temp, nextTemps, ltl)) {
return {
isFirstHighMeasurement: true,
rules: {
regular: true,
},
ltl
}
}
if (regularRuleApplies() || firstExceptionRuleApplies()) {
acc.shiftDetected = true
acc.high = acc.potentialHigh
delete acc.potentialHigh
if (firstExceptionRuleApplies(temp, nextTemps, ltl)) {
return {
isFirstHighMeasurement: true,
rules: {
firstException: true,
},
ltl
}
}
return {
isFirstHighMeasurement: false
}
}
function regularRuleApplies(temp, nextTemps, ltl) {
if (!nextTemps.every(temp => temp > ltl)) return false
const thirdTemp = nextTemps[1]
// we round the difference because of JS decimal weirdness
if (rounded(thirdTemp - ltl, 0.1) < 0.2) return false
return true
}
function firstExceptionRuleApplies(temp, nextTemps, ltl) {
if (!nextTemps.every(temp => temp > ltl)) return false
const fourthTemp = nextTemps[2]
if (fourthTemp > ltl) return true
return false
}
export {