John Smith commited on 2022-323 22:54:29
Showing 2 changed files, with 60 additions and 19 deletions.
* reorganise code * fix bug encountered for small datasets * allow user to filter for cards containing a given query * show upcoming review quantities
| ... | ... |
@@ -136,7 +136,7 @@ local function showpctiles(list, pctiles, func, name) |
| 136 | 136 |
end |
| 137 | 137 |
s = s .. "\n" .. name |
| 138 | 138 |
for _, v in ipairs(pctiles) do |
| 139 |
- s = s .. "\t" .. func(list[math.floor(v * #list)]) |
|
| 139 |
+ s = s .. "\t" .. func(list[math.ceil(v * #list)]) |
|
| 140 | 140 |
end |
| 141 | 141 |
return s .. "\n" |
| 142 | 142 |
end |
| ... | ... |
@@ -329,24 +329,43 @@ local actions = {
|
| 329 | 329 |
s = {
|
| 330 | 330 |
desc = "(s)tatistics", |
| 331 | 331 |
nd = true, |
| 332 |
- fn = function(config, deck, deckfname) |
|
| 332 |
+ nq = true, |
|
| 333 |
+ fn = function(config, deck, deckfname, qs) |
|
| 334 |
+ local tcc = 0 |
|
| 333 | 335 |
local tsc = 0 |
| 334 | 336 |
local tfc = 0 |
| 337 |
+ local spc = 0 |
|
| 335 | 338 |
local expdeck = {}
|
| 336 | 339 |
for _, card in ipairs(deck) do |
| 340 |
+ local rtc |
|
| 337 | 341 |
for _, pr in ipairs(card) do |
| 342 |
+ if not qs or (pr.text:find(qs) or pr.ans:find(qs)) then |
|
| 343 |
+ rtc = true |
|
| 338 | 344 |
table.insert(expdeck, pr) |
| 339 | 345 |
tsc = tsc + pr.succ |
| 340 | 346 |
tfc = tfc + pr.fail |
| 347 |
+ if pr.delay < 0 then |
|
| 348 |
+ spc = spc + 1 |
|
| 349 |
+ end |
|
| 350 |
+ end |
|
| 351 |
+ end |
|
| 352 |
+ if rtc then |
|
| 353 |
+ tcc = tcc + 1 |
|
| 341 | 354 |
end |
| 342 | 355 |
end |
| 356 |
+ local qfn |
|
| 357 |
+ if qs then |
|
| 358 |
+ qfn = string.format(" (filtered with query %q)", qs)
|
|
| 359 |
+ else |
|
| 360 |
+ qfn = "" |
|
| 361 |
+ end |
|
| 343 | 362 |
io.write(string.format( |
| 344 |
- "%s has %d cards and %d total prompts\n", |
|
| 345 |
- deckfname, #deck, #expdeck |
|
| 363 |
+ "%s%s has %d cards and %d total prompts\n", |
|
| 364 |
+ deckfname, qfn, tcc, #expdeck |
|
| 346 | 365 |
)) |
| 347 | 366 |
io.write(string.format( |
| 348 |
- "(average %.2f prompts per card).\n", |
|
| 349 |
- #expdeck / #deck |
|
| 367 |
+ "(average %.2f prompts per card, %d/%.1f%% prompts suspended).\n", |
|
| 368 |
+ #expdeck / tcc, spc, 100 * spc / #expdeck |
|
| 350 | 369 |
)) |
| 351 | 370 |
io.write(string.format( |
| 352 | 371 |
"The deck's prompts have been reviewed a total of %d times\n", |
| ... | ... |
@@ -356,30 +375,46 @@ local actions = {
|
| 356 | 375 |
"(average %.2f reviews per prompt), overall retention %.2f%%.\n", |
| 357 | 376 |
(tsc + tfc) / #expdeck, 100 * tsc / (tsc + tfc) |
| 358 | 377 |
)) |
| 359 |
- table.sort(expdeck, function(a, b) |
|
| 360 |
- return a.ease < b.ease |
|
| 361 |
- end) |
|
| 378 |
+ table.sort(expdeck, function(a, b) return a.ease < b.ease end) |
|
| 362 | 379 |
io.write("\n" .. showpctiles(expdeck, { 0.01, 0.05, 0.1, 0.25, 0.5, 0.8, 0.95 }, function(pr)
|
| 363 | 380 |
return string.format("%.2f", pr.ease)
|
| 364 | 381 |
end, "Ease")) |
| 365 |
- table.sort(expdeck, function(a, b) |
|
| 366 |
- return a:retention() < b:retention() |
|
| 367 |
- end) |
|
| 382 |
+ table.sort(expdeck, function(a, b) return a.delay > 0 and a.delay < b.delay end) |
|
| 383 |
+ io.write("\n" .. showpctiles(expdeck, { 0.01, 0.05, 0.2, 0.5, 0.8, 0.95, 0.99 }, function(pr)
|
|
| 384 |
+ return disptime(pr.delay) |
|
| 385 |
+ end, "Delay")) |
|
| 386 |
+ table.sort(expdeck, function(a, b) return a:retention() < b:retention() end) |
|
| 368 | 387 |
io.write("\n" .. showpctiles(expdeck, { 0.01, 0.05, 0.1, 0.15, 0.2, 0.25, 0.4 }, function(pr)
|
| 369 | 388 |
return math.floor(100 * pr:retention()) |
| 370 | 389 |
end, "Ret. %")) |
| 371 |
- table.sort(expdeck, function(a, b) |
|
| 372 |
- return a.succ + a.fail < b.succ + b.fail |
|
| 373 |
- end) |
|
| 374 |
- io.write("\n" .. showpctiles(expdeck, { 0.25, 0.5, 0.7, 0.85, 0.95, 0.99, 0.995 }, function(pr)
|
|
| 390 |
+ table.sort(expdeck, function(a, b) return a.succ + a.fail < b.succ + b.fail end) |
|
| 391 |
+ io.write("\n" .. showpctiles(expdeck, { 0.25, 0.5, 0.7, 0.85, 0.95, 0.99, 0.998 }, function(pr)
|
|
| 375 | 392 |
return pr.succ + pr.fail |
| 376 | 393 |
end, "Reviews")) |
| 377 |
- table.sort(expdeck, function(a, b) |
|
| 378 |
- return (a.created or 99^98) > (b.created or 99^99) |
|
| 379 |
- end) |
|
| 394 |
+ table.sort(expdeck, function(a, b) return (a.created or 99^98) > (b.created or 99^99) end) |
|
| 380 | 395 |
io.write("\n" .. showpctiles(expdeck, { 0.1, 0.25, 0.5, 0.75, 0.9, 0.95, 0.99 }, function(pr)
|
| 381 | 396 |
return disptime(os.time() - pr.created) |
| 382 | 397 |
end, "Age")) |
| 398 |
+ table.sort(deck, function(a, b) return #a < #b end) |
|
| 399 |
+ io.write("\n" .. showpctiles(deck, { 0.2, 0.5, 0.8, 0.95, 0.99, 0.998 }, function(card)
|
|
| 400 |
+ return #card |
|
| 401 |
+ end, "Prompts")) |
|
| 402 |
+ table.sort(expdeck, function(a, b) return a.time + a.delay < b.time + b.delay end) |
|
| 403 |
+ io.write("\nUpcoming due prompts wrt days from now:\n")
|
|
| 404 |
+ local ppi = 1 |
|
| 405 |
+ local mpi = 1 |
|
| 406 |
+ for dc = 1,100 do |
|
| 407 |
+ for uc = ppi,#expdeck do |
|
| 408 |
+ if expdeck[uc].time + expdeck[uc].delay - os.time() > dc * 86400 then |
|
| 409 |
+ mpi = uc |
|
| 410 |
+ break |
|
| 411 |
+ end |
|
| 412 |
+ end |
|
| 413 |
+ if dc <= 10 or dc % 10 == 0 then |
|
| 414 |
+ io.write(string.format("%d\t%s %d\n", dc, ("\u{2588}"):rep(math.ceil((mpi - ppi) / 10)), mpi - ppi))
|
|
| 415 |
+ end |
|
| 416 |
+ ppi = mpi |
|
| 417 |
+ end |
|
| 383 | 418 |
end |
| 384 | 419 |
}, |
| 385 | 420 |
|
| ... | ... |
@@ -95,6 +95,12 @@ if action.nd then |
| 95 | 95 |
else |
| 96 | 96 |
io.write("Bad prompt index (must be cardnum:promptnum)\n")
|
| 97 | 97 |
end |
| 98 |
+ elseif action.nq then |
|
| 99 |
+ local qs |
|
| 100 |
+ if arg[2] then |
|
| 101 |
+ qs = arg[2] |
|
| 102 |
+ end |
|
| 103 |
+ deck = action.fn(config, deck, deckfname, qs) |
|
| 98 | 104 |
else |
| 99 | 105 |
deck = action.fn(config, deck, deckfname) |
| 100 | 106 |
end |
| 101 | 107 |