From 6c92cf4ec30ec49b41190d6fac83352a977bafc0 Mon Sep 17 00:00:00 2001 From: Trey t Date: Sat, 13 Dec 2025 10:40:50 -0600 Subject: [PATCH] Fix AI insights data calculations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Change mood scale from 0-4 to 1-5 for human-readable averages (Horrible=1, Bad=2, Average=3, Good=4, Great=5) - Fix streak calculation to check consecutive calendar days, not just consecutive entries in array - Update prompt to show /5 scale instead of /4 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- Shared/Services/MoodDataSummarizer.swift | 51 ++++++++++++++++++------ 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/Shared/Services/MoodDataSummarizer.swift b/Shared/Services/MoodDataSummarizer.swift index a02415e..85723c2 100644 --- a/Shared/Services/MoodDataSummarizer.swift +++ b/Shared/Services/MoodDataSummarizer.swift @@ -116,7 +116,8 @@ class MoodDataSummarizer { for entry in entries { let moodName = entry.mood.widgetDisplayName.lowercased() counts[moodName, default: 0] += 1 - totalScore += Int(entry.moodValue) + // Use 1-5 scale (add 1 to raw 0-4 values) for human-readable averages + totalScore += Int(entry.moodValue) + 1 } var percentages: [String: Int] = [:] @@ -138,14 +139,15 @@ class MoodDataSummarizer { for entry in entries { let weekday = Int(entry.weekDay) let current = weekdayTotals[weekday, default: (0, 0)] - weekdayTotals[weekday] = (current.total + Int(entry.moodValue), current.count + 1) + // Use 1-5 scale (add 1 to raw 0-4 values) + weekdayTotals[weekday] = (current.total + Int(entry.moodValue) + 1, current.count + 1) } var weekdayAverages: [String: Double] = [:] var bestDay = "Monday" var worstDay = "Monday" var bestAvg = -1.0 - var worstAvg = 5.0 + var worstAvg = 6.0 for (weekday, data) in weekdayTotals { let avg = Double(data.total) / Double(data.count) @@ -162,12 +164,12 @@ class MoodDataSummarizer { } } - // Weekend vs weekday + // Weekend vs weekday (use 1-5 scale) let weekendEntries = entries.filter { [1, 7].contains(Int($0.weekDay)) } let weekdayEntries = entries.filter { ![1, 7].contains(Int($0.weekDay)) } - let weekendAvg = weekendEntries.isEmpty ? 0 : Double(weekendEntries.reduce(0) { $0 + Int($1.moodValue) }) / Double(weekendEntries.count) - let weekdayAvg = weekdayEntries.isEmpty ? 0 : Double(weekdayEntries.reduce(0) { $0 + Int($1.moodValue) }) / Double(weekdayEntries.count) + let weekendAvg = weekendEntries.isEmpty ? 0 : Double(weekendEntries.reduce(0) { $0 + Int($1.moodValue) + 1 }) / Double(weekendEntries.count) + let weekdayAvg = weekdayEntries.isEmpty ? 0 : Double(weekdayEntries.reduce(0) { $0 + Int($1.moodValue) + 1 }) / Double(weekdayEntries.count) return (weekdayAverages, weekendAvg, weekdayAvg, bestDay, worstDay) } @@ -183,8 +185,9 @@ class MoodDataSummarizer { let firstHalf = Array(entries.prefix(halfCount)) let secondHalf = Array(entries.suffix(halfCount)) - let firstAvg = Double(firstHalf.reduce(0) { $0 + Int($1.moodValue) }) / Double(firstHalf.count) - let secondAvg = Double(secondHalf.reduce(0) { $0 + Int($1.moodValue) }) / Double(secondHalf.count) + // Use 1-5 scale + let firstAvg = Double(firstHalf.reduce(0) { $0 + Int($1.moodValue) + 1 }) / Double(firstHalf.count) + let secondAvg = Double(secondHalf.reduce(0) { $0 + Int($1.moodValue) + 1 }) / Double(secondHalf.count) let diff = secondAvg - firstAvg @@ -252,16 +255,39 @@ class MoodDataSummarizer { } private func calculateMoodStreak(entries: [MoodEntryModel], moods: [Mood]) -> Int { + guard !entries.isEmpty else { return 0 } + + // Sort by date to ensure proper ordering + let sortedEntries = entries.sorted { $0.forDate < $1.forDate } + var longest = 0 var current = 0 + var previousDate: Date? + + for entry in sortedEntries { + let entryDate = calendar.startOfDay(for: entry.forDate) + + // Check if this is a consecutive calendar day from the previous entry + let isConsecutive: Bool + if let prevDate = previousDate { + let dayDiff = calendar.dateComponents([.day], from: prevDate, to: entryDate).day ?? 0 + isConsecutive = dayDiff == 1 + } else { + isConsecutive = true // First entry starts a potential streak + } - for entry in entries { if moods.contains(entry.mood) { - current += 1 + if isConsecutive || previousDate == nil { + current += 1 + } else { + current = 1 // Reset to 1 (this entry starts new streak) + } longest = max(longest, current) } else { current = 0 } + + previousDate = entryDate } return longest @@ -297,7 +323,8 @@ class MoodDataSummarizer { return (0, []) } - let average = Double(recentEntries.reduce(0) { $0 + Int($1.moodValue) }) / Double(recentEntries.count) + // Use 1-5 scale + let average = Double(recentEntries.reduce(0) { $0 + Int($1.moodValue) + 1 }) / Double(recentEntries.count) let moods = recentEntries.map { $0.mood.widgetDisplayName } return (average, moods) @@ -363,7 +390,7 @@ class MoodDataSummarizer { // Compact format to stay under token limit var lines: [String] = [] - lines.append("Period: \(summary.periodName), \(summary.totalEntries) entries, avg \(String(format: "%.1f", summary.averageMoodScore))/4") + lines.append("Period: \(summary.periodName), \(summary.totalEntries) entries, avg \(String(format: "%.1f", summary.averageMoodScore))/5") // Mood distribution - compact let moodDist = summary.moodPercentages.sorted { $0.key < $1.key }