From 751cb7df674815ba14d7b717326766f82daa53d8 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Wed, 7 Sep 2011 19:11:37 +0900 Subject: [PATCH] add a new default for counts() As per the forum thread, the current due counts are really demotivating when there's a backlog of cards. In attempt to solve this, I'm trying out a new behaviour as the default: instead of reporting all the due cards including the backlog, the status bar will show an increasing count of cards studied that day. Theoretically this should allow users to focus on what they've done rather than what they have to do. The old behaviour is still there as an option. --- anki/consts.py | 4 ++++ anki/deck.py | 1 + anki/sched.py | 18 ++++++++++------- tests/test_deck.py | 2 ++ tests/test_sched.py | 47 +++++++++++++++++++++++++++++++++++++++++++-- tests/test_undo.py | 3 +++ 6 files changed, 66 insertions(+), 9 deletions(-) diff --git a/anki/consts.py b/anki/consts.py index 4dbdcbacb..d6d0a2957 100644 --- a/anki/consts.py +++ b/anki/consts.py @@ -24,6 +24,10 @@ REV_CARDS_RANDOM = 2 REM_CARD = 0 REM_FACT = 1 +# count display +COUNT_ANSWERED = 0 +COUNT_REMAINING = 1 + # Labels ########################################################################## diff --git a/anki/deck.py b/anki/deck.py index 32a080980..2c0ddffe6 100644 --- a/anki/deck.py +++ b/anki/deck.py @@ -24,6 +24,7 @@ defaultConf = { 'topGroup': 1, 'curGroup': None, 'revOrder': REV_CARDS_RANDOM, + 'counts': COUNT_ANSWERED, # other config 'nextPos': 1, 'fontFamilies': [ diff --git a/anki/sched.py b/anki/sched.py index 84a531a2c..dd7aa79ef 100644 --- a/anki/sched.py +++ b/anki/sched.py @@ -66,7 +66,14 @@ class Scheduler(object): def counts(self): "Does not include fetched but unanswered." - return (self.newCount, self.lrnCount, self.revCount) + if self.deck.conf['counts'] == COUNT_REMAINING: + return (self.newCount, self.lrnCount, self.revCount) + else: + return self.answeredCounts() + + def answeredCounts(self): + t = self.deck.groups.top() + return (t['newToday'][1], t['lrnToday'][1], t['revToday'][1]) def dueForecast(self, days=7): "Return counts over next DAYS. Includes today." @@ -726,15 +733,12 @@ queue = 2 %s and due <= :lim order by %s limit %d""" % ( def timeToday(self): "Time spent learning today, in seconds." - return self.deck.db.scalar( - "select sum(time/1000.0) from revlog where id > ?*1000", - self.dayCutoff-86400) or 0 + t = self.deck.groups.top() + return t['timeToday'][1] / 1000 def repsToday(self): "Number of cards answered today." - return self.deck.db.scalar( - "select count() from revlog where id > ?*1000", - self.dayCutoff-86400) + return sum(self.answeredCounts()) # Dynamic indices ########################################################################## diff --git a/tests/test_deck.py b/tests/test_deck.py index 3a21e256d..042919b2e 100644 --- a/tests/test_deck.py +++ b/tests/test_deck.py @@ -3,6 +3,7 @@ import os, re, datetime from tests.shared import assertException, getEmptyDeck, testDir from anki.stdmodels import addBasicModel +from anki.consts import * from anki import Deck @@ -126,6 +127,7 @@ def test_upgrade(): d = datetime.datetime.fromtimestamp(deck.crt) assert d.hour == 4 and d.minute == 0 # 3 new, 2 failed, 1 due + deck.conf['counts'] = COUNT_REMAINING assert deck.sched.counts() == (3,2,1) # now's a good time to test the integrity check too deck.fixIntegrity() diff --git a/tests/test_sched.py b/tests/test_sched.py index 502431c53..1c843d2ef 100644 --- a/tests/test_sched.py +++ b/tests/test_sched.py @@ -4,6 +4,7 @@ import time, copy from tests.shared import assertException, getEmptyDeck from anki.utils import stripHTML, intTime from anki.hooks import addHook +from anki.consts import * def test_basics(): d = getEmptyDeck() @@ -578,8 +579,47 @@ def test_ordcycle(): assert d.sched.getCard().ord == 1 assert d.sched.getCard().ord == 2 -def test_counts(): +def test_counts_up(): d = getEmptyDeck() + # for each card type + for type in range(3): + # create a new fact + f = d.newFact() + f['Front'] = u"one" + d.addFact(f) + c = f.cards()[0] + # set type/gid + c.type = type + c.queue = type + c.due = 0 + c.flush() + d.reset() + # all zeros first + assert d.sched.counts() == (0,0,0) + # answer the first card, which is a lrn one + c = d.sched.getCard() + assert c.queue == 1 + d.sched.answerCard(c, 4) + assert d.sched.counts() == (0,1,0) + # and the next, which is a rev card + c = d.sched.getCard() + assert c.queue == 2 + d.sched.answerCard(c, 4) + assert d.sched.counts() == (0,1,1) + # and the last, which is a new one + c = d.sched.getCard() + assert c.queue == 0 + d.sched.answerCard(c, 4) + assert d.sched.counts() == (1,1,1) + # total should match + assert d.sched.repsToday() == 3 + # the time should have been updated as well, but it gets rounded to zero + # in the test so we need to grab it manually + assert d.groups.top()['timeToday'][1] + +def test_counts_down(): + d = getEmptyDeck() + d.conf['counts'] = COUNT_REMAINING # add a second group grp = d.groups.id("new group") # for each card type @@ -605,8 +645,9 @@ def test_counts(): d.reset() assert d.sched.counts() == (1,1,1) -def test_counts2(): +def test_counts_idx(): d = getEmptyDeck() + d.conf['counts'] = COUNT_REMAINING f = d.newFact() f['Front'] = u"one"; f['Back'] = u"two" d.addFact(f) @@ -669,6 +710,7 @@ def test_collapse(): def test_groupCounts(): d = getEmptyDeck() + d.conf['counts'] = COUNT_REMAINING # add a fact with default group f = d.newFact() f['Front'] = u"one" @@ -754,6 +796,7 @@ def test_reorder(): def test_forget(): d = getEmptyDeck() + d.conf['counts'] = COUNT_REMAINING f = d.newFact() f['Front'] = u"one" d.addFact(f) diff --git a/tests/test_undo.py b/tests/test_undo.py index 8150d7ebe..9400f971f 100644 --- a/tests/test_undo.py +++ b/tests/test_undo.py @@ -2,6 +2,8 @@ import time from tests.shared import assertException, getEmptyDeck +from anki.consts import * + def test_op(): d = getEmptyDeck() # should have no undo by default @@ -35,6 +37,7 @@ def test_op(): def test_review(): d = getEmptyDeck() + d.conf['counts'] = COUNT_REMAINING f = d.newFact() f['Front'] = u"one" d.addFact(f)