Monkeytype pylib/anki/stats.py

This commit is contained in:
Alan Du 2020-02-26 20:23:03 -05:00
parent 1942d97cf5
commit ad90af3c37

View file

@ -6,7 +6,7 @@ from __future__ import annotations
import datetime import datetime
import json import json
import time import time
from typing import Any, Dict, List, Optional, Tuple from typing import Any, Dict, List, Optional, Sequence, Tuple, Union
import anki import anki
from anki.consts import * from anki.consts import *
@ -17,6 +17,7 @@ from anki.utils import ids2str
# Card stats # Card stats
########################################################################## ##########################################################################
PERIOD_MONTH = 0 PERIOD_MONTH = 0
PERIOD_YEAR = 1 PERIOD_YEAR = 1
PERIOD_LIFE = 2 PERIOD_LIFE = 2
@ -71,15 +72,15 @@ class CardStats:
self.txt += "</table>" self.txt += "</table>"
return self.txt return self.txt
def addLine(self, k, v) -> None: def addLine(self, k: str, v: Union[int, str]) -> None:
self.txt += self.makeLine(k, v) self.txt += self.makeLine(k, v)
def makeLine(self, k, v) -> str: def makeLine(self, k: str, v: Union[str, int]) -> str:
txt = "<tr><td align=left style='padding-right: 3px;'>" txt = "<tr><td align=left style='padding-right: 3px;'>"
txt += "<b>%s</b></td><td>%s</td></tr>" % (k, v) txt += "<b>%s</b></td><td>%s</td></tr>" % (k, v)
return txt return txt
def date(self, tm) -> str: def date(self, tm: float) -> str:
return time.strftime("%Y-%m-%d", time.localtime(tm)) return time.strftime("%Y-%m-%d", time.localtime(tm))
def time(self, tm: float) -> str: def time(self, tm: float) -> str:
@ -114,7 +115,7 @@ class CollectionStats:
self.wholeCollection = False self.wholeCollection = False
# assumes jquery & plot are available in document # assumes jquery & plot are available in document
def report(self, type=PERIOD_MONTH) -> str: def report(self, type: int = PERIOD_MONTH) -> str:
# 0=month, 1=year, 2=deck life # 0=month, 1=year, 2=deck life
self.type = type self.type = type
from .statsbg import bg from .statsbg import bg
@ -131,7 +132,7 @@ class CollectionStats:
txt += self._section(self.footer()) txt += self._section(self.footer())
return "<center>%s</center>" % txt return "<center>%s</center>" % txt
def _section(self, txt) -> str: def _section(self, txt: str) -> str:
return "<div class=section>%s</div>" % txt return "<div class=section>%s</div>" % txt
css = """ css = """
@ -212,7 +213,7 @@ from revlog where id > ? """
# Due and cumulative due # Due and cumulative due
###################################################################### ######################################################################
def get_start_end_chunk(self, by="review") -> Tuple[int, Optional[int], int]: def get_start_end_chunk(self, by: str = "review") -> Tuple[int, Optional[int], int]:
start = 0 start = 0
if self.type == PERIOD_MONTH: if self.type == PERIOD_MONTH:
end, chunk = 31, 1 end, chunk = 31, 1
@ -273,7 +274,7 @@ from revlog where id > ? """
txt += self._dueInfo(tot, len(totd) * chunk) txt += self._dueInfo(tot, len(totd) * chunk)
return txt return txt
def _dueInfo(self, tot, num) -> str: def _dueInfo(self, tot: int, num: int) -> str:
i: List[str] = [] i: List[str] = []
self._line( self._line(
i, _("Total"), self.col.tr(TR.STATISTICS_REVIEWS, reviews=tot), i, _("Total"), self.col.tr(TR.STATISTICS_REVIEWS, reviews=tot),
@ -290,7 +291,9 @@ and due = ?"""
self._line(i, _("Due tomorrow"), tomorrow) self._line(i, _("Due tomorrow"), tomorrow)
return self._lineTbl(i) return self._lineTbl(i)
def _due(self, start=None, end=None, chunk=1) -> Any: def _due(
self, start: Optional[int] = None, end: Optional[int] = None, chunk: int = 1
) -> Any:
lim = "" lim = ""
if start is not None: if start is not None:
lim += " and due-:today >= %d" % start lim += " and due-:today >= %d" % start
@ -414,7 +417,13 @@ group by day order by day"""
return self._section(txt1) + self._section(txt2) return self._section(txt1) + self._section(txt2)
def _ansInfo( def _ansInfo(
self, totd, studied, first, unit, convHours=False, total=None self,
totd: List[Tuple[int, float]],
studied: int,
first: int,
unit: str,
convHours: bool = False,
total: Optional[int] = None,
) -> Tuple[str, int]: ) -> Tuple[str, int]:
assert totd assert totd
tot = totd[-1][1] tot = totd[-1][1]
@ -460,14 +469,16 @@ group by day order by day"""
) )
return self._lineTbl(i), int(tot) return self._lineTbl(i), int(tot)
def _splitRepData(self, data, spec) -> Tuple[List[dict], List[Tuple[Any, Any]]]: def _splitRepData(
self, data: List[Tuple[Any, ...]], spec: Sequence[Tuple[int, str, str]],
) -> Tuple[List[Dict[str, Any]], List[Tuple[Any, Any]]]:
sep: Dict[int, Any] = {} sep: Dict[int, Any] = {}
totcnt = {} totcnt = {}
totd: Dict[int, Any] = {} totd: Dict[int, Any] = {}
alltot = [] alltot = []
allcnt = 0 allcnt: float = 0
for (n, col, lab) in spec: for (n, col, lab) in spec:
totcnt[n] = 0 totcnt[n] = 0.0
totd[n] = [] totd[n] = []
for row in data: for row in data:
for (n, col, lab) in spec: for (n, col, lab) in spec:
@ -497,7 +508,7 @@ group by day order by day"""
) )
return (ret, alltot) return (ret, alltot)
def _added(self, num=7, chunk=1) -> Any: def _added(self, num: Optional[int] = 7, chunk: int = 1) -> Any:
lims = [] lims = []
if num is not None: if num is not None:
lims.append( lims.append(
@ -525,7 +536,7 @@ group by day order by day"""
chunk=chunk, chunk=chunk,
) )
def _done(self, num=7, chunk=1) -> Any: def _done(self, num: Optional[int] = 7, chunk: int = 1) -> Any:
lims = [] lims = []
if num is not None: if num is not None:
lims.append( lims.append(
@ -637,7 +648,7 @@ group by day order by day)"""
) )
return txt + self._lineTbl(i) return txt + self._lineTbl(i)
def _ivls(self) -> Tuple[list, int]: def _ivls(self) -> Tuple[List[Any], int]:
start, end, chunk = self.get_start_end_chunk() start, end, chunk = self.get_start_end_chunk()
lim = "and grp <= %d" % end if end else "" lim = "and grp <= %d" % end if end else ""
data = [ data = [
@ -712,7 +723,7 @@ select count(), avg(ivl), max(ivl) from cards where did in %s and queue = {QUEUE
txt += self._easeInfo(eases) txt += self._easeInfo(eases)
return txt return txt
def _easeInfo(self, eases) -> str: def _easeInfo(self, eases: List[Tuple[int, int, int]]) -> str:
types = {PERIOD_MONTH: [0, 0], PERIOD_YEAR: [0, 0], PERIOD_LIFE: [0, 0]} types = {PERIOD_MONTH: [0, 0], PERIOD_YEAR: [0, 0], PERIOD_LIFE: [0, 0]}
for (type, ease, cnt) in eases: for (type, ease, cnt) in eases:
if ease == 1: if ease == 1:
@ -909,7 +920,9 @@ when you answer "good" on a review."""
) )
return txt return txt
def _line(self, i, a, b, bold=True) -> None: def _line(
self, i: List[str], a: str, b: Union[int, str], bold: bool = True
) -> None:
# T: Symbols separating first and second column in a statistics table. Eg in "Total: 3 reviews". # T: Symbols separating first and second column in a statistics table. Eg in "Total: 3 reviews".
colon = _(":") colon = _(":")
if bold: if bold:
@ -923,7 +936,7 @@ when you answer "good" on a review."""
% (a, colon, b) % (a, colon, b)
) )
def _lineTbl(self, i) -> str: def _lineTbl(self, i: List[str]) -> str:
return "<table width=400>" + "".join(i) + "</table>" return "<table width=400>" + "".join(i) + "</table>"
def _factors(self) -> Any: def _factors(self) -> Any:
@ -969,7 +982,14 @@ from cards where did in %s"""
###################################################################### ######################################################################
def _graph( def _graph(
self, id, data, conf=None, type="bars", xunit=1, ylabel=_("Cards"), ylabel2="" self,
id: str,
data: Any,
conf: Optional[Any] = None,
type: str = "bars",
xunit: int = 1,
ylabel: str = _("Cards"),
ylabel2: str = "",
) -> str: ) -> str:
if conf is None: if conf is None:
conf = {} conf = {}
@ -1088,10 +1108,10 @@ $(function () {
self.col.decks.active() self.col.decks.active()
) )
def _title(self, title, subtitle="") -> str: def _title(self, title: str, subtitle: str = "") -> str:
return "<h1>%s</h1>%s" % (title, subtitle) return "<h1>%s</h1>%s" % (title, subtitle)
def _deckAge(self, by) -> int: def _deckAge(self, by: str) -> int:
lim = self._revlogLimit() lim = self._revlogLimit()
if lim: if lim:
lim = " where " + lim lim = " where " + lim
@ -1112,7 +1132,7 @@ $(function () {
return None return None
return end * chunk return end * chunk
def _avgDay(self, tot, num, unit) -> str: def _avgDay(self, tot: float, num: int, unit: str) -> str:
vals = [] vals = []
try: try:
vals.append(_("%(a)0.1f %(b)s/day") % dict(a=tot / float(num), b=unit)) vals.append(_("%(a)0.1f %(b)s/day") % dict(a=tot / float(num), b=unit))