mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 08:46:37 -04:00
revlog work
- remove revlog.py and move code into scheduler - add a routine to log a learn repetition - rename flags to type and set type=0 for learn mode - add to unit test
This commit is contained in:
parent
2dadb2c933
commit
e4cc3e3013
5 changed files with 58 additions and 33 deletions
|
@ -118,7 +118,8 @@ streak=?, lapses=?, grade=?, cycles=? where id = ?""",
|
|||
self.timerStarted = time.time()
|
||||
|
||||
def timeTaken(self):
|
||||
return min(time.time() - self.timerStarted, MAX_TIMER)
|
||||
"Time taken to answer card, in integer MS."
|
||||
return int(min(time.time() - self.timerStarted, MAX_TIMER)*1000)
|
||||
|
||||
# Questions and answers
|
||||
##########################################################################
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright: Damien Elmes <anki@ichi2.net>
|
||||
# License: GNU GPL, version 3 or later; http://www.gnu.org/copyleft/gpl.html
|
||||
|
||||
import time
|
||||
|
||||
# Flags: 0=standard review, 1=reschedule due to cram, drill, etc
|
||||
# Rep: Repetition number. The same number may appear twice if a card has been
|
||||
# manually rescheduled or answered on multiple sites before a sync.
|
||||
#
|
||||
# We store the times in integer milliseconds to avoid an extra index on the
|
||||
# primary key.
|
||||
|
||||
def logReview(db, card, ease, flags=0):
|
||||
db.execute("""
|
||||
insert into revlog values (
|
||||
:created, :cardId, :ease, :rep, :lastInterval, :interval, :factor,
|
||||
:userTime, :flags)""",
|
||||
created=int(time.time()*1000), cardId=card.id, ease=ease, rep=card.reps,
|
||||
lastInterval=card.lastInterval, interval=card.interval,
|
||||
factor=card.factor, userTime=int(card.userTime()*1000),
|
||||
flags=flags)
|
|
@ -25,7 +25,9 @@ class Scheduler(object):
|
|||
self.checkDay()
|
||||
id = self.getCardId()
|
||||
if id:
|
||||
return self.deck.getCard(id)
|
||||
c = self.deck.getCard(id)
|
||||
c.startTimer()
|
||||
return c
|
||||
|
||||
def reset(self):
|
||||
self.resetConf()
|
||||
|
@ -167,8 +169,17 @@ limit %d""" % self.learnLimit, lim=self.dayCutoff)
|
|||
card.grade = 0
|
||||
if card.grade >= len(conf['delays']):
|
||||
self.graduateLearnCard(card, conf)
|
||||
return
|
||||
else:
|
||||
card.due = time.time() + conf['delays'][card.grade]*60
|
||||
card.due = time.time() + self.delayForGrade(conf, card.grade)
|
||||
try:
|
||||
self.logLearn(card, ease, conf)
|
||||
except:
|
||||
time.sleep(0.01)
|
||||
self.logLearn(card, ease, conf)
|
||||
|
||||
def delayForGrade(self, conf, grade):
|
||||
return conf['delays'][grade]*60
|
||||
|
||||
def learnConf(self, card):
|
||||
conf = self.confForCard(card)
|
||||
|
@ -197,12 +208,23 @@ limit %d""" % self.learnLimit, lim=self.dayCutoff)
|
|||
|
||||
def rescheduleAsReview(self, card, conf, int_):
|
||||
card.queue = 1
|
||||
card.factor = conf['initialFactor']
|
||||
if int_:
|
||||
# new card
|
||||
card.type = 1
|
||||
card.interval = int_
|
||||
print "handle log, etc"
|
||||
card.factor = conf['initialFactor']
|
||||
print "logs for learning cards?"
|
||||
else:
|
||||
# failed card
|
||||
pass
|
||||
|
||||
def logLearn(self, card, ease, conf):
|
||||
self.deck.db.execute(
|
||||
"insert into revlog values (?,?,?,?,?,?,?,?,?)",
|
||||
int(time.time()*1000), card.id, ease, card.cycles,
|
||||
self.delayForGrade(conf, card.grade),
|
||||
self.delayForGrade(conf, max(0, card.grade-1)),
|
||||
0, card.timeTaken(), 0)
|
||||
|
||||
# Reviews
|
||||
##########################################################################
|
||||
|
@ -230,8 +252,8 @@ queue = 1 %s and due < :lim order by %s limit %d""" % (
|
|||
return self.revQueue
|
||||
|
||||
def revOrder(self):
|
||||
return ("interval desc",
|
||||
"interval",
|
||||
return ("ivl desc",
|
||||
"ivl",
|
||||
"due")[self.deck.qconf['revCardOrder']]
|
||||
|
||||
# FIXME: rewrite
|
||||
|
@ -253,8 +275,7 @@ queue = 1 %s and due < :lim order by %s limit %d""" % (
|
|||
oldSuc = card.successive
|
||||
# update card details
|
||||
last = card.interval
|
||||
card.interval = self.nextInterval(card, ease)
|
||||
card.lastInterval = last
|
||||
card.ivl = self.nextInterval(card, ease)
|
||||
if card.reps:
|
||||
# only update if card was not new
|
||||
card.lastDue = card.due
|
||||
|
@ -329,6 +350,23 @@ and queue between 1 and 2""",
|
|||
# update local cache of seen facts
|
||||
self.spacedFacts[card.fid] = new
|
||||
|
||||
# Flags: 0=standard review, 1=reschedule due to cram, drill, etc
|
||||
# Rep: Repetition number. The same number may appear twice if a card has been
|
||||
# manually rescheduled or answered on multiple sites before a sync.
|
||||
#
|
||||
# We store the times in integer milliseconds to avoid an extra index on the
|
||||
# primary key.
|
||||
|
||||
def logReview(db, card, ease, flags=0):
|
||||
db.execute("""
|
||||
insert into revlog values (
|
||||
:created, :cardId, :ease, :rep, :lastInterval, :interval, :factor,
|
||||
:userTime, :flags)""",
|
||||
created=int(time.time()*1000), cardId=card.id, ease=ease, rep=card.reps,
|
||||
lastInterval=card.lastInterval, interval=card.interval,
|
||||
factor=card.factor, userTime=int(card.userTime()*1000),
|
||||
flags=flags)
|
||||
|
||||
# Interval management
|
||||
##########################################################################
|
||||
|
||||
|
|
|
@ -151,7 +151,7 @@ create table if not exists revlog (
|
|||
lastInt integer not null,
|
||||
factor integer not null,
|
||||
taken integer not null,
|
||||
flags integer not null
|
||||
type integer not null
|
||||
);
|
||||
|
||||
create table if not exists tags (
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import time
|
||||
from tests.shared import assertException, getEmptyDeck
|
||||
from anki.stdmodels import BasicModel
|
||||
from anki.utils import stripHTML
|
||||
from anki.utils import stripHTML, intTime
|
||||
|
||||
def test_basics():
|
||||
d = getEmptyDeck()
|
||||
|
@ -24,9 +24,11 @@ def test_new():
|
|||
assert c.queue == 2
|
||||
assert c.type == 2
|
||||
# if we answer it, it should become a learn card
|
||||
t = intTime()
|
||||
d.sched.answerCard(c, 1)
|
||||
assert c.queue == 0
|
||||
assert c.type == 2
|
||||
assert c.due >= t
|
||||
# the default order should ensure siblings are not seen together, and
|
||||
# should show all cards
|
||||
m = d.currentModel()
|
||||
|
@ -73,6 +75,12 @@ def test_learn():
|
|||
# and it should be grade 1 now
|
||||
assert c.grade == 1
|
||||
assert c.cycles == 2
|
||||
# check log is accurate
|
||||
log = d.db.first("select * from revlog order by time desc")
|
||||
assert log[2] == 2
|
||||
assert log[3] == 2
|
||||
assert log[4] == 180
|
||||
assert log[5] == 30
|
||||
# pass again
|
||||
d.sched.answerCard(c, 2)
|
||||
# it should by due in 10 minutes
|
||||
|
|
Loading…
Reference in a new issue