Raw LaTeX guard: vdots/ddots/sqrt( converted, leftover() sees bare words, matrix lesson and 4 intro texts fixed in seed

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-15 13:24:11 +03:30
parent 0c6e155232
commit 7973bf4100
4 changed files with 16 additions and 9 deletions

View File

@@ -25,7 +25,7 @@ _SYMBOLS = {
'angle': '∠', 'triangle': '△', 'approx': '≈', 'equiv': '≡', 'sim': '∼', 'cong': '≅', 'mid': '|', 'vert': '|',
'Delta': 'Δ', 'delta': 'δ', 'gamma': 'γ', 'lambda': 'λ', 'mu': 'μ', 'sigma': 'σ', 'Sigma': 'Σ', 'phi': 'φ',
'varphi': 'φ', 'omega': 'ω', 'epsilon': 'ε', 'varepsilon': 'ε', 'rho': 'ρ', 'tau': 'τ', 'Leftrightarrow': '⇔',
'iff': '⇔', 'implies': '⇒', 'leftarrow': '←', 'cdots': '⋯', 'therefore': '∴', 'setminus': '−', 'neg': '¬',
'iff': '⇔', 'implies': '⇒', 'leftarrow': '←', 'cdots': '⋯', 'vdots': '⋮', 'ddots': '⋱', 'therefore': '∴', 'setminus': '−', 'neg': '¬',
'quad': ' ', 'qquad': ' ', 'max': 'max', 'min': 'min', 'cot': 'cot', 'sec': 'sec', 'csc': 'csc',
'arcsin': 'arcsin', 'arccos': 'arccos', 'arctan': 'arctan', 'exp': 'exp', 'det': 'det', 'gcd': 'gcd',
'degree': '°', 'prime': '′',
@@ -69,7 +69,7 @@ def _strip_markdown(s: str) -> str:
def convert(text: str) -> str:
if not isinstance(text, str) or not re.search(r'[\\^$ÂÊ]|[A-Za-z]_|\*\*|__|`|^#{1,6}\s', text, re.M):
if not isinstance(text, str) or not re.search(r'[\\^$ÂÊ]|[A-Za-z]_|sqrt\(|vdots|ddots|\*\*|__|`|^#{1,6}\s', text, re.M):
return text
s = text
if re.search('[ÂÊ]', s):
@@ -87,6 +87,8 @@ def convert(text: str) -> str:
s = re.sub(r'\\(?:text|mathrm|operatorname)' + _GROUP, r'\1', s)
s = re.sub(r'\\[dt]?frac' + _GROUP + _GROUP, lambda m: f'{_wrap(m[1])}/{_wrap(m[2])}', s)
s = re.sub(r'\\sqrt' + _GROUP, lambda m: '√' + _wrap(m[1]), s)
s = re.sub(r'(?<![A-Za-z\\])sqrt\(', '√(', s) # sqrt(x) به‌شکلِ کد
s = re.sub(r'(?<![A-Za-z\\])(vdots|ddots)(?![A-Za-z])', lambda m: _SYMBOLS[m[1]], s) # بدونِ بک‌اسلش
s = re.sub(r'\\lim\s*_' + _GROUP, r'lim(\1)', s) # lim_{x→0} پایینِ حد است، نه زیرنویس
s = re.sub(r'\\(left|right)\s*', '', s)
s = s.replace('\\|', '|').replace('\\{', '{').replace('\\}', '}').replace('\\,', ' ').replace('\\ ', ' ')
@@ -112,7 +114,7 @@ def convert(text: str) -> str:
return s
_LEFTOVER = re.compile(r'\\[A-Za-z]+|\\[()\[\]]|\$|[_^]\{|\^[0-9۰-۹(a-z−+-]|\*\*|(?<![_\s])__|`|^#{1,6}\s', re.M)
_LEFTOVER = re.compile(r'\\[A-Za-z]+|(?<![A-Za-z])(?:vdots|ddots|cdots|ldots|dfrac|tfrac|sqrt\(|overrightarrow|widehat)(?![A-Za-z])|\\[()\[\]]|\$|[_^]\{|\^[0-9۰-۹(a-z−+-]|\*\*|(?<![_\s])__|`|^#{1,6}\s', re.M)
def leftover(text: str) -> list[str]:

View File

@@ -124536,7 +124536,7 @@
},
{
"title": "محاسبه مساحت چندضلعی‌های شبکه‌ای با استفاده از مختصات رئوس",
"introText": "برای محاسبه مساحت چندضلعی‌ای که رئوس آن روی نقاط شبکه‌ای با مختصات صحیح قرار دارند، از فرمول پیک استفاده می‌کنیم. ابتدا مختصات رئوس چندضلعی را به صورت (x,y) یادداشت می‌کنیم. سپس با استفاده از فرمول S = b/2 + i - 1 که در آن b تعداد نقاط روی محیط چندضلعی و i تعداد نقاط داخل چندضلعی است، مساحت را به دست می‌آوریم. اگر چندضلعی مربع یا مستطیل باشد، می‌توان مساحت را با اختلاف مختصات رئوس محاسبه کرد. همچنین برای مثلث‌های متساوی‌الاضلاع شبکه‌ای، فرمول مساحت به صورت S = (m² * sqrt(3))/4 است که m طول ضلع مثلث است. در نهایت با توجه به نوع چندضلعی و مختصات رئوس، مساحت را محاسبه می‌کنیم.",
"introText": "برای محاسبه مساحت چندضلعی‌ای که رئوس آن روی نقاط شبکه‌ای با مختصات صحیح قرار دارند، از فرمول پیک استفاده می‌کنیم. ابتدا مختصات رئوس چندضلعی را به صورت (x,y) یادداشت می‌کنیم. سپس با استفاده از فرمول S = b/2 + i - 1 که در آن b تعداد نقاط روی محیط چندضلعی و i تعداد نقاط داخل چندضلعی است، مساحت را به دست می‌آوریم. اگر چندضلعی مربع یا مستطیل باشد، می‌توان مساحت را با اختلاف مختصات رئوس محاسبه کرد. همچنین برای مثلث‌های متساوی‌الاضلاع شبکه‌ای، فرمول مساحت به صورت S = (m² * √(3))/4 است که m طول ضلع مثلث است. در نهایت با توجه به نوع چندضلعی و مختصات رئوس، مساحت را محاسبه می‌کنیم.",
"example": "مستطیل با رأس‌های (۲،۱) و (۲،۵) و (۷،۵) و (۷،۱) مساحتش؟",
"steps": [
"طول: ۷ − ۲ = ۵؛ عرض: ۵ − ۱ = ۴.",
@@ -165814,19 +165814,19 @@
},
{
"title": "برآورد بازه‌ای نسبت جامعه",
"introText": "1. فرض کنید n تعداد نمونه تصادفی ساده از جامعه بزرگ است و m تعداد نمونه‌هایی است که ویژگی مورد نظر را دارند.\n2. نسبت نمونه p را به صورت p = m/n محاسبه کنید.\n3. بازه اطمینان 95 درصد برای نسبت واقعی جامعه را با فرمول زیر محاسبه کنید:\n p - 2 * sqrt(p(1-p)/n) ≤ نسبت واقعی ≤ p + 2 * sqrt(p(1-p)/n)\n4. مقدار بازه اطمینان نشان‌دهنده حد خطا و دقت برآورد نسبت جامعه است.\n5. اگر بخواهیم دقت را افزایش دهیم، باید تعداد نمونه‌ها را افزایش دهیم که طول بازه اطمینان کاهش یابد.\n6. برای افزایش دقت k برابر، طول بازه اطمینان را بر sqrt(k) تقسیم می‌کنیم و تعداد نمونه‌ها را به k برابر افزایش می‌دهیم.",
"introText": "1. فرض کنید n تعداد نمونه تصادفی ساده از جامعه بزرگ است و m تعداد نمونه‌هایی است که ویژگی مورد نظر را دارند.\n2. نسبت نمونه p را به صورت p = m/n محاسبه کنید.\n3. بازه اطمینان 95 درصد برای نسبت واقعی جامعه را با فرمول زیر محاسبه کنید:\n p - 2 * √(p(1-p)/n) ≤ نسبت واقعی ≤ p + 2 * √(p(1-p)/n)\n4. مقدار بازه اطمینان نشان‌دهنده حد خطا و دقت برآورد نسبت جامعه است.\n5. اگر بخواهیم دقت را افزایش دهیم، باید تعداد نمونه‌ها را افزایش دهیم که طول بازه اطمینان کاهش یابد.\n6. برای افزایش دقت k برابر، طول بازه اطمینان را بر √(k) تقسیم می‌کنیم و تعداد نمونه‌ها را به k برابر افزایش می‌دهیم.",
"example": "",
"steps": []
},
{
"title": "برآورد فاصله‌ای برای نسبت جامعه",
"introText": "1. تعیین نسبت نمونه‌ای p=m/n که m تعداد موفقیت‌ها و n حجم نمونه است.\n2. تعیین سطح اطمینان و مقدار z متناظر با آن (مثلاً 95% اطمینان متناظر با z=1.96).\n3. محاسبه خطای استاندارد نسبت به صورت sqrt(p(1-p)/n).\n4. محاسبه طول بازه اطمینان به صورت 2*z*sqrt(p(1-p)/n).\n5. تعیین بازه اطمینان به صورت [p - z*sqrt(p(1-p)/n), p + z*sqrt(p(1-p)/n)].\n6. تفسیر بازه اطمینان به عنوان بازه‌ای که با احتمال مشخص شامل نسبت واقعی جامعه است.",
"introText": "1. تعیین نسبت نمونه‌ای p=m/n که m تعداد موفقیت‌ها و n حجم نمونه است.\n2. تعیین سطح اطمینان و مقدار z متناظر با آن (مثلاً 95% اطمینان متناظر با z=1.96).\n3. محاسبه خطای استاندارد نسبت به صورت √(p(1-p)/n).\n4. محاسبه طول بازه اطمینان به صورت 2*z*√(p(1-p)/n).\n5. تعیین بازه اطمینان به صورت [p - z*√(p(1-p)/n), p + z*√(p(1-p)/n)].\n6. تفسیر بازه اطمینان به عنوان بازه‌ای که با احتمال مشخص شامل نسبت واقعی جامعه است.",
"example": "",
"steps": []
},
{
"title": "تعیین حجم نمونه برای طول بازه اطمینان مشخص",
"introText": "1. تعیین طول بازه اطمینان دلخواه L.\n2. تعیین سطح اطمینان و مقدار z متناظر با آن.\n3. فرض مقدار p (نسبت نمونه‌ای یا بیشینه مقدار p(1-p) که برابر 0.25 است).\n4. استفاده از فرمول طول بازه اطمینان L = 2*z*sqrt(p(1-p)/n) و حل آن برای n.\n5. محاسبه n به صورت n = (2*z)² * p(1-p) / L².\n6. گرد کردن n به عدد صحیح بزرگ‌تر و استفاده از آن به عنوان حجم نمونه لازم.",
"introText": "1. تعیین طول بازه اطمینان دلخواه L.\n2. تعیین سطح اطمینان و مقدار z متناظر با آن.\n3. فرض مقدار p (نسبت نمونه‌ای یا بیشینه مقدار p(1-p) که برابر 0.25 است).\n4. استفاده از فرمول طول بازه اطمینان L = 2*z*√(p(1-p)/n) و حل آن برای n.\n5. محاسبه n به صورت n = (2*z)² * p(1-p) / L².\n6. گرد کردن n به عدد صحیح بزرگ‌تر و استفاده از آن به عنوان حجم نمونه لازم.",
"example": "",
"steps": []
},
@@ -173254,7 +173254,7 @@
"ماتریس B به صورت زیر نمایش داده می‌شود:",
"B(m×n) = b₁₁ b₁₂ ⋯ b(1j) ⋯ b(1n)",
"b₂₁ b₂₂ ⋯ b(2j) ⋯ b(2n)",
"vdots vdots ddots vdots ddots vdots",
"⋮ ⋮ ⋱ ⋮ ⋱ ⋮",
"b(i1) b(i2) ⋯ b(ij) ⋯ b(in)",
"✅ جواب: نمایش درایه‌ای ماتریس B با b(ij) برای سطر i و ستون j صحیح است."
]

View File

@@ -42,6 +42,11 @@ class MarkupTests(SimpleTestCase):
self.assertEqual(convert(r'\int_0^1 x\,dx'), '∫₀¹ x dx')
self.assertEqual(convert(r'$\vec{a}\cdot\vec{b}$'), 'a·b')
self.assertEqual(leftover(convert('x^2y^3 و log_a b')), [])
# «sqrt(x)» و «vdots» بدونِ بک‌اسلش هم LaTeXِ خام‌اند (درسِ ماتریس‌ها، ۲۰۲۶-۱۰-۱۵)
self.assertEqual(convert('S = sqrt(3)/4'), 'S = √(3)/4')
self.assertEqual(convert(r'a \vdots b \ddots c'), 'a ⋮ b ⋱ c')
self.assertEqual(leftover('vdots vdots ddots'), ['vdots', 'vdots', 'ddots'])
self.assertEqual(leftover('⋮ ⋱ و sqrt بدونِ پرانتز'), [])
class SeedHasNoLatexTests(SimpleTestCase):

View File

@@ -35,7 +35,7 @@ _SYMBOLS = {
'cup': '∪', 'cap': '∩', 'emptyset': '∅', 'varnothing': '∅',
'forall': '∀', 'exists': '∃', 'angle': '∠', 'perp': '⊥', 'parallel': '∥',
'triangle': '△', 'circ': '∘', 'degree': '°', 'prime': '′',
'ldots': '…', 'dots': '…', 'cdots': '⋯', 'int': '∫', 'sum': 'Σ',
'ldots': '…', 'dots': '…', 'cdots': '⋯', 'vdots': '⋮', 'ddots': '⋱', 'int': '∫', 'sum': 'Σ',
'prod': '∏', 'therefore': '∴', 'propto': '∝', 'neg': '¬',
'quad': ' ', 'qquad': ' ', 'lbrace': '{', 'rbrace': '}',
'setminus': '−', 'mid': '|', 'vert': '|',