John Smith commited on 2022-306 22:44:44
Showing 2 changed files, with 73 additions and 4 deletions.
The "s" option on main.lua leads it to display statistics about the user's deck: totals, averages, and percentile values.
| ... | ... |
@@ -123,6 +123,22 @@ local function badness(pr) |
| 123 | 123 |
return pr.fail / (pr.fail + pr.succ) * math.log(pr.fail) |
| 124 | 124 |
end |
| 125 | 125 |
|
| 126 |
+--[[ |
|
| 127 |
+ show list of selected percentile-samples into a list, |
|
| 128 |
+ with each entry modulated by the given function |
|
| 129 |
+]] |
|
| 130 |
+local function showpctiles(list, pctiles, func, name) |
|
| 131 |
+ local s = "%ile" |
|
| 132 |
+ for _, v in ipairs(pctiles) do |
|
| 133 |
+ s = string.format("%s\t%.1f", s, 100 * v)
|
|
| 134 |
+ end |
|
| 135 |
+ s = s .. "\n" .. name |
|
| 136 |
+ for _, v in ipairs(pctiles) do |
|
| 137 |
+ s = s .. "\t" .. func(list[math.floor(v * #list)]) |
|
| 138 |
+ end |
|
| 139 |
+ return s .. "\n" |
|
| 140 |
+end |
|
| 141 |
+ |
|
| 126 | 142 |
local actions = {
|
| 127 | 143 |
a = {
|
| 128 | 144 |
desc = "(a)dd card", |
| ... | ... |
@@ -305,9 +321,58 @@ local actions = {
|
| 305 | 321 |
|
| 306 | 322 |
s = {
|
| 307 | 323 |
desc = "(s)tatistics", |
| 308 |
- nd = false, |
|
| 309 |
- fn = function() |
|
| 310 |
- io.write("Not yet implemented ...\n")
|
|
| 324 |
+ nd = true, |
|
| 325 |
+ fn = function(config, deck, deckfname) |
|
| 326 |
+ local tsc = 0 |
|
| 327 |
+ local tfc = 0 |
|
| 328 |
+ local expdeck = {}
|
|
| 329 |
+ for _, card in ipairs(deck) do |
|
| 330 |
+ for _, pr in ipairs(card) do |
|
| 331 |
+ table.insert(expdeck, pr) |
|
| 332 |
+ tsc = tsc + pr.succ |
|
| 333 |
+ tfc = tfc + pr.fail |
|
| 334 |
+ end |
|
| 335 |
+ end |
|
| 336 |
+ io.write(string.format( |
|
| 337 |
+ "%s has %d cards and %d total prompts\n", |
|
| 338 |
+ deckfname, #deck, #expdeck |
|
| 339 |
+ )) |
|
| 340 |
+ io.write(string.format( |
|
| 341 |
+ "(average %.2f prompts per card).\n", |
|
| 342 |
+ #expdeck / #deck |
|
| 343 |
+ )) |
|
| 344 |
+ io.write(string.format( |
|
| 345 |
+ "The deck's prompts have been reviewed a total of %d times\n", |
|
| 346 |
+ tsc + tfc |
|
| 347 |
+ )) |
|
| 348 |
+ io.write(string.format( |
|
| 349 |
+ "(average %.2f reviews per prompt), overall retention %.2f%%.\n", |
|
| 350 |
+ (tsc + tfc) / #expdeck, 100 * tsc / (tsc + tfc) |
|
| 351 |
+ )) |
|
| 352 |
+ table.sort(expdeck, function(a, b) |
|
| 353 |
+ return a.ease < b.ease |
|
| 354 |
+ end) |
|
| 355 |
+ io.write("\n" .. showpctiles(expdeck, { 0.01, 0.05, 0.1, 0.25, 0.5, 0.8, 0.95 }, function(pr)
|
|
| 356 |
+ return string.format("%.2f", pr.ease)
|
|
| 357 |
+ end, "Ease")) |
|
| 358 |
+ table.sort(expdeck, function(a, b) |
|
| 359 |
+ return a:retention() < b:retention() |
|
| 360 |
+ end) |
|
| 361 |
+ io.write("\n" .. showpctiles(expdeck, { 0.01, 0.05, 0.1, 0.15, 0.2, 0.25, 0.4 }, function(pr)
|
|
| 362 |
+ return math.floor(100 * pr:retention()) |
|
| 363 |
+ end, "Ret. %")) |
|
| 364 |
+ table.sort(expdeck, function(a, b) |
|
| 365 |
+ return a.succ + a.fail < b.succ + b.fail |
|
| 366 |
+ end) |
|
| 367 |
+ io.write("\n" .. showpctiles(expdeck, { 0.25, 0.5, 0.7, 0.85, 0.95, 0.99, 0.995 }, function(pr)
|
|
| 368 |
+ return pr.succ + pr.fail |
|
| 369 |
+ end, "Reviews")) |
|
| 370 |
+ table.sort(expdeck, function(a, b) |
|
| 371 |
+ return (a.created or 99^98) > (b.created or 99^99) |
|
| 372 |
+ end) |
|
| 373 |
+ io.write("\n" .. showpctiles(expdeck, { 0.1, 0.25, 0.5, 0.75, 0.9, 0.95, 0.99 }, function(pr)
|
|
| 374 |
+ return disptime(os.time() - pr.created) |
|
| 375 |
+ end, "Age")) |
|
| 311 | 376 |
end |
| 312 | 377 |
}, |
| 313 | 378 |
|
| ... | ... |
@@ -23,7 +23,7 @@ function Prompt:new(pt, ca, rts, rd, sc, fc, ct, ez) |
| 23 | 23 |
o.delay = tonumber(rd) |
| 24 | 24 |
o.succ = tonumber(sc) |
| 25 | 25 |
o.fail = tonumber(fc) |
| 26 |
- o.created = ct |
|
| 26 |
+ o.created = tonumber(ct) |
|
| 27 | 27 |
o.ease = tonumber(ez) |
| 28 | 28 |
return o |
| 29 | 29 |
end |
| ... | ... |
@@ -37,6 +37,10 @@ function Prompt:__tostring() |
| 37 | 37 |
) |
| 38 | 38 |
end |
| 39 | 39 |
|
| 40 |
+function Prompt:retention() |
|
| 41 |
+ return self.succ / (self.succ + self.fail) |
|
| 42 |
+end |
|
| 43 |
+ |
|
| 40 | 44 |
--[[ |
| 41 | 45 |
derive the `PromptText` used to create this `Prompt` |
| 42 | 46 |
]] |
| 43 | 47 |