20251004
This commit is contained in:
17
.run/Тест ArrayExtension.run.xml
Normal file
17
.run/Тест ArrayExtension.run.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Тест ArrayExtension" type="tests" factoryName="Autodetect">
|
||||
<module name="anb_python_components" />
|
||||
<option name="ENV_FILES" value="" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
<option name="SDK_HOME" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/tests/extensions" />
|
||||
<option name="IS_MODULE_SDK" value="true" />
|
||||
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||
<option name="_new_additionalArguments" value="""" />
|
||||
<option name="_new_target" value=""$PROJECT_DIR$/tests/extensions/array_extension_test.py"" />
|
||||
<option name="_new_targetType" value=""PATH"" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
17
.run/Тест TypeExtension.run.xml
Normal file
17
.run/Тест TypeExtension.run.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Тест TypeExtension" type="tests" factoryName="Autodetect">
|
||||
<module name="anb_python_components" />
|
||||
<option name="ENV_FILES" value="" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
<option name="SDK_HOME" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/tests/extensions" />
|
||||
<option name="IS_MODULE_SDK" value="true" />
|
||||
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||
<option name="_new_additionalArguments" value="""" />
|
||||
<option name="_new_target" value=""$PROJECT_DIR$/tests/extensions/type_extension_test.py"" />
|
||||
<option name="_new_targetType" value=""PATH"" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
1
anb_python_components/classes/__init__.py
Normal file
1
anb_python_components/classes/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# anb_python_components/classes/__init__.py
|
66
anb_python_components/classes/guid.py
Normal file
66
anb_python_components/classes/guid.py
Normal file
@@ -0,0 +1,66 @@
|
||||
# anb_python_components/classes/guid.py
|
||||
import re
|
||||
|
||||
from anb_python_components.exceptions.wrong_type_exception import WrongTypeException
|
||||
|
||||
# Константа пустого GUID
|
||||
GUID_EMPTY: str = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
|
||||
class GUID:
|
||||
|
||||
def __init__(self, guid: str = GUID_EMPTY):
|
||||
"""
|
||||
Инициализация расширения.
|
||||
:param guid: Передаваемый GUID
|
||||
"""
|
||||
|
||||
# Проверка GUID на валидность
|
||||
if not self.validate_str(guid):
|
||||
# и если GUID невалидный, то генерируем исключение
|
||||
raise WrongTypeException("Неверный формат GUID!", "GUID", guid, "guid")
|
||||
|
||||
# Инициализируем приватный атрибут __value (текстовое представление хранящегося GUID)
|
||||
self.__value = guid
|
||||
|
||||
def __str__(self):
|
||||
"""
|
||||
Переопределение метода __str__.
|
||||
:return: Текстовое представление GUID.
|
||||
"""
|
||||
return self.__value if self.__value else GUID_EMPTY
|
||||
|
||||
def __eq__(self, other):
|
||||
"""
|
||||
Переопределение метода __eq__.
|
||||
:param other: Объект для сравнения.
|
||||
:return: True, если GUID равны, иначе False.
|
||||
"""
|
||||
|
||||
# Если аргумент не является экземпляром GUID
|
||||
if not isinstance(other, GUID):
|
||||
# - генерируем исключение
|
||||
raise WrongTypeException("Неверный тип аргумента!", "GUID", type(other), "other")
|
||||
|
||||
# Преобразование второго аргумента в строку
|
||||
other_str = str(other)
|
||||
|
||||
# Сравниваем строки
|
||||
return self.__value == other_str
|
||||
|
||||
@staticmethod
|
||||
def validate_str(guid: str | None) -> bool:
|
||||
"""
|
||||
Проверка строки на валидность GUID.
|
||||
:return: True, если GUID валидный, иначе False.
|
||||
"""
|
||||
|
||||
# Проверка на пустоту
|
||||
if not guid:
|
||||
return False
|
||||
|
||||
# Регулярное выражение для проверки формата GUID
|
||||
pattern = r'^[0-9A-Fa-f]{8}-([0-9A-Fa-f]{4}-){3}[0-9A-Fa-f]{12}$'
|
||||
|
||||
# Проверка на соответствие формату
|
||||
return bool(re.fullmatch(pattern, guid))
|
1
anb_python_components/exceptions/__init__.py
Normal file
1
anb_python_components/exceptions/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# anb_python_components/exceptions/__init__.py
|
20
anb_python_components/exceptions/wrong_type_exception.py
Normal file
20
anb_python_components/exceptions/wrong_type_exception.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# anb_python_components/exceptions/wrong_type_exception.py
|
||||
|
||||
class WrongTypeException(Exception):
|
||||
"""
|
||||
Ошибка, возникающая при попытке присвоить значение другого типа данным полям.
|
||||
"""
|
||||
|
||||
def __init__(self, message: str = None, type_name: str = None, real_type_name: str = None, var_name: str = None):
|
||||
"""
|
||||
Инициализация экземпляра класса WrongTypeException.
|
||||
:param message: Сообщение об ошибке.
|
||||
:param type_name: Имя типа (по умолчанию None).
|
||||
:param real_type_name: Имя реального типа (по умолчанию None).
|
||||
:param var_name: Имя переменной (по умолчанию None).
|
||||
"""
|
||||
super().__init__(message)
|
||||
self.message = message
|
||||
self.type_name = type_name,
|
||||
self.real_type_name = real_type_name,
|
||||
self.var_name = var_name
|
35
anb_python_components/extensions/array_extension.py
Normal file
35
anb_python_components/extensions/array_extension.py
Normal file
@@ -0,0 +1,35 @@
|
||||
# anb_python_components/extensions/array_extension.py
|
||||
|
||||
from anb_python_components.extensions.string_extension import StringExtension
|
||||
|
||||
|
||||
class ArrayExtension:
|
||||
"""
|
||||
Класс расширения для работы с массивами.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Инициализация расширения.
|
||||
"""
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def remove_empties(array: list[str], re_sort: bool = False) -> list[str]:
|
||||
"""
|
||||
Удаляет пустые строки из массива.
|
||||
|
||||
:param array: Массив строк.
|
||||
:param re_sort: Пересортировать массив после удаления пустых строк.
|
||||
:return: Массив строк без пустых строк.
|
||||
"""
|
||||
# Удаляем пустые строки
|
||||
result = list(filter(lambda x: not StringExtension.is_none_or_whitespace(x), array))
|
||||
|
||||
# Если нужно пересортировать массив
|
||||
if re_sort:
|
||||
# - сортируем массив
|
||||
result.sort()
|
||||
|
||||
# Возвращаем результат
|
||||
return result
|
123
anb_python_components/extensions/guid_extension.py
Normal file
123
anb_python_components/extensions/guid_extension.py
Normal file
@@ -0,0 +1,123 @@
|
||||
# anb_python_components/extensions/guid_extension.py
|
||||
import secrets
|
||||
|
||||
from anb_python_components.classes.guid import GUID, GUID_EMPTY
|
||||
from anb_python_components.exceptions.wrong_type_exception import WrongTypeException
|
||||
|
||||
|
||||
class GUIDExtension:
|
||||
"""
|
||||
Класс GUIDExtension реализует расширение для работы с GUID.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Инициализация расширения.
|
||||
"""
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def generate() -> GUID:
|
||||
"""
|
||||
Генерирует уникальный идентификатор GUID согласно стандарту RFC 4122.
|
||||
"""
|
||||
# Генерация отдельных компонентов GUID
|
||||
time_low = secrets.randbits(32) & 0xffffffff
|
||||
time_mid = secrets.randbits(16) & 0xffff
|
||||
time_hi_and_version = ((secrets.randbits(12) << 4) | 0x4000) & 0xffff
|
||||
clock_seq_hi_and_reserved = ((secrets.randbits(14) << 2) | 0x8000) & 0xffff
|
||||
node_id = secrets.randbits(48) & 0xffffffffffff
|
||||
|
||||
# Объединение компонентов в единый GUID
|
||||
guid_parts = [
|
||||
time_low >> 16, time_low & 0xffff,
|
||||
time_mid,
|
||||
time_hi_and_version,
|
||||
clock_seq_hi_and_reserved,
|
||||
node_id >> 32, (node_id >> 16) & 0xffff, node_id & 0xffff
|
||||
]
|
||||
|
||||
# Форматируем компоненты в виде строки GUID
|
||||
guid_str = "-".join([
|
||||
"%08x" % guid_parts[0],
|
||||
"%04x" % guid_parts[1],
|
||||
"%04x" % guid_parts[2],
|
||||
"%04x" % guid_parts[3],
|
||||
("%04x%04x%04x" % tuple(guid_parts[4:])),
|
||||
])
|
||||
|
||||
# Возвращаем экземпляр GUID
|
||||
return GUID(guid_str)
|
||||
|
||||
@staticmethod
|
||||
def is_equal(guid1: str | GUID, guid2: str | GUID) -> bool:
|
||||
|
||||
# Если guid1 не является GUID или строкой
|
||||
if not isinstance(guid1, GUID) or not isinstance(guid1, str):
|
||||
# - генерируем исключение
|
||||
raise WrongTypeException("Неверный тип аргумента!", "GUID|str", var_name="guid1")
|
||||
|
||||
# Если guid2 не является GUID или строкой
|
||||
if not isinstance(guid2, GUID) or not isinstance(guid2, str):
|
||||
# - генерируем исключение
|
||||
raise WrongTypeException("Неверный тип аргумента!", "GUID|str", var_name="guid2")
|
||||
|
||||
# Если guid1 является строкой
|
||||
if not isinstance(guid1, GUID):
|
||||
# - преобразуем её в GUID
|
||||
guid1 = GUID(guid1)
|
||||
|
||||
# Если guid2 является строкой
|
||||
if not isinstance(guid2, GUID):
|
||||
# - преобразуем её в GUID
|
||||
guid2 = GUID(guid2)
|
||||
|
||||
# Сравниваем GUID
|
||||
return guid1 == guid2
|
||||
|
||||
@staticmethod
|
||||
def validate(guid: str | GUID) -> bool:
|
||||
"""
|
||||
Проверка GUID на валидность.
|
||||
:param guid: GUID для проверки.
|
||||
:return: True, если GUID валидный, иначе False.
|
||||
"""
|
||||
# Если guid не является строкой, то преобразуем его в неё
|
||||
guid = guid if isinstance(guid, str) else str(guid)
|
||||
|
||||
# Проверяем GUID
|
||||
return bool(GUID.validate_str(guid))
|
||||
|
||||
@staticmethod
|
||||
def is_invalid_or_empty(guid: str | GUID) -> bool:
|
||||
"""
|
||||
Проверка GUID на валидность и не пустоту.
|
||||
:param guid: Класс или строка GUID для проверки.
|
||||
:return: True, если GUID не валидный или пустой, иначе False.
|
||||
"""
|
||||
# Если guid не является строкой, то преобразуем его в неё
|
||||
guid = guid if isinstance(guid, str) else str(guid)
|
||||
|
||||
# Проверяем GUID
|
||||
return not GUID.validate_str(guid) or guid == GUID_EMPTY
|
||||
|
||||
@classmethod
|
||||
def parse(cls, guid_string: str, empty_if_not_valid: bool = True) -> GUID:
|
||||
"""
|
||||
Парсинг GUID из строки.
|
||||
:param guid_string: Строка GUID.
|
||||
:param empty_if_not_valid: Если True, то возвращается пустой GUID, если GUID недействителен.
|
||||
"""
|
||||
|
||||
# Проверяем строку на соответствие формату GUID
|
||||
if cls.validate(guid_string):
|
||||
# - если GUID действителен, возвращаем экземпляр GUID
|
||||
return GUID(guid_string)
|
||||
|
||||
# Если же GUID недействителен и запрещено выбрасывать исключение
|
||||
if empty_if_not_valid:
|
||||
# -- то возвращаем пустой GUID
|
||||
return GUID(GUID_EMPTY)
|
||||
else:
|
||||
# -- иначе выбрасываем исключение
|
||||
raise WrongTypeException('Предан неверный GUID / Wrong GUID.')
|
63
help/class_desc/exceptions/wrong_type_exception.md
Normal file
63
help/class_desc/exceptions/wrong_type_exception.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# Класс `WrongTypeException`
|
||||
|
||||
Класс `WrongTypeException` представляет собой настраиваемое исключение, возникающее при некорректном присваивании
|
||||
значения другому типу данных. Обычно такое исключение применяется для контроля целостности типов в строгих системах
|
||||
разработки программного обеспечения, предотвращая потенциальные проблемы и неопределённое поведение программы.
|
||||
|
||||
## Основная информация
|
||||
|
||||
- **Имя файла**: anb_python_components\exceptions\wrong_type_exception.py
|
||||
- **Автор**: Александр Бабаев
|
||||
- **Версия**: 1.0.0
|
||||
- **Дата начала поддержки**: с версии 1.0
|
||||
|
||||
## Атрибуты и методы класса
|
||||
|
||||
### Конструктор (`__init__`)
|
||||
|
||||
Создаёт экземпляр исключения, принимая необязательные параметры для детального описания ошибки.
|
||||
|
||||
Параметры конструктора:
|
||||
|
||||
- `message`: Пользовательское сообщение об ошибке.
|
||||
- `type_name`: Ожидаемый тип данных (например, `int`, `float`, `str`).
|
||||
- `real_type_name`: Реальный тип данных, который был использован ошибочно.
|
||||
- `var_name`: Название переменной, вызвавшей ошибку.
|
||||
|
||||
Пример использования:
|
||||
|
||||
```python
|
||||
from anb_python_components.exceptions.wrong_type_exception import WrongTypeException
|
||||
|
||||
|
||||
# Допустим, задана какая-то функция
|
||||
def some_function(value):
|
||||
# в этой функции стоит проверка на тип
|
||||
if not isinstance(value, int):
|
||||
# и в случае неудачной проверки выбрасывается исключение
|
||||
raise WrongTypeException("Неверный тип!", "int", type(value), "value")
|
||||
|
||||
# Пусть эта функция для примера просто добавляет 1 к value
|
||||
return value + 1
|
||||
|
||||
|
||||
try:
|
||||
# Зададим переменную a как произвольную строку
|
||||
a = "hello, word"
|
||||
|
||||
# и при вызове функции будет выброшено исключение
|
||||
some_function(a)
|
||||
except WrongTypeException as e:
|
||||
print(
|
||||
f"Произошла ошибка: {e.message}. Ожидается тип {e.type_name}, а в переменную {e.var_name} передан {e.real_type_name}")
|
||||
|
||||
# Произошла ошибка: Неверный тип!. Ожидается тип int, а в переменную value передан str
|
||||
```
|
||||
|
||||
## Заключение
|
||||
|
||||
Исключения играют важную роль в обеспечении надёжности и предсказуемости программ. Класс `WrongTypeException` позволяет
|
||||
разработчикам легко создавать контролируемые условия для предотвращения неправильного использования типов данных и
|
||||
повышения качества ПО.
|
||||
|
||||
[На главную](../../index.md)
|
39
help/class_desc/extensions/array_extension.md
Normal file
39
help/class_desc/extensions/array_extension.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# Класс `ArrayExtension`
|
||||
|
||||
Класс `ArrayExtension` предназначен для работы с массивами строк в Python. Главная задача класса — удаление пустых строк
|
||||
из массива и возможная последующая сортировка оставшихся элементов.
|
||||
|
||||
## Основная информация
|
||||
|
||||
- **Имя файла**: anb_python_components\extensions\array_extension.py
|
||||
- **Автор**: Александр Бабаев
|
||||
- **Версия**: 1.0.0
|
||||
- **Дата начала поддержки**: с версии 1.0
|
||||
|
||||
## Атрибуты и методы класса
|
||||
|
||||
### Метод `remove_empties`
|
||||
|
||||
Удаляет пустые строки из массива, дополнительно предоставляя возможность отсортировать оставшиеся элементы.
|
||||
|
||||
**Параметры**:
|
||||
|
||||
- `array`: Входной массив строк.
|
||||
- `re_sort`: Флаг, определяющий необходимость сортировки результата (по умолчанию установлен в `False`).
|
||||
|
||||
**Пример использования**:
|
||||
|
||||
```python
|
||||
from anb_python_components.extensions.array_extension import ArrayExtension
|
||||
|
||||
arr = ["apple", "", "banana", " ", ""]
|
||||
clean_arr = ArrayExtension.remove_empties(arr)
|
||||
print(clean_arr) # ['apple', 'banana']
|
||||
```
|
||||
|
||||
## Заключение
|
||||
|
||||
Класс `ArrayExtension` полезен при очистке массивов от ненужных элементов, улучшая качество данных и повышая
|
||||
эффективность дальнейшей обработки. Особенно удобен в приложениях, где важны чистота и порядок данных.
|
||||
|
||||
[На главную](../../index.md)
|
@@ -14,6 +14,12 @@
|
||||
|
||||
- [перечисление `NotBoolAction`](class_desc/enums/not_bool_action.md)
|
||||
|
||||
### Исключения
|
||||
|
||||
**Расположение модулей**: anb_python_components\exceptions\*
|
||||
|
||||
- [класс-исключение `WrongTypeException`](class_desc/exceptions/wrong_type_exception.md)
|
||||
|
||||
### Расширения стандартных типов
|
||||
|
||||
**Расположение модулей**: anb_python_components\extensions\*
|
||||
@@ -21,4 +27,5 @@
|
||||
- [класс `StringExtensionConstants`](class_desc/extensions/string_extension_constant.md)
|
||||
- [класс `StringExtension`](class_desc/extensions/string_extension.md)
|
||||
- [класс `BoolExtension`](class_desc/extensions/bool_extension.md)
|
||||
- [класс `TypeExtension`](class_desc/extensions/type_extension.md)
|
||||
- [класс `TypeExtension`](class_desc/extensions/type_extension.md)
|
||||
- [класс `ArrayExtension`](class_desc/extensions/array_extension.md)
|
21
tests/extensions/array_extension_test.py
Normal file
21
tests/extensions/array_extension_test.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# array_extension_test.py
|
||||
|
||||
import unittest
|
||||
|
||||
from anb_python_components.extensions.array_extension import ArrayExtension
|
||||
|
||||
|
||||
class ArrayExtensionTest(unittest.TestCase):
|
||||
def test_remove_empties(self):
|
||||
array = ["Мама", "Папа", "", "", "он", "", "она", "вместе", "", "дружная", "", "семья", ""]
|
||||
|
||||
removed_empties = ["Мама", "Папа", "он", "она", "вместе", "дружная", "семья"]
|
||||
|
||||
sorted_removed_empties = ["Мама", "Папа", "вместе", "дружная", "он", "она", "семья"]
|
||||
|
||||
self.assertEqual(removed_empties, ArrayExtension.remove_empties(array))
|
||||
self.assertEqual(sorted_removed_empties, ArrayExtension.remove_empties(array, True))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Reference in New Issue
Block a user