adds more tests for period predictions, moves getcycleslength into cycle module

This commit is contained in:
tina
2018-08-23 11:36:57 +02:00
parent ea21fc92a2
commit 497a3a3ff5
4 changed files with 152 additions and 45 deletions
-12
View File
@@ -1,6 +1,4 @@
import assert from 'assert'
import { LocalDate, ChronoUnit } from 'js-joda'
import cycleModule from '../lib/cycle'
export function getCycleLengthStats(cycleLengths) {
throwIfArgsAreNotInRequiredFormat(cycleLengths)
@@ -48,14 +46,4 @@ function throwIfArgsAreNotInRequiredFormat(cycleLengths) {
assert.equal(typeof cycleLength, 'number', 'Elements in the array should be of type number.')
assert.ok(!isNaN(cycleLength), 'Elements of array should not be NaN.')
})
}
export function getCycleLength(cycleStartDates) {
const cycleLengths = []
for (let i = 0; i < cycleStartDates.length - 1; i++) {
const nextCycleStart = LocalDate.parse(cycleStartDates[i])
const cycleStart = LocalDate.parse(cycleStartDates[i + 1])
cycleLengths.push(cycleStart.until(nextCycleStart, ChronoUnit.DAYS))
}
return cycleLengths
}
+29 -7
View File
@@ -1,5 +1,5 @@
import * as joda from 'js-joda'
import {getCycleLengthStats, getCycleLength} from './cycle-length'
import {getCycleLengthStats} from './cycle-length'
const LocalDate = joda.LocalDate
const DAYS = joda.ChronoUnit.DAYS
@@ -7,6 +7,8 @@ export default function config(opts) {
let bleedingDaysSortedByDate
let cycleDaysSortedByDate
let maxBreakInBleeding
let maxCycleLength
let minCyclesForPrediction
if (!opts) {
// we only want to require (and run) the db module
@@ -14,10 +16,14 @@ export default function config(opts) {
bleedingDaysSortedByDate = require('../db').bleedingDaysSortedByDate
cycleDaysSortedByDate = require('../db').cycleDaysSortedByDate
maxBreakInBleeding = 1
maxCycleLength = 99
minCyclesForPrediction = 3
} else {
bleedingDaysSortedByDate = opts.bleedingDaysSortedByDate || []
cycleDaysSortedByDate = opts.cycleDaysSortedByDate || []
maxBreakInBleeding = opts.maxBreakInBleeding || 1
maxCycleLength = opts.maxCycleLength || 99
minCyclesForPrediction = opts.minCyclesForPrediction || 3
}
function getLastMensesStart(targetDateString) {
@@ -144,22 +150,37 @@ export default function config(opts) {
}
}
function getPredictedMenses(maxCycleLength, minCyclesForPrediction) {
maxCycleLength = maxCycleLength || 99
minCyclesForPrediction = minCyclesForPrediction || 3
function getCycleLength(cycleStartDates) {
const cycleLengths = []
for (let i = 0; i < cycleStartDates.length - 1; i++) {
const nextCycleStart = LocalDate.parse(cycleStartDates[i])
const cycleStart = LocalDate.parse(cycleStartDates[i + 1])
const cycleLength = cycleStart.until(nextCycleStart, DAYS)
if (cycleLength <= maxCycleLength) { cycleLengths.push(cycleLength) }
}
return cycleLengths
}
function getPredictedMenses() {
const allMensesStarts = getAllMensesStarts()
const atLeastOneCycle = allMensesStarts.length > 1
if (!atLeastOneCycle ||
allMensesStarts.length < minCyclesForPrediction ||
getCycleDayNumber(LocalDate.now().toString()) > maxCycleLength
allMensesStarts.length < minCyclesForPrediction
) {
return {}
}
const cycleLengths = getCycleLength(allMensesStarts)
const cycleInfo = getCycleLengthStats(cycleLengths)
const periodDistance = Math.round(cycleInfo.mean)
const periodStartVariation = (cycleInfo.stdDeviation < 1.5) ? 1 : 2 // threshold is choosen a little arbitrarily
let periodStartVariation
if (cycleInfo.stdDeviation === null) {
periodStartVariation = 2
} else if (cycleInfo.stdDeviation < 1.5) { // threshold is choosen a little arbitrarily
periodStartVariation = 1
} else {
periodStartVariation = 2
}
var lastStart = allMensesStarts[0]
const predictedMenses = []
for (let i = 0; i < 3; i++) {
@@ -179,6 +200,7 @@ export default function config(opts) {
getPreviousCycle,
getCyclesBefore,
getAllMensesStarts,
getCycleLength,
getPredictedMenses
}
}