Spaces:
Sleeping
Sleeping
| """Генератор задач: выбор предмета из смеси с pymorphy3""" | |
| from core.base_generator import BaseTaskGenerator | |
| from models.task import Task | |
| from fractions import Fraction | |
| from config import COMPLEXITY_CONFIG | |
| import random | |
| import pymorphy3 | |
| morph = pymorphy3.MorphAnalyzer() | |
| class MixedItemsGenerator(BaseTaskGenerator): | |
| """Генератор задач про выбор предмета из смеси с корректной морфологией""" | |
| ITEM_WEIGHTS = { | |
| 'пирожок': 1.0, | |
| 'конфета': 1.0, | |
| 'шар': 1.0, | |
| 'пазл': 1.0, | |
| 'ручка': 1.0, # ручки реже | |
| } | |
| def generate(self) -> Task: | |
| config = COMPLEXITY_CONFIG[self.complexity] | |
| item_variants = [ | |
| ('тарелке', 'лежат', 'пирожок', 'муж', 'с', | |
| [('с мясом', 'с мясом'), ('с капустой', 'с капустой'), ('с вишней', 'с вишней')]), | |
| ('коробке', 'лежат', 'конфета', 'жен', 'прил', | |
| [('шоколадных', 'шоколадная'), ('карамельных', 'карамельная'), ('фруктовых', 'фруктовая')]), | |
| ('ящике', 'лежат', 'шар', 'муж', 'прил', | |
| [('красных', 'красный'), ('синих', 'синий'), ('зелёных', 'зелёный')]), | |
| ('стакане', 'лежат', 'ручка', 'жен', 'прил', | |
| [('чёрных', 'чёрная'), ('синих', 'синяя'), ('красных', 'красная')]), | |
| ('коробке', 'находятся', 'пазл', 'муж', 'прил', | |
| [('с животными', 'с животными'), | |
| ('с картинами', 'с картинами'), | |
| ('с пейзажами', 'с пейзажами')]), | |
| ] | |
| weights = [self.ITEM_WEIGHTS.get(v[2], 1.0) for v in item_variants] | |
| ( | |
| container, | |
| verb, | |
| item_singular, | |
| gender, | |
| desc_type, | |
| categories | |
| ) = random.choices(item_variants, weights=weights, k=1)[0] | |
| count_options = { | |
| 'easy': [(4, 8, 3), (5, 7, 3), (6, 10, 4)], | |
| 'medium': [(4, 8, 3), (5, 7, 3), (6, 10, 4), (7, 13, 5)], | |
| 'hard': [(4, 8, 3), (5, 7, 3), (6, 10, 4), (7, 13, 5), (9, 15, 6)], | |
| } | |
| counts = random.choice(count_options[self.complexity]) | |
| total = sum(counts) | |
| target_idx = random.randint(0, 2) | |
| items_desc = [] | |
| for num, (adj, _) in zip(counts, categories): | |
| noun_parsed = morph.parse(item_singular)[0].make_agree_with_number(num) | |
| noun_form = noun_parsed.word if noun_parsed is not None else item_singular | |
| items_desc.append(f"{num} {adj}") | |
| items_description = ', '.join(items_desc[:-1]) + ' и ' + items_desc[-1] | |
| if desc_type == 'с': | |
| verb_form = f"окажется {categories[target_idx][1]}" | |
| else: | |
| adj = categories[target_idx][1] | |
| adj_parsed = morph.parse(adj)[0].inflect({'sing', 'masc' if gender=='муж' else 'femn', 'ablt'}) | |
| adj_instr = adj_parsed.word if adj_parsed is not None else adj | |
| verb_form = f"окажется {adj_instr}" | |
| selected_form = "выбранный" if gender == 'муж' else "выбранная" | |
| preposition = 'На' if container == 'тарелке' else 'В' | |
| noun_total_parsed = morph.parse(item_singular)[0].make_agree_with_number(total) | |
| noun_total = noun_total_parsed.word if noun_total_parsed is not None else item_singular | |
| question = ( | |
| f"{preposition} {container} {verb} {total} {noun_total}: " | |
| f"{items_description}. Найдите вероятность того, что случайно {selected_form} {item_singular} {verb_form}." | |
| ) | |
| favorable = counts[target_idx] | |
| fraction = Fraction(favorable, total) | |
| noun_fav_parsed = morph.parse(item_singular)[0].make_agree_with_number(favorable) | |
| noun_fav = noun_fav_parsed.word if noun_fav_parsed is not None else item_singular | |
| if desc_type != 'с': | |
| step2 = f"{categories[target_idx][0].capitalize()} {noun_fav}: {favorable}" | |
| else: | |
| step2 = f"{noun_fav.capitalize()} {categories[target_idx][0]}: {favorable}" | |
| steps = [ | |
| f"1. Общее число {noun_total}: {total}", | |
| f"2. {step2}", | |
| f"3. Вероятность = {favorable}/{total} = {fraction}", | |
| ] | |
| return Task( | |
| type='mixed_items', | |
| question=question, | |
| answer=float(fraction), | |
| answer_fraction=str(fraction), | |
| solution=f"Вероятность = {favorable}/{total} = {fraction}", | |
| steps=steps, | |
| complexity=self.complexity, | |
| ) | |
| def get_type(self) -> str: | |
| return 'mixed_items' | |