Fix AI insights data calculations
- 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 <noreply@anthropic.com>
This commit is contained in:
@@ -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 }
|
||||
|
||||
Reference in New Issue
Block a user