diff --git a/stats.py b/stats.py index 6e38de8..0ac24aa 100644 --- a/stats.py +++ b/stats.py @@ -116,6 +116,7 @@ def get_steps_stats(self: CollectionStats): span.hard { color: #ff8c00 } span.good { color: #008000 } span.again-then-good { color: #fdd835 } + span.good-then-again { color: #007bff } @@ -136,7 +137,14 @@ def get_steps_stats(self: CollectionStats): """ - ratings = {1: "again", 2: "hard", 3: "good", 4: "again-then-good", 0: "lapse"} + ratings = { + 1: "again", + 2: "hard", + 3: "good", + 4: "again-then-good", + 5: "good-then-again", + 0: "lapse", + } for rating, style in ratings.items(): stats = results["stats"].get(rating, {}) if not stats: diff --git a/steps.py b/steps.py index fc79b7c..df3c7e8 100644 --- a/steps.py +++ b/steps.py @@ -97,10 +97,50 @@ def steps_stats(deck_lim, period_lim): ) SELECT delta_t, recall FROM review_stats - WHERE first_rating = 1 AND second_rating = 3 + WHERE second_rating = 3 ORDER BY delta_t """ - learning_next_revlogs = mw.col.db.all(sql) + again_then_good_revlogs = mw.col.db.all(sql) + sql = f""" + WITH first_review AS ( + SELECT cid, MIN(id) AS first_id, ease AS first_rating + FROM revlog + WHERE ease BETWEEN 1 AND 4 + {"AND " + deck_lim if deck_lim else ""} + GROUP BY cid + HAVING first_rating = 3 + {"AND " + period_lim if period_lim else ""} + ), + second_review AS ( + SELECT r.cid, r.id AS second_id, r.ease AS second_rating, + ROW_NUMBER() OVER (PARTITION BY r.cid ORDER BY r.id) AS review_order + FROM revlog r + JOIN first_review fr ON r.cid = fr.cid AND r.id > fr.first_id + WHERE r.ease BETWEEN 1 AND 4 + ), + third_review AS ( + SELECT r.cid, r.id AS third_id, CASE WHEN r.ease=1 THEN 0 ELSE 1 END AS recall, + ROW_NUMBER() OVER (PARTITION BY r.cid ORDER BY r.id) AS review_order + FROM revlog r + JOIN second_review sr ON r.cid = sr.cid AND r.id > sr.second_id + WHERE r.ease BETWEEN 1 AND 4 + ), + review_stats AS ( + SELECT fr.first_rating, + sr.second_rating, + (tr.third_id - sr.second_id) / 1000.0 AS delta_t, + tr.recall + FROM first_review fr + JOIN second_review sr ON fr.cid = sr.cid + JOIN third_review tr ON sr.cid = tr.cid + WHERE sr.review_order = 1 AND tr.review_order = 1 + ) + SELECT delta_t, recall + FROM review_stats + WHERE second_rating = 1 + ORDER BY delta_t + """ + good_then_again_revlogs = mw.col.db.all(sql) sql = f""" WITH first_fail AS ( SELECT cid, id AS first_id @@ -143,10 +183,14 @@ def steps_stats(deck_lim, period_lim): for delta_t, recall in relearning_revlogs: stats_dict[0].append((delta_t, recall)) - if len(learning_next_revlogs) > 0: - for delta_t, recall in learning_next_revlogs: + if len(again_then_good_revlogs) > 0: + for delta_t, recall in again_then_good_revlogs: stats_dict[4].append((delta_t, recall)) + if len(good_then_again_revlogs) > 0: + for delta_t, recall in good_then_again_revlogs: + stats_dict[5].append((delta_t, recall)) + display_dict = {} # Calculate median delta_t and mean recall for each first_rating
Reviews