mirror of
https://github.com/ankitects/anki.git
synced 2025-09-19 06:22:22 -04:00
spread reviews before sibling check
This commit is contained in:
parent
d11a1e0d54
commit
26ae5e1c47
2 changed files with 34 additions and 7 deletions
|
@ -18,6 +18,7 @@ from anki.hooks import runHook
|
|||
class Scheduler(object):
|
||||
name = "std"
|
||||
haveCustomStudy = True
|
||||
_spreadRev = True
|
||||
|
||||
def __init__(self, col):
|
||||
self.col = col
|
||||
|
@ -873,6 +874,25 @@ select id from cards where did in %s and queue = 2 and due <= ? limit ?)"""
|
|||
# interval capped?
|
||||
return min(interval, conf['maxIvl'])
|
||||
|
||||
def _fuzzedIvl(self, ivl):
|
||||
min, max = self._fuzzIvlRange(ivl)
|
||||
return random.randint(min, max)
|
||||
|
||||
def _fuzzIvlRange(self, ivl):
|
||||
if ivl < 2:
|
||||
return [1, 1]
|
||||
elif ivl == 2:
|
||||
return [2, 3]
|
||||
elif ivl < 7:
|
||||
fuzz = int(ivl*0.25)
|
||||
elif ivl < 30:
|
||||
fuzz = max(2, int(ivl*0.15))
|
||||
else:
|
||||
fuzz = max(4, int(ivl*0.05))
|
||||
# fuzz at least a day
|
||||
fuzz = max(fuzz, 1)
|
||||
return [ivl-fuzz, ivl+fuzz]
|
||||
|
||||
def _constrainedIvl(self, ivl, conf, prev):
|
||||
"Integer interval after interval factor and prev+1 constraints applied."
|
||||
new = ivl * conf.get('ivlFct', 1)
|
||||
|
@ -890,6 +910,8 @@ select id from cards where did in %s and queue = 2 and due <= ? limit ?)"""
|
|||
|
||||
def _adjRevIvl(self, card, idealIvl):
|
||||
"Given IDEALIVL, return an IVL away from siblings."
|
||||
if self._spreadRev:
|
||||
idealIvl = self._fuzzedIvl(idealIvl)
|
||||
idealDue = self.today + idealIvl
|
||||
conf = self._revConf(card)
|
||||
# find sibling positions
|
||||
|
|
|
@ -5,6 +5,10 @@ from tests.shared import getEmptyDeck
|
|||
from anki.utils import intTime
|
||||
from anki.hooks import addHook
|
||||
|
||||
def checkRevIvl(d, targetIvl):
|
||||
min, max = d.sched._fuzzIvlRange(targetIvl)
|
||||
return min <= targetIvl <= max
|
||||
|
||||
def test_basics():
|
||||
d = getEmptyDeck()
|
||||
d.reset()
|
||||
|
@ -148,7 +152,7 @@ def test_learn():
|
|||
d.sched.answerCard(c, 3)
|
||||
assert c.type == 2
|
||||
assert c.queue == 2
|
||||
assert c.ivl == 4
|
||||
assert checkRevIvl(d, 4)
|
||||
# revlog should have been updated each time
|
||||
assert d.db.scalar("select count() from revlog where type = 0") == 5
|
||||
# now failed card handling
|
||||
|
@ -302,8 +306,8 @@ def test_reviews():
|
|||
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
|
||||
assert checkRevIvl(d, 122)
|
||||
assert c.due == d.sched.today + c.ivl
|
||||
# factor should have been decremented
|
||||
assert c.factor == 2350
|
||||
# check counters
|
||||
|
@ -315,8 +319,8 @@ def test_reviews():
|
|||
c.flush()
|
||||
d.sched.answerCard(c, 3)
|
||||
# the new interval should be (100 + 8/2) * 2.5 = 260
|
||||
assert c.ivl == 260
|
||||
assert c.due == d.sched.today + 260
|
||||
assert checkRevIvl(d, 260)
|
||||
assert c.due == d.sched.today + c.ivl
|
||||
# factor should have been left alone
|
||||
assert c.factor == 2500
|
||||
# ease 4
|
||||
|
@ -325,8 +329,8 @@ def test_reviews():
|
|||
c.flush()
|
||||
d.sched.answerCard(c, 4)
|
||||
# the new interval should be (100 + 8) * 2.5 * 1.3 = 351
|
||||
assert c.ivl == 351
|
||||
assert c.due == d.sched.today + 351
|
||||
assert checkRevIvl(d, 351)
|
||||
assert c.due == d.sched.today + c.ivl
|
||||
# factor should have been increased
|
||||
assert c.factor == 2650
|
||||
# leech handling
|
||||
|
@ -767,6 +771,7 @@ def test_cram_resched():
|
|||
|
||||
def test_adjIvl():
|
||||
d = getEmptyDeck()
|
||||
d.sched._spreadRev = False
|
||||
# add two more templates and set second active
|
||||
m = d.models.current(); mm = d.models
|
||||
t = mm.newTemplate("Reverse")
|
||||
|
|
Loading…
Reference in a new issue