Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 35 additions & 1 deletion src/review_heatmap/activity.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class StatsReport(NamedTuple):
streak_cur: StatsEntryStreak
pct_days_active: StatsEntryPercentage
activity_daily_avg: StatsEntryCards
habit: StatsEntryPercentage


class ActivityReport(NamedTuple):
Expand Down Expand Up @@ -187,11 +188,24 @@ def _get_activity(
total: int = 0
idx: int = 0
next_timestamp: Optional[int]
MULTIPLIER = 0.5 ** (1/13)
habit_ema: float = 0
previous_habit_ema: float = 0
avg_cur_ema: float = 0
previous_avg_cur_ema: float = 0
habit: int = 0
avg_cur: int = 0

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

previous_habit_ema = habit_ema
habit_ema = MULTIPLIER * previous_habit_ema + (1 - MULTIPLIER)

previous_avg_cur_ema = avg_cur_ema
avg_cur_ema = MULTIPLIER * previous_avg_cur_ema + (1 - MULTIPLIER) * activity

try:
next_timestamp = history[idx + 1][0]
except IndexError: # last item
Expand All @@ -203,6 +217,14 @@ def _get_activity(
streak_max = current
current = 0

if next_timestamp is not None:
for i in range(1, (next_timestamp - timestamp) // 86400):
previous_habit_ema = habit_ema
habit_ema = MULTIPLIER * previous_habit_ema

previous_avg_cur_ema = avg_cur_ema
avg_cur_ema = MULTIPLIER * previous_avg_cur_ema

total += activity

days_learned: int = idx + 1
Expand All @@ -212,9 +234,20 @@ def _get_activity(
if history[-1][0] in (today, today - 86400):
# last recorded date today or yesterday?
streak_cur = streak_last
else:
for _ in range(0, (today - timestamp) // 86400):
previous_habit_ema = habit_ema
habit_ema = MULTIPLIER * previous_habit_ema

previous_avg_cur_ema = avg_cur_ema
avg_cur_ema = MULTIPLIER * previous_avg_cur_ema

habit = round(habit_ema * 100)
avg_cur = round(avg_cur_ema)


# Stats: average count on days with activity
avg_cur = int(round(total / max(days_learned, 1)))
# avg_cur = int(round(total / max(days_learned, 1)))

# Stats: percentage of days with activity
#
Expand Down Expand Up @@ -249,6 +282,7 @@ def _get_activity(
streak_cur=StatsEntryStreak(value=streak_cur),
pct_days_active=StatsEntryPercentage(value=pdays),
activity_daily_avg=StatsEntryCards(value=avg_cur),
habit=StatsEntryPercentage(value=habit),
),
)

Expand Down
3 changes: 3 additions & 0 deletions src/review_heatmap/web_content.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@
<span class="streak-info">Daily average:</span>
<span title="Average reviews on active days"
class="sstats {class_activity_daily_avg}">{text_activity_daily_avg}</span>
<span class="streak-info">Habit strength:</span>
<span title="Exponential Moving Average of days with review activity"
class="sstats {class_habit}">{text_habit}%</span>
<span class="streak-info">Days learned:</span>
<span title="Percentage of days with review activity over entire review history"
class="sstats {class_pct_days_active}">{text_pct_days_active}%</span>
Expand Down