diagrams for every grade, sectioned prompt, repair of real model slips; fill lesson texts and thin islands
Diagrams: 14 kinds drawn by the app (plane with constructed points, graphs with computed roots/extrema/tangents, number lines with intervals, solids, charts, tables, Venn, mapping, trees, fractions, grids, groups, clock). The catalog is split by topic and only the matching sections go next to a question (200-1073 tokens instead of 1854). parse() repairs slips seen on 96 real book problems: Persian digits in JSON numbers, 2*pi, // comments, bare items, Venn with Persian set names. Measured: 45/48 valid on the second round, 0/8 on plain arithmetic; visual review of 83: 64 right, 3 weak, 16 wrong. Content: 82 new questions so no island has fewer than four; fill_lesson_texts writes Unit.blurb (58) and Lesson.example/steps (590) from verified book problems, never the lesson's own quiz problem. seed_content only fills empty fields, so admin edits survive a deploy. Tedi unlocks at 500 xp. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -93,6 +93,8 @@ def parse(raw: bytes) -> list[dict]:
|
||||
{
|
||||
'title': _text(lesson.get('title'), 'title', f'{nwhere} › نوع {li + 1}'),
|
||||
'intro_text': (lesson.get('introText') or lesson.get('intro_text') or ''),
|
||||
'example': str(lesson.get('example') or ''),
|
||||
'steps': [str(x) for x in (lesson.get('steps') or []) if str(x).strip()][:12],
|
||||
}
|
||||
for li, lesson in enumerate(lessons)
|
||||
],
|
||||
@@ -100,6 +102,7 @@ def parse(raw: bytes) -> list[dict]:
|
||||
|
||||
clean_units.append({
|
||||
'title': _text(unit.get('title'), 'title', uwhere),
|
||||
'blurb': str(unit.get('blurb') or '')[:120],
|
||||
'order': int(unit.get('order') or ui + 1),
|
||||
'nodes': clean_nodes,
|
||||
})
|
||||
@@ -136,6 +139,10 @@ def import_curriculum(grades: list[dict]) -> dict:
|
||||
defaults={'order': unit_row['order']},
|
||||
)
|
||||
counts['units'] += 1 if created else 0
|
||||
# متنِ ادمین برنده است: فقط خانهی خالی از فایل پر میشود
|
||||
if unit_row.get('blurb') and not unit.blurb:
|
||||
unit.blurb = unit_row['blurb']
|
||||
unit.save(update_fields=['blurb'])
|
||||
|
||||
for node_row in unit_row['nodes']:
|
||||
node, created = Node.objects.get_or_create(
|
||||
@@ -149,12 +156,24 @@ def import_curriculum(grades: list[dict]) -> dict:
|
||||
node=node, title=lesson_row['title'],
|
||||
defaults={'intro_text': lesson_row['intro_text']},
|
||||
)
|
||||
changed = []
|
||||
if created:
|
||||
counts['lessons'] += 1
|
||||
elif lesson_row['intro_text'] and lesson.intro_text != lesson_row['intro_text']:
|
||||
lesson.intro_text = lesson_row['intro_text']
|
||||
lesson.save(update_fields=['intro_text'])
|
||||
counts['updated'] += 1
|
||||
changed.append('intro_text')
|
||||
# مثال و قدمها فقط وقتی از فایل میآیند که در دیتابیس خالیاند؛ آنچه
|
||||
# کسی از پنلِ ادمین نوشته با دیپلوی بازنویسی نمیشود.
|
||||
if lesson_row.get('example') and not lesson.example:
|
||||
lesson.example = lesson_row['example']
|
||||
changed.append('example')
|
||||
if lesson_row.get('steps') and not lesson.steps:
|
||||
lesson.steps = lesson_row['steps']
|
||||
changed.append('steps')
|
||||
if changed:
|
||||
lesson.save(update_fields=changed)
|
||||
if not created:
|
||||
counts['updated'] += 1
|
||||
|
||||
return counts
|
||||
|
||||
@@ -171,12 +190,17 @@ def export_curriculum(grades_queryset) -> dict:
|
||||
{
|
||||
'title': unit.title,
|
||||
'order': unit.order,
|
||||
**({'blurb': unit.blurb} if unit.blurb else {}),
|
||||
'nodes': [
|
||||
{
|
||||
'title': node.title,
|
||||
'order': node.order,
|
||||
'lessons': [
|
||||
{'title': lesson.title, 'introText': lesson.intro_text}
|
||||
{
|
||||
'title': lesson.title, 'introText': lesson.intro_text,
|
||||
**({'example': lesson.example} if lesson.example else {}),
|
||||
**({'steps': lesson.steps} if lesson.steps else {}),
|
||||
}
|
||||
for lesson in node.lessons.all()
|
||||
],
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user