From 509af486ebf38df752875d1bd04db6fb7b8ad5d5 Mon Sep 17 00:00:00 2001 From: Quentin Hibon Date: Mon, 8 Nov 2021 22:07:48 +0100 Subject: [PATCH] Start the cumulative numerical habit implementation --- .../isoron/uhabits/core/models/EntryList.kt | 22 ++++++++++++++++++- .../uhabits/core/models/EntryListTest.kt | 22 ++++++++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/EntryList.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/EntryList.kt index b11baea24..45d99a514 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/EntryList.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/models/EntryList.kt @@ -95,7 +95,27 @@ open class EntryList { clear() val original = originalEntries.getKnown() if (isNumerical) { - original.forEach { add(it) } + assert(frequency.numerator == 1) + + val intervals = buildIntervals(frequency, original) + snapIntervalsTogether(intervals) + val computed = buildEntriesFromInterval(original, intervals).sortedBy { it.timestamp } + var currentValue = 0 + val currentWindow = ArrayDeque() + for (entry in computed) { + if (entry.value == UNKNOWN) { + continue + } + currentValue += entry.value + currentWindow.addLast(entry) + while (entry.timestamp.minus(frequency.denominator - 1).isNewerThan(currentWindow.first().timestamp)) { + currentValue -= currentWindow.first().value + currentWindow.removeFirst() + assert(currentValue >= 0) + } + // TODO: we need to keep track of both today's value and the current cumulative value + add(Entry(entry.timestamp, currentValue)) + } } else { val intervals = buildIntervals(frequency, original) snapIntervalsTogether(intervals) diff --git a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/models/EntryListTest.kt b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/models/EntryListTest.kt index 9c7de4bb3..d131b40a9 100644 --- a/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/models/EntryListTest.kt +++ b/uhabits-core/src/jvmTest/java/org/isoron/uhabits/core/models/EntryListTest.kt @@ -96,7 +96,7 @@ class EntryListTest { } @Test - fun testComputeNumerical() { + fun testComputeNumericalDaily() { val today = DateUtils.getToday() val original = EntryList() @@ -115,6 +115,26 @@ class EntryListTest { assertEquals(expected, computed.getKnown()) } + @Test + fun testComputeNumericalWeekly() { + val today = DateUtils.getToday() + + val original = EntryList() + original.add(Entry(today.minus(4), 100)) + original.add(Entry(today.minus(9), 200)) + original.add(Entry(today.minus(10), 300)) + + val computed = EntryList() + computed.recomputeFrom(original, Frequency.WEEKLY, isNumerical = true) + + val expected = listOf( + Entry(today.minus(4), 600), + Entry(today.minus(9), 500), + Entry(today.minus(10), 300), + ) + assertEquals(expected, computed.getKnown()) + } + @Test fun testGroupByNumerical() { val offsets = intArrayOf(