xloft 0.1.19__py3-none-any.whl → 0.10.10__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
xloft/__init__.py CHANGED
@@ -1,14 +1,35 @@
1
- """(XLOFT) X-Library of tools.
2
-
3
- Modules exported by this package:
4
-
5
- - `NamedTuple`: Class imitates the behavior of the _named tuple_.
6
- """
7
-
8
- __all__ = (
9
- "to_human_size",
10
- "NamedTuple",
11
- )
12
-
13
- from xloft.humanism import to_human_size
14
- from xloft.namedtuple import NamedTuple
1
+ #        ___              ___  __
2
+ #       /\_ \           /'___\/\ \__
3
+ #  __  _\//\ \     ___ /\ \__/\ \ ,_\
4
+ # /\ \/'\ \ \ \   / __`\ \ ,__\\ \ \/
5
+ # \/>  </  \_\ \_/\ \L\ \ \ \_/ \ \ \_
6
+ #  /\_/\_\ /\____\ \____/\ \_\   \ \__\
7
+ #  \//\/_/ \/____/\/___/  \/_/    \/__/
8
+ #
9
+ # Copyright (c) 2025 Gennady Kostyunin
10
+ # SPDX-License-Identifier: MIT
11
+ """(XLOFT) X-Library of tools.
12
+
13
+ Modules exported by this package:
14
+
15
+ - `types`- Custom data types.
16
+ - `converters` - Collection of tools for converting data.
17
+ - `itis` - Tools for determining something.
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ __all__ = (
23
+ "int_to_roman",
24
+ "roman_to_int",
25
+ "to_human_size",
26
+ "is_number",
27
+ "is_palindrome",
28
+ "AliasDict",
29
+ "NamedTuple",
30
+ )
31
+
32
+ from xloft.converters import int_to_roman, roman_to_int, to_human_size
33
+ from xloft.itis import is_number, is_palindrome
34
+ from xloft.types.alias_dict import AliasDict
35
+ from xloft.types.named_tuple import NamedTuple
@@ -0,0 +1,22 @@
1
+ # XLOFT - X-Library of tools.
2
+ # Copyright (c) 2025 Gennady Kostyunin
3
+ # SPDX-License-Identifier: MIT
4
+ """Collection of tools for converting data.
5
+
6
+ The module contains the following functions:
7
+
8
+ - `to_human_size(n_bytes)` - Returns a humanized string: 200 bytes | 1 KB | 1.5 MB etc.
9
+ - `int_to_roman` - Convert an integer to Roman.
10
+ - `roman_to_int` - Convert to integer from Roman.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ __all__ = (
16
+ "to_human_size",
17
+ "int_to_roman",
18
+ "roman_to_int",
19
+ )
20
+
21
+ from xloft.converters.human_size import to_human_size
22
+ from xloft.converters.roman import int_to_roman, roman_to_int
@@ -0,0 +1,42 @@
1
+ # XLOFT - X-Library of tools.
2
+ # Copyright (c) 2025 Gennady Kostyunin
3
+ # SPDX-License-Identifier: MIT
4
+ """Converts the number of bytes into a human-readable format.
5
+
6
+ The module contains the following functions:
7
+
8
+ - `to_human_size(n_bytes)` - Returns a humanized string: 200 bytes | 1 KB | 1.5 MB etc.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ __all__ = ("to_human_size",)
14
+
15
+ import math
16
+
17
+
18
+ def to_human_size(n_bytes: int) -> str:
19
+ """Converts the number of bytes into a human-readable format.
20
+
21
+ Examples:
22
+ >>> from xloft import to_human_size
23
+ >>> to_human_size(200)
24
+ 200 bytes
25
+ >>> to_human_size(1048576)
26
+ 1 MB
27
+ >>> to_human_size(1048575)
28
+ 1023.999 KB
29
+
30
+ Args:
31
+ n_bytes: The number of bytes.
32
+
33
+ Returns:
34
+ Returns a humanized string: 200 bytes | 1 KB | 1.5 MB etc.
35
+ """
36
+ idx: int = math.floor(math.log(n_bytes) / math.log(1024))
37
+ ndigits: int = [0, 3, 6, 9, 12][idx]
38
+ human_size: int | float = n_bytes if n_bytes < 1024 else abs(round(n_bytes / pow(1024, idx), ndigits))
39
+ order = ["bytes", "KB", "MB", "GB", "TB"][idx]
40
+ if math.modf(human_size)[0] == 0.0:
41
+ human_size = int(human_size)
42
+ return f"{human_size} {order}"
@@ -0,0 +1,119 @@
1
+ # XLOFT - X-Library of tools.
2
+ # Copyright (c) 2025 Gennady Kostyunin
3
+ # SPDX-License-Identifier: MIT
4
+ """Convert an integer to Roman and vice versa.
5
+
6
+ The module contains the following functions:
7
+
8
+ - `int_to_roman` - Convert an integer to Roman.
9
+ - `roman_to_int` - Convert to integer from Roman.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ __all__ = (
15
+ "int_to_roman",
16
+ "roman_to_int",
17
+ )
18
+
19
+ ROMAN = [
20
+ (1000, "M"),
21
+ (900, "CM"),
22
+ (500, "D"),
23
+ (400, "CD"),
24
+ (100, "C"),
25
+ (90, "XC"),
26
+ (50, "L"),
27
+ (40, "XL"),
28
+ (10, "X"),
29
+ (9, "IX"),
30
+ (5, "V"),
31
+ (4, "IV"),
32
+ (1, "I"),
33
+ ]
34
+
35
+
36
+ def int_to_roman(number: int) -> str:
37
+ """Convert an integer to Roman.
38
+
39
+ Examples:
40
+ >>> from xloft import int_to_roman
41
+ >>> int_to_roman(1994)
42
+ MCMXCIV
43
+
44
+ Args:
45
+ number (int): Integer.
46
+
47
+ Returns:
48
+ Roman numeral string.
49
+ """
50
+ result = ""
51
+ for arabic, roman in ROMAN:
52
+ (factor, number) = divmod(number, arabic)
53
+ result += roman * factor
54
+ return result
55
+
56
+
57
+ def roman_to_int(roman: str) -> int:
58
+ """Convert to integer from Roman.
59
+
60
+ Examples:
61
+ >>> from xloft import roman_to_int
62
+ >>> roman_to_int("MCMXCIV")
63
+ 1994
64
+
65
+ Args:
66
+ roman (str): Roman numeral string.
67
+
68
+ Returns:
69
+ Integer.
70
+ """
71
+ i_count = roman.count("I")
72
+ v_count = roman.count("V")
73
+ x_count = roman.count("X")
74
+ l_count = roman.count("L")
75
+ c_count = roman.count("C")
76
+ d_count = roman.count("D")
77
+ m_count = roman.count("M")
78
+
79
+ iv_count = roman.count("IV")
80
+ i_count -= iv_count
81
+ v_count -= iv_count
82
+
83
+ ix_count = roman.count("IX")
84
+ i_count -= ix_count
85
+ x_count -= ix_count
86
+
87
+ xl_count = roman.count("XL")
88
+ x_count -= xl_count
89
+ l_count -= xl_count
90
+
91
+ xc_count = roman.count("XC")
92
+ x_count -= xc_count
93
+ c_count -= xc_count
94
+
95
+ cd_count = roman.count("CD")
96
+ c_count -= cd_count
97
+ d_count -= cd_count
98
+
99
+ cm_count = roman.count("CM")
100
+ c_count -= cm_count
101
+ m_count -= cm_count
102
+
103
+ total = 0
104
+ total += 1 * i_count
105
+ total += 5 * v_count
106
+ total += 10 * x_count
107
+ total += 50 * l_count
108
+ total += 100 * c_count
109
+ total += 500 * d_count
110
+ total += 1000 * m_count
111
+
112
+ total += 4 * iv_count
113
+ total += 9 * ix_count
114
+ total += 40 * xl_count
115
+ total += 90 * xc_count
116
+ total += 400 * cd_count
117
+ total += 900 * cm_count
118
+
119
+ return total
xloft/errors.py CHANGED
@@ -1,24 +1,43 @@
1
- """XLOT Exceptions."""
2
-
3
-
4
- class XLOTException(Exception):
5
- """Root Custom Exception."""
6
-
7
- def __init__(self, *args, **kwargs) -> None: # type: ignore[no-untyped-def]# noqa: D107
8
- super().__init__(*args, **kwargs)
9
-
10
-
11
- class AttributeDoesNotSetValue(XLOTException):
12
- """Exception is raised if the attribute does not setting value."""
13
-
14
- def __init__(self, attribute_name: str) -> None: # noqa: D107
15
- self.message = f"The attribute `{attribute_name}` does not setting value!"
16
- super().__init__(self.message)
17
-
18
-
19
- class AttributeCannotBeDelete(XLOTException):
20
- """Exception is raised if the attribute cannot be delete."""
21
-
22
- def __init__(self, attribute_name: str) -> None: # noqa: D107
23
- self.message = f"The attribute `{attribute_name}` cannot be delete!"
24
- super().__init__(self.message)
1
+ # XLOFT - X-Library of tools.
2
+ # Copyright (c) 2025 Gennady Kostyunin
3
+ # SPDX-License-Identifier: MIT
4
+ """XLOT Exceptions."""
5
+
6
+ from __future__ import annotations
7
+
8
+ __all__ = (
9
+ "XLOTException",
10
+ "AttributeDoesNotSetValueError",
11
+ "AttributeCannotBeDeleteError",
12
+ )
13
+
14
+
15
+ class XLOTException(Exception):
16
+ """Root Custom Exception."""
17
+
18
+ def __init__(self, *args, **kwargs) -> None: # type: ignore[no-untyped-def]# noqa: D107
19
+ super().__init__(*args, **kwargs)
20
+
21
+
22
+ class AttributeDoesNotGetValueError(XLOTException):
23
+ """Exception is raised if the attribute tries to get a value."""
24
+
25
+ def __init__(self, attribute_name: str) -> None:
26
+ self.message = f"The attribute `{attribute_name}` does not get value!"
27
+ super().__init__(self.message)
28
+
29
+
30
+ class AttributeDoesNotSetValueError(XLOTException):
31
+ """Exception is raised if the attribute tries to set a value."""
32
+
33
+ def __init__(self, attribute_name: str) -> None: # noqa: D107
34
+ self.message = f"The attribute `{attribute_name}` does not set value!"
35
+ super().__init__(self.message)
36
+
37
+
38
+ class AttributeCannotBeDeleteError(XLOTException):
39
+ """Exception is raised if the attribute cannot be delete."""
40
+
41
+ def __init__(self, attribute_name: str) -> None: # noqa: D107
42
+ self.message = f"The attribute `{attribute_name}` cannot be delete!"
43
+ super().__init__(self.message)
xloft/itis.py ADDED
@@ -0,0 +1,63 @@
1
+ # XLOFT - X-Library of tools.
2
+ # Copyright (c) 2025 Gennady Kostyunin
3
+ # SPDX-License-Identifier: MIT
4
+ """Tools for determining something.
5
+
6
+ The module contains the following functions:
7
+
8
+ - `is_number` - Check if a string is a number.
9
+ - `is_palindrome` - Check if a string is a palindrome.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ __all__ = (
15
+ "is_number",
16
+ "is_palindrome",
17
+ )
18
+
19
+
20
+ def is_number(value: str) -> bool:
21
+ """Check if a string is a number.
22
+
23
+ Only decimal numbers.
24
+
25
+ Examples:
26
+ >>> from xloft import is_number
27
+ >>> is_number("123")
28
+ True
29
+
30
+ Args:
31
+ value (str): Some kind of string.
32
+
33
+ Returns:
34
+ True, if the string is a number.
35
+ """
36
+ try:
37
+ float(value)
38
+ return True
39
+ except ValueError:
40
+ return False
41
+
42
+
43
+ def is_palindrome(value: str) -> bool:
44
+ """Check if a string is a palindrome.
45
+
46
+ Examples:
47
+ >>> from xloft import is_palindrome
48
+ >>> is_palindrome("Go hang a salami, I'm a lasagna hog")
49
+ True
50
+
51
+ Args:
52
+ value (str): Alpha-numeric string.
53
+
54
+ Returns:
55
+ Boolean value.
56
+ """
57
+ if not isinstance(value, str):
58
+ raise TypeError("The value is not a string!")
59
+ if not len(value):
60
+ raise ValueError("The string must not be empty!")
61
+ string_list = [char.lower() for char in value if char.isalnum()]
62
+ reverse_list = string_list[::-1]
63
+ return reverse_list == string_list
@@ -0,0 +1,20 @@
1
+ # XLOFT - X-Library of tools.
2
+ # Copyright (c) 2025 Gennady Kostyunin
3
+ # SPDX-License-Identifier: MIT
4
+ """Custom data types.
5
+
6
+ This module exports the following data types:
7
+
8
+ - `AliasDict` - Pseudo dictionary with supports aliases for keys.
9
+ - `NamedTuple` - Imitates the behavior of the *named tuple*.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ __all__ = (
15
+ "AliasDict",
16
+ "NamedTuple",
17
+ )
18
+
19
+ from xloft.types.alias_dict import AliasDict
20
+ from xloft.types.named_tuple import NamedTuple