tweaks to interval constraining

- move fuzzing into _constrainedIvl() so it's applied prior to limits
like maxIvl

- don't fuzz early reviews, so cards get the same interval if a filtered
deck is rebuilt again
This commit is contained in:
Damien Elmes 2017-12-24 21:04:13 +10:00
parent 765ec0fb36
commit 575f61c384

View File

@ -912,23 +912,22 @@ select id from cards where did in %s and queue = 2 and due <= ? limit ?)"""
# Interval management # Interval management
########################################################################## ##########################################################################
def _nextRevIvl(self, card, ease): def _nextRevIvl(self, card, ease, fuzz):
"Ideal next interval for CARD, given EASE." "Next review interval for CARD, given EASE."
delay = self._daysLate(card) delay = self._daysLate(card)
conf = self._revConf(card) conf = self._revConf(card)
fct = card.factor / 1000 fct = card.factor / 1000
ivl2 = self._constrainedIvl((card.ivl + delay // 4) * 1.2, conf, card.ivl) ivl2 = self._constrainedIvl((card.ivl + delay // 4) * 1.2, conf, card.ivl, fuzz)
ivl3 = self._constrainedIvl((card.ivl + delay // 2) * fct, conf, ivl2)
ivl4 = self._constrainedIvl(
(card.ivl + delay) * fct * conf['ease4'], conf, ivl3)
if ease == 2: if ease == 2:
interval = ivl2 return ivl2
elif ease == 3:
interval = ivl3 ivl3 = self._constrainedIvl((card.ivl + delay // 2) * fct, conf, ivl2, fuzz)
elif ease == 4: if ease == 3:
interval = ivl4 return ivl3
# interval capped?
return min(interval, conf['maxIvl']) ivl4 = self._constrainedIvl(
(card.ivl + delay) * fct * conf['ease4'], conf, ivl3, fuzz)
return ivl4
def _fuzzedIvl(self, ivl): def _fuzzedIvl(self, ivl):
min, max = self._fuzzIvlRange(ivl) min, max = self._fuzzIvlRange(ivl)
@ -949,10 +948,13 @@ select id from cards where did in %s and queue = 2 and due <= ? limit ?)"""
fuzz = max(fuzz, 1) fuzz = max(fuzz, 1)
return [ivl-fuzz, ivl+fuzz] return [ivl-fuzz, ivl+fuzz]
def _constrainedIvl(self, ivl, conf, prev): def _constrainedIvl(self, ivl, conf, prev, fuzz):
"Integer interval after interval factor and prev+1 constraints applied." ivl = int(ivl * conf.get('ivlFct', 1))
new = ivl * conf.get('ivlFct', 1) if fuzz:
return int(max(new, prev+1)) ivl = self._fuzzedIvl(ivl)
ivl = min(ivl, conf['maxIvl'])
ivl = max(ivl, prev+1, 1)
return int(ivl)
def _daysLate(self, card): def _daysLate(self, card):
"Number of days later than scheduled." "Number of days later than scheduled."
@ -960,14 +962,10 @@ select id from cards where did in %s and queue = 2 and due <= ? limit ?)"""
return max(0, self.today - due) return max(0, self.today - due)
def _updateRevIvl(self, card, ease): def _updateRevIvl(self, card, ease):
idealIvl = self._nextRevIvl(card, ease) card.ivl = self._nextRevIvl(card, ease, fuzz=True)
card.ivl = min(max(self._fuzzedIvl(idealIvl), card.ivl+1),
self._revConf(card)['maxIvl'])
def _updateEarlyRevIvl(self, card, ease): def _updateEarlyRevIvl(self, card, ease):
idealIvl = self._earlyReviewIvl(card, ease) card.ivl = self._earlyReviewIvl(card, ease)
card.ivl = min(max(self._fuzzedIvl(idealIvl), card.ivl+1),
self._revConf(card)['maxIvl'])
# next interval for card when answered early+correctly # next interval for card when answered early+correctly
def _earlyReviewIvl(self, card, ease): def _earlyReviewIvl(self, card, ease):
@ -1000,10 +998,9 @@ select id from cards where did in %s and queue = 2 and due <= ? limit ?)"""
# cap interval decreases # cap interval decreases
ivl = max(card.ivl*minNewIvl+easyBonus, ivl) ivl = max(card.ivl*minNewIvl+easyBonus, ivl)
# don't require prev+1 for early ivl = self._constrainedIvl(ivl, conf, prev=0, fuzz=False)
ivl = self._constrainedIvl(ivl, conf, 0)
return min(conf['maxIvl'], ivl) return ivl
# Dynamic deck handling # Dynamic deck handling
########################################################################## ##########################################################################
@ -1320,7 +1317,7 @@ To study outside of the normal schedule, click the Custom Study button below."""
else: else:
return 0 return 0
else: else:
return self._nextRevIvl(card, ease)*86400 return self._nextRevIvl(card, ease, fuzz=False)*86400
# 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):