absfuyu 4.1.1__py3-none-any.whl → 5.0.0__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.

Potentially problematic release.


This version of absfuyu might be problematic. Click here for more details.

Files changed (76) hide show
  1. absfuyu/__init__.py +4 -4
  2. absfuyu/__main__.py +13 -1
  3. absfuyu/cli/__init__.py +4 -2
  4. absfuyu/cli/color.py +7 -0
  5. absfuyu/cli/do_group.py +9 -91
  6. absfuyu/cli/tool_group.py +136 -0
  7. absfuyu/config/__init__.py +17 -34
  8. absfuyu/core/__init__.py +49 -0
  9. absfuyu/core/baseclass.py +299 -0
  10. absfuyu/core/baseclass2.py +165 -0
  11. absfuyu/core/decorator.py +67 -0
  12. absfuyu/core/docstring.py +163 -0
  13. absfuyu/core/dummy_cli.py +67 -0
  14. absfuyu/core/dummy_func.py +47 -0
  15. absfuyu/dxt/__init__.py +42 -0
  16. absfuyu/dxt/dictext.py +201 -0
  17. absfuyu/dxt/dxt_support.py +79 -0
  18. absfuyu/dxt/intext.py +586 -0
  19. absfuyu/dxt/listext.py +508 -0
  20. absfuyu/dxt/strext.py +530 -0
  21. absfuyu/{extensions → extra}/__init__.py +3 -2
  22. absfuyu/extra/beautiful.py +251 -0
  23. absfuyu/{extensions/extra → extra}/data_analysis.py +51 -82
  24. absfuyu/fun/__init__.py +110 -135
  25. absfuyu/fun/tarot.py +9 -17
  26. absfuyu/game/__init__.py +6 -0
  27. absfuyu/game/game_stat.py +6 -0
  28. absfuyu/game/sudoku.py +7 -1
  29. absfuyu/game/tictactoe.py +12 -5
  30. absfuyu/game/wordle.py +14 -8
  31. absfuyu/general/__init__.py +6 -79
  32. absfuyu/general/content.py +22 -36
  33. absfuyu/general/generator.py +17 -42
  34. absfuyu/general/human.py +108 -228
  35. absfuyu/general/shape.py +1334 -0
  36. absfuyu/logger.py +8 -13
  37. absfuyu/pkg_data/__init__.py +137 -99
  38. absfuyu/pkg_data/deprecated.py +133 -0
  39. absfuyu/pkg_data/passwordlib_lzma.pkl +0 -0
  40. absfuyu/sort.py +6 -130
  41. absfuyu/tools/__init__.py +2 -2
  42. absfuyu/tools/checksum.py +44 -22
  43. absfuyu/tools/converter.py +82 -50
  44. absfuyu/tools/keygen.py +25 -30
  45. absfuyu/tools/obfuscator.py +246 -112
  46. absfuyu/tools/passwordlib.py +330 -0
  47. absfuyu/tools/shutdownizer.py +287 -0
  48. absfuyu/tools/web.py +2 -9
  49. absfuyu/util/__init__.py +15 -15
  50. absfuyu/util/api.py +10 -15
  51. absfuyu/util/json_method.py +7 -24
  52. absfuyu/util/lunar.py +3 -9
  53. absfuyu/util/path.py +22 -27
  54. absfuyu/util/performance.py +43 -67
  55. absfuyu/util/shorten_number.py +65 -14
  56. absfuyu/util/zipped.py +9 -15
  57. absfuyu-5.0.0.dist-info/METADATA +143 -0
  58. absfuyu-5.0.0.dist-info/RECORD +68 -0
  59. absfuyu/core.py +0 -57
  60. absfuyu/everything.py +0 -32
  61. absfuyu/extensions/beautiful.py +0 -188
  62. absfuyu/extensions/dev/__init__.py +0 -244
  63. absfuyu/extensions/dev/password_hash.py +0 -80
  64. absfuyu/extensions/dev/passwordlib.py +0 -258
  65. absfuyu/extensions/dev/project_starter.py +0 -60
  66. absfuyu/extensions/dev/shutdownizer.py +0 -156
  67. absfuyu/extensions/extra/__init__.py +0 -24
  68. absfuyu/fun/WGS.py +0 -134
  69. absfuyu/general/data_extension.py +0 -1796
  70. absfuyu/tools/stats.py +0 -226
  71. absfuyu/util/pkl.py +0 -67
  72. absfuyu-4.1.1.dist-info/METADATA +0 -121
  73. absfuyu-4.1.1.dist-info/RECORD +0 -61
  74. {absfuyu-4.1.1.dist-info → absfuyu-5.0.0.dist-info}/WHEEL +0 -0
  75. {absfuyu-4.1.1.dist-info → absfuyu-5.0.0.dist-info}/entry_points.txt +0 -0
  76. {absfuyu-4.1.1.dist-info → absfuyu-5.0.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,67 @@
1
+ """
2
+ Absfuyu: Core
3
+ -------------
4
+ Dummy cli
5
+
6
+ Version: 5.0.0
7
+ Date updated: 25/02/2025 (dd/mm/yyyy)
8
+ """
9
+
10
+ # Module Package
11
+ # ---------------------------------------------------------------------------
12
+ __all__ = ["cli"]
13
+
14
+
15
+ # Library
16
+ # ---------------------------------------------------------------------------
17
+ import sys
18
+ from argparse import ArgumentDefaultsHelpFormatter, ArgumentParser
19
+
20
+ from absfuyu import __title__, __version__
21
+
22
+
23
+ # Function
24
+ # ---------------------------------------------------------------------------
25
+ def get_parser(
26
+ name: str | None = None,
27
+ description: str | None = None,
28
+ epilog: str | None = None,
29
+ *,
30
+ version: str = "",
31
+ add_help: bool = True,
32
+ add_logging: bool = True,
33
+ ) -> ArgumentParser:
34
+ arg_parser = ArgumentParser(
35
+ prog=name,
36
+ description=description,
37
+ epilog=epilog,
38
+ add_help=add_help,
39
+ formatter_class=ArgumentDefaultsHelpFormatter,
40
+ # allow_abbrev=False, # Disable long options recognize
41
+ # exit_on_error=True
42
+ )
43
+ arg_parser.add_argument(
44
+ "--version", action="version", version=f"%(prog)s {version}"
45
+ )
46
+ if add_logging:
47
+ _ll_val = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
48
+ arg_parser.add_argument(
49
+ "--log-level",
50
+ metavar="LOG_LEVEL",
51
+ dest="log_level",
52
+ choices=_ll_val,
53
+ default="INFO",
54
+ help=f"Log level: {_ll_val}",
55
+ )
56
+ return arg_parser
57
+
58
+
59
+ def cli() -> None:
60
+ desc = "This is a dummy cli, please install <click> and <colorama> package to use this feature"
61
+ arg_parser = get_parser(
62
+ name=__title__,
63
+ description=desc,
64
+ version=__version__,
65
+ add_logging=False,
66
+ )
67
+ args = arg_parser.parse_args(args=None if sys.argv[1:] else ["--help"]) # noqa
@@ -0,0 +1,47 @@
1
+ """
2
+ Absfuyu: Core
3
+ -------------
4
+ Dummy functions when other libraries are unvailable
5
+
6
+ Version: 5.0.0
7
+ Date updated: 14/02/2025 (dd/mm/yyyy)
8
+ """
9
+
10
+ # Module Package
11
+ # ---------------------------------------------------------------------------
12
+ __all__ = [
13
+ "tqdm",
14
+ "unidecode",
15
+ ]
16
+
17
+
18
+ # Library
19
+ # ---------------------------------------------------------------------------
20
+ from importlib import import_module
21
+
22
+ # Wrapper
23
+ # ---------------------------------------------------------------------------
24
+ # tqdm wrapper
25
+ try:
26
+ tqdm = import_module("tqdm").tqdm
27
+ except ModuleNotFoundError:
28
+
29
+ def tqdm(iterable, *args, **kwargs):
30
+ """
31
+ Dummy tqdm function,
32
+ install package ``tqdm`` to fully use this feature
33
+ """
34
+ return iterable
35
+
36
+
37
+ # unidecode wrapper
38
+ try:
39
+ unidecode = import_module("unidecode").unidecode
40
+ except ModuleNotFoundError:
41
+
42
+ def unidecode(*args, **kwargs):
43
+ """
44
+ Dummy unidecode function,
45
+ install package ``unidecode`` to fully use this feature
46
+ """
47
+ return args[0]
@@ -0,0 +1,42 @@
1
+ """
2
+ Absfuyu: Data Extension
3
+ -----------------------
4
+ Extension for data type such as ``list``, ``str``, ``dict``, ...
5
+
6
+ Version: 5.0.0
7
+ Date updated: 11/01/2025 (dd/mm/yyyy)
8
+
9
+ Features:
10
+ ---------
11
+ - DictExt
12
+ - IntExt
13
+ - ListExt
14
+ - Text
15
+ """
16
+
17
+ # Module Package
18
+ # ---------------------------------------------------------------------------
19
+ __all__ = [
20
+ # Main
21
+ "DictExt",
22
+ "IntExt",
23
+ "ListExt",
24
+ "Text",
25
+ # Support
26
+ "DictAnalyzeResult",
27
+ "DictBoolFalse",
28
+ "DictBoolTrue",
29
+ "ListNoDunder",
30
+ "ListREPR",
31
+ "Pow",
32
+ "TextAnalyzeDictFormat",
33
+ ]
34
+
35
+
36
+ # Library
37
+ # ---------------------------------------------------------------------------
38
+ from absfuyu.dxt.dictext import DictAnalyzeResult, DictExt
39
+ from absfuyu.dxt.dxt_support import DictBoolFalse, DictBoolTrue, ListNoDunder, ListREPR
40
+ from absfuyu.dxt.intext import IntExt, Pow
41
+ from absfuyu.dxt.listext import ListExt
42
+ from absfuyu.dxt.strext import Text, TextAnalyzeDictFormat
absfuyu/dxt/dictext.py ADDED
@@ -0,0 +1,201 @@
1
+ """
2
+ Absfuyu: Data Extension
3
+ -----------------------
4
+ dict extension
5
+
6
+ Version: 5.0.0
7
+ Date updated: 14/02/2025 (dd/mm/yyyy)
8
+ """
9
+
10
+ # Module Package
11
+ # ---------------------------------------------------------------------------
12
+ __all__ = ["DictExt", "DictAnalyzeResult"]
13
+
14
+
15
+ # Library
16
+ # ---------------------------------------------------------------------------
17
+ import operator
18
+ from collections.abc import Callable
19
+ from typing import Any, NamedTuple, Self
20
+
21
+ from absfuyu.core import ShowAllMethodsMixin, versionadded, versionchanged
22
+
23
+
24
+ # Class
25
+ # ---------------------------------------------------------------------------
26
+ class DictAnalyzeResult(NamedTuple):
27
+ """
28
+ Result for ``DictExt.analyze()``
29
+ """
30
+
31
+ max_value: int | float
32
+ min_value: int | float
33
+ max_list: list
34
+ min_list: list
35
+
36
+
37
+ class DictExt(ShowAllMethodsMixin, dict):
38
+ """
39
+ ``dict`` extension
40
+ """
41
+
42
+ @versionchanged("3.3.0", reason="Updated return type")
43
+ def analyze(self) -> DictAnalyzeResult:
44
+ """
45
+ Analyze all the key values (``int``, ``float``)
46
+ in ``dict`` then return highest/lowest index
47
+
48
+ Returns
49
+ -------
50
+ dict
51
+ Analyzed data
52
+
53
+
54
+ Example:
55
+ --------
56
+ >>> test = DictExt({
57
+ ... "abc": 9,
58
+ ... "def": 9,
59
+ ... "ghi": 8,
60
+ ... "jkl": 1,
61
+ ... "mno": 1
62
+ ... })
63
+ >>> test.analyze()
64
+ DictAnalyzeResult(max_value=9, min_value=1, max_list=[('abc', 9), ('def', 9)], min_list=[('jkl', 1), ('mno', 1)])
65
+ """
66
+ try:
67
+ dct: dict = self.copy()
68
+
69
+ max_val: int | float = max(list(dct.values()))
70
+ min_val: int | float = min(list(dct.values()))
71
+ max_list = []
72
+ min_list = []
73
+
74
+ for k, v in dct.items():
75
+ if v == max_val:
76
+ max_list.append((k, v))
77
+ if v == min_val:
78
+ min_list.append((k, v))
79
+
80
+ return DictAnalyzeResult(max_val, min_val, max_list, min_list)
81
+
82
+ except TypeError:
83
+ err_msg = "Value must be int or float"
84
+ # logger.error(err_msg)
85
+ raise ValueError(err_msg) # noqa: B904
86
+
87
+ def swap_items(self) -> Self:
88
+ """
89
+ Swap ``dict.keys()`` with ``dict.values()``
90
+
91
+ Returns
92
+ -------
93
+ DictExt
94
+ Swapped dict
95
+
96
+
97
+ Example:
98
+ --------
99
+ >>> test = DictExt({"abc": 9})
100
+ >>> test.swap_items()
101
+ {9: 'abc'}
102
+ """
103
+ # return self.__class__(zip(self.values(), self.keys()))
104
+ return self.__class__({v: k for k, v in self.items()})
105
+
106
+ def apply(self, func: Callable, apply_to_value: bool = True) -> Self:
107
+ """
108
+ Apply function to ``DictExt.keys()`` or ``DictExt.values()``
109
+
110
+ Parameters
111
+ ----------
112
+ func : Callable
113
+ Callable function
114
+
115
+ apply_to_value : bool
116
+ | ``True``: Apply ``func`` to ``DictExt.values()``
117
+ | ``False``: Apply ``func`` to ``DictExt.keys()``
118
+
119
+ Returns
120
+ -------
121
+ DictExt
122
+ DictExt
123
+
124
+
125
+ Example:
126
+ --------
127
+ >>> test = DictExt({"abc": 9})
128
+ >>> test.apply(str)
129
+ {'abc': '9'}
130
+ """
131
+ if apply_to_value:
132
+ new_dict = {k: func(v) for k, v in self.items()}
133
+ else:
134
+ new_dict = {func(k): v for k, v in self.items()}
135
+ return self.__class__(new_dict)
136
+
137
+ @versionchanged("5.0.0", reason="Updated to handle more types and operator")
138
+ @versionadded("3.4.0")
139
+ def aggregate(
140
+ self,
141
+ other_dict: dict,
142
+ default_value: Any = 0,
143
+ operator_func: Callable[[Any, Any], Any] = operator.add, # operator add
144
+ ) -> Self:
145
+ """
146
+ Aggregates the values of the current dictionary with another dictionary.
147
+
148
+ For each unique key, this method applies the specified operator to the values
149
+ from both dictionaries. If a key exists in only one dictionary, its value is used.
150
+ If an error occurs during aggregation (e.g., incompatible types), the values
151
+ from both dictionaries are returned as a list.
152
+
153
+ Parameters
154
+ ----------
155
+ other_dict : dict
156
+ The dictionary to aggregate with.
157
+
158
+ default_value : Any, optional
159
+ The value to use for missing keys, by default ``0``
160
+
161
+
162
+ operator_func : Callable[[Any, Any], Any], optional
163
+ A function that takes two arguments and returns a single value,
164
+ by default ``operator.add``
165
+
166
+ Returns
167
+ -------
168
+ Self
169
+ A new instance of the aggregated dictionary.
170
+
171
+
172
+ Example:
173
+ --------
174
+ >>> test = DictExt({"test": 5, "test2": 9})
175
+ >>> agg = {"test1": 10, "test2": 1}
176
+ >>> print(test.aggregate(agg))
177
+ {'test1': 10, 'test': 5, 'test2': 10}
178
+
179
+ >>> test = DictExt({"test": 5, "test2": 9})
180
+ >>> agg = {"test1": 10, "test2": "1"}
181
+ >>> print(test.aggregate(agg))
182
+ {'test1': 10, 'test': 5, 'test2': [9, '1']}
183
+ """
184
+ merged_output = {}
185
+
186
+ # Create a set of all unique keys from both dictionaries
187
+ all_keys = set(self) | set(other_dict)
188
+
189
+ for k in all_keys:
190
+ # Retrieve values with default fallback
191
+ value_self = self.get(k, default_value)
192
+ value_other = other_dict.get(k, default_value)
193
+
194
+ try:
195
+ # Attempt to apply the operator for existing keys
196
+ merged_output[k] = operator_func(value_self, value_other)
197
+ except TypeError:
198
+ # If a TypeError occurs (e.g., if values are not compatible), store values as a list
199
+ merged_output[k] = [value_self, value_other]
200
+
201
+ return self.__class__(merged_output)
@@ -0,0 +1,79 @@
1
+ """
2
+ Absfuyu: Data Extension
3
+ -----------------------
4
+ Support classes
5
+
6
+ Version: 5.0.0
7
+ Date updated: 11/02/2025 (dd/mm/yyyy)
8
+ """
9
+
10
+ # Module Package
11
+ # ---------------------------------------------------------------------------
12
+ __all__ = ["DictBoolTrue", "DictBoolFalse"]
13
+
14
+
15
+ # Library
16
+ # ---------------------------------------------------------------------------
17
+ from typing import Any
18
+
19
+ from absfuyu.logger import _compress_list_for_print
20
+
21
+
22
+ # Dict Boolean Masking Repr
23
+ # ---------------------------------------------------------------------------
24
+ def _dict_bool(dict_object: dict, option: bool) -> dict | None:
25
+ """
26
+ Support function DictBool class
27
+ """
28
+ out = dict()
29
+ for k, v in dict_object.items():
30
+ if v == option:
31
+ out[k] = v
32
+ if out:
33
+ return out
34
+ else:
35
+ return None
36
+
37
+
38
+ class DictBoolTrue(dict[Any, bool]):
39
+ """Only show items when ``values == True`` in ``__repr__()``"""
40
+
41
+ def __repr__(self) -> str:
42
+ temp = self.copy()
43
+ return _dict_bool(temp, True).__repr__()
44
+
45
+
46
+ class DictBoolFalse(dict[Any, bool]):
47
+ """Only show items when ``values == False`` in ``__repr__()``"""
48
+
49
+ def __repr__(self) -> str:
50
+ temp = self.copy()
51
+ return _dict_bool(temp, False).__repr__()
52
+
53
+
54
+ # ---------------------------------------------------------------------------
55
+ class ListREPR(list):
56
+ """Show ``list`` in shorter form"""
57
+
58
+ def __repr__(self) -> str:
59
+ return _compress_list_for_print(self, 9)
60
+
61
+
62
+ class ListNoDunder(list[str]):
63
+ """Use with ``object.__dir__()``"""
64
+
65
+ def __repr__(self) -> str:
66
+ out = [x for x in self if not x.startswith("__")]
67
+ return out.__repr__()
68
+
69
+
70
+ # class DictNoDunder(dict): # W.I.P
71
+ # """Remove dunder methods in ``__repr__()`` of dict"""
72
+
73
+ # def __repr__(self) -> str:
74
+ # temp = self.copy()
75
+ # out = dict()
76
+ # for k, v in temp.items():
77
+ # if not str(k).startswith("__"):
78
+ # out.__setattr__(k, v)
79
+ # return out.__repr__()