| """ |
| parent_report.py — Print a progress report for a learner. |
| |
| Usage: |
| python3 parent_report.py <learner_name> [--lang en|fr|kin|sw] [--db tutor_progress.db] |
| """ |
| from __future__ import annotations |
| import argparse, sys |
| from pathlib import Path |
| from tutor.progress_store import ProgressStore |
|
|
| SKILL_ICONS = { |
| "counting": "🔢", |
| "number_sense": "🧠", |
| "addition": "➕", |
| "subtraction": "➖", |
| "word_problem": "📖", |
| } |
|
|
| LABELS = { |
| "en": {"title":"Progress Report","skill":"Skill","attempts":"Attempts", |
| "correct":"Correct","accuracy":"Accuracy","none":"No data yet."}, |
| "fr": {"title":"Rapport de progrès","skill":"Compétence","attempts":"Essais", |
| "correct":"Corrects","accuracy":"Précision","none":"Pas encore de données."}, |
| "kin": {"title":"Raporo y'Imbere","skill":"Ubumenyi","attempts":"Ibigeragezwa", |
| "correct":"Byikosowe","accuracy":"Ubushobozi","none":"Nta makuru arahari."}, |
| "sw": {"title":"Ripoti ya Maendeleo","skill":"Ujuzi","attempts":"Majaribio", |
| "correct":"Sahihi","accuracy":"Usahihi","none":"Hakuna data bado."}, |
| } |
|
|
|
|
| def main(): |
| parser = argparse.ArgumentParser(description="Math Tutor parent report") |
| parser.add_argument("learner_id", help="Learner name / ID") |
| parser.add_argument("--lang", default="en", choices=["en","fr","kin","sw"]) |
| parser.add_argument("--db", default="tutor_progress.db") |
| args = parser.parse_args() |
|
|
| db_path = Path(args.db) |
| if not db_path.exists(): |
| print(f"Database not found: {db_path}") |
| sys.exit(1) |
|
|
| store = ProgressStore(db_path) |
| summary = store.skill_summary(args.learner_id) |
| L = LABELS.get(args.lang, LABELS["en"]) |
|
|
| print(f"\n{'='*50}") |
| print(f" {L['title']}: {args.learner_id}") |
| print(f"{'='*50}") |
|
|
| if not summary: |
| print(f" {L['none']}") |
| else: |
| print(f" {'':2} {L['skill']:<16} {L['attempts']:>9} {L['correct']:>9} {L['accuracy']:>10}") |
| print(f" {'-'*50}") |
| for skill, data in sorted(summary.items()): |
| icon = SKILL_ICONS.get(skill, " ") |
| acc = f"{data['accuracy']*100:.0f}%" |
| print(f" {icon} {skill:<16} {data['attempts']:>9} {data['correct']:>9} {acc:>10}") |
|
|
| total_attempts = sum(d["attempts"] for d in summary.values()) |
| total_correct = sum(d["correct"] for d in summary.values()) |
| overall_acc = f"{total_correct/total_attempts*100:.0f}%" if total_attempts else "—" |
| print(f"\n Overall: {total_correct}/{total_attempts} correct ({overall_acc})") |
| print(f"{'='*50}\n") |
|
|
|
|
| if __name__ == "__main__": |
| main() |
|
|