mirror of
https://github.com/ankitects/anki.git
synced 2025-09-23 00:12:25 -04:00
space exiting new cards; fix 1 fact freeze
This commit is contained in:
parent
8b2971f91c
commit
da0fb0c555
2 changed files with 103 additions and 6 deletions
|
@ -126,8 +126,13 @@ queue = 0 %s order by due limit %d""" % (self._groupLimit('new'),
|
|||
(id, due) = self.newQueue.pop()
|
||||
# move any siblings to the end?
|
||||
if self.deck.qconf['newTodayOrder'] == NEW_TODAY_ORD:
|
||||
n = len(self.newQueue)
|
||||
while self.newQueue and self.newQueue[-1][1] == due:
|
||||
self.newQueue.insert(0, self.newQueue.pop())
|
||||
n -= 1
|
||||
if not n:
|
||||
# we only have one fact in the queue; stop rotating
|
||||
break
|
||||
self.newCount -= 1
|
||||
return id
|
||||
|
||||
|
@ -219,13 +224,14 @@ limit %d""" % self.reportLimit, lim=self.dayCutoff)
|
|||
def _graduatingIvl(self, card, conf, early):
|
||||
if not early:
|
||||
# graduate
|
||||
return conf['ints'][0]
|
||||
ideal = conf['ints'][0]
|
||||
elif card.cycles:
|
||||
# remove
|
||||
return conf['ints'][2]
|
||||
ideal = conf['ints'][2]
|
||||
else:
|
||||
# first time bonus
|
||||
return conf['ints'][1]
|
||||
ideal = conf['ints'][1]
|
||||
return self._adjRevIvl(card, ideal)
|
||||
|
||||
def _rescheduleNew(self, card, conf, early):
|
||||
card.ivl = self._graduatingIvl(card, conf, early)
|
||||
|
@ -374,6 +380,10 @@ queue = 2 %s and due <= :lim order by %s limit %d""" % (
|
|||
def _updateRevIvl(self, card, ease):
|
||||
"Update CARD's interval, trying to avoid siblings."
|
||||
idealIvl = self._nextRevIvl(card, ease)
|
||||
card.ivl = self._adjRevIvl(card, idealIvl)
|
||||
|
||||
def _adjRevIvl(self, card, idealIvl):
|
||||
"Given IDEALIVL, return an IVL away from siblings."
|
||||
idealDue = self.today + idealIvl
|
||||
conf = self._cardConf(card)['rev']
|
||||
# find sibling positions
|
||||
|
@ -381,12 +391,12 @@ queue = 2 %s and due <= :lim order by %s limit %d""" % (
|
|||
"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
|
||||
return idealIvl
|
||||
else:
|
||||
leeway = max(conf['minSpace'], int(idealIvl * conf['fuzz']))
|
||||
fudge = 0
|
||||
# do we have any room to adjust the interval?
|
||||
if leeway:
|
||||
fudge = 0
|
||||
# loop through possible due dates for an empty one
|
||||
for diff in range(1, leeway+1):
|
||||
# ensure we're due at least tomorrow
|
||||
|
@ -396,7 +406,7 @@ queue = 2 %s and due <= :lim order by %s limit %d""" % (
|
|||
elif (idealDue + diff) not in dues:
|
||||
fudge = diff
|
||||
break
|
||||
card.ivl = idealIvl + fudge
|
||||
return idealIvl + fudge
|
||||
|
||||
# Leeches
|
||||
##########################################################################
|
||||
|
|
|
@ -409,3 +409,90 @@ def test_cramLimits():
|
|||
assert d.sched.counts()[0] == 1
|
||||
d.cramGroups([1], min=0, max=1)
|
||||
assert d.sched.counts()[0] == 2
|
||||
|
||||
def test_adjIvl():
|
||||
d = getEmptyDeck()
|
||||
# add two more templates and set second active
|
||||
m = d.currentModel()
|
||||
m.templates[1]['actv'] = True
|
||||
t = m.newTemplate()
|
||||
t['name'] = "f2"
|
||||
t['qfmt'] = "{{Front}}"
|
||||
t['afmt'] = "{{Back}}"
|
||||
m.addTemplate(t)
|
||||
t = m.newTemplate()
|
||||
t['name'] = "f3"
|
||||
t['qfmt'] = "{{Front}}"
|
||||
t['afmt'] = "{{Back}}"
|
||||
m.addTemplate(t)
|
||||
m.flush()
|
||||
# create a new fact; it should have 4 cards
|
||||
f = d.newFact()
|
||||
f['Front'] = "1"; f['Back'] = "1"
|
||||
d.addFact(f)
|
||||
assert d.cardCount() == 4
|
||||
d.reset()
|
||||
# immediately remove first; it should get ideal ivl
|
||||
c = d.sched.getCard()
|
||||
d.sched.answerCard(c, 3)
|
||||
assert c.ivl == 7
|
||||
# with the default settings, second card should be -1
|
||||
c = d.sched.getCard()
|
||||
d.sched.answerCard(c, 3)
|
||||
assert c.ivl == 6
|
||||
# and third +1
|
||||
c = d.sched.getCard()
|
||||
d.sched.answerCard(c, 3)
|
||||
assert c.ivl == 8
|
||||
# fourth exceeds default settings, so gets ideal again
|
||||
c = d.sched.getCard()
|
||||
d.sched.answerCard(c, 3)
|
||||
assert c.ivl == 7
|
||||
# try again with another fact
|
||||
f = d.newFact()
|
||||
f['Front'] = "2"; f['Back'] = "2"
|
||||
d.addFact(f)
|
||||
d.reset()
|
||||
# set a minSpacing of 0
|
||||
conf = d.sched._cardConf(c)
|
||||
conf['rev']['minSpace'] = 0
|
||||
# first card gets ideal
|
||||
c = d.sched.getCard()
|
||||
d.sched.answerCard(c, 3)
|
||||
assert c.ivl == 7
|
||||
# and second too, because it's below the threshold
|
||||
c = d.sched.getCard()
|
||||
d.sched.answerCard(c, 3)
|
||||
assert c.ivl == 7
|
||||
# if we increase the ivl minSpace isn't needed
|
||||
conf['new']['ints'][1] = 20
|
||||
# ideal..
|
||||
c = d.sched.getCard()
|
||||
d.sched.answerCard(c, 3)
|
||||
assert c.ivl == 20
|
||||
# adjusted
|
||||
c = d.sched.getCard()
|
||||
d.sched.answerCard(c, 3)
|
||||
assert c.ivl == 19
|
||||
|
||||
def test_ordcycle():
|
||||
d = getEmptyDeck()
|
||||
# add two more templates and set second active
|
||||
m = d.currentModel()
|
||||
m.templates[1]['actv'] = True
|
||||
t = m.newTemplate()
|
||||
t['name'] = "f2"
|
||||
t['qfmt'] = "{{Front}}"
|
||||
t['afmt'] = "{{Back}}"
|
||||
m.addTemplate(t)
|
||||
m.flush()
|
||||
# create a new fact; it should have 4 cards
|
||||
f = d.newFact()
|
||||
f['Front'] = "1"; f['Back'] = "1"
|
||||
d.addFact(f)
|
||||
assert d.cardCount() == 3
|
||||
d.reset()
|
||||
# ordinals should arrive in order
|
||||
assert d.sched.getCard().ord == 0
|
||||
assert d.sched.getCard().ord == 1
|
||||
assert d.sched.getCard().ord == 2
|
||||
|
|
Loading…
Reference in a new issue