ground grade 9's questions in the textbook, and catch the book's own errors

پایه نهم تا دیروز ناقص بود: ۲۸ صفحه از کتاب ingest نشده بود و فصل ۸ (حجم و
مساحت) اصلاً وجود نداشت. حالا ۱۴۳ از ۱۴۳ صفحه رفته و برنامه‌ی درسی ۸ فصل،
۲۸ مبحث و ۲۵۸ درس دارد.

۱۷۱ سوالِ تازه از روی مسئله‌های واقعیِ همان کتاب ساخته شد (جمعِ فایل: ۳۳۹).
برخلافِ سوال‌های نمونه‌ی قبلی که از عنوانِ مبحث ساخته شده بودند، این‌ها به
مسئله‌ی مشخصی در کتاب وصل‌اند.

مهم‌تر از خودِ سوال‌ها، چیزی که وسطِ کار معلوم شد: **بخشی از راه‌حل‌هایی که
vision از PDF استخراج کرده غلط است.** ۱۷ مورد پیدا شد، از جمله:

    شمارنده‌های ۶۰ که نه اول‌اند و نه مرکب → کتاب: {۱, ۶۰}   (۶۰ مرکب است)
    x−y=۵ و y=x−۳ → کتاب: (۸,۵)            (خطوط موازی‌اند، بی‌جواب)
    نور در ۱۰۰ ساعت → کتاب: ۱۰۸×۱۰¹³        (ده برابر؛ درست ۱٫۰۸×۱۰¹⁴)
    |۱−√۳| → کتاب: ۱−√۳                     (منفی است؛ درست √۳−۱)
    استوانه ۶۰cm×۱m → کتاب: ۲۸۲٫۷ m³        (خطای واحد؛ درست ۰٫۲۸۳)

اجرای قبلی با gpt-4o-mini همین جواب‌های غلط را بی‌صدا به‌عنوانِ گزینه‌ی درست
علامت می‌زد، چون فقط بازنویسی می‌کرد. مسیرِ تازه اول مسئله را مستقل حل می‌کند
و بعد با راه‌حلِ کتاب مقایسه می‌کند؛ هر اختلاف علامت می‌خورد و دستی بررسی شد.

۷۵ مسئله عمداً سوال نشدند — به شکل یا جدولی در کتاب ارجاع می‌دادند که در متن
نیست. حدس زدن در این موارد یعنی سوالِ بی‌جواب.

`seed_content --export` هم دیگر نمی‌تواند سوال‌ها را بی‌صدا پاک کند: فایل
دست‌نویس است و در دیتابیسِ هر ماشینی نیست، و یک export ساده آن را با آرایه‌ی
خالی بازنویسی می‌کرد. حالا خطا می‌دهد و `--only curriculum` را پیشنهاد می‌کند.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-15 20:40:09 +03:30
parent 0c374fed99
commit 1131569b76
3 changed files with 3172 additions and 8 deletions

View File

