Lesson figures: 1-based step index, smaller graph ranges, no tick marks; regenerated 4 calculus-12 lessons

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-07 16:47:35 +03:30
parent 25b3d24eb4
commit b93f43ef02
2 changed files with 261 additions and 33 deletions

View File

@@ -20,15 +20,17 @@ from rag.services.generation import chat_model_for, completion_kwargs
PROMPT = (
'تو برای یک درسِ ریاضی (اپِ آموزشی) شکل‌های آموزشی می‌سازی. متنِ درس: «توضیح»، «مثال» و '
'«قدم‌ها» (شماره از صفر). فقط جاهایی شکل بگذار که دیدنش مفهوم را روشن می‌کند (نمودار، '
'«قدم‌ها» (شماره‌ی قدم‌ها از ۱، همان شماره‌ای که کاربر می‌بیند). فقط جاهایی شکل بگذار که دیدنش مفهوم را روشن می‌کند (نمودار، '
'انتقال، تقارن، محور، جدول، هندسه)؛ هر شکل باید دقیقاً همان چیزی را نشان دهد که آن بخش '
'می‌گوید، با همان اعداد. بخشِ بی‌نیاز شکل نمی‌گیرد؛ اگر هیچ‌جا لازم نبود []. حداکثر ۵ شکل.\n'
'خروجی فقط یک آرایه‌ی JSON: [{"where":"intro"|"example"|"step","index":0,"diagram":{...}}] '
'(index فقط برای step). بدونِ توضیح و بدونِ ```.\n'
'(index فقط برای step و همان شماره‌ی ۱‌به‌بعدِ قدم). بدونِ توضیح و بدونِ ```.\n'
'مثال‌های کاتالوگ فقط قالب‌اند: نقطه، تابع یا آیتمی را که این درس لازم ندارد کپی نکن؛ فقط '
'چیزهایی بگذار که همین شکل نشان می‌دهد (برای نمودارِ تابع معمولاً فقط items با type=function). نمودارِ خط‌شکسته یا تکه‌ای از نقطه‌ها را '
'با type=segment بین نقطه‌های متوالی بکش، نه type=line (آن خطِ بی‌پایان است). نقطه‌هایی که '
'در items نمی‌آیند تعریف نکن.\n\n'
'در items نمی‌آیند تعریف نکن. شکلِ هر قدم باید همان چیزی را نشان دهد که متنِ همان قدم می‌گوید '
'(نه قدمِ قبل یا بعد). بازه‌ی x نمودارِ تابع را کوچک بگیر (مثلاً دو واحد دور از رأس/نقطه‌های مهم) تا '
'مقدارِ y از حدود ۹ بیشتر نشود و منحنی له نشود؛ marks فقط برای یک منحنی بگذار تا برچسب‌ها روی هم نیفتند.\n\n'
)
@@ -57,7 +59,7 @@ class Command(BaseCommand):
spent = prompt_t = out_t = 0
for lesson in lessons:
body = (f'عنوان: {lesson.title}\nتوضیح: {lesson.intro_text}\nمثال: {lesson.example}\n'
+ '\n'.join(f'قدم {i}: {s}' for i, s in enumerate(lesson.steps or [])))
+ '\n'.join(f'قدم {i}: {s}' for i, s in enumerate(lesson.steps or [], 1)))
r = client.chat.completions.create(
model=model, **completion_kwargs(model),
messages=[{'role': 'system', 'content': PROMPT + diagram_mod.DIAGRAM_SPEC},
@@ -80,11 +82,16 @@ class Command(BaseCommand):
where = it.get('where') if isinstance(it, dict) else None
spec = diagram_mod.validate(it.get('diagram')) if where else None
idx = it.get('index')
if where == 'step' and isinstance(idx, int):
idx -= 1 # مدل ۱‌به‌بعد می‌نویسد؛ ذخیره از صفر
if (spec is None or where not in ('intro', 'example', 'step')
or (where == 'step' and not (isinstance(idx, int) and 0 <= idx < len(lesson.steps or [])))
or (where == 'example' and not lesson.example)):
dropped += 1
continue
for item in spec.get('items', []):
if item.get('type') == 'segment':
item.pop('ticks', None) # علامتِ «ضلع مساوی» روی نمودارِ تابع فقط شلوغی است
figures.append({'where': where, **({'index': idx} if where == 'step' else {}), 'diagram': spec})
self.stdout.write(f'درس {lesson.id} «{lesson.title}»: {len(figures)} شکل، {dropped} ردشده')
for f in figures: