diff --git a/anki/cram.py b/anki/cram.py index 9ba5608e8..41736f48e 100644 --- a/anki/cram.py +++ b/anki/cram.py @@ -34,6 +34,13 @@ class CramScheduler(Scheduler): self._answerLrnCard(card, ease) else: raise Exception("Invalid queue") + if ease == 1: + conf = self._lrnConf(card) + if conf['reset']: + # reset interval + card.ivl = max(1, int(card.ivl * conf['mult'])) + # mark card as due today so that it doesn't get rescheduled + card.due = card.edue = self.today card.mod = intTime() card.flushSched() @@ -47,9 +54,11 @@ class CramScheduler(Scheduler): ########################################################################## def _resetNew(self): + "All review cards that are not due yet." self.newQueue = self.db.list(""" -select id from cards where queue = 2 -and gid in %s order by %s limit %d""" % (ids2str(self.gids), +select id from cards where queue = 2 and due > %d +and gid in %s order by %s limit %d""" % (self.today, + ids2str(self.gids), self.order, self.reportLimit)) self.newCount = len(self.newQueue) @@ -72,15 +81,15 @@ and gid in %s order by %s limit %d""" % (ids2str(self.gids), def _rescheduleAsRev(self, card, conf, early): Scheduler._rescheduleAsRev(self, card, conf, early) - card.ivl = self._graduatingIvl(card, conf, early) - card.due = self.today + card.ivl + ivl = self._graduatingIvl(card, conf, early) + card.due = self.today + ivl # temporarily suspend it card.queue = -3 def _graduatingIvl(self, card, conf, early): if conf['resched']: - print "fixme" - return card.ivl + # shift card by the time it was delayed + return card.ivl - card.edue - self.today else: return card.ivl diff --git a/anki/groups.py b/anki/groups.py index 908106a86..1c6916ee8 100644 --- a/anki/groups.py +++ b/anki/groups.py @@ -2,7 +2,7 @@ # Copyright: Damien Elmes # License: GNU GPL, version 3 or later; http://www.gnu.org/copyleft/gpl.html -import simplejson, time +import simplejson from anki.utils import intTime # maybe define a random cutoff at say +/-30% which controls exit interval @@ -26,6 +26,8 @@ defaultConf = { 'cram': { 'delays': [0.5, 3, 10], 'resched': True, + 'reset': True, + 'mult': 0, }, 'rev': { 'ease4': 1.3, diff --git a/anki/media.py b/anki/media.py index 740ec6b00..2a5813405 100644 --- a/anki/media.py +++ b/anki/media.py @@ -160,6 +160,7 @@ If the same name exists, compare checksums.""" ########################################################################## def downloadMissing(self): + raise Exception() urlbase = self.deck.getVar("mediaURL") if not urlbase: return None @@ -189,6 +190,7 @@ If the same name exists, compare checksums.""" ########################################################################## def downloadRemote(self): + raise Exception() mdir = self.deck.dir(create=True) refs = {} for (question, answer) in self.deck.db.all( diff --git a/tests/test_sched.py b/tests/test_sched.py index f25adc6f8..5084c66ee 100644 --- a/tests/test_sched.py +++ b/tests/test_sched.py @@ -310,19 +310,29 @@ def test_cram(): c = f.cards()[0] c.ivl = 100 c.type = c.queue = 2 - c.due = d.sched.today + 50 + # due in 25 days, so it's been waiting 75 days + c.due = d.sched.today + 25 c.mod = 1 + c.startTimer() c.flush() + cardcopy = copy.copy(c) d.cramGroups([1]) + # first, test with initial intervals preserved + conf = d.sched._lrnConf(c) + conf['reset'] = False + conf['resched'] = False assert d.sched.counts() == (1, 0, 0) c = d.sched.getCard() assert d.sched.counts() == (0, 0, 0) # check that estimates work assert d.sched.nextIvl(c, 1) == 30 assert d.sched.nextIvl(c, 2) == 180 - print "fixme" - print d.sched.nextIvl(c, 3) == 86400*100 - # answer it + assert d.sched.nextIvl(c, 3) == 86400*100 + # failing it should not reset ivl + assert c.ivl == 100 + d.sched.answerCard(c, 1) + assert c.ivl == 100 + # reset ivl for exit test, and pass card d.sched.answerCard(c, 2) delta = c.due - time.time() assert delta > 175 and delta <= 180 @@ -331,8 +341,34 @@ def test_cram(): d.sched.answerCard(c, 2) d.sched.answerCard(c, 2) assert c.queue == -3 - print "fixme" assert c.ivl == 100 # and if the queue is reset, it shouldn't appear in the new queue again d.reset() assert d.sched.counts() == (0, 0, 0) + # now try again with ivl rescheduling + c = copy.copy(cardcopy) + c.flush() + d.cramGroups([1]) + conf = d.sched._lrnConf(c) + conf['reset'] = False + conf['resched'] = True + # failures shouldn't matter + 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) + assert d.sched.nextIvl(c, 3) == 75*86400 + d.sched.answerCard(c, 3) + assert c.ivl == 100 + assert c.due == d.sched.today + 75 + # try with ivl reset + c = copy.copy(cardcopy) + c.flush() + d.cramGroups([1]) + conf = d.sched._lrnConf(c) + conf['reset'] = True + conf['resched'] = True + d.sched.answerCard(c, 1) + assert d.sched.nextIvl(c, 3) == 1*86400 + d.sched.answerCard(c, 3) + assert c.ivl == 1 + assert c.due == d.sched.today + 1