@@ -44,10 +44,13 @@ class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument('--export', action='store_true',
help='به‌جای وارد کردن، از دیتابیسِ فعلی خروجی بگیر.')
parser.add_argument('--only', choices=('curriculum', 'questions'), default=None,
help='فقط یکی از دو فایل را خروجی بگیر.')
parser.add_argument('--dry-run', action='store_true',
help='فقط گزارش بده؛ چیزی ننویس.')
def handle(self, *args, **options):
self.only = options.get('only')
if options['export']:
return self._export()
return self._load(dry_run=options['dry_run'])
@@ -66,21 +69,37 @@ class Command(BaseCommand):
curriculum = curriculum_io.export_curriculum(grades)
rows = question_io.export_questions_by_path(questions)
# محافظ در برابرِ پاک شدنِ خاموشِ سوال‌ها: فایلِ سوال‌ها دست‌نویس است و
# ممکن است در دیتابیسِ این ماشین نباشد (مثلاً وقتی فقط کوریکولوم را
# محلی ساخته‌ایم). یک export بی‌احتیاط آن را با آرایه‌ی خالی بازنویسی
# می‌کرد و کلِ کار از بین می‌رفت — بدونِ خطا.
only = self.only
if only != 'questions':
_write_json(CURRICULUM_FILE, curriculum)
if only != 'curriculum':
if not rows and _has_questions(QUESTIONS_FILE):
raise CommandError(
f'{QUESTIONS_FILE.name} سوال دارد ولی دیتابیسِ این ماشین ندارد؛ '
'بازنویسی‌اش یعنی پاک شدنشان. اگر کوریکولوم را می‌خواهید: '
'--export --only curriculum'
)
_write_json(QUESTIONS_FILE, {'questions': rows})
lessons = Lesson.objects.filter(node__unit__grade__in=grades).count()
self.stdout.write(self.style.SUCCESS(
f'نوشته شد: {CURRICULUM_FILE.name} '
f'({len(curriculum["grades"])} پایه، {lessons} درس) '
f'و {QUESTIONS_FILE.name} ({len(rows)} سوال)'
))
written = []
if only != 'questions':
written.append(f'{CURRICULUM_FILE.name} '
f'({len(curriculum["grades"])} پایه، {lessons} درس)')
if only != 'curriculum':
written.append(f'{QUESTIONS_FILE.name} ({len(rows)} سوال)')
self.stdout.write(self.style.SUCCESS('نوشته شد: ' + ' و '.join(written)))
skipped = Grade.objects.count() - grades.count()
if skipped:
self.stdout.write(
f' {skipped} پایه‌ی نمونه ([DEMO]/[SEED]) کنار گذاشته شد.'
)
if not rows:
if not rows and only != 'curriculum':
self.stdout.write(self.style.WARNING(
' هشدار: هیچ سوالِ واقعی‌ای برای خروجی نبود — '
'برنامه‌ی درسی بدونِ سوال منتشر می‌شود.'
@@ -134,6 +153,16 @@ class Command(BaseCommand):
return question_io.import_questions(parsed, skip_existing=True)
def _has_questions(path: Path) -> bool:
if not path.exists():
return False
try:
data = json.loads(path.read_text(encoding='utf-8'))
except json.JSONDecodeError:
return False
return bool(data.get('questions') if isinstance(data, dict) else data)
def _write_json(path: Path, payload) -> None:
# ensure_ascii=False تا فارسی در دیفِ گیت خوانا بماند، و newline انتهایی
# تا هر بار export یک دیفِ تمیز بدهد نه یک خطِ تغییرکرده‌ی الکی.

View File

@@ -282,6 +282,14 @@
{
"title": "محاسبه حاصل عبارات",
"introText": "۱. عبارات داخل پرانتز یا ریشه را محاسبه کنید. ۲. عملیات ریاضی را انجام دهید تا به حاصل نهایی برسید."
},
{
"title": "محاسبه قدر مطلق و ریشه دوم",
"introText": "برای محاسبه قدر مطلق یک عدد، اگر عدد مثبت یا صفر باشد، خود عدد و اگر منفی باشد، معکوس آن را در نظر می‌گیریم. برای محاسبه ریشه دوم، اگر عدد زیر ریشه منفی باشد، ریشه دوم تعریف نمی‌شود."
},
{
"title": "تکمیل جدول با محاسبه ریشه دوم",
"introText": "برای تکمیل جدول، ابتدا ریشه دوم هر عدد را محاسبه کرده و سپس در صورت نیاز، قدر مطلق آن را در نظر می‌گیریم."
}
]
}
@@ -1020,6 +1028,226 @@
{
"title": "ساده کردن عبارت گویا",
"introText": "برای ساده کردن یک عبارت گویا، صورت و مخرج را به عوامل اول تجزیه کرده و عوامل مشترک را حذف کنید."
},
{
"title": "ساده‌سازی عبارت‌های گویا",
"introText": "۱. صورت و مخرج کسر را تجزیه کنید.\n۲. عوامل مشترک صورت و مخرج را حذف کنید.\n۳. عبارت ساده شده را بنویسید."
},
{
"title": "تشخیص عبارت‌های ساده شده",
"introText": "۱. هر دو عبارت را ساده کنید.\n۲. بررسی کنید که آیا دو عبارت برابر هستند یا خیر."
},
{
"title": "یافتن مقادیر تعریف نشده",
"introText": "۱. مخرج کسر را برابر صفر قرار دهید.\n۲. معادله را حل کنید تا مقادیر تعریف نشده را بیابید."
},
{
"title": "ساده‌سازی حاصل عبارت",
"introText": "۱. صورت و مخرج کسر را تجزیه کنید.\n۲. عوامل مشترک صورت و مخرج را حذف کنید.\n۳. عبارت ساده شده را بنویسید."
},
{
"title": "محاسبه مقدار عبارت‌های گویا",
"introText": "۱. صورت و مخرج کسر را ساده کنید.\n۲. مقدار عددی را جایگذاری کنید.\n۳. عملیات ریاضی را انجام دهید تا مقدار نهایی به دست آید."
},
{
"title": "تشخیص عبارت‌های معادل",
"introText": "۱. هر عبارت را ساده کنید.\n۲. عبارات ساده شده را با یکدیگر مقایسه کنید.\n۳. عبارات معادل را مشخص کنید."
},
{
"title": "جایگذاری عبارت‌های گویا",
"introText": "۱. عبارت داده شده را بررسی کنید.\n۲. مقدار مجهول را با استفاده از معادله پیدا کنید.\n۳. مقدار به دست آمده را جایگذاری کنید."
}
]
},
{
"title": "محاسبات عبارت‌های گویا",
"order": 2,
"lessons": [
{
"title": "ضرب و تقسیم عبارت‌های گویا",
"introText": "۱. صورت و مخرج کسرها را به عوامل اول تجزیه کنید.\n۲. عوامل مشترک در صورت و مخرج را ساده کنید.\n۳. حاصل ضرب یا تقسیم را محاسبه کنید.\n۴. در صورت امکان، عبارت نهایی را ساده کنید."
},
{
"title": "جمع و تفریق عبارت‌های گویا",
"introText": "۱. مخرج مشترک برای همه کسرها پیدا کنید.\n۲. صورت‌ها را با توجه به مخرج مشترک جدید جمع یا تفریق کنید.\n۳. عبارت به دست آمده را ساده کنید."
},
{
"title": "ساده کردن عبارت‌های گویا",
"introText": "۱. صورت و مخرج را به صورت جداگانه ساده کنید.\n۲. صورت و مخرج را بر هم تقسیم کنید.\n۳. در صورت لزوم، صورت و مخرج را در عبارتی مناسب ضرب کنید."
},
{
"title": "ساده کردن کسر مرکب",
"introText": "۱. صورت و مخرج کسر مرکب را جداگانه ساده کنید.\n۲. صورت و مخرج را بر هم تقسیم کنید.\n۳. در صورت لزوم، صورت و مخرج را در عبارتی مناسب ضرب کنید."
},
{
"title": "ساده‌سازی عبارت‌های گویا",
"introText": "۱. مخرج‌ها را یکسان کنید.\n۲. صورت‌ها را با هم جمع یا تفریق کنید.\n۳. عبارت را تا حد ممکن ساده کنید."
},
{
"title": "محاسبه مساحت با استفاده از عبارت‌های گویا",
"introText": "۱. طول و عرض مستطیل را بر اساس داده‌ها تعیین کنید.\n۲. مساحت مستطیل را محاسبه کنید.\n۳. معادله را حل کنید تا طول و عرض را بیابید."
},
{
"title": "محاسبه محیط شکل",
"introText": "۱. طول هر ضلع را بر حسب x بنویسید. ۲. طول اضلاع را جمع کنید تا محیط به دست آید. ۳. عبارت به دست آمده را ساده کنید."
},
{
"title": "محاسبه مساحت مستطیل",
"introText": "۱. طول و عرض مستطیل را بر حسب x بنویسید. ۲. طول را در عرض ضرب کنید تا مساحت به دست آید."
},
{
"title": "تشخیص ساده شدن عبارت‌های گویا",
"introText": "عبارت‌ها را بررسی کنید و ببینید آیا می‌توان آن‌ها را ساده کرد یا خیر."
},
{
"title": "برابری عبارت‌های گویا",
"introText": "عبارت‌ها را با هم مقایسه کنید و ببینید آیا برابر هستند یا خیر."
},
{
"title": "محاسبه حاصل عبارت‌های گویا",
"introText": "مقادیر داده شده را در عبارت جایگذاری کنید و حاصل را محاسبه کنید."
},
{
"title": "تشخیص عبارت‌های درست و نادرست",
"introText": "برای تشخیص درستی یا نادرستی عبارت‌های جبری، باید هر عبارت را با استفاده از قوانین جبری بررسی کرده و درستی یا نادرستی آن را تعیین کنید."
},
{
"title": "نسبت محیط به مساحت",
"introText": "برای یافتن نسبت محیط به مساحت، ابتدا محیط و مساحت شکل را محاسبه کرده و سپس نسبت آن‌ها را به دست آورید."
}
]
},
{
"title": "تقسیم چندجمله‌ای‌ها",
"order": 3,
"lessons": [
{
"title": "تقسیم تک جمله‌ای بر تک جمله‌ای",
"introText": "برای تقسیم دو تک جمله‌ای، ضرایب را بر هم تقسیم کرده و توان‌های متغیرها را از هم کم می‌کنیم."
},
{
"title": "تقسیم چند جمله‌ای بر تک جمله‌ای",
"introText": "هر جمله از چند جمله‌ای را به صورت جداگانه بر تک جمله‌ای تقسیم کرده و نتایج را جمع می‌کنیم."
},
{
"title": "تقسیم چند جمله‌ای بر چند جمله‌ای",
"introText": "۱. چند جمله‌ای مقسوم و مقسوم‌علیه را مرتب کنید. ۲. جمله اول مقسوم را بر جمله اول مقسوم‌علیه تقسیم کنید. ۳. حاصل را در مقسوم‌علیه ضرب کرده و از مقسوم کم کنید. ۴. مراحل را تا زمانی که درجه باقی‌مانده کمتر از درجه مقسوم‌علیه شود، تکرار کنید."
},
{
"title": "تقسیم چندجمله‌ای‌ها",
"introText": "۱. چندجمله‌ای مقسوم را بر چندجمله‌ای مقسوم‌علیه تقسیم کنید. ۲. اولین جمله مقسوم را بر اولین جمله مقسوم‌علیه تقسیم کنید. ۳. حاصل را در مقسوم‌علیه ضرب کرده و از مقسوم کم کنید. ۴. مراحل را تا زمانی که درجه باقیمانده کمتر از درجه مقسوم‌علیه شود، تکرار کنید."
}
]
}
]
},
{
"title": "فصل ۸: حجم و مساحت",
"order": 8,
"nodes": [
{
"title": "حجم و مساحت کره",
"order": 1,
"lessons": [
{
"title": "محاسبه حجم کره و استوانه",
"introText": "۱. فرمول حجم کره: V = \\frac{4}{3} \\pi R^3\n۲. فرمول حجم استوانه: V = \\pi R^2 h\n۳. جایگذاری مقادیر داده شده در فرمول مناسب.\n۴. محاسبه و ساده‌سازی نتیجه."
},
{
"title": "محاسبه مساحت سطح کره",
"introText": "۱. شعاع کره را مشخص کنید.\n۲. از فرمول مساحت سطح کره کامل استفاده کنید: S = ۴πR².\n۳. اگر نیم‌کره باشد، مساحت را نصف کنید و سطح قاعده را اضافه کنید."
},
{
"title": "محاسبه حجم استوانه",
"introText": "۱. شعاع قاعده استوانه را با تقسیم قطر بر ۲ محاسبه کنید.\n۲. مساحت قاعده را با استفاده از فرمول πr^2 محاسبه کنید.\n۳. حجم استوانه را با ضرب مساحت قاعده در ارتفاع محاسبه کنید."
},
{
"title": "محاسبه ارتفاع مایع در استوانه",
"introText": "۱. حجم مایع را محاسبه کنید.\n۲. شعاع قاعده استوانه را با تقسیم قطر بر ۲ محاسبه کنید.\n۳. مساحت قاعده را با استفاده از فرمول πr^2 محاسبه کنید.\n۴. ارتفاع مایع را با تقسیم حجم مایع بر مساحت قاعده محاسبه کنید."
}
]
},
{
"title": "حجم هرم و مخروط",
"order": 2,
"lessons": [
{
"title": "حجم هرم",
"introText": "برای محاسبه حجم هرم، مساحت قاعده را در ارتفاع هرم ضرب کرده و سپس بر ۳ تقسیم می‌کنیم."
},
{
"title": "مقایسه حجم هرم‌ها",
"introText": "۱. مساحت قاعده هر هرم را محاسبه کنید.\n۲. ارتفاع هر هرم را بیابید.\n۳. حجم هر هرم را با استفاده از فرمول حجم هرم (۱/۳ × مساحت قاعده × ارتفاع) محاسبه کنید.\n۴. حجم‌ها را با یکدیگر مقایسه کنید."
},
{
"title": "مقایسه مساحت و ارتفاع هرم‌ها",
"introText": "۱. مساحت قاعده هر هرم را محاسبه کنید.\n۲. ارتفاع هر هرم را بیابید.\n۳. مقایسه کنید که آیا مساحت و ارتفاع‌ها برابر هستند یا خیر."
},
{
"title": "محاسبه حجم هرم",
"introText": "برای محاسبه حجم هرم، ابتدا مساحت قاعده را محاسبه کنید. سپس ارتفاع هرم را پیدا کنید. حجم هرم برابر است با یک سوم مساحت قاعده ضربدر ارتفاع."
},
{
"title": "محاسبه حجم و مساحت هرم",
"introText": "۱. محاسبه مساحت قاعده هرم.\n۲. محاسبه مساحت جانبی با استفاده از مساحت مثلث‌های جانبی.\n۳. استفاده از فرمول حجم هرم: V = (1/3) × مساحت قاعده × ارتفاع."
},
{
"title": "حجم مخروط",
"introText": "برای محاسبه حجم مخروط از فرمول V = (1/3) * π * R^2 * h استفاده می‌کنیم. در این فرمول R شعاع قاعده و h ارتفاع مخروط است."
},
{
"title": "مقایسه حجم‌ها",
"introText": "برای مقایسه حجم‌ها، ابتدا حجم هر شکل را جداگانه محاسبه کرده و سپس مقایسه می‌کنیم."
}
]
},
{
"title": "سطح و حجم",
"order": 3,
"lessons": [
{
"title": "گسترش مکعب و مکعب مستطیل",
"introText": "۱. ابعاد مکعب یا مکعب مستطیل را مشخص کنید. ۲. گسترش شکل را رسم کنید. ۳. اندازه هر ضلع را در گسترش مشخص کنید."
},
{
"title": "محاسبه مساحت گسترش هرم",
"introText": "۱. گسترش هرم را رسم کنید. ۲. اندازه‌های روی هرم را مشخص کنید. ۳. مساحت گسترش را با استفاده از فرمول‌های مربوطه محاسبه کنید."
},
{
"title": "محاسبه شعاع قاعده مخروط",
"introText": "۱. شعاع دایره را مشخص کنید. ۲. طول کمان را با استفاده از فرمول محیط دایره محاسبه کنید. ۳. شعاع قاعده مخروط را با استفاده از رابطه بین طول کمان و محیط دایره پیدا کنید."
},
{
"title": "محاسبه مساحت کل هرم",
"introText": "۱. طول بال‌ها را مشخص کنید. ۲. مساحت قاعده را محاسبه کنید. ۳. مساحت بال‌ها را محاسبه کنید. ۴. مجموع مساحت قاعده و بال‌ها را به دست آورید."
},
{
"title": "محاسبه حجم شکل حاصل از دوران",
"introText": "۱. شعاع قاعده شکل را مشخص کنید. ۲. ارتفاع شکل را مشخص کنید. ۳. از فرمول حجم برای محاسبه استفاده کنید."
},
{
"title": "حجم دوران",
"introText": "۱. شعاع دایره را مشخص کنید.\n۲. فرمول حجم دوران را بنویسید: V = πr²h.\n۳. مقادیر را در فرمول جایگذاری کنید و محاسبه کنید."
},
{
"title": "نمایش سه‌بعدی",
"introText": "۱. حجم شکل را مشخص کنید.\n۲. از جهت‌های مختلف به شکل نگاه کنید.\n۳. شکل‌های دوبعدی حاصل از هر جهت را رسم کنید."
},
{
"title": "برش کره",
"introText": "۱. کره را در نظر بگیرید.\n۲. سطح برش داده شده را مشخص کنید.\n۳. مساحت سطح برش داده شده را محاسبه کنید."
},
{
"title": "حجم کره",
"introText": "۱. شعاع کره را مشخص کنید.\n۲. فرمول حجم کره را بنویسید: V = 4/3πr³.\n۳. کسر مورد نظر را از حجم کل کم کنید."
},
{
"title": "محاسبه حجم و سطح اشکال هندسی",
"introText": "۱. فرمول حجم و سطح هر شکل را بنویسید. ۲. مقادیر داده شده را در فرمول جایگذاری کنید. ۳. محاسبات را انجام دهید تا حجم و سطح به دست آید."
},
{
"title": "نسبت حجم به سطح",
"introText": "۱. حجم و سطح هر شکل را محاسبه کنید. ۲. نسبت حجم به سطح را برای هر شکل پیدا کنید. ۳. نسبت‌ها را مقایسه کنید تا بزرگترین را بیابید."
}
]
}

File diff suppressed because it is too large Load Diff