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):
|
class Scheduler(object):
|
||||||
name = "std"
|
name = "std"
|
||||||
haveCustomStudy = True
|
haveCustomStudy = True
|
||||||
|
_spreadRev = True
|
||||||
|
|
||||||
def __init__(self, col):
|
def __init__(self, col):
|
||||||
self.col = col
|
self.col = col
|
||||||
|
@ -873,6 +874,25 @@ select id from cards where did in %s and queue = 2 and due <= ? limit ?)"""
|
||||||
# interval capped?
|
# interval capped?
|
||||||
return min(interval, conf['maxIvl'])
|
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):
|
def _constrainedIvl(self, ivl, conf, prev):
|
||||||
"Integer interval after interval factor and prev+1 constraints applied."
|
"Integer interval after interval factor and prev+1 constraints applied."
|
||||||
new = ivl * conf.get('ivlFct', 1)
|
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):
|
def _adjRevIvl(self, card, idealIvl):
|
||||||
"Given IDEALIVL, return an IVL away from siblings."
|
"Given IDEALIVL, return an IVL away from siblings."
|
||||||
|
if self._spreadRev:
|
||||||
|
idealIvl = self._fuzzedIvl(idealIvl)
|
||||||
idealDue = self.today + idealIvl
|
idealDue = self.today + idealIvl
|
||||||
conf = self._revConf(card)
|
conf = self._revConf(card)
|
||||||
# find sibling positions
|
# find sibling positions
|
||||||
|
|
|
@ -5,6 +5,10 @@ from tests.shared import getEmptyDeck
|
||||||
from anki.utils import intTime
|
from anki.utils import intTime
|
||||||
from anki.hooks import addHook
|
from anki.hooks import addHook
|
||||||
|
|
||||||
|
def checkRevIvl(d, targetIvl):
|
||||||
|
min, max = d.sched._fuzzIvlRange(targetIvl)
|
||||||
|
return min <= targetIvl <= max
|
||||||
|
|
||||||
def test_basics():
|
def test_basics():
|
||||||
d = getEmptyDeck()
|
d = getEmptyDeck()
|
||||||
d.reset()
|
d.reset()
|
||||||
|
@ -148,7 +152,7 @@ def test_learn():
|
||||||
d.sched.answerCard(c, 3)
|
d.sched.answerCard(c, 3)
|
||||||
assert c.type == 2
|
assert c.type == 2
|
||||||
assert c.queue == 2
|
assert c.queue == 2
|
||||||
assert c.ivl == 4
|
assert checkRevIvl(d, 4)
|
||||||
# revlog should have been updated each time
|
# revlog should have been updated each time
|
||||||
assert d.db.scalar("select count() from revlog where type = 0") == 5
|
assert d.db.scalar("select count() from revlog where type = 0") == 5
|
||||||
# now failed card handling
|
# now failed card handling
|
||||||
|
@ -302,8 +306,8 @@ def test_reviews():
|
||||||
d.sched.answerCard(c, 2)
|
d.sched.answerCard(c, 2)
|
||||||
assert c.queue == 2
|
assert c.queue == 2
|
||||||
# the new interval should be (100 + 8/4) * 1.2 = 122
|
# the new interval should be (100 + 8/4) * 1.2 = 122
|
||||||
assert c.ivl == 122
|
assert checkRevIvl(d, 122)
|
||||||
assert c.due == d.sched.today + 122
|
assert c.due == d.sched.today + c.ivl
|
||||||
# factor should have been decremented
|
# factor should have been decremented
|
||||||
assert c.factor == 2350
|
assert c.factor == 2350
|
||||||
# check counters
|
# check counters
|
||||||
|
@ -315,8 +319,8 @@ def test_reviews():
|
||||||
c.flush()
|
c.flush()
|
||||||
d.sched.answerCard(c, 3)
|
d.sched.answerCard(c, 3)
|
||||||
# the new interval should be (100 + 8/2) * 2.5 = 260
|
# the new interval should be (100 + 8/2) * 2.5 = 260
|
||||||
assert c.ivl == 260
|
assert checkRevIvl(d, 260)
|
||||||
assert c.due == d.sched.today + 260
|
assert c.due == d.sched.today + c.ivl
|
||||||
# factor should have been left alone
|
# factor should have been left alone
|
||||||
assert c.factor == 2500
|
assert c.factor == 2500
|
||||||
# ease 4
|
# ease 4
|
||||||
|
@ -325,8 +329,8 @@ def test_reviews():
|
||||||
c.flush()
|
c.flush()
|
||||||
d.sched.answerCard(c, 4)
|
d.sched.answerCard(c, 4)
|
||||||
# the new interval should be (100 + 8) * 2.5 * 1.3 = 351
|
# the new interval should be (100 + 8) * 2.5 * 1.3 = 351
|
||||||
assert c.ivl == 351
|
assert checkRevIvl(d, 351)
|
||||||
assert c.due == d.sched.today + 351
|
assert c.due == d.sched.today + c.ivl
|
||||||
# factor should have been increased
|
# factor should have been increased
|
||||||
assert c.factor == 2650
|
assert c.factor == 2650
|
||||||
# leech handling
|
# leech handling
|
||||||
|
@ -767,6 +771,7 @@ def test_cram_resched():
|
||||||
|
|
||||||
def test_adjIvl():
|
def test_adjIvl():
|
||||||
d = getEmptyDeck()
|
d = getEmptyDeck()
|
||||||
|
d.sched._spreadRev = False
|
||||||
# add two more templates and set second active
|
# add two more templates and set second active
|
||||||
m = d.models.current(); mm = d.models
|
m = d.models.current(); mm = d.models
|
||||||
t = mm.newTemplate("Reverse")
|
t = mm.newTemplate("Reverse")
|
||||||
|
|
Loading…
Reference in a new issue