mirror of
https://github.com/ankitects/anki.git
synced 2025-09-25 17:26:36 -04:00
removing cram decks, estimates, failure handling
This commit is contained in:
parent
01404fafaa
commit
ffaf7ffc66
3 changed files with 68 additions and 29 deletions
|
@ -122,14 +122,20 @@ class DeckManager(object):
|
||||||
# do nothing else if doesn't exist
|
# do nothing else if doesn't exist
|
||||||
if not str(did) in self.decks:
|
if not str(did) in self.decks:
|
||||||
return
|
return
|
||||||
# delete children first
|
deck = self.get(did)
|
||||||
if childrenToo:
|
if deck.get('cram'):
|
||||||
# we don't want to delete children when syncing
|
# deleting a cramming deck returns cards to their previous deck
|
||||||
for name, id in self.children(did):
|
# rather than deleting the cards
|
||||||
self.rem(id, cardsToo)
|
self.col.sched.remCram(did)
|
||||||
# delete cards too?
|
else:
|
||||||
if cardsToo:
|
# delete children first
|
||||||
self.col.remCards(self.cids(did))
|
if childrenToo:
|
||||||
|
# we don't want to delete children when syncing
|
||||||
|
for name, id in self.children(did):
|
||||||
|
self.rem(id, cardsToo)
|
||||||
|
# delete cards too?
|
||||||
|
if cardsToo:
|
||||||
|
self.col.remCards(self.cids(did))
|
||||||
# delete the deck and add a grave
|
# delete the deck and add a grave
|
||||||
del self.decks[str(did)]
|
del self.decks[str(did)]
|
||||||
# ensure we have an active deck
|
# ensure we have an active deck
|
||||||
|
|
|
@ -64,10 +64,7 @@ class Scheduler(object):
|
||||||
# cramming?
|
# cramming?
|
||||||
if self._cramming and card.type == 2:
|
if self._cramming and card.type == 2:
|
||||||
# reviews get their ivl boosted on first sight
|
# reviews get their ivl boosted on first sight
|
||||||
elapsed = card.ivl - card.odue - self.today
|
card.ivl = self._cramIvlBoost(card)
|
||||||
assert card.factor
|
|
||||||
factor = ((card.factor/1000.0)+1.2)/2.0
|
|
||||||
card.ivl = int(max(card.ivl, elapsed * factor, 1))+1
|
|
||||||
card.odue = self.today + card.ivl
|
card.odue = self.today + card.ivl
|
||||||
self._updateStats(card, 'new')
|
self._updateStats(card, 'new')
|
||||||
if card.queue == 1:
|
if card.queue == 1:
|
||||||
|
@ -437,6 +434,10 @@ limit %d""" % (self._deckLimit(), self.reportLimit), lim=self.dayCutoff)
|
||||||
# failed
|
# failed
|
||||||
else:
|
else:
|
||||||
card.left = self._startingLeft(card)
|
card.left = self._startingLeft(card)
|
||||||
|
if self._cramming:
|
||||||
|
print "fixme: configurable failure handling"
|
||||||
|
card.ivl = 1
|
||||||
|
card.odue = self.today + 1
|
||||||
self.lrnCount += card.left
|
self.lrnCount += card.left
|
||||||
delay = self._delayForGrade(conf, card.left)
|
delay = self._delayForGrade(conf, card.left)
|
||||||
if card.due < time.time():
|
if card.due < time.time():
|
||||||
|
@ -485,6 +486,8 @@ limit %d""" % (self._deckLimit(), self.reportLimit), lim=self.dayCutoff)
|
||||||
def _graduatingIvl(self, card, conf, early, adj=True):
|
def _graduatingIvl(self, card, conf, early, adj=True):
|
||||||
if card.type == 2:
|
if card.type == 2:
|
||||||
# lapsed card being relearnt
|
# lapsed card being relearnt
|
||||||
|
if self._cramming:
|
||||||
|
return self._cramIvlBoost(card)
|
||||||
return card.ivl
|
return card.ivl
|
||||||
if not early:
|
if not early:
|
||||||
# graduate
|
# graduate
|
||||||
|
@ -739,6 +742,11 @@ did = ? and queue = 2 and due <= ? %s limit ?""" % order,
|
||||||
# and change to our new deck
|
# and change to our new deck
|
||||||
self.col.decks.select(did)
|
self.col.decks.select(did)
|
||||||
|
|
||||||
|
def remCram(self, did):
|
||||||
|
self.col.db.execute("""
|
||||||
|
update cards set did = odid, queue = type, due = odue, odue = 0, odid = 0,
|
||||||
|
usn = ?, mod = ? where did = ?""", self.col.usn(), intTime(), did)
|
||||||
|
|
||||||
def _cramOrder(self, order):
|
def _cramOrder(self, order):
|
||||||
if order == "due":
|
if order == "due":
|
||||||
return "order by c.due"
|
return "order by c.due"
|
||||||
|
@ -770,6 +778,13 @@ did = ? and queue = 2 and due <= ? %s limit ?""" % order,
|
||||||
update cards set odid = did, odue = due, did = ?, queue = 0, due = ?,
|
update cards set odid = did, odue = due, did = ?, queue = 0, due = ?,
|
||||||
mod = ?, usn = ? where id = ?""", data)
|
mod = ?, usn = ? where id = ?""", data)
|
||||||
|
|
||||||
|
def _cramIvlBoost(self, card):
|
||||||
|
assert self._cramming and card.type == 2
|
||||||
|
assert card.factor
|
||||||
|
elapsed = card.ivl - card.odue - self.today
|
||||||
|
factor = ((card.factor/1000.0)+1.2)/2.0
|
||||||
|
return int(max(card.ivl, elapsed * factor, 1))
|
||||||
|
|
||||||
# Leeches
|
# Leeches
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
|
@ -893,7 +908,6 @@ your short-term review workload will become."""))
|
||||||
# this isn't easily extracted from the learn code
|
# this isn't easily extracted from the learn code
|
||||||
def _nextLrnIvl(self, card, ease):
|
def _nextLrnIvl(self, card, ease):
|
||||||
if card.queue == 0:
|
if card.queue == 0:
|
||||||
card.type = 1
|
|
||||||
card.left = self._startingLeft(card)
|
card.left = self._startingLeft(card)
|
||||||
conf = self._lrnConf(card)
|
conf = self._lrnConf(card)
|
||||||
if ease == 1:
|
if ease == 1:
|
||||||
|
|
|
@ -453,33 +453,52 @@ def test_cram():
|
||||||
assert sorted(d.sched.deckDueList())[0][3] == 1
|
assert sorted(d.sched.deckDueList())[0][3] == 1
|
||||||
# and should appear in the counts
|
# and should appear in the counts
|
||||||
assert d.sched.counts() == (1,0,0)
|
assert d.sched.counts() == (1,0,0)
|
||||||
# grab it and make one step
|
# grab it and check estimates
|
||||||
c = d.sched.getCard()
|
c = d.sched.getCard()
|
||||||
|
assert d.sched.nextIvl(c, 1) == 60
|
||||||
|
assert d.sched.nextIvl(c, 2) == 600
|
||||||
|
assert d.sched.nextIvl(c, 3) == 138*60*60*24
|
||||||
d.sched.answerCard(c, 2)
|
d.sched.answerCard(c, 2)
|
||||||
# elapsed time was 75 days
|
# elapsed time was 75 days
|
||||||
# factor = 2.5+1.2/2 = 1.85
|
# factor = 2.5+1.2/2 = 1.85
|
||||||
# int(75*1.85)+1 = 139
|
# int(75*1.85) = 138
|
||||||
assert c.ivl == 139
|
assert c.ivl == 138
|
||||||
assert c.odue == 139
|
assert c.odue == 138
|
||||||
assert c.queue == 1
|
assert c.queue == 1
|
||||||
|
# check ivls again
|
||||||
|
assert d.sched.nextIvl(c, 1) == 60
|
||||||
|
assert d.sched.nextIvl(c, 2) == 138*60*60*24
|
||||||
|
assert d.sched.nextIvl(c, 3) == 138*60*60*24
|
||||||
# when it graduates, due is updated
|
# when it graduates, due is updated
|
||||||
c = d.sched.getCard()
|
c = d.sched.getCard()
|
||||||
d.sched.answerCard(c, 2)
|
d.sched.answerCard(c, 2)
|
||||||
assert c.ivl == 139
|
assert c.ivl == 138
|
||||||
assert c.due == 139
|
assert c.due == 138
|
||||||
assert c.queue == 2
|
assert c.queue == 2
|
||||||
# and it will have moved back to the previous deck
|
# and it will have moved back to the previous deck
|
||||||
assert c.did == 1
|
assert c.did == 1
|
||||||
|
# cram the deck again
|
||||||
|
d.sched.cram("")
|
||||||
# card will have moved b
|
d.reset()
|
||||||
#assert sorted(d.sched.deckDueList())[0][3] == 1
|
c = d.sched.getCard()
|
||||||
|
# check ivls again - passing should be idempotent
|
||||||
return
|
assert d.sched.nextIvl(c, 1) == 60
|
||||||
# check that estimates work
|
assert d.sched.nextIvl(c, 2) == 600
|
||||||
assert d.sched.nextIvl(c, 1) == 30
|
assert d.sched.nextIvl(c, 3) == 138*60*60*24
|
||||||
assert d.sched.nextIvl(c, 2) == 180
|
d.sched.answerCard(c, 2)
|
||||||
assert d.sched.nextIvl(c, 3) == 86400*100
|
assert c.ivl == 138
|
||||||
|
assert c.odue == 138
|
||||||
|
# fail
|
||||||
|
d.sched.answerCard(c, 1)
|
||||||
|
assert d.sched.nextIvl(c, 1) == 60
|
||||||
|
assert d.sched.nextIvl(c, 2) == 600
|
||||||
|
assert d.sched.nextIvl(c, 3) == 86400
|
||||||
|
# delete the deck, returning the card mid-study
|
||||||
|
d.decks.rem(d.decks.selected())
|
||||||
|
assert len(d.sched.deckDueList()) == 1
|
||||||
|
c.load()
|
||||||
|
assert c.ivl == 1
|
||||||
|
assert c.due == d.sched.today+1
|
||||||
|
|
||||||
def test_adjIvl():
|
def test_adjIvl():
|
||||||
d = getEmptyDeck()
|
d = getEmptyDeck()
|
||||||
|
|
Loading…
Reference in a new issue