Last active
July 18, 2024 18:25
-
-
Save danila-schelkov/268517d8a411676f1f8b01ff3dd81508 to your computer and use it in GitHub Desktop.
Скрипт для склонения слов в зависимости от числа перед ним. Тесты прилагаются.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import annotations | |
import sys | |
from typing import Tuple | |
try: | |
if sys.version_info >= (3, 11): | |
from typing import LiteralString | |
else: | |
from typing_extensions import LiteralString | |
except ImportError as e: | |
print( | |
"Cannot import LiteralString. Please update your python version to an actual." | |
) | |
raise e | |
def inflect_with_num( | |
number: int, forms: Tuple[LiteralString, LiteralString, LiteralString] | |
) -> str: | |
"""В русском языке есть особенность, что идущее перед словом число | |
может его в корни изменить. | |
Например: 1 год, 2 года, 3 года, 4 года, 5 лет. Формы у групп 1, | |
2-4, 5-10 отличается. В промежутке с 10 до 20 будут идти именно «лета». | |
А после результат будет зависеть от цифры в разряде единиц. | |
И так повторяется с каждой сотней. | |
Для удобства восприятия назовём группы цифрами: | |
1. Для единицы (1). | |
2. Единица 0, от 5 до 9 и от 10 до 20 включительно. | |
3. Единицы от 2 до 4 включительно. | |
Массив forms принимает формы в том же порядке. | |
:param number: Число, предшествующее слову | |
:param forms: Три заданные формы исчисляемого слова | |
:return: | |
""" | |
units = number % 10 | |
tens = number % 100 - units | |
if tens == 10 or units >= 5 or units == 0: | |
needed_form = 1 | |
elif units > 1: | |
needed_form = 2 | |
else: | |
needed_form = 0 | |
return forms[needed_form] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from inflector import inflect_with_num | |
def main() -> None: | |
"""A kinda test function.""" | |
apple_forms = ("яблоко", "яблок", "яблока") | |
_assert("яблок", inflect_with_num(0, apple_forms)) | |
_assert("яблоко", inflect_with_num(1, apple_forms)) | |
_assert("яблока", inflect_with_num(2, apple_forms)) | |
_assert("яблок", inflect_with_num(5, apple_forms)) | |
_assert("яблок", inflect_with_num(10, apple_forms)) | |
_assert("яблок", inflect_with_num(13, apple_forms)) | |
_assert("яблок", inflect_with_num(20, apple_forms)) | |
_assert("яблоко", inflect_with_num(21, apple_forms)) | |
_assert("яблок", inflect_with_num(100, apple_forms)) | |
_assert("яблока", inflect_with_num(103, apple_forms)) | |
_assert("яблок", inflect_with_num(110, apple_forms)) | |
year_forms = ("год", "лет", "года") | |
_assert("лет", inflect_with_num(0, year_forms)) | |
_assert("год", inflect_with_num(1, year_forms)) | |
_assert("года", inflect_with_num(2, year_forms)) | |
_assert("лет", inflect_with_num(5, year_forms)) | |
_assert("лет", inflect_with_num(10, year_forms)) | |
_assert("лет", inflect_with_num(13, year_forms)) | |
_assert("лет", inflect_with_num(20, year_forms)) | |
_assert("год", inflect_with_num(21, year_forms)) | |
_assert("лет", inflect_with_num(100, year_forms)) | |
_assert("года", inflect_with_num(103, year_forms)) | |
_assert("лет", inflect_with_num(110, year_forms)) | |
def _assert(expected: str, actual: str) -> None: | |
assert actual == expected, f"Unexpected value: {actual} instead of {expected}" | |
if __name__ == "__main__": | |
try: | |
main() | |
except KeyboardInterrupt: | |
exit(-1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment