Spaces:
Running on Zero
Running on Zero
Sync from GitHub via hub-sync
Browse files- learning_engine.py +10 -1
- server.py +6 -1
learning_engine.py
CHANGED
|
@@ -33,6 +33,7 @@ def init_session(deck: list[Card]) -> Session:
|
|
| 33 |
|
| 34 |
WEAK_TOPIC_THRESHOLD = 3.0 # avg grade below this = a topic the user is weak on
|
| 35 |
WEAK_LOOKAHEAD = 4 # how far down the queue we'll reach to surface a weak card
|
|
|
|
| 36 |
|
| 37 |
|
| 38 |
def next_card(session: Session) -> Card | None:
|
|
@@ -170,7 +171,15 @@ def apply_result(session: Session, card: Card, grade: GradeResult,
|
|
| 170 |
st["ease"] = min(3.0, st["ease"] + 0.1)
|
| 171 |
st["interval"] = max(2, int(st["interval"] * st["ease"]))
|
| 172 |
session["streak"] += 1
|
| 173 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 174 |
else:
|
| 175 |
st["lapses"] += 1
|
| 176 |
st["ease"] = max(1.3, st["ease"] - 0.2)
|
|
|
|
| 33 |
|
| 34 |
WEAK_TOPIC_THRESHOLD = 3.0 # avg grade below this = a topic the user is weak on
|
| 35 |
WEAK_LOOKAHEAD = 4 # how far down the queue we'll reach to surface a weak card
|
| 36 |
+
GRADUATE_AT_CORRECT = 2 # correct answers needed before a card leaves the queue
|
| 37 |
|
| 38 |
|
| 39 |
def next_card(session: Session) -> Card | None:
|
|
|
|
| 171 |
st["ease"] = min(3.0, st["ease"] + 0.1)
|
| 172 |
st["interval"] = max(2, int(st["interval"] * st["ease"]))
|
| 173 |
session["streak"] += 1
|
| 174 |
+
# Graduate once the card has been answered correctly GRADUATE_AT_CORRECT
|
| 175 |
+
# times — only then does it leave the queue for good. (reps counts every
|
| 176 |
+
# answer, lapses counts the misses, so reps - lapses = correct answers.)
|
| 177 |
+
# Re-enqueuing a card *every* time it was right is what made the queue
|
| 178 |
+
# never drain: the session never ended and the same cards came back with
|
| 179 |
+
# no forward progress. A still-learning card comes back later as before.
|
| 180 |
+
corrects = st["reps"] - st["lapses"]
|
| 181 |
+
if corrects < GRADUATE_AT_CORRECT:
|
| 182 |
+
_insert_at(session, card["id"], st["interval"]) # comes back later
|
| 183 |
else:
|
| 184 |
st["lapses"] += 1
|
| 185 |
st["ease"] = max(1.3, st["ease"] - 0.2)
|
server.py
CHANGED
|
@@ -197,6 +197,11 @@ def _view(session: dict) -> dict:
|
|
| 197 |
history = session["history"]
|
| 198 |
answered = len(history)
|
| 199 |
total = len(deck)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 200 |
|
| 201 |
stats: dict[str, dict] = {}
|
| 202 |
for h in history:
|
|
@@ -208,7 +213,7 @@ def _view(session: dict) -> dict:
|
|
| 208 |
return {
|
| 209 |
"total": total,
|
| 210 |
"answered": answered,
|
| 211 |
-
"posDisplay": min(
|
| 212 |
"streak": session["streak"],
|
| 213 |
"topicStats": stats,
|
| 214 |
"rail": [
|
|
|
|
| 197 |
history = session["history"]
|
| 198 |
answered = len(history)
|
| 199 |
total = len(deck)
|
| 200 |
+
# Cards that have graduated out of the queue (mastered this session). Progress
|
| 201 |
+
# tracks this rather than `answered` so the bar climbs as cards are mastered
|
| 202 |
+
# and reaches total exactly when the queue drains — instead of pinning at
|
| 203 |
+
# total/total the moment you've seen every card once.
|
| 204 |
+
mastered = total - len(session["queue"])
|
| 205 |
|
| 206 |
stats: dict[str, dict] = {}
|
| 207 |
for h in history:
|
|
|
|
| 213 |
return {
|
| 214 |
"total": total,
|
| 215 |
"answered": answered,
|
| 216 |
+
"posDisplay": min(mastered + 1, total) if total else 0,
|
| 217 |
"streak": session["streak"],
|
| 218 |
"topicStats": stats,
|
| 219 |
"rail": [
|