mathly / mathly2 /scripts /content_gaps.py
3v324v23's picture
Add specifications for exercise tests, grades, learning path, lesson quizzes, readiness meter, real tests, rewards, simulation tests, skill mastery, smart board, student home, and test countdown
a7ffb22
Raw History Blame Contribute Delete
1.95 kB
"""List the content the bank still lacks. venv/bin/python -m mathly2.scripts.content_gaps [--min-questions N]
A skill needs: a solved example for the help button, and enough questions for "a different question" (practice, quizzes and tests
draw from them). Mistakes should say which skill to go back to. Lesson quizzes need no authored content: they are drawn from
the questions."""
from __future__ import annotations
import argparse
import sys
from mathly2.bank import load_bank
MIN_QUESTIONS = 10
def find_gaps(data: dict, min_questions: int = MIN_QUESTIONS) -> dict[str, list[str]]:
gaps: dict[str, list[str]] = {
"skills without a solved example": [],
"skills without questions": [],
f"skills with fewer than {min_questions} questions": [],
"mistakes without a skill to go back to": [],
}
for skill in data["skills"]:
sid = skill["id"]
if not skill.get("worked_example"):
gaps["skills without a solved example"].append(sid)
count = len(skill.get("questions", []))
if count == 0:
gaps["skills without questions"].append(sid)
elif count < min_questions:
gaps[f"skills with fewer than {min_questions} questions"].append(f"{sid} ({count})")
for mid, mistake in data["mistakes"].items():
if not mistake.get("back"):
gaps["mistakes without a skill to go back to"].append(mid)
return gaps
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
parser.add_argument("--min-questions", type=int, default=MIN_QUESTIONS)
args = parser.parse_args(argv)
gaps = find_gaps(load_bank().data, args.min_questions)
for title, items in gaps.items():
print(f"{title}: {len(items)}")
if 0 < len(items) <= 30:
print(" " + ", ".join(items))
return 0
if __name__ == "__main__":
sys.exit(main())