Implement review feature in main interface
John Smith

John Smith commited on 2021-340 22:14:25
Showing 3 changed files, with 83 additions and 14 deletions.


The Review option of `main.lua` loads a deck,
checks which prompts the user must review,
presents these prompts for the user to review,
and records updated records to the deck file.
... ...
@@ -1,13 +1,14 @@
1
-PromptText: paper size: {A4} = {210 mm} x {297 mm}
2
-LastReview: 1636245675
3
-LastDelay: 65536
4
-Successes: 0
1
+
2
+LastReview: 1638933016
3
+LastReview: 1638933017
4
+LastReview: 1638933020
5
+LastDelay: 5374682
6
+LastDelay: 5374676
7
+LastDelay: 5374674
5 8
 Failures: 0
6
-LastReview: 1636245679
7
-LastDelay: 65536
8
-Successes: 0
9 9
 Failures: 0
10
-LastReview: 1636245683
11
-LastDelay: 65536
12
-Successes: 0
13 10
 Failures: 0
11
+Successes: 1
12
+Successes: 1
13
+Successes: 1
14
+PromptText: paper size: {A4} = {210 mm} x {297 mm}
... ...
@@ -2,6 +2,42 @@
2 2
     the main user interface for memoire
3 3
 ]]
4 4
 
5
+local Prompt = dofile "prompt.lua"
6
+local recrw = dofile "recrw.lua"
7
+local review = dofile "review.lua"
8
+
9
+--[[
10
+    load a deck (a table of tables of `Prompts`) from a Recfile
11
+]]
12
+local function loaddeck(fname)
13
+    local fh = io.open(fname)
14
+    if not fh then return nil end
15
+    local rt = fh:read "a"
16
+    if not rt then return nil end
17
+    fh:close()
18
+    local pr = recrw.read(rt)
19
+    if not pr then return nil end
20
+    local ep = Prompt:fromrecs(pr)
21
+    return ep
22
+end
23
+
24
+--[[
25
+    checks (returns boolean) if a response-string is affirmative
26
+]]
27
+local function isyes(s)
28
+    local f = s:sub(1, 1):lower()
29
+    return f == "y" or f == "t"
30
+end
31
+
32
+--[[
33
+    clears the terminal
34
+    implementation may be platform-specific
35
+]]
36
+local function clear()
37
+    -- XTerm
38
+    io.write("\x1bc")
39
+end
40
+
5 41
 --[[
6 42
     check action based on first command-line argument;
7 43
     if nothing valid given, default to help
... ...
@@ -38,7 +74,39 @@ elseif action == "h" then
38 74
     ))
39 75
 -- Review session
40 76
 elseif action == "r" then
41
-    -- TODO
77
+    local deck = loaddeck(deckfname)
78
+    -- review each card that needs it
79
+    for i, cg in ipairs(deck) do
80
+        for j, pr in ipairs(cg) do
81
+            if review.should(pr) then
82
+                local st = os.time()
83
+                io.write(string.format(
84
+                    "%s\n",
85
+                    pr.text:gsub("%%A", "___")
86
+                ))
87
+                io.read("l")
88
+                io.write(string.format(
89
+                    "%s\nDid you get it? ",
90
+                    pr.text:gsub("%%A", pr.ans)
91
+                ))
92
+                local resp = io.read("l")
93
+                review.update(pr, st, isyes(resp))
94
+                clear()
95
+            end
96
+        end
97
+    end
98
+    -- write out updated cards
99
+    -- TODO: split this out into a function
100
+    local rrf = {}
101
+    for i, cg in ipairs(deck) do
102
+        rrf[i] = Prompt:torec(cg)
103
+    end
104
+    local wot = recrw.write(rrf)
105
+    local wfh = io.open(deckfname, "w")
106
+    if not wfh then io.write("couldn't open output\n") end
107
+    local _wr, wr = wfh:write(wot)
108
+    if not _wr then io.write("couldn't write to output\n") end
109
+    wfh:close()
42 110
 -- Statistics
43 111
 elseif action == "s" then
44 112
     -- TODO
... ...
@@ -20,8 +20,8 @@ function Prompt:new(pt, ca, rts, rd, sc, fc)
20 20
     o.ans = ca
21 21
     o.time = tonumber(rts)
22 22
     o.delay = tonumber(rd)
23
-    n.succ = sc
24
-    n.fail = fc
23
+    o.succ = sc
24
+    o.fail = fc
25 25
     return o
26 26
 end
27 27
 
... ...
@@ -74,7 +74,7 @@ end
74 74
 ]]
75 75
 function Prompt:torec(prompts)
76 76
     local fspt = prompts[1]:spt()
77
-    local ret = { PromptText = { fspt }, LastReview = {}, LastDelay = {} }
77
+    local ret = { PromptText = { fspt }, LastReview = {}, LastDelay = {}, Successes = {}, Failures = {} }
78 78
     for i, pr in ipairs(prompts) do
79 79
         if pr:spt() ~= fspt then
80 80
             -- not from the same `PromptText`
81 81