def _fuzz_interval(self, interval): '''Returns a fuzzed interval.''' # Conservatively favors shorter intervals. fuzz = interval * random.triangular( -INTERVAL_FUZZ_MAX, INTERVAL_FUZZ_MAX, (-INTERVAL_FUZZ_MAX) / 4.5) # Fuzz less for early reviews. if self._is_early_review(): #TODO-OLD refactor / DRY all these early review calculations if self.last_reviewed_at: last_effective_interval = timedelta_to_float( self.due_at - self.last_reviewed_at) if (is_early_review_due_to_sibling and last_reviewed_sibling.last_reviewed_at > self.last_reviewed_at): last_effectively_reviewed_at = \ last_reviewed_sibling.last_reviewed_at else: last_effectively_reviewed_at = self.last_reviewed_at percentage_waited = ( timedelta_to_float(reviewed_at - last_effectively_reviewed_at) / last_effective_interval) # New card. else: percentage_waited = percentage_waited_for_sibling #print 'fuzz was to be: ' + str(fuzz) fuzz *= self._adjustment_curve(percentage_waited) #print 'adjusted fuzz: ' + str(fuzz) next_interval += timedelta(days=fuzz)
def _fuzz_interval(self, interval): '''Returns a fuzzed interval.''' # Conservatively favors shorter intervals. fuzz = interval * random.triangular( -INTERVAL_FUZZ_MAX, INTERVAL_FUZZ_MAX, (-INTERVAL_FUZZ_MAX) / 4.5) # Fuzz less for early reviews. if self._is_early_review(): #TODO-OLD refactor / DRY all these early review calculations if self.last_reviewed_at: last_effective_interval = timedelta_to_float( self.due_at - self.last_reviewed_at) if (is_early_review_due_to_sibling and last_reviewed_sibling.last_reviewed_at > self.last_reviewed_at): last_effectively_reviewed_at = \ last_reviewed_sibling.last_reviewed_at else: last_effectively_reviewed_at = self.last_reviewed_at percentage_waited = ( timedelta_to_float( reviewed_at - last_effectively_reviewed_at) / last_effective_interval) # New card. else: percentage_waited = percentage_waited_for_sibling #print 'fuzz was to be: ' + str(fuzz) fuzz *= self._adjustment_curve(percentage_waited) #print 'adjusted fuzz: ' + str(fuzz) next_interval += timedelta(days=fuzz)
def _percent_waited(self): ''' Returns the percent of the last repetition the user waited before reviewing. So if the next due date was in 5 days, and the user waited just 3 days before reviewing again, this would return .6. Assumes the last review was successful. This method may be overriden for new and failed cards. Could be considered early (< 1.0) for 2 reasons: 1. Reviewed before its due date. 2. Sibling card was reviewed too recently, regardless of due dates. Determining "too recently" for #2 relies on the amount decided on for simultaneously due cards to be delayed for being siblings. See the card's `calculated_interval` docstring for info on the denominator here. ''' from cards import Card denominator = self.card.calculated_interval() # Was this reviewed too soon after a sibling? How early? # If not too early, still factor the delay into our return value. try: sibling = self.card.siblings.latest('last_reviewed_at') if sibling.last_reviewed_at: difference = (self.card.due_at - sibling.last_reviewed_at) if abs(difference) <= self.card.sibling_spacing(): denominator += self.card.sibling_spacing() except Card.DoesNotExist: pass return (timedelta_to_float(self._time_waited()) / timedelta_to_float(denominator))