From 3eb7f2e3981e6dc05ecaf905402fc496c7623fb2 Mon Sep 17 00:00:00 2001 From: babaev-an Date: Thu, 2 Oct 2025 23:36:28 +0300 Subject: [PATCH] 20251002-2 --- .run/Тест StringExtension.run.xml | 17 ++++ anb_python_components/__init__.py | 4 +- anb_python_components/enums/__init__.py | 1 + .../enums/not_bool_action.py | 25 ++++++ .../extensions/bool_extension.py | 81 +++++++++++++++++ .../extensions/string_extension.py | 33 ++++--- .../extensions/string_extension_constant.py | 86 ++++++++++++++++--- .../class_desc/extensions/string_extension.md | 8 +- .../extensions/string_extension_constant.md | 36 ++------ tests/__init__.py | 1 + tests/extensions/__init__.py | 1 + tests/extensions/string_extension_test.py | 55 ++++++++++++ 12 files changed, 282 insertions(+), 66 deletions(-) create mode 100644 .run/Тест StringExtension.run.xml create mode 100644 anb_python_components/enums/__init__.py create mode 100644 anb_python_components/enums/not_bool_action.py create mode 100644 anb_python_components/extensions/bool_extension.py create mode 100644 tests/__init__.py create mode 100644 tests/extensions/__init__.py create mode 100644 tests/extensions/string_extension_test.py diff --git a/.run/Тест StringExtension.run.xml b/.run/Тест StringExtension.run.xml new file mode 100644 index 0000000..8a384a9 --- /dev/null +++ b/.run/Тест StringExtension.run.xml @@ -0,0 +1,17 @@ + + + + + \ No newline at end of file diff --git a/anb_python_components/__init__.py b/anb_python_components/__init__.py index 5492e24..4a50878 100644 --- a/anb_python_components/__init__.py +++ b/anb_python_components/__init__.py @@ -1,3 +1 @@ -# anb_python_components/__init__.py - -from . import greet \ No newline at end of file +# anb_python_components/__init__.py \ No newline at end of file diff --git a/anb_python_components/enums/__init__.py b/anb_python_components/enums/__init__.py new file mode 100644 index 0000000..91486fe --- /dev/null +++ b/anb_python_components/enums/__init__.py @@ -0,0 +1 @@ +# anb_python_components/enums/__init__.py \ No newline at end of file diff --git a/anb_python_components/enums/not_bool_action.py b/anb_python_components/enums/not_bool_action.py new file mode 100644 index 0000000..42446be --- /dev/null +++ b/anb_python_components/enums/not_bool_action.py @@ -0,0 +1,25 @@ +# anb_python_components/enums/not_bool_action.py + +from enum import Enum + + +class NotBoolAction(Enum): + """ + Перечисление типов действий, которые необходимо выполнить, если переменная не является булевым типом. + - IGNORE: Игнорировать это утверждение. + - IT_TRUE: Считать это утверждение истинным. + - IT_FALSE: Считать это утверждение ложным. + - RAISE: Вызвать исключение. + """ + + # Игнорировать это утверждение. + IGNORE = 0 + + # Считать это утверждение истинным. + IT_TRUE = 1 + + # Считать это утверждение ложным. + IT_FALSE = 2 + + # Вызвать исключение + RAISE = 3 diff --git a/anb_python_components/extensions/bool_extension.py b/anb_python_components/extensions/bool_extension.py new file mode 100644 index 0000000..288ca47 --- /dev/null +++ b/anb_python_components/extensions/bool_extension.py @@ -0,0 +1,81 @@ +# anb_python_components/extensions/bool_extension.py + +from anb_python_components.enums.not_bool_action import NotBoolAction + + +class BoolExtension: + """ + Расширение типа "правда/ложь". + """ + + def __init__(self): + pass + + @staticmethod + def to_str(b: bool, if_true: str = "True", if_false: str = "False") -> str: + """ + Конвертирует булево значение в строку. + :param b: Булево значение. + :param if_true: Возвращаемое значение, если b == True (по умолчанию "True") + :param if_false: Возвращаемое значение, если b == False (по умолчанию "False") + :return: Строка, соответствующая булевому значению. + """ + return if_true if b else if_false + + @staticmethod + def true_count(expressions: list[bool], if_not_bool: NotBoolAction = NotBoolAction.IGNORE) -> int: + """ + Возвращает количество истинных значений в списке аргументов. + :param expressions: Список аргументов. + :param if_not_bool: Действие при не булевом значении. + :return: Количество истинных значений в списке аргументов. + """ + # Создаем пустой массив для хранения проверяемых аргументов + check_array = [] + + # Проверяем все входящие аргументы + for expression in expressions: + # - если аргумент не является типом правда/ложь + if not isinstance(expression, bool): + # -- если указано действие при не булевом значении - игнорирование + if if_not_bool == NotBoolAction.IGNORE: + # - игнорируем аргумент и продолжаем цикл + continue + + # -- если указано действие при не булевом значении - считать как истинное значение + if if_not_bool == NotBoolAction.IT_TRUE: + # --- добавляем True в массив проверяемых аргументов + check_array.append(True) + # --- и продолжаем цикл + continue + + # -- если указано действие при не булевом значении - считать как ложное значение + if if_not_bool == NotBoolAction.IT_TRUE: + # --- добавляем False в массив проверяемых аргументов + check_array.append(False) + # --- и продолжаем цикл + continue + + # -- если указано действие при не булевом значении - выбросить исключение + if if_not_bool == NotBoolAction.RAISE: + # --- то вызываем исключение + raise ValueError(f"{expression} не является булевым значением") + + else: + # - иначе добавляем аргумент в массив проверяемых аргументов + check_array.append(expression) + + # Используем фильтрацию массива для получения массива только истинных значений + filtered = [value for value in check_array if value] + + # Возвращаем количество истинных значений в отфильтрованном массиве + return len(filtered) + + @staticmethod + def any_true(expressions: list[bool]) -> int: + """ + Возвращает количество истинных значений в списке аргументов. + :param expressions: Список аргументов. + :return: Количество истинных значений в списке аргументов. + """ + return 0 if len(expressions) == 0 else BoolExtension.true_count(expressions, NotBoolAction.IGNORE) diff --git a/anb_python_components/extensions/string_extension.py b/anb_python_components/extensions/string_extension.py index 80e8fe8..c04289b 100644 --- a/anb_python_components/extensions/string_extension.py +++ b/anb_python_components/extensions/string_extension.py @@ -1,7 +1,7 @@ # anb_python_components/extensions/string_extension.py import re -from string_extension_constant import StringExtensionConstants +from .string_extension_constant import StringExtensionConstants class StringExtension: @@ -16,7 +16,7 @@ class StringExtension: pass @staticmethod - def is_none_or_empty(text: str) -> bool: + def is_none_or_empty(text: str | None) -> bool: """ Проверяет, пуста ли строка. :param text: Проверяемая строка. @@ -25,7 +25,7 @@ class StringExtension: return text is None or text == "" @classmethod - def is_none_or_whitespace(cls, text: str) -> bool: + def is_none_or_whitespace(cls, text: str | None) -> bool: """ Проверяет, пуста ли строка, содержит ли вместо текста только пробелы. :param text: Проверяемая строка. @@ -50,22 +50,21 @@ class StringExtension: :param letter: Буква русского алфавита. :return: Транслитерированная буква. """ - # Если размерность массивов разная - if (len(StringExtensionConstants.russian_letters) != - len(StringExtensionConstants.russian_letters_transliteration)): - # - то вывожу ошибку + + try: + # Получаю транслитерированную букву + transliteration = StringExtensionConstants.russian_letters[letter] + + # Если не удалось получить транслитерированную букву + if transliteration is None: + # - то возбуждаю исключение + raise KeyError + except KeyError: + # Если возбуждено исключение, то возвращаю None return None - # Получаю индекс буквы - ind = StringExtensionConstants.russian_letters.find(letter) - - # Если индекс буквы не найден - if ind == -1: - # - то вывожу ошибку - return None - - # Получаю транслитерированную букву - return StringExtensionConstants.russian_letters[ind] + # Возвращаю транслитерированную букву + return transliteration @classmethod def convert_to_latin(cls, source: str) -> str: diff --git a/anb_python_components/extensions/string_extension_constant.py b/anb_python_components/extensions/string_extension_constant.py index 2cca390..630f491 100644 --- a/anb_python_components/extensions/string_extension_constant.py +++ b/anb_python_components/extensions/string_extension_constant.py @@ -4,19 +4,77 @@ class StringExtensionConstants: """ Константы для расширения строк. + + Attributes: + russian_letters (dict): Словарь соответствия русских букв в транслитерации. """ - # Кортеж из русских букв - russian_letters = ('а', 'б', 'в', 'г', 'д', 'е', 'ё', 'ж', 'з', 'и', 'й', 'к', 'л', 'м', 'н', - 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'щ', 'ъ', 'ы', 'ь', - 'э', 'ю', 'я', 'А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ё', 'Ж', 'З', 'И', 'Й', 'К', - 'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ', - 'Ъ', 'Ы', 'Ь', 'Э', 'Ю', 'Я') - - # Кортеж из русских букв в транслитерации - russian_letters_transliteration = ("a", "b", "v", "g", "d", "e", "yo", "zh", "z", "i", "j", - "k", "l", "m", "n", "o", "p", "r", "s", "t", "u", "f", - "h", "c", "ch", "sh", "sch", "j", "i", "j", "e", "yu", "ya", - "A", "B", "V", "G", "D", "E", "Yo", "Zh", "Z", "I", "J", - "K", "L", "M", "N", "O", "P", "R", "S", "T", "U", "F", - "H", "C", "Ch", "Sh", "Sch", "J", "I", "J", "E", "Yu", "Ya") + # Словарь соответствия русских букв в транслитерации + russian_letters = { + 'а': 'a', + 'б': 'b', + 'в': 'v', + 'г': 'g', + 'д': 'd', + 'е': 'e', + 'ё': 'yo', + 'ж': 'zh', + 'з': 'z', + 'и': 'i', + 'й': 'j', + 'к': 'k', + 'л': 'l', + 'м': 'm', + 'н': 'n', + 'о': 'o', + 'п': 'p', + 'р': 'r', + 'с': 's', + 'т': 't', + 'у': 'u', + 'ф': 'f', + 'х': 'h', + 'ц': 'c', + 'ч': 'ch', + 'ш': 'sh', + 'щ': 'sch', + 'ъ': 'j', + 'ы': 'i', + 'ь': 'j', + 'э': 'e', + 'ю': 'yu', + 'я': 'ya', + 'А': 'A', + 'Б': 'B', + 'В': 'V', + 'Г': 'G', + 'Д': 'D', + 'Е': 'E', + 'Ё': 'Yo', + 'Ж': 'Zh', + 'З': 'Z', + 'И': 'I', + 'Й': 'J', + 'К': 'K', + 'Л': 'L', + 'М': 'M', + 'Н': 'N', + 'О': 'O', + 'П': 'P', + 'Р': 'R', + 'С': 'S', + 'Т': 'T', + 'У': 'U', + 'Ф': 'F', + 'Х': 'H', + 'Ц': 'C', + 'Ч': 'Ch', + 'Ш': 'Sh', + 'Щ': 'Sch', + 'Ъ': 'J', + 'Ы': 'I', + 'Ь': 'J', + 'Э': 'E', + 'Ю': 'Yu', + 'Я': 'Ya' + } diff --git a/help/class_desc/extensions/string_extension.md b/help/class_desc/extensions/string_extension.md index a1ce8f6..00336e3 100644 --- a/help/class_desc/extensions/string_extension.md +++ b/help/class_desc/extensions/string_extension.md @@ -7,10 +7,10 @@ ## Основная информация -**Имя файла**: anb_python_components\extensions\string_extension.py -**Автор**: Александр Бабаев -**Версия**: 1.0.0 -**Дата начала поддержки**: с версии 1.0 +- **Имя файла**: anb_python_components\extensions\string_extension.py +- **Автор**: Александр Бабаев +- **Версия**: 1.0.0 +- **Дата начала поддержки**: с версии 1.0 ## Атрибуты и методы класса diff --git a/help/class_desc/extensions/string_extension_constant.md b/help/class_desc/extensions/string_extension_constant.md index 0ae4939..1833844 100644 --- a/help/class_desc/extensions/string_extension_constant.md +++ b/help/class_desc/extensions/string_extension_constant.md @@ -3,9 +3,9 @@ Этот класс предназначен для хранения констант, используемых при расширениях функционала работы со строками на Python. Основные цели класса включают поддержку русской транслитерации и удобство обработки текста на кириллице. -Класс включает два основных атрибута-константы: -* атрибут `russian_letters`; -* атрибут `russian_letters_transliteration`. +Класс включает один основной атрибут-константу: + +* атрибут `russian_letters`. ## Основная информация @@ -15,11 +15,14 @@ - **Дата начала поддержки**: с версии 1.0 ## Атрибуты и методы класса + ### Атрибут `russian_letters` -Это кортеж, содержащий все русские буквы (строчные и прописные). Используется для проверки принадлежности символов -русским буквам, операций сортировки и фильтрации текста. + +Это словарь, содержащий все русские буквы (строчные и прописные) и их транслитерацию. Используется для проверки +принадлежности символов русским буквам, операций сортировки и фильтрации текста и транслитерации слов. Пример использования: + ```python from anb_python_components.extensions.string_extension_constant import StringExtensionConstants @@ -29,29 +32,6 @@ if char in StringExtensionConstants.russian_letters: print("Символ является русской буквой") ``` -### Атрибут `russian_letters_transliteration` -Это кортеж, соответствующий русскому алфавиту в транслитерированном виде латиницей. Например, русская буква «А» -соответствует английскому символу «A», а буква «Ч» соответствует последовательности «Ch». - -Используется для преобразования русского текста в транслитерационный вид, что полезно для интеграции с международными -системами, упрощения экспорта данных и поддержки кросс-платформенных решений. - -Пример использования: - -```python -from anb_python_components.extensions.string_extension_constant import StringExtensionConstants - -translit_map = dict( - zip( - StringExtensionConstants.russian_letters, - StringExtensionConstants.russian_letters_transliteration - )) - - -def transliterate(text): - return ''.join(translit_map.get(char, char) for char in text) -``` - ## Вывод Таким образом, этот класс позволяет легко реализовать базовые операции для нормализации и трансформации строки на diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..4a50878 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1 @@ +# anb_python_components/__init__.py \ No newline at end of file diff --git a/tests/extensions/__init__.py b/tests/extensions/__init__.py new file mode 100644 index 0000000..7ba3d65 --- /dev/null +++ b/tests/extensions/__init__.py @@ -0,0 +1 @@ +# anb_python_components/extensions/__init__.py \ No newline at end of file diff --git a/tests/extensions/string_extension_test.py b/tests/extensions/string_extension_test.py new file mode 100644 index 0000000..fcf3b55 --- /dev/null +++ b/tests/extensions/string_extension_test.py @@ -0,0 +1,55 @@ +# string_extension_test.py + +import unittest + +from anb_python_components.extensions.string_extension import * + + +class StringExtensionTest(unittest.TestCase): + def test_is_none_or_empty(self): + self.assertTrue(StringExtension.is_none_or_empty(None)) + self.assertTrue(StringExtension.is_none_or_empty("")) + self.assertFalse(StringExtension.is_none_or_empty("Некий текст")) + self.assertFalse(StringExtension.is_none_or_empty(" ")) + + def test_is_none_or_whitespace(self): + self.assertTrue(StringExtension.is_none_or_whitespace(None)) + self.assertTrue(StringExtension.is_none_or_whitespace("")) + self.assertFalse(StringExtension.is_none_or_whitespace("Некий текст")) + self.assertTrue(StringExtension.is_none_or_whitespace(" ")) + + def test_is_russian_letter(self): + self.assertTrue(StringExtension.is_russian_letter('п')) + self.assertFalse(StringExtension.is_russian_letter("p")) + + def test_get_russian_letter_transliteration(self): + self.assertEqual(StringExtension.get_russian_letter_transliteration('Ю'), 'Yu') + self.assertNotEqual(StringExtension.get_russian_letter_transliteration('я'), 'Yu') + + def test_convert_to_latin(self): + self.assertEqual(StringExtension.convert_to_latin('Россия'), 'Rossiya') + + def test_compare(self): + self.assertEqual(StringExtension.compare('Россия', 'Россия'), 0) + self.assertEqual(StringExtension.compare('Россия', 'Россия', True), 0) + self.assertEqual(StringExtension.compare('Россия', 'россия', True), 0) + self.assertEqual(StringExtension.compare('Россия', 'россия'), 1) + self.assertEqual(StringExtension.compare('Россия - Великая держава', 'Россия'), 1) + self.assertEqual(StringExtension.compare('Россия', 'Россия, мы гордимся Тобою'), -1) + + def test_get_short_text(self): + self.assertEqual(StringExtension.get_short_text('Я люблю Python', 10), 'Я люблю Py') + self.assertEqual(StringExtension.get_short_text('Я люблю Python', 10, '...'), 'Я люблю...') + + def test_replace(self): + self.assertEqual(StringExtension.replace('Я люблю Python. Хотя только изучаю сам Python', 'Python', 'PHP'), + "Я люблю PHP. Хотя только изучаю сам PHP") + + def test_replace_all(self): + self.assertEqual(StringExtension.replace_all({'Python': 'PHP', 'сам': 'последнюю версию'}, + 'Я люблю Python. Хотя только изучаю сам Python'), + "Я люблю PHP. Хотя только изучаю последнюю версию PHP") + + +if __name__ == '__main__': + unittest.main()