From 0df95eafc0b5629f95d3b402a0d0a871f763bf38 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Tue, 19 Apr 2011 13:00:51 +0900 Subject: [PATCH] revlog updates - use negative numbers to denote second intervals - record the rev ivl when leaving lrn queue - improve revlog upgrade - don't truncate precision when recording time taken --- anki/cards.py | 2 +- anki/sched.py | 13 ++++++++----- anki/stats.py | 5 ++--- anki/storage.py | 28 +++++++++++++++++++--------- tests/test_sched.py | 4 ++-- 5 files changed, 32 insertions(+), 20 deletions(-) diff --git a/anki/cards.py b/anki/cards.py index 80a8173c5..90c9d6b74 100644 --- a/anki/cards.py +++ b/anki/cards.py @@ -143,4 +143,4 @@ lapses=?, grade=?, cycles=?, edue=? where id = ?""", def timeTaken(self): "Time taken to answer card, in integer MS." - return int(time.time() - self.timerStarted)*1000 + return int((time.time() - self.timerStarted)*1000) diff --git a/anki/sched.py b/anki/sched.py index 8573e2b6e..c57a2047a 100644 --- a/anki/sched.py +++ b/anki/sched.py @@ -13,6 +13,10 @@ from anki.hooks import runHook # fixme: on upgrade cards are ordered but order defaults to random +# revlog: +# types: 0=lrn, 1=rev, 2=relrn, 3=cram, 4=resched +# positive intervals are in days (rev), negative intervals in seconds (lrn) + # the standard Anki scheduler class Scheduler(object): name = "std" @@ -359,15 +363,14 @@ limit %d""" % (self._groupLimit(), self.reportLimit), lim=self.dayCutoff) def _logLrn(self, card, ease, conf, leaving, type): # limit time taken to global setting taken = min(card.timeTaken(), self._cardConf(card)['maxTaken']*1000) + lastIvl = -(self._delayForGrade(conf, max(0, card.grade-1))) + ivl = card.ivl if leaving else -(self._delayForGrade(conf, card.grade)) def log(): self.deck.db.execute( "insert into revlog values (?,?,?,?,?,?,?,?,?)", int(time.time()*1000), card.id, ease, card.cycles, - # interval - self._delayForGrade(conf, card.grade), - # last interval - self._delayForGrade(conf, max(0, card.grade-1)), - leaving, taken, type) + ivl, lastIvl, + card.factor, taken, type) try: log() except: diff --git a/anki/stats.py b/anki/stats.py index f4fee7403..adf2ce1a5 100644 --- a/anki/stats.py +++ b/anki/stats.py @@ -64,14 +64,13 @@ class CardStats(object): def date(self, tm): return time.strftime("%Y-%m-%d", time.localtime(tm)) - s = anki.utils.fmtTimeSpan(time.time() - tm) - return _("%s ago") % s def time(self, tm): str = "" if tm >= 60: str = fmtTimeSpan((tm/60)*60, short=True, point=-1, unit=1) - str += fmtTimeSpan(tm%60, short=True) + if tm%60 != 0 or not str: + str += fmtTimeSpan(tm%60, point=2 if not str else -1, short=True) return str # Deck stats diff --git a/anki/storage.py b/anki/storage.py index 2630cb776..0f003494f 100644 --- a/anki/storage.py +++ b/anki/storage.py @@ -329,7 +329,7 @@ select cast(time*1000 as int), cardId, ease, reps, cast(nextInterval as int), cast(lastInterval as int), cast(nextFactor*1000 as int), cast(min(thinkingTime, 60)*1000 as int), -1 from reviewHistory"""): +yesCount from reviewHistory"""): row = list(row) # new card ids try: @@ -339,15 +339,25 @@ cast(nextFactor*1000 as int), cast(min(thinkingTime, 60)*1000 as int), continue # no ease 0 anymore row[2] = row[2] or 1 - if row[3] == 1: - # initial rep; set type=lrn - row[8] = 0 - elif row[2] == 1 and row[5] >= 3: - # lapsed card + # determine type, overwriting yesCount + reps = row[3] + newInt = row[4] + oldInt = row[5] + yesCnt = row[8] + # yesCnt included the current answer + if row[2] > 1: + yesCnt -= 1 + if oldInt < 1: + # new or failed + if yesCnt: + # type=relrn + row[8] = 2 + else: + # type=lrn + row[8] = 0 + else: + # type=rev row[8] = 1 - elif row[4] < 3: - # low interval; set type=relrn - row[8] = 2 r.append(row) db.executemany( "insert or ignore into revlog values (?,?,?,?,?,?,?,?,?)", r) diff --git a/tests/test_sched.py b/tests/test_sched.py index 2167343b4..31421fa2e 100644 --- a/tests/test_sched.py +++ b/tests/test_sched.py @@ -81,8 +81,8 @@ def test_learn(): log = d.db.first("select * from revlog order by time desc") assert log[2] == 2 assert log[3] == 2 - assert log[4] == 180 - assert log[5] == 30 + assert log[4] == -180 + assert log[5] == -30 # pass again d.sched.answerCard(c, 2) # it should by due in 10 minutes