Revert "Skip days implemented. Scores not correct yet"

This reverts commit ec08b602
This commit is contained in:
Dharanish
2024-06-25 11:46:48 +02:00
parent 832d51a055
commit 2146ce71a0
13 changed files with 49 additions and 226 deletions

View File

@@ -38,12 +38,11 @@ open class EntryList {
/**
* Returns the entry corresponding to the given timestamp. If no entry with such timestamp
* has been previously added, returns Entry(timestamp, UNKNOWN). or Entry(timestamp, SKIP) if
* skip days are enabled and that day is to be skipped
* has been previously added, returns Entry(timestamp, UNKNOWN).
*/
@Synchronized
open fun get(timestamp: Timestamp, skipDays: SkipDays = SkipDays.NONE): Entry {
return if (skipDays.isDaySkipped(timestamp)) Entry(timestamp, SKIP) else entriesByTimestamp[timestamp] ?: Entry(timestamp, UNKNOWN)
open fun get(timestamp: Timestamp): Entry {
return entriesByTimestamp[timestamp] ?: Entry(timestamp, UNKNOWN)
}
/**
@@ -52,12 +51,12 @@ open class EntryList {
* included.
*/
@Synchronized
open fun getByInterval(from: Timestamp, to: Timestamp, skipDays: SkipDays = SkipDays.NONE): List<Entry> {
open fun getByInterval(from: Timestamp, to: Timestamp): List<Entry> {
val result = mutableListOf<Entry>()
if (from.isNewerThan(to)) return result
var current = to
while (current >= from) {
result.add(get(current, skipDays))
result.add(get(current))
current = current.minus(1)
}
return result
@@ -91,18 +90,16 @@ open class EntryList {
open fun recomputeFrom(
originalEntries: EntryList,
frequency: Frequency,
isNumerical: Boolean,
skipDays: SkipDays
isNumerical: Boolean
) {
clear()
val original = originalEntries.getKnown()
if (isNumerical) {
val computed = addEntriesWithSkipDays(original, skipDays)
computed.forEach { add(it) }
original.forEach { add(it) }
} else {
val intervals = buildIntervals(frequency, original)
snapIntervalsTogether(intervals)
val computed = buildEntriesFromInterval(original, intervals, skipDays)
val computed = buildEntriesFromInterval(original, intervals)
computed.filter { it.value != UNKNOWN || it.notes.isNotEmpty() }.forEach { add(it) }
}
}
@@ -131,10 +128,10 @@ open class EntryList {
fun computeWeekdayFrequency(isNumerical: Boolean): HashMap<Timestamp, Array<Int>> {
val entries = getKnown()
val map = hashMapOf<Timestamp, Array<Int>>()
for ((computedTimestamp, value) in entries) {
val weekday = computedTimestamp.weekday
for ((originalTimestamp, value) in entries) {
val weekday = originalTimestamp.weekday
val truncatedTimestamp = Timestamp(
computedTimestamp.toCalendar().apply {
originalTimestamp.toCalendar().apply {
set(Calendar.DAY_OF_MONTH, 1)
}.timeInMillis
)
@@ -145,7 +142,7 @@ open class EntryList {
map[truncatedTimestamp] = list
}
if (isNumerical && value != SKIP) {
if (isNumerical) {
list[weekday] += value
} else if (value == YES_MANUAL) {
list[weekday] += 1
@@ -170,8 +167,7 @@ open class EntryList {
*/
fun buildEntriesFromInterval(
original: List<Entry>,
intervals: List<Interval>,
skipDays: SkipDays
intervals: List<Interval>
): List<Entry> {
val result = arrayListOf<Entry>()
if (original.isEmpty()) return result
@@ -200,17 +196,15 @@ open class EntryList {
current = interval.end
while (current >= interval.begin) {
val offset = current.daysUntil(to)
result[offset] = if (skipDays.isDaySkipped(current)) Entry(current, SKIP) else Entry(current, YES_AUTO)
result[offset] = Entry(current, YES_AUTO)
current = current.minus(1)
}
}
// Copy original entries except for the skipped days
// Copy original entries
original.forEach { entry ->
val offset = entry.timestamp.daysUntil(to)
val value = if (skipDays.isDaySkipped(entry)) {
SKIP
} else if (
val value = if (
result[offset].value == UNKNOWN ||
entry.value == SKIP ||
entry.value == YES_MANUAL
@@ -277,29 +271,6 @@ open class EntryList {
}
return intervals
}
fun addEntriesWithSkipDays(original: List<Entry>, skipDays: SkipDays): List<Entry> {
if (original.isEmpty()) return original
val earliest = original.last().timestamp
val today = DateUtils.getTodayWithOffset()
val computed = mutableListOf<Entry>()
var current = today
var offset = 0
while (current >= earliest) {
if (current == original[offset].timestamp) {
if (!skipDays.isDaySkipped(current)) {
computed.add(original[offset])
} else {
computed.add(Entry(current, SKIP))
}
offset++
} else if (skipDays.isDaySkipped(current)) {
computed.add(Entry(current, SKIP))
}
current = current.minus(1)
}
return computed
}
}
}
@@ -352,12 +323,10 @@ fun List<Entry>.groupedSum(
*/
fun List<Entry>.countSkippedDays(
truncateField: DateUtils.TruncateField,
firstWeekday: Int = Calendar.SATURDAY,
skipDays: SkipDays
firstWeekday: Int = Calendar.SATURDAY
): List<Entry> {
val thisIntervalStart = DateUtils.getTodayWithOffset().truncate(truncateField, firstWeekday)
return this.map { (timestamp, value) ->
if (value == SKIP || skipDays.isDaySkipped(timestamp)) {
if (value == SKIP) {
Entry(timestamp, 1)
} else {
Entry(timestamp, 0)
@@ -371,5 +340,5 @@ fun List<Entry>.countSkippedDays(
Entry(timestamp, entries.sumOf { it.value })
}.sortedBy { (timestamp, _) ->
-timestamp.unixTime
}.filter { it.timestamp == thisIntervalStart }
}
}

View File

@@ -25,7 +25,6 @@ data class Habit(
var color: PaletteColor = PaletteColor(8),
var description: String = "",
var frequency: Frequency = Frequency.DAILY,
var skipDays: SkipDays = SkipDays.NONE,
var id: Long? = null,
var isArchived: Boolean = false,
var name: String = "",
@@ -40,15 +39,12 @@ data class Habit(
val computedEntries: EntryList,
val originalEntries: EntryList,
val scores: ScoreList,
val streaks: StreakList,
var parentID: Long? = null,
var parentUUID: String? = null
val streaks: StreakList
) {
init {
if (uuid == null) this.uuid = UUID.randomUUID().toString().replace("-", "")
}
var parent: HabitGroup? = null
var observable = ModelObservable()
val isNumerical: Boolean
@@ -82,8 +78,7 @@ data class Habit(
computedEntries.recomputeFrom(
originalEntries = originalEntries,
frequency = frequency,
isNumerical = isNumerical,
skipDays = skipDays
isNumerical = isNumerical
)
val today = DateUtils.getTodayWithOffset()
@@ -95,7 +90,6 @@ data class Habit(
scores.recompute(
frequency = frequency,
isNumerical = isNumerical,
skipDays = skipDays,
numericalHabitType = targetType,
targetValue = targetValue,
computedEntries = computedEntries,
@@ -110,23 +104,10 @@ data class Habit(
)
}
fun firstEntryDate(): Timestamp {
return computedEntries.getKnown().lastOrNull()?.timestamp ?: DateUtils.getTodayWithOffset()
}
fun hierarchyLevel(): Int {
return if (parentID == null) {
0
} else {
1 + parent!!.hierarchyLevel()
}
}
fun copyFrom(other: Habit) {
this.color = other.color
this.description = other.description
this.frequency = other.frequency
this.skipDays = other.skipDays
// this.id should not be copied
this.isArchived = other.isArchived
this.name = other.name
@@ -138,8 +119,6 @@ data class Habit(
this.type = other.type
this.unit = other.unit
this.uuid = other.uuid
this.parentID = other.parentID
this.parentUUID = other.parentUUID
}
override fun equals(other: Any?): Boolean {
@@ -149,7 +128,6 @@ data class Habit(
if (color != other.color) return false
if (description != other.description) return false
if (frequency != other.frequency) return false
if (skipDays != other.skipDays) return false
if (id != other.id) return false
if (isArchived != other.isArchived) return false
if (name != other.name) return false
@@ -161,8 +139,6 @@ data class Habit(
if (type != other.type) return false
if (unit != other.unit) return false
if (uuid != other.uuid) return false
if (parentID != other.parentID) return false
if (parentUUID != other.parentUUID) return false
return true
}
@@ -171,7 +147,6 @@ data class Habit(
var result = color.hashCode()
result = 31 * result + description.hashCode()
result = 31 * result + frequency.hashCode()
result = 31 * result + skipDays.hashCode()
result = 31 * result + (id?.hashCode() ?: 0)
result = 31 * result + isArchived.hashCode()
result = 31 * result + name.hashCode()
@@ -183,8 +158,6 @@ data class Habit(
result = 31 * result + type.value
result = 31 * result + unit.hashCode()
result = 31 * result + (uuid?.hashCode() ?: 0)
result = 31 * result + (parentID?.hashCode() ?: 0)
result = 31 * result + (parentUUID?.hashCode() ?: 0)
return result
}
}

View File

@@ -19,6 +19,8 @@
package org.isoron.uhabits.core.models
import org.isoron.uhabits.core.models.Score.Companion.compute
import java.util.ArrayList
import java.util.HashMap
import javax.annotation.concurrent.ThreadSafe
import kotlin.math.max
import kotlin.math.min
@@ -66,7 +68,6 @@ class ScoreList {
fun recompute(
frequency: Frequency,
isNumerical: Boolean,
skipDays: SkipDays,
numericalHabitType: NumericalHabitType,
targetValue: Double,
computedEntries: EntryList,
@@ -78,7 +79,7 @@ class ScoreList {
var numerator = frequency.numerator
var denominator = frequency.denominator
val freq = frequency.toDouble()
val values = computedEntries.getByInterval(from, to, skipDays).map { it.value }.toIntArray()
val values = computedEntries.getByInterval(from, to).map { it.value }.toIntArray()
val isAtMost = numericalHabitType == NumericalHabitType.AT_MOST
// For non-daily boolean habits, we double the numerator and the denominator to smooth
@@ -137,19 +138,4 @@ class ScoreList {
map[timestamp] = Score(timestamp, previousValue)
}
}
@Synchronized
fun combineFrom(
habitList: HabitList,
from: Timestamp,
to: Timestamp
) {
var current = to
while (current >= from) {
val habitScores = habitList.map { it.scores[current].value }
val averageScore = habitScores.average()
map[current] = Score(current, averageScore)
current = current.minus(1)
}
}
}

View File

@@ -38,13 +38,6 @@ class WeekdayList {
this.weekdays = Arrays.copyOf(weekdays, 7)
}
constructor(addDays: BooleanArray, removeDays: BooleanArray) {
weekdays = BooleanArray(7)
for (i in 0..6) {
weekdays[i] = addDays[i] && !removeDays[i]
}
}
val isEmpty: Boolean
get() {
for (d in weekdays) if (d) return false
@@ -65,10 +58,6 @@ class WeekdayList {
return packedList
}
fun isDayTrue(dayNum: Int): Boolean {
return weekdays[dayNum]
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || javaClass != other.javaClass) return false
@@ -84,6 +73,5 @@ class WeekdayList {
companion object {
val EVERY_DAY = WeekdayList(127)
val NO_DAY = WeekdayList(booleanArrayOf(false, false, false, false, false, false, false))
}
}

View File

@@ -24,7 +24,6 @@ import org.isoron.uhabits.core.database.Repository
import org.isoron.uhabits.core.models.Entry
import org.isoron.uhabits.core.models.EntryList
import org.isoron.uhabits.core.models.Frequency
import org.isoron.uhabits.core.models.SkipDays
import org.isoron.uhabits.core.models.Timestamp
import org.isoron.uhabits.core.models.sqlite.records.EntryRecord
@@ -44,13 +43,14 @@ class SQLiteEntryList(database: Database) : EntryList() {
isLoaded = true
}
override fun get(timestamp: Timestamp, skipDays: SkipDays): Entry {
override fun get(timestamp: Timestamp): Entry {
loadRecords()
return super.get(timestamp, skipDays)
return super.get(timestamp)
}
override fun getByInterval(from: Timestamp, to: Timestamp, skipDays: SkipDays): List<Entry> {
override fun getByInterval(from: Timestamp, to: Timestamp): List<Entry> {
loadRecords()
return super.getByInterval(from, to, skipDays)
return super.getByInterval(from, to)
}
override fun add(entry: Entry) {
@@ -78,7 +78,7 @@ class SQLiteEntryList(database: Database) : EntryList() {
return super.getKnown()
}
override fun recomputeFrom(originalEntries: EntryList, frequency: Frequency, isNumerical: Boolean, skipDays: SkipDays) {
override fun recomputeFrom(originalEntries: EntryList, frequency: Frequency, isNumerical: Boolean) {
throw UnsupportedOperationException()
}

View File

@@ -26,7 +26,6 @@ import org.isoron.uhabits.core.models.HabitType
import org.isoron.uhabits.core.models.NumericalHabitType
import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.models.Reminder
import org.isoron.uhabits.core.models.SkipDays
import org.isoron.uhabits.core.models.WeekdayList
import java.util.Objects.requireNonNull
@@ -50,12 +49,6 @@ class HabitRecord {
@field:Column(name = "freq_den")
var freqDen: Int? = null
@field:Column(name = "skip_days")
var skipDays: Int? = null
@field:Column(name = "skip_days_list")
var skipDaysList: Int? = null
@field:Column
var color: Int? = null
@@ -95,12 +88,6 @@ class HabitRecord {
@field:Column
var uuid: String? = null
@field:Column(name = "parent_id")
var parentID: Long? = null
@field:Column(name = "parent_uuid")
var parentUUID: String? = null
fun copyFrom(model: Habit) {
id = model.id
name = model.name
@@ -115,13 +102,9 @@ class HabitRecord {
position = model.position
question = model.question
uuid = model.uuid
parentID = model.parentID
parentUUID = model.parentUUID
val (numerator, denominator) = model.frequency
freqNum = numerator
freqDen = denominator
skipDays = if (model.skipDays.isSkipDays) 1 else 0
skipDaysList = model.skipDays.days.toInteger()
reminderDays = 0
reminderMin = null
reminderHour = null
@@ -139,7 +122,6 @@ class HabitRecord {
habit.description = description!!
habit.question = question!!
habit.frequency = Frequency(freqNum!!, freqDen!!)
habit.skipDays = SkipDays(skipDays!! == 1, WeekdayList(skipDaysList!!))
habit.color = PaletteColor(color!!)
habit.isArchived = archived != 0
habit.type = HabitType.fromInt(type!!)
@@ -148,8 +130,6 @@ class HabitRecord {
habit.unit = unit!!
habit.position = position!!
habit.uuid = uuid
habit.parentID = parentID
habit.parentUUID = parentUUID
if (reminderHour != null && reminderMin != null) {
habit.reminder = Reminder(
reminderHour!!,

View File

@@ -311,8 +311,7 @@ class HabitCardListCache @Inject constructor(
newData.scores[habit.id] = habit.scores[today].value
val list: MutableList<Int> = ArrayList()
val notes: MutableList<String> = ArrayList()
val skipDays = habit.skipDays
for ((_, value, note) in habit.computedEntries.getByInterval(dateFrom, today, skipDays)) {
for ((_, value, note) in habit.computedEntries.getByInterval(dateFrom, today)) {
list.add(value)
notes.add(note)
}

View File

@@ -20,7 +20,6 @@ package org.isoron.uhabits.core.ui.screens.habits.list
import org.isoron.uhabits.core.commands.CommandRunner
import org.isoron.uhabits.core.commands.CreateRepetitionCommand
import org.isoron.uhabits.core.models.Entry
import org.isoron.uhabits.core.models.Entry.Companion.YES_MANUAL
import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.models.HabitList
@@ -54,12 +53,10 @@ open class ListHabitsBehavior @Inject constructor(
fun onEdit(habit: Habit, timestamp: Timestamp?) {
val entry = habit.computedEntries.get(timestamp!!)
if (habit.skipDays.isDaySkipped(timestamp)) return
if (habit.type == HabitType.NUMERICAL) {
val oldValue = entry.value.toDouble() / 1000
screen.showNumberPopup(oldValue, entry.notes) { newValue: Double, newNotes: String, x: Float, y: Float ->
val value = if (habit.skipDays.isDaySkipped(timestamp)) Entry.SKIP else (newValue * 1000).roundToInt()
val value = (newValue * 1000).roundToInt()
if (newValue != oldValue) {
if (
(habit.targetType == AT_LEAST && newValue >= habit.targetValue) ||