From 31427f0133e0576c90e760aaaa92cb11657307ac Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Thu, 24 Mar 2011 08:04:04 +0900 Subject: [PATCH] fix lapse card scheduling - make sure we set a timestamp due time, and put the card back in the queue - add a unit test for it --- anki/groups.py | 4 ---- anki/sched.py | 5 ++++- tests/test_sched.py | 32 ++++++++++++++++++++++++++++++-- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/anki/groups.py b/anki/groups.py index a69b8c73f..cb294b192 100644 --- a/anki/groups.py +++ b/anki/groups.py @@ -5,10 +5,6 @@ import simplejson from anki.utils import intTime -# maybe define a random cutoff at say +/-30% which controls exit interval -# variation - 30% of 1 day is 0.7 or 1.3 so always 1 day; 30% of 4 days is -# 2.8-5.2, so any time from 3-5 days is acceptable - defaultConf = { 'new': { 'delays': [0.5, 3, 10], diff --git a/anki/sched.py b/anki/sched.py index 866e809ab..1fb25f905 100644 --- a/anki/sched.py +++ b/anki/sched.py @@ -354,11 +354,14 @@ queue = 2 %s and due <= :lim order by %s limit %d""" % ( card.lastIvl = card.ivl card.ivl = self._nextLapseIvl(card, conf) card.factor = max(1300, card.factor-200) - card.due = card.edue = self.today + card.ivl + card.due = self.today + card.ivl # put back in the learn queue? if conf['relearn']: + card.edue = card.due + card.due = int(self._delayForGrade(conf, 0) + time.time()) card.queue = 1 self.lrnCount += 1 + heappush(self.lrnQueue, (card.due, card.id)) # leech? self._checkLeech(card, conf) diff --git a/tests/test_sched.py b/tests/test_sched.py index 71a05cd14..a3a33f7f0 100644 --- a/tests/test_sched.py +++ b/tests/test_sched.py @@ -158,8 +158,11 @@ def test_reviews(): d.sched.answerCard(c, 1) assert c.queue == 1 # it should be due tomorrow, with an interval of 1 - assert c.due == d.sched.today + 1 + assert c.edue == d.sched.today + 1 assert c.ivl == 1 + # but because it's in the learn queue, its current due time should be in + # the future + assert c.due >= time.time() # factor should have been decremented assert c.factor == 2300 # check counters @@ -364,7 +367,6 @@ def test_cram(): d.sched.answerCard(c, 1) # graduating the card will keep the same interval, but shift the card # forward the number of days it had been waiting (75) - print d.sched.nextIvl(c, 3) assert d.sched.nextIvl(c, 3) == 75*86400 d.sched.answerCard(c, 3) assert c.ivl == 100 @@ -541,3 +543,29 @@ def test_counts(): assert d.sched.allCounts() == (2,2,2) assert d.sched.selCounts() == (1,2,1) assert d.sched.allCounts() == (2,2,2) + +def test_timing(): + d = getEmptyDeck() + # add a few review cards, due today + for i in range(5): + f = d.newFact() + f['Front'] = "num"+str(i) + d.addFact(f) + c = f.cards()[0] + c.type = 2 + c.queue = 2 + c.due = 0 + c.flush() + # fail the first one + d.reset() + c = d.sched.getCard() + # set a a fail delay of 1 second so we don't have to wait + d.sched._cardConf(c)['lapse']['delays'][0] = 1/60.0 + d.sched.answerCard(c, 1) + # the next card should be another review + c = d.sched.getCard() + assert c.queue == 2 + # but if we wait for a second, the failed card should come back + time.sleep(1) + c = d.sched.getCard() + assert c.queue == 1