Skip to content

Commit 29b7c6d

Browse files
committed
added ema for habit and average cards
1 parent b796468 commit 29b7c6d

2 files changed

Lines changed: 38 additions & 1 deletion

File tree

src/review_heatmap/activity.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ class StatsReport(NamedTuple):
9999
streak_cur: StatsEntryStreak
100100
pct_days_active: StatsEntryPercentage
101101
activity_daily_avg: StatsEntryCards
102+
habit: StatsEntryPercentage
102103

103104

104105
class ActivityReport(NamedTuple):
@@ -187,11 +188,24 @@ def _get_activity(
187188
total: int = 0
188189
idx: int = 0
189190
next_timestamp: Optional[int]
191+
MULTIPLIER = 0.5 ** (1/13)
192+
habit_ema: float = 0
193+
previous_habit_ema: float = 0
194+
avg_cur_ema: float = 0
195+
previous_avg_cur_ema: float = 0
196+
habit: int = 0
197+
avg_cur: int = 0
190198

191199
for idx, item in enumerate(history):
192200
current += 1
193201
timestamp, activity = item
194202

203+
previous_habit_ema = habit_ema
204+
habit_ema = MULTIPLIER * previous_habit_ema + (1 - MULTIPLIER)
205+
206+
previous_avg_cur_ema = avg_cur_ema
207+
avg_cur_ema = MULTIPLIER * previous_avg_cur_ema + (1 - MULTIPLIER) * activity
208+
195209
try:
196210
next_timestamp = history[idx + 1][0]
197211
except IndexError: # last item
@@ -203,6 +217,14 @@ def _get_activity(
203217
streak_max = current
204218
current = 0
205219

220+
if next_timestamp is not None:
221+
for i in range(1, (next_timestamp - timestamp) // 86400):
222+
previous_habit_ema = habit_ema
223+
habit_ema = MULTIPLIER * previous_habit_ema
224+
225+
previous_avg_cur_ema = avg_cur_ema
226+
avg_cur_ema = MULTIPLIER * previous_avg_cur_ema
227+
206228
total += activity
207229

208230
days_learned: int = idx + 1
@@ -212,9 +234,20 @@ def _get_activity(
212234
if history[-1][0] in (today, today - 86400):
213235
# last recorded date today or yesterday?
214236
streak_cur = streak_last
237+
else:
238+
for _ in range(0, (today - timestamp) // 86400):
239+
previous_habit_ema = habit_ema
240+
habit_ema = MULTIPLIER * previous_habit_ema
241+
242+
previous_avg_cur_ema = avg_cur_ema
243+
avg_cur_ema = MULTIPLIER * previous_avg_cur_ema
244+
245+
habit = round(ema)
246+
avg_cur = round(avg_cur_ema)
247+
215248

216249
# Stats: average count on days with activity
217-
avg_cur = int(round(total / max(days_learned, 1)))
250+
# avg_cur = int(round(total / max(days_learned, 1)))
218251

219252
# Stats: percentage of days with activity
220253
#
@@ -249,6 +282,7 @@ def _get_activity(
249282
streak_cur=StatsEntryStreak(value=streak_cur),
250283
pct_days_active=StatsEntryPercentage(value=pdays),
251284
activity_daily_avg=StatsEntryCards(value=avg_cur),
285+
habit=StatsEntryPercentage(value=habit),
252286
),
253287
)
254288

src/review_heatmap/web_content.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@
9898
<span class="streak-info">Daily average:</span>
9999
<span title="Average reviews on active days"
100100
class="sstats {class_activity_daily_avg}">{text_activity_daily_avg}</span>
101+
<span class="streak-info">Habit strength:</span>
102+
<span title="Exponential Moving Average of days with review activity"
103+
class="sstats {class_habit}">{text_habit}%</span>
101104
<span class="streak-info">Days learned:</span>
102105
<span title="Percentage of days with review activity over entire review history"
103106
class="sstats {class_pct_days_active}">{text_pct_days_active}%</span>

0 commit comments

Comments
 (0)