def test_match_string(self): form = GramForm("мр,ед,им") self.assertEqual(form.match_string("мр"), "мр") self.assertEqual(form.match_string("ед"), "ед") self.assertEqual(form.match_string("им"), "им") self.assertEqual(form.match_string("!имя"), "!имя") self.assertFalse(form.match_string("жр"))
def test_match_string(self): form = GramForm(u'мр,ед,им') self.assertEqual(form.match_string(u'мр'), u'мр') self.assertEqual(form.match_string(u'ед'), u'ед') self.assertEqual(form.match_string(u'им'), u'им') self.assertEqual(form.match_string(u'!имя'), u'!имя') self.assertFalse(form.match_string(u'жр'))
def inflect(morph, lastname, gram_form): ''' Вернуть вариант фамилии который соотвествует данной грамматической форме Параметры: * morph - объект Morph * lastname - фамилия которую хотим склонять * gram_form - желаемые характеристики грам. формы (если u'жр' отсутствует в этом параметре, то по-умолчанию принимается u'мр', или u'мр-жр', если указано u'мн') ''' expected_form = GramForm(gram_form) gender_tag = (u'мр-жр' if expected_form.match_string(u'мн') else None) if not gender_tag: gender_tag = (expected_form.match_string(u'жр') or u'мр') # За один проход проверяется, что исходное слово может быть склонено как # фамилия и выбирается форма подходящая под gram_form present_in_decline = False accepted = {} for item in decline(lastname): form = GramForm(item.get('info', u'')) # Если в результате склонения не получилось исходной формы - ложное срабатывание # Обязательно проверяется род: при склонении в противоположном роде # может получиться исходная форма но нас интересует совпадение только в # заданном роде if item.get('word', '') == lastname: # В случае склонения во множественную форму, род игнорируется. # Род всех фамилий во множественном числе - мр-жр. if expected_form.match_string(u'мн') or form.match_string(gender_tag): present_in_decline = True expected = form.match(expected_form) if expected and not accepted: accepted = item # Здесь break не нужен т.к. present_in_decline всё ещё может быть # не установлена в корректное значение # Если в результате склонения исходной формы не получилось, # возвращается результат склонения как для обычного слова if present_in_decline and accepted: return accepted.get('word', u'') else: return morph.inflect_ru(lastname, gram_form, smart_guess=False)
def pluralize(morph, lastname, gram_form=u''): ''' Вернуть фамилию во множественном числе. Параметры: * morph - объект Morph * lastname - фамилия которую хотим склонять * gram_form - желаемые характеристики грам. формы ''' expected_form = GramForm(gram_form) # Удалить из желаемой формы признаки рода и числа refined_form = GramForm(gram_form).clear_gender().clear_number() # Если дан gram_form - склонить в указанную форму if refined_form.get_form_string(): return inflect( morph, lastname, u','.join((refined_form.get_form_string(), u'мн',))) # Иначе - найти форму исходной фамилии и склонить в неё же, но во мн. числе # Если в желаемой форме был указан род - использовать как подсказку gender_tag = (expected_form.match_string(u'жр') or u'мр') for item in decline(lastname): form = GramForm(item.get('info', u'')) # Проверить наличие исходной формы в заданном роде (аналогично inflect()) if item.get('word', u'') == lastname and form.match_string(gender_tag): for case in (u'им', u'рд', u'дт', u'вн', u'тв', u'пр'): if form.match_string(case): return inflect(morph, lastname, u'мн,%s' % case) # В случае неудачи - просклонять как обычное слово return morph.pluralize_ru(lastname, gram_form)
def normalize(morph, lastname, hints=u''): ''' Возвращает нормальную форму (именительный падеж) фамилии для заданного рода Параметры: * hints - подсказки об исходной форме фамилии (u'мр' или u'жр', по-умолчанию принимается u'мр') ''' hints_form = GramForm(hints) gender_tag = (hints_form.match_string(u'жр') or u'мр') # FIXME: эта функция возвращает саму форму, а Morph.normalize возвращает # множество (set) возможных форм, одно из двух лучше поправить. return inflect(morph, lastname, u'им,ед,%s' % gender_tag)
def pluralize_inflected(morph, lastname, num, hints=u''): ''' Вернуть фамилию в форме, которая будет сочетаться с переданным числом. Например: 1 Попугаев, 2 Попугаевых, 5 Попугаевых. Параметры: * morph - объект Morph * lastname - фамилия которую хотим склонять * num - число * hints - подсказки об исходной форме фамилии (u'мр' или u'жр') ''' if num == 1: return normalize(morph, lastname, hints) hints_form = GramForm(hints) gender_tag = (hints_form.match_string(u'жр') or u'мр') return pluralize(morph, lastname, u'мн,рд,%s' % gender_tag)