File size: 4,570 Bytes
6bdf07a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
"""
scripts/generate_curriculum.py
Expands the seed curriculum with additional generated items and writes
data/T3.1_Math_Tutor/curriculum_full.json

Run once before starting the app:
    python3 scripts/generate_curriculum.py
"""
from __future__ import annotations
import json, random, sys
from pathlib import Path

SEED_PATH = Path("data/T3.1_Math_Tutor/curriculum_seed.json")
OUT_PATH  = Path("data/T3.1_Math_Tutor/curriculum_full.json")

# โ”€โ”€ Generators โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

def _counting_items(n_start: int) -> list[dict]:
    items = []
    for count in range(1, 11):
        diff = max(1, round(count / 2))
        for label in ["apple","star","ball","flower"]:
            items.append({
                "id":       f"cnt_gen_{count}_{label}",
                "skill":    "counting",
                "difficulty": diff,
                "answer_int": count,
                "stem_en":  f"How many {label}s do you see?",
                "stem_fr":  f"Combien de {label}s vois-tu ?",
                "stem_kin": f"Ubona {label} zingahe?",
                "stem_sw":  f"Unaona {label} ngapi?",
                "visual":   f"{label}_{count}",
            })
    return items


def _addition_items() -> list[dict]:
    items = []
    for a in range(0, 8):
        for b in range(0, 8):
            if a + b > 10:
                continue
            diff = max(1, min(9, a + b))
            items.append({
                "id":       f"add_gen_{a}_{b}",
                "skill":    "addition",
                "difficulty": diff,
                "answer_int": a + b,
                "stem_en":  f"{a} + {b} = ?",
                "stem_fr":  f"{a} + {b} = ?",
                "stem_kin": f"{a} + {b} = ?",
                "stem_sw":  f"{a} + {b} = ?",
                "visual":   "",
            })
    return items


def _subtraction_items() -> list[dict]:
    items = []
    for a in range(1, 11):
        for b in range(0, a + 1):
            diff = max(2, min(9, a))
            items.append({
                "id":       f"sub_gen_{a}_{b}",
                "skill":    "subtraction",
                "difficulty": diff,
                "answer_int": a - b,
                "stem_en":  f"{a} - {b} = ?",
                "stem_fr":  f"{a} - {b} = ?",
                "stem_kin": f"{a} - {b} = ?",
                "stem_sw":  f"{a} - {b} = ?",
                "visual":   "",
            })
    return items


def _number_sense_items() -> list[dict]:
    items = []
    for n in range(1, 10):
        items.append({
            "id": f"ns_gen_after_{n}",
            "skill": "number_sense", "difficulty": max(1, n//2),
            "answer_int": n + 1,
            "stem_en": f"What number comes after {n}?",
            "stem_fr": f"Quel nombre vient aprรจs {n} ?",
            "stem_kin": f"Ni umubare ukomeza {n}?",
            "stem_sw":  f"Nambari gani inakuja baada ya {n}?",
            "visual": "",
        })
        items.append({
            "id": f"ns_gen_before_{n+1}",
            "skill": "number_sense", "difficulty": max(1, n//2),
            "answer_int": n,
            "stem_en": f"What number comes before {n+1}?",
            "stem_fr": f"Quel nombre vient avant {n+1} ?",
            "stem_kin": f"Ni umubare uba imbere ya {n+1}?",
            "stem_sw":  f"Nambari gani inakuja kabla ya {n+1}?",
            "visual": "",
        })
    return items


# โ”€โ”€ Main โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

def main():
    with open(SEED_PATH, "r", encoding="utf-8") as f:
        seed = json.load(f)

    existing_ids = {item["id"] for item in seed}

    generated = (
        _counting_items(len(seed))
        + _addition_items()
        + _subtraction_items()
        + _number_sense_items()
    )

    # De-duplicate against seed
    new_items = [i for i in generated if i["id"] not in existing_ids]
    full      = seed + new_items
    random.shuffle(full)

    OUT_PATH.parent.mkdir(parents=True, exist_ok=True)
    with open(OUT_PATH, "w", encoding="utf-8") as f:
        json.dump(full, f, ensure_ascii=False, indent=2)

    print(f"โœ… Generated {len(full)} items ({len(seed)} seed + {len(new_items)} new)")
    print(f"   Saved to {OUT_PATH}")


if __name__ == "__main__":
    main()