""" کاتالوگِ دقیقِ collectionهای موجود روی Qdrant تیمِ دیگر (qdrant.tadrisino2.ir) — استخراج‌شده و بررسی‌شده در ۱۴۰۵/۰۶/۰۶ (2026-08-28). هدف: کاربر لازم نباشه رشته‌های دقیقِ گرید/فصل رو حفظ کنه. با داشتنِ subject و یک شماره‌ی ساده (شماره‌ی درس یا شماره‌ی فصل)، retrieval خودش: - کلیدِ فیلترِ درست رو انتخاب می‌کنه (ریاضی → chapter ، بقیه → lesson_number) - برای ریاضی، شماره‌ی فصل رو به رشته‌ی دقیقِ فصل تبدیل می‌کنه. اگه تیمِ دیگه collection جدید اضافه/تغییر داد، فقط همین فایل به‌روز بشه. """ from .textbooks import TEXTBOOKS, chapter_titles # --- درس‌های متنی: payload کلیدِ `lesson_number` (رشته) + `summary` دارد --- # نامِ collection = f"{subject} {grade}".lower() TEXT_SUBJECT_LESSON_FILTER_KEY = 'lesson_number' # --- ریاضی: payload کلیدِ `chapter` (رشته) + `generalSolution` دارد، `summary` ندارد --- MATH_LESSON_FILTER_KEY = 'chapter' # subjectهایی که ساختارِ «ریاضی» دارند (فیلتر با chapter، متن از generalSolution) # «حسابان» کتابِ رشته‌ی ریاضی‌فیزیک در پایه‌های یازدهم/دوازدهم است و دقیقاً # همان شکلِ payload را دارد. اگر اینجا نباشد، retrieval آن را درسِ متنی حساب # می‌کند و به‌جای `chapter` روی `lesson_number` فیلتر می‌زند — بدونِ هیچ خطایی # همیشه صفر نتیجه. MATH_SUBJECTS = {'ریاضی', 'حسابان', 'هندسه', 'آمار و احتمال', 'گسسته'} # فصول ریاضی به تفکیکِ (subject, grade) — کلیدِ داخلی هم شماره‌ی فصل و هم # رشته‌ی کامل رو می‌پذیره. # # پایه‌های سوم/ششم/هفتم را تیمِ دیگر آپلود کرده بود و این جدول از روی دادهٔ # زنده‌ی Qdrant درآمده. پایه‌های نهم/دهم را خودمان ingest می‌کنیم، پس عنوانِ # فصلشان از rag/services/textbooks.py می‌آید تا رشته‌ای که ingest می‌نویسد و # رشته‌ای که retrieval رویش فیلتر می‌کند نتوانند از هم جدا بیفتند. MATH_CHAPTERS = { ('ریاضی', 'سوم'): { 1: 'فصل ۱: الگوها', 2: 'فصل ۲: عددهای چهار رقمی', 3: 'فصل ۳: عددهای کسری', 4: 'فصل ۴: ضرب و تقسیم', 5: 'فصل ۵: محیط و مساحت', 6: 'فصل ۶: جمع و تفریق', 7: 'فصل ۷: آمار و احتمال', 8: 'فصل ۸: ضرب عددها', }, ('ریاضی', 'ششم'): { 1: 'فصل ۱: عدد و الگوهای عددی', 2: 'فصل ۲: کسر', 3: 'فصل ۳: اعداد اعشاری', 4: 'فصل ۴: تقارن و مختصات', 5: 'فصل ۵: اندازه گیری', 6: 'فصل ۶: تناسب و درصد', 7: 'فصل ۷: تقریب', }, ('ریاضی', 'هفتم'): { 1: 'فصل ۱: راهبردهای حل مسئله', 2: 'فصل ۲: عددهای صحیح', 3: 'فصل ۳: جبر و معادله', 4: 'فصل ۴: هندسه و استدلال', 5: 'فصل ۵: شمارنده‌ها و اعداد اول', 6: 'فصل ۶: سطح و حجم', 7: 'فصل ۷: توان و جذر', 8: 'فصل ۸: بردار و مختصات', 9: 'فصل ۹: آمار و احتمال', }, } MATH_CHAPTERS.update({ (b.subject, b.grade): chapter_titles(b) for b in TEXTBOOKS.values() }) # درس‌های علوم/اجتماعی — فقط برای مرجع/اعتبارسنجی (lesson_number → عنوان). TEXT_LESSONS = { ('علوم تجربی', 'سوم'): { 1: 'زنگ علوم', 2: 'خوراکی‌ها', 3: 'اندازه‌گیری مواد', 4: 'مواد اطراف ما', 5: 'آب ماده‌ی باارزش', 6: 'زندگی ما و آب', 7: 'نور و مشاهده‌ی اجسام', 8: 'جستجو کنیم و بسازیم', 9: 'نیرو همه‌جا ۱', 10: 'نیرو همه‌جا ۲', 11: 'بکارید و ببینید', 12: 'هرکدام جای خود ۱', 13: 'هرکدام جای خود ۲', 14: 'از گذشته تا آینده(نگهداری مواد غذایی)', }, ('مطالعات اجتماعی', 'ششم'): {1: 'lesson_1', 2: 'lesson_2', 3: 'lesson_3', 9: 'lesson_9'}, ('مطالعات اجتماعی', 'چهارم'): {1: 'lesson_1', 2: 'lesson_2', 3: 'lesson_3'}, } # فهرستِ کاملِ collectionهای موجود (نامِ نهایی، lowercase). KNOWN_COLLECTIONS = { 'ریاضی سوم', 'ریاضی ششم', 'ریاضی هفتم', 'علوم تجربی سوم', 'مطالعات اجتماعی ششم', 'مطالعات اجتماعی چهارم', } | {b.key for b in TEXTBOOKS.values()} def is_math_subject(subject: str) -> bool: return (subject or '').strip() in MATH_SUBJECTS def filter_key_for_subject(subject: str) -> str: return MATH_LESSON_FILTER_KEY if is_math_subject(subject) else TEXT_SUBJECT_LESSON_FILTER_KEY def resolve_math_chapter(subject: str, grade: str, lesson_or_chapter) -> str | None: """ برای ریاضی: ورودی می‌تونه شماره‌ی فصل (2 / '2' / '۲') یا خودِ رشته‌ی کامل باشه. خروجی رشته‌ی دقیقِ `chapter` در Qdrant یا None. """ if lesson_or_chapter is None: return None table = MATH_CHAPTERS.get((( subject or '').strip(), (grade or '').strip())) text = str(lesson_or_chapter).strip() if text.startswith('فصل'): return text # نرمال‌سازی ارقامِ فارسی → لاتین trans = str.maketrans('۰۱۲۳۴۵۶۷۸۹', '0123456789') digits = text.translate(trans) if table and digits.isdigit() and int(digits) in table: return table[int(digits)] return text or None