From 22a72d82c6927a53a6a790761dc8e559bad199ba Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Fri, 18 Mar 2011 11:01:26 +0900 Subject: [PATCH] give card types a more logical order they are now 0=new, 1=learning, 2=due, to reflect the natural progression --- anki/cards.py | 10 ++++----- anki/deck.py | 2 +- anki/sched.py | 49 ++++++++++++++++++++-------------------- tests/test_sched.py | 54 +++++++++++++++++++++++---------------------- 4 files changed, 58 insertions(+), 57 deletions(-) diff --git a/anki/cards.py b/anki/cards.py index 6fed4f948..f403c9945 100644 --- a/anki/cards.py +++ b/anki/cards.py @@ -10,9 +10,9 @@ MAX_TIMER = 60 # Cards ########################################################################## -# Type: 0=learning, 1=due, 2=new -# Queue: 0=learning, 1=due, 2=new -# -1=suspended, -2=user buried, -3=sched buried +# Type: 0=new, 1=learning, 2=due +# Queue: same as above, and: +# -1=suspended, -2=user buried, -3=sched buried, -4=deleted # Due is used differently for different queues. # - new queue: fact id or random int # - rev queue: integer day @@ -32,8 +32,8 @@ class Card(object): self.id = None self.gid = 1 self.crt = intTime() - self.type = 2 - self.queue = 2 + self.type = 0 + self.queue = 0 self.ivl = 0 self.factor = 0 self.reps = 0 diff --git a/anki/deck.py b/anki/deck.py index 71598c00f..d8f750949 100644 --- a/anki/deck.py +++ b/anki/deck.py @@ -256,7 +256,7 @@ select id from facts where id not in (select distinct fid from cards)""") if self.qconf['newCardOrder'] == NEW_CARDS_RANDOM: # if this fact has existing new cards, use their due time due = self.db.scalar( - "select due from cards where fid = ? and queue = 2", fact.id) + "select due from cards where fid = ? and queue = 0", fact.id) due = due or random.randrange(1, 1000000) else: due = fact.id diff --git a/anki/sched.py b/anki/sched.py index 98a1583bf..9961da377 100644 --- a/anki/sched.py +++ b/anki/sched.py @@ -42,13 +42,12 @@ class Scheduler(object): def answerCard(self, card, ease): if card.queue == 0: - self._answerLearnCard(card, ease) - elif card.queue == 1: - self._answerRevCard(card, ease) - elif card.queue == 2: # put it in the learn queue - card.queue = 0 + card.queue = 1 + if card.queue == 1: self._answerLearnCard(card, ease) + elif card.queue == 2: + self._answerRevCard(card, ease) else: raise Exception("Invalid queue") card.mod = intTime() @@ -56,7 +55,7 @@ class Scheduler(object): def counts(self): "Does not include fetched but unanswered." - return (self.learnCount, self.revCount, self.newCount) + return (self.newCount, self.learnCount, self.revCount) def cardQueue(self, card): return card.queue @@ -110,14 +109,14 @@ class Scheduler(object): else: self.newCount = self.db.scalar(""" select count() from (select id from cards where -queue = 2 %s limit %d)""" % (self._groupLimit('new'), lim)) +queue = 0 %s limit %d)""" % (self._groupLimit('new'), lim)) def _resetNew(self): self._resetNewCount() lim = min(self.queueLimit, self.newCount) self.newQueue = self.db.all(""" select id, due from cards where -queue = 2 %s order by due limit %d""" % (self._groupLimit('new'), +queue = 0 %s order by due limit %d""" % (self._groupLimit('new'), lim)) self.newQueue.reverse() self._updateNewCardRatio() @@ -159,14 +158,14 @@ queue = 2 %s order by due limit %d""" % (self._groupLimit('new'), def _resetLearnCount(self): self.learnCount = self.db.scalar( - "select count() from cards where queue = 0 and due < ?", + "select count() from cards where queue = 1 and due < ?", intTime() + self.deck.qconf['collapseTime']) def _resetLearn(self): self._resetLearnCount() self.learnQueue = self.db.all(""" select due, id from cards where -queue = 0 and due < :lim order by due +queue = 1 and due < :lim order by due limit %d""" % self.reportLimit, lim=self.dayCutoff) def _getLearnCard(self, collapse=False): @@ -208,18 +207,18 @@ limit %d""" % self.reportLimit, lim=self.dayCutoff) def _learnConf(self, card): conf = self._cardConf(card) if card.type == 2: - return conf['new'] - else: return conf['lapse'] + else: + return conf['new'] def _rescheduleAsReview(self, card, conf, early): - if card.type == 1: + if card.type == 2: # failed; put back entry due card.due = card.edue else: self._rescheduleNew(card, conf, early) - card.queue = 1 - card.type = 1 + card.queue = 2 + card.type = 2 def _graduatingIvl(self, card, conf, early): if not early: @@ -258,8 +257,8 @@ limit %d""" % self.reportLimit, lim=self.dayCutoff) "Remove failed cards from the learning queue." self.deck.db.execute(""" update cards set -due = edue, queue = 1 -where queue = 0 and type = 1 +due = edue, queue = 2 +where queue = 1 and type = 2 """) # Reviews @@ -268,7 +267,7 @@ where queue = 0 and type = 1 def _resetReviewCount(self): self.revCount = self.db.scalar(""" select count() from (select id from cards where -queue = 1 %s and due <= :lim limit %d)""" % ( +queue = 2 %s and due <= :lim limit %d)""" % ( self._groupLimit("rev"), self.reportLimit), lim=self.today) @@ -276,7 +275,7 @@ queue = 1 %s and due <= :lim limit %d)""" % ( self._resetReviewCount() self.revQueue = self.db.list(""" select id from cards where -queue = 1 %s and due <= :lim order by %s limit %d""" % ( +queue = 2 %s and due <= :lim order by %s limit %d""" % ( self._groupLimit("rev"), self._revOrder(), self.queueLimit), lim=self.today) if self.deck.qconf['revCardOrder'] == REV_CARDS_RANDOM: @@ -321,7 +320,7 @@ queue = 1 %s and due <= :lim order by %s limit %d""" % ( card.due = card.edue = self.today + card.ivl # put back in the learn queue? if conf['relearn']: - card.queue = 0 + card.queue = 1 self.learnCount += 1 # leech? self._checkLeech(card, conf) @@ -382,7 +381,7 @@ queue = 1 %s and due <= :lim order by %s limit %d""" % ( conf = self._cardConf(card)['rev'] # find sibling positions dues = self.db.list( - "select due from cards where fid = ? and queue = 1" + "select due from cards where fid = ? and queue = 2" " and id != ?", card.fid, card.id) if not dues or idealDue not in dues: card.ivl = idealIvl @@ -508,13 +507,13 @@ queue = 1 %s and due <= :lim order by %s limit %d""" % ( def lrnTomorrow(self): "Number of cards in the learning queue due tomorrow." return self.db.scalar( - "select count() from cards where queue = 0 and due < ?", + "select count() from cards where queue = 1 and due < ?", self.dayCutoff+86400) def revTomorrow(self): "Number of reviews due tomorrow." return self.db.scalar( - "select count() from cards where queue = 1 and due = ?"+ + "select count() from cards where queue = 2 and due = ?"+ self._groupLimit("rev"), self.today+1) @@ -523,7 +522,7 @@ queue = 1 %s and due <= :lim order by %s limit %d""" % ( lim = self.deck.qconf['newPerDay'] return self.db.scalar( "select count() from (select id from cards where " - "queue = 2 limit %d)" % lim) + "queue = 0 limit %d)" % lim) # Next time reports ########################################################################## @@ -535,7 +534,7 @@ queue = 1 %s and due <= :lim order by %s limit %d""" % ( def nextIvl(self, card, ease): "Return the next interval for CARD, in seconds." - if card.queue in (0,2): + if card.queue in (0,1): # in learning return self._nextLrnIvl(card, ease) elif ease == 1: diff --git a/tests/test_sched.py b/tests/test_sched.py index a17fc8c18..69bbd7d9a 100644 --- a/tests/test_sched.py +++ b/tests/test_sched.py @@ -22,13 +22,13 @@ def test_new(): # fetch it c = d.sched.getCard() assert c - assert c.queue == 2 - assert c.type == 2 + assert c.queue == 0 + assert c.type == 0 # if we answer it, it should become a learn card t = intTime() d.sched.answerCard(c, 1) - assert c.queue == 0 - assert c.type == 2 + assert c.queue == 1 + assert c.type == 0 assert c.due >= t # the default order should ensure siblings are not seen together, and # should show all cards @@ -55,7 +55,7 @@ def test_learn(): f['Front'] = u"one"; f['Back'] = u"two" f = d.addFact(f) # set as a learn card and rebuild queues - d.db.execute("update cards set queue=0, type=2") + d.db.execute("update cards set queue=0, type=0") d.reset() # sched.getCard should return it, since it's due in the past c = d.sched.getCard() @@ -90,46 +90,47 @@ def test_learn(): assert c.grade == 2 assert c.cycles == 3 # the next pass should graduate the card - assert c.queue == 0 - assert c.type == 2 - d.sched.answerCard(c, 2) assert c.queue == 1 - assert c.type == 1 + assert c.type == 0 + d.sched.answerCard(c, 2) + assert c.queue == 2 + assert c.type == 2 # should be due tomorrow, with an interval of 1 assert c.due == d.sched.today+1 assert c.ivl == 1 # let's try early removal bonus - c.type = 2 - c.queue = 0 + c.type = 0 + c.queue = 1 c.cycles = 0 d.sched.answerCard(c, 3) - assert c.type == 1 + assert c.type == 2 assert c.ivl == 7 # or normal removal - c.type = 2 - c.queue = 0 + c.type = 0 + c.queue = 1 c.cycles = 1 d.sched.answerCard(c, 3) - assert c.type == 1 + assert c.type == 2 + assert c.queue == 2 assert c.ivl == 4 # revlog should have been updated each time d.db.scalar("select count() from revlog where type = 0") == 6 # now failed card handling - c.type = 1 - c.queue = 0 + c.type = 2 + c.queue = 1 c.edue = 123 d.sched.answerCard(c, 3) assert c.due == 123 - assert c.type == 1 - assert c.queue == 1 + assert c.type == 2 + assert c.queue == 2 # we should be able to remove manually, too - c.type = 1 - c.queue = 0 + c.type = 2 + c.queue = 1 c.edue = 321 c.flush() d.sched.removeFailed() c.load() - assert c.queue == 1 + assert c.queue == 2 assert c.due == 321 def test_reviews(): @@ -140,8 +141,8 @@ def test_reviews(): d.addFact(f) # set the card up as a review card, due yesterday c = f.cards()[0] - c.type = 1 - c.queue = 1 + c.type = 2 + c.queue = 2 c.due = d.sched.today - 8 c.factor = 2500 c.reps = 3 @@ -156,7 +157,7 @@ def test_reviews(): # failing it should put it in the learn queue with the default options ################################################## d.sched.answerCard(c, 1) - assert c.queue == 0 + assert c.queue == 1 # it should be due tomorrow, with an interval of 1 assert c.due == d.sched.today + 1 assert c.ivl == 1 @@ -171,6 +172,7 @@ def test_reviews(): c = copy.copy(cardcopy) c.flush() d.sched.answerCard(c, 2) + assert c.queue == 2 # the new interval should be (100 + 8/4) * 1.2 = 122 assert c.ivl == 122 assert c.due == d.sched.today + 122 @@ -257,7 +259,7 @@ def test_nextIvl(): assert ni(c, 3) == 4*86400 # review cards ################################################## - c.queue = 1 + c.queue = 2 c.ivl = 100 c.factor = 2500 # failing it puts it at tomorrow