diff --git a/anki/stats.py b/anki/stats.py
index 8e5e73b60..8aa63e972 100644
--- a/anki/stats.py
+++ b/anki/stats.py
@@ -21,7 +21,7 @@ class CardStats(object):
c = self.card
fmt = anki.utils.fmtTimeSpan
fmtFloat = anki.utils.fmtFloat
- self.txt = "
"
+ self.txt = ""
self.addLine(_("Added"), self.strTime(c.crt))
first = self.deck.db.scalar(
"select time/1000 from revlog where rep = 1 and cid = :id", id=c.id)
@@ -29,7 +29,10 @@ class CardStats(object):
self.addLine(_("First Review"), self.strTime(first))
self.addLine(_("Changed"), self.strTime(c.mod))
if c.reps:
- next = time.time() - c.due
+ if c.queue == 2:
+ next = (self.deck.sched.today - c.due)*86400
+ else:
+ next = time.time() - c.due
if next > 0:
next = _("%s ago") % fmt(next)
else:
@@ -80,6 +83,10 @@ class DeckStats(object):
return self.deck.db.scalar(
"select count(id) from cards where type = 0")
+ def info(self, txt):
+ return """
+%s
""" % txt
+
def report(self):
"Return an HTML string with a report."
fmtPerc = anki.utils.fmtPercentage
@@ -87,7 +94,9 @@ class DeckStats(object):
if not self.deck.cardCount():
return _("Please add some cards first.") + ""
d = self.deck
- html="" + _("Deck Statistics") + "
"
+ # General
+ ##################################################
+ html = ""+_("General")+"
"
html += _("Deck created: %s ago
") % self.crtTimeStr()
total = d.cardCount()
new = self.newCountAll()
@@ -101,9 +110,13 @@ class DeckStats(object):
(stats["old"], stats["oldP"]) = (old, oldP)
(stats["young"], stats["youngP"]) = (young, youngP)
html += _("Total number of cards:") + " %d
" % total
- html += _("Total number of facts:") + " %d
" % d.factCount()
-
- html += "" + _("Card Maturity") + "
"
+ html += _("Total number of facts:") + " %d" % d.factCount()
+ # Maturity
+ ##################################################
+ html += "" + _("Card Maturity") + "
"
+ html += self.info(_("""\
+Mature cards are cards that have an interval over 21 days.
+A card's interval is the time before it will be shown again."""))
html += _("Mature cards: ") + " %(old)d (%(oldP)s)
" % {
'old': stats['old'], 'oldP' : fmtPerc(stats['oldP'])}
html += _("Young cards: ") + " %(young)d (%(youngP)s)
" % {
@@ -113,9 +126,9 @@ class DeckStats(object):
avgInt = self.getAverageIvl()
if avgInt:
html += _("Average interval: ") + ("%s ") % fmtFloat(avgInt) + _("days")
- html += "
"
- html += "
"
- html += "" + _("Correct Answers") + "
"
+ # Correct
+ ##################################################
+ html += "" + _("Correct Answers") + "
"
(mAll, mYes, mPerc) = self.getMatureCorrect()
(yAll, yYes, yPerc) = self.getYoungCorrect()
(nAll, nYes, nPerc) = self.getNewCorrect()
@@ -139,12 +152,14 @@ class DeckStats(object):
retval = ("%d " % reps) + ngettext("rep", "reps", reps)
retval += ("/%d " % days) + ngettext("day", "days", days)
return retval
+ # Recent work
+ ##################################################
if existing and avgInt:
- html += "" + _("Recent Work") + ""
- if sys.platform.startswith("darwin"):
- html += ""
- else:
- html += ""
+ html += "" + _("Recent Work") + "
"
+ html += self.info(_("""\
+The number of cards you have answered recently. Each time you answer a card,
+it counts as a repetition - or rep."""))
+ html += ""
html += tr(_("In last week"), repsPerDay(
self.getRepsDone(-7, 0),
self.getDaysReviewed(-7, 0)))
@@ -164,12 +179,12 @@ class DeckStats(object):
self.getRepsDone(-13000, 0),
self.getDaysReviewed(-13000, 0)))
html += "
"
-
- html += "
" + _("Average Daily Reviews") + ""
- if sys.platform.startswith("darwin"):
- html += ""
- else:
- html += ""
+ # Average daily
+ ##################################################
+ html += "" + _("Average Daily Reviews") + "
"
+ html += self.info(_("""\
+The number of cards answered in a period, divided by the days in that period."""))
+ html += ""
html += tr(_("Deck life"), ("%s ") % (
fmtFloat(self.getSumInverseRoundIvl())) + _("cards/day"))
html += tr(_("In next week"), ("%s ") % (
@@ -187,12 +202,12 @@ class DeckStats(object):
html += tr(_("In last year"), ("%s ") % (
fmtFloat(self.getPastWorkloadPeriod(365))) + _("cards/day"))
html += "
"
-
- html += "
" + _("Average Added") + ""
- if sys.platform.startswith("darwin"):
- html += ""
- else:
- html += ""
+ # Average added
+ ##################################################
+ html += "" + _("Average Added") + "
"
+ html += self.info(_("""\
+The number of cards added in a period, divided by the days in that period."""))
+ html += ""
html += tr(_("Deck life"), _("%(a)s/day, %(b)s/mon") % {
'a': fmtFloat(self.newAverage()), 'b': fmtFloat(self.newAverage()*30)})
np = self.getNewPeriod(7)
@@ -211,12 +226,13 @@ class DeckStats(object):
html += tr(_("In last year"), _("%(a)d (%(b)s/day)") % (
{'a': np, 'b': fmtFloat(np / float(365))}))
html += "
"
-
- html += "
" + _("Average New Seen") + ""
- if sys.platform.startswith("darwin"):
- html += ""
- else:
- html += ""
+ # Average first seen
+ ##################################################
+ html += "" + _("Average First Seen") + "
"
+ html += self.info(_("""\
+The number of cards seen for the first time in a period, divided by the days
+in that period."""))
+ html += ""
np = self.getFirstPeriod(7)
html += tr(_("In last week"), _("%(a)d (%(b)s/day)") % (
{'a': np, 'b': fmtFloat(np / float(7))}))
@@ -233,8 +249,13 @@ class DeckStats(object):
html += tr(_("In last year"), _("%(a)d (%(b)s/day)") % (
{'a': np, 'b': fmtFloat(np / float(365))}))
html += "
"
-
- html += "
" + _("Card Ease") + "
"
+ # Card ease
+ ##################################################
+ html += "" + _("Card Ease") + "
"
+ html += self.info(_("""\
+A card's factor is the amount its interval will increase when you answer 'good'.
+A card with an interval of 10 days and a factor of 2.5 will get a next
+interval of 25 days."""))
html += _("Lowest factor: %.2f") % d.db.scalar(
"select min(factor)/1000.0 from cards") + "
"
html += _("Average factor: %.2f") % d.db.scalar(
@@ -242,6 +263,7 @@ class DeckStats(object):
html += _("Highest factor: %.2f") % d.db.scalar(
"select max(factor)/1000.0 from cards") + "
"
+ html += ""
html = runFilter("deckStats", html)
return html