absfuyu 5.0.0__py3-none-any.whl → 5.1.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.
- absfuyu/__init__.py +1 -1
- absfuyu/__main__.py +2 -2
- absfuyu/cli/__init__.py +2 -2
- absfuyu/cli/color.py +30 -14
- absfuyu/cli/config_group.py +9 -2
- absfuyu/cli/do_group.py +13 -6
- absfuyu/cli/game_group.py +9 -2
- absfuyu/cli/tool_group.py +16 -9
- absfuyu/config/__init__.py +2 -2
- absfuyu/core/__init__.py +2 -2
- absfuyu/core/baseclass.py +449 -80
- absfuyu/core/baseclass2.py +2 -2
- absfuyu/core/decorator.py +69 -3
- absfuyu/core/docstring.py +25 -22
- absfuyu/core/dummy_cli.py +2 -2
- absfuyu/core/dummy_func.py +19 -6
- absfuyu/core/typings.py +40 -0
- absfuyu/dxt/__init__.py +2 -2
- absfuyu/dxt/dictext.py +2 -2
- absfuyu/dxt/dxt_support.py +2 -2
- absfuyu/dxt/intext.py +31 -3
- absfuyu/dxt/listext.py +28 -3
- absfuyu/dxt/strext.py +3 -3
- absfuyu/extra/__init__.py +2 -2
- absfuyu/extra/beautiful.py +3 -2
- absfuyu/extra/da/__init__.py +36 -0
- absfuyu/extra/da/dadf.py +1138 -0
- absfuyu/extra/da/dadf_base.py +186 -0
- absfuyu/extra/da/df_func.py +97 -0
- absfuyu/extra/da/mplt.py +219 -0
- absfuyu/extra/data_analysis.py +10 -1067
- absfuyu/fun/__init__.py +2 -2
- absfuyu/fun/tarot.py +2 -2
- absfuyu/game/__init__.py +2 -2
- absfuyu/game/game_stat.py +2 -2
- absfuyu/game/sudoku.py +2 -2
- absfuyu/game/tictactoe.py +2 -2
- absfuyu/game/wordle.py +2 -2
- absfuyu/general/__init__.py +4 -4
- absfuyu/general/content.py +2 -2
- absfuyu/general/human.py +2 -2
- absfuyu/general/shape.py +2 -2
- absfuyu/logger.py +2 -2
- absfuyu/pkg_data/__init__.py +2 -2
- absfuyu/pkg_data/deprecated.py +2 -2
- absfuyu/sort.py +2 -2
- absfuyu/tools/__init__.py +25 -2
- absfuyu/tools/checksum.py +27 -7
- absfuyu/tools/converter.py +93 -28
- absfuyu/{general → tools}/generator.py +2 -2
- absfuyu/tools/inspector.py +433 -0
- absfuyu/tools/keygen.py +2 -2
- absfuyu/tools/obfuscator.py +46 -8
- absfuyu/tools/passwordlib.py +88 -23
- absfuyu/tools/shutdownizer.py +2 -2
- absfuyu/tools/web.py +2 -2
- absfuyu/util/__init__.py +2 -2
- absfuyu/util/api.py +2 -2
- absfuyu/util/json_method.py +2 -2
- absfuyu/util/lunar.py +2 -2
- absfuyu/util/path.py +190 -82
- absfuyu/util/performance.py +4 -4
- absfuyu/util/shorten_number.py +40 -10
- absfuyu/util/text_table.py +272 -0
- absfuyu/util/zipped.py +6 -6
- absfuyu/version.py +59 -42
- {absfuyu-5.0.0.dist-info → absfuyu-5.1.0.dist-info}/METADATA +10 -3
- absfuyu-5.1.0.dist-info/RECORD +76 -0
- absfuyu-5.0.0.dist-info/RECORD +0 -68
- {absfuyu-5.0.0.dist-info → absfuyu-5.1.0.dist-info}/WHEEL +0 -0
- {absfuyu-5.0.0.dist-info → absfuyu-5.1.0.dist-info}/entry_points.txt +0 -0
- {absfuyu-5.0.0.dist-info → absfuyu-5.1.0.dist-info}/licenses/LICENSE +0 -0
absfuyu/core/decorator.py
CHANGED
|
@@ -3,13 +3,17 @@ Absfuyu: Core
|
|
|
3
3
|
-------------
|
|
4
4
|
Decorator
|
|
5
5
|
|
|
6
|
-
Version: 5.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 5.1.0
|
|
7
|
+
Date updated: 10/03/2025 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
# Module Package
|
|
11
11
|
# ---------------------------------------------------------------------------
|
|
12
|
-
__all__ = [
|
|
12
|
+
__all__ = [
|
|
13
|
+
"dummy_decorator",
|
|
14
|
+
"dummy_decorator_with_args",
|
|
15
|
+
"add_subclass_methods_decorator",
|
|
16
|
+
]
|
|
13
17
|
|
|
14
18
|
|
|
15
19
|
# Library
|
|
@@ -52,8 +56,10 @@ def dummy_decorator_with_args(*args, **kwargs):
|
|
|
52
56
|
|
|
53
57
|
@overload
|
|
54
58
|
def decorator(obj: T) -> T: ...
|
|
59
|
+
|
|
55
60
|
@overload
|
|
56
61
|
def decorator(obj: Callable[P, R]) -> Callable[P, R]: ...
|
|
62
|
+
|
|
57
63
|
def decorator(obj: Callable[P, R] | T) -> Callable[P, R] | T:
|
|
58
64
|
if isinstance(obj, type):
|
|
59
65
|
return obj
|
|
@@ -65,3 +71,63 @@ def dummy_decorator_with_args(*args, **kwargs):
|
|
|
65
71
|
return wrapper
|
|
66
72
|
|
|
67
73
|
return decorator
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def add_subclass_methods_decorator(cls: T) -> T:
|
|
77
|
+
"""
|
|
78
|
+
Class decorator replace the ``__init_subclass__`` method.
|
|
79
|
+
|
|
80
|
+
This method populates a dictionary with subclass names as keys
|
|
81
|
+
and their available methods as values.
|
|
82
|
+
|
|
83
|
+
- Create 2 class attributes: ``_METHOD_INCLUDE`` (bool) and ``SUBCLASS_METHODS`` (dict[str, list[str]])
|
|
84
|
+
- Automatically add subclass methods to class variable: ``SUBCLASS_METHODS``
|
|
85
|
+
- Set class attribute ``_METHOD_INCLUDE`` to ``False`` to exclude from ``SUBCLASS_METHODS``
|
|
86
|
+
|
|
87
|
+
Example:
|
|
88
|
+
--------
|
|
89
|
+
>>> # Normal behavior
|
|
90
|
+
>>> @add_subclass_methods_decorator
|
|
91
|
+
>>> class TestParent: ...
|
|
92
|
+
>>> class TestChild(TestParent):
|
|
93
|
+
... def method1(self): ...
|
|
94
|
+
>>> TestChild.SUBCLASS_METHODS
|
|
95
|
+
{'__main__.TestChild': ['method1']}
|
|
96
|
+
|
|
97
|
+
>>> # Hidden from ``SUBCLASS_METHODS``
|
|
98
|
+
>>> @add_subclass_methods_decorator
|
|
99
|
+
>>> class TestParent: ...
|
|
100
|
+
>>> class TestChildHidden(TestParent):
|
|
101
|
+
... _METHOD_INCLUDE = False
|
|
102
|
+
... def method1(self): ...
|
|
103
|
+
>>> TestChildHidden.SUBCLASS_METHODS
|
|
104
|
+
{}
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
# Check for class
|
|
108
|
+
if not isinstance(cls, type):
|
|
109
|
+
raise ValueError("Object is not a class")
|
|
110
|
+
|
|
111
|
+
class AutoSubclassMixin:
|
|
112
|
+
_METHOD_INCLUDE: bool = True # Include in SUBCLASS_METHODS
|
|
113
|
+
SUBCLASS_METHODS: dict[str, list[str]] = {}
|
|
114
|
+
|
|
115
|
+
def __init_subclass__(cls, *args, **kwargs) -> None:
|
|
116
|
+
"""
|
|
117
|
+
This create a dictionary with:
|
|
118
|
+
- key (str) : Subclass
|
|
119
|
+
- value (list[str]): List of available methods
|
|
120
|
+
"""
|
|
121
|
+
super().__init_subclass__(*args, **kwargs)
|
|
122
|
+
|
|
123
|
+
if cls._METHOD_INCLUDE and not any(
|
|
124
|
+
[x.endswith(cls.__name__) for x in cls.SUBCLASS_METHODS.keys()]
|
|
125
|
+
):
|
|
126
|
+
methods_list: list[str] = [
|
|
127
|
+
k for k, v in cls.__dict__.items() if callable(v)
|
|
128
|
+
]
|
|
129
|
+
if len(methods_list) > 0:
|
|
130
|
+
name = f"{cls.__module__}.{cls.__name__}"
|
|
131
|
+
cls.SUBCLASS_METHODS.update({name: sorted(methods_list)})
|
|
132
|
+
|
|
133
|
+
return type("AutoSubclass", (AutoSubclassMixin, cls), {}) # type: ignore[return-value]
|
absfuyu/core/docstring.py
CHANGED
|
@@ -3,8 +3,8 @@ Absfuyu: Core
|
|
|
3
3
|
-------------
|
|
4
4
|
Sphinx docstring decorator
|
|
5
5
|
|
|
6
|
-
Version: 5.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 5.1.0
|
|
7
|
+
Date updated: 10/03/2025 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
# Module Package
|
|
@@ -28,9 +28,9 @@ from typing import ClassVar, ParamSpec, TypeVar, overload
|
|
|
28
28
|
|
|
29
29
|
# Type
|
|
30
30
|
# ---------------------------------------------------------------------------
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
_P = ParamSpec("_P") # Parameter type
|
|
32
|
+
_R = TypeVar("_R") # Return type - Can be anything
|
|
33
|
+
_T = TypeVar("_T", bound=type) # Type type - Can be any subtype of `type`
|
|
34
34
|
|
|
35
35
|
_SPHINX_DOCS_TEMPLATE = Template("$line_break*$mode in version $version$reason*")
|
|
36
36
|
|
|
@@ -88,10 +88,13 @@ class SphinxDocstring:
|
|
|
88
88
|
self.mode = mode
|
|
89
89
|
|
|
90
90
|
@overload
|
|
91
|
-
def __call__(self, obj:
|
|
91
|
+
def __call__(self, obj: _T) -> _T: ... # Class overload
|
|
92
|
+
|
|
92
93
|
@overload
|
|
93
|
-
def __call__(
|
|
94
|
-
|
|
94
|
+
def __call__(
|
|
95
|
+
self, obj: Callable[_P, _R]
|
|
96
|
+
) -> Callable[_P, _R]: ... # Function overload
|
|
97
|
+
def __call__(self, obj: _T | Callable[_P, _R]) -> _T | Callable[_P, _R]:
|
|
95
98
|
# Class wrapper
|
|
96
99
|
if isinstance(obj, type): # if inspect.isclass(obj):
|
|
97
100
|
obj.__doc__ = (obj.__doc__ or "") + self._generate_version_note(
|
|
@@ -101,7 +104,7 @@ class SphinxDocstring:
|
|
|
101
104
|
|
|
102
105
|
# Function wrapper
|
|
103
106
|
@wraps(obj)
|
|
104
|
-
def wrapper(*args:
|
|
107
|
+
def wrapper(*args: _P.args, **kwargs: _P.kwargs) -> _R:
|
|
105
108
|
return obj(*args, **kwargs)
|
|
106
109
|
|
|
107
110
|
# Add docstring
|
|
@@ -127,19 +130,19 @@ class SphinxDocstring:
|
|
|
127
130
|
if docs is None:
|
|
128
131
|
return res
|
|
129
132
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
if
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
133
|
+
try:
|
|
134
|
+
# Replace tabs with space and split line
|
|
135
|
+
lines = docs.expandtabs(4).splitlines()
|
|
136
|
+
except UnicodeError:
|
|
137
|
+
return res
|
|
138
|
+
else:
|
|
139
|
+
# Get indentation of each line and unique it
|
|
140
|
+
indent_set = {len(line) - len(line.lstrip()) for line in lines[1:]}
|
|
141
|
+
# Drop 0
|
|
142
|
+
res_list = sorted([x for x in indent_set if x > 0])
|
|
143
|
+
|
|
144
|
+
if res_list:
|
|
145
|
+
return res_list[0]
|
|
143
146
|
return res
|
|
144
147
|
|
|
145
148
|
def _generate_version_note(self, num_of_white_spaces: int) -> str:
|
absfuyu/core/dummy_cli.py
CHANGED
absfuyu/core/dummy_func.py
CHANGED
|
@@ -3,8 +3,8 @@ Absfuyu: Core
|
|
|
3
3
|
-------------
|
|
4
4
|
Dummy functions when other libraries are unvailable
|
|
5
5
|
|
|
6
|
-
Version: 5.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 5.1.0
|
|
7
|
+
Date updated: 10/03/2025 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
# Module Package
|
|
@@ -12,6 +12,7 @@ Date updated: 14/02/2025 (dd/mm/yyyy)
|
|
|
12
12
|
__all__ = [
|
|
13
13
|
"tqdm",
|
|
14
14
|
"unidecode",
|
|
15
|
+
"dummy_function",
|
|
15
16
|
]
|
|
16
17
|
|
|
17
18
|
|
|
@@ -23,8 +24,9 @@ from importlib import import_module
|
|
|
23
24
|
# ---------------------------------------------------------------------------
|
|
24
25
|
# tqdm wrapper
|
|
25
26
|
try:
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
_tqdm = import_module("tqdm")
|
|
28
|
+
tqdm = getattr(_tqdm, "tqdm") # noqa
|
|
29
|
+
except (ModuleNotFoundError, AttributeError):
|
|
28
30
|
|
|
29
31
|
def tqdm(iterable, *args, **kwargs):
|
|
30
32
|
"""
|
|
@@ -36,8 +38,9 @@ except ModuleNotFoundError:
|
|
|
36
38
|
|
|
37
39
|
# unidecode wrapper
|
|
38
40
|
try:
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
_unidecode = import_module("unidecode")
|
|
42
|
+
unidecode = getattr(_unidecode, "unidecode") # noqa
|
|
43
|
+
except (ModuleNotFoundError, AttributeError):
|
|
41
44
|
|
|
42
45
|
def unidecode(*args, **kwargs):
|
|
43
46
|
"""
|
|
@@ -45,3 +48,13 @@ except ModuleNotFoundError:
|
|
|
45
48
|
install package ``unidecode`` to fully use this feature
|
|
46
49
|
"""
|
|
47
50
|
return args[0]
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# dummy
|
|
54
|
+
def dummy_function(*args, **kwargs):
|
|
55
|
+
"""This is a dummy function"""
|
|
56
|
+
if args:
|
|
57
|
+
return args[0]
|
|
58
|
+
if kwargs:
|
|
59
|
+
return kwargs[list(kwargs)[0]]
|
|
60
|
+
return None
|
absfuyu/core/typings.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Absfuyu: Core
|
|
3
|
+
-------------
|
|
4
|
+
Pre-defined typing
|
|
5
|
+
|
|
6
|
+
Version: 5.1.0
|
|
7
|
+
Date updated: 10/03/2025 (dd/mm/yyyy)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
# Module Package
|
|
11
|
+
# ---------------------------------------------------------------------------
|
|
12
|
+
__all__ = ["_T", "_P", "_R", "_CALLABLE", "_CT", "_N", "_Number", "override"]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# Library
|
|
16
|
+
# ---------------------------------------------------------------------------
|
|
17
|
+
from collections.abc import Callable
|
|
18
|
+
from typing import ParamSpec, TypeVar
|
|
19
|
+
|
|
20
|
+
try:
|
|
21
|
+
from typing import override # type: ignore
|
|
22
|
+
except ImportError:
|
|
23
|
+
from absfuyu.core.decorator import dummy_decorator as override
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# Type
|
|
27
|
+
# ---------------------------------------------------------------------------
|
|
28
|
+
_T = TypeVar("_T") # Type
|
|
29
|
+
|
|
30
|
+
# Callable
|
|
31
|
+
_P = ParamSpec("_P") # Parameter type
|
|
32
|
+
_R = TypeVar("_R") # Return type - Can be anything
|
|
33
|
+
_CALLABLE = Callable[_P, _R]
|
|
34
|
+
|
|
35
|
+
# Class type - Can be any subtype of `type`
|
|
36
|
+
_CT = TypeVar("_CT", bound=type)
|
|
37
|
+
|
|
38
|
+
# Number type
|
|
39
|
+
_N = TypeVar("_N", int, float)
|
|
40
|
+
_Number = int | float
|
absfuyu/dxt/__init__.py
CHANGED
absfuyu/dxt/dictext.py
CHANGED
absfuyu/dxt/dxt_support.py
CHANGED
absfuyu/dxt/intext.py
CHANGED
|
@@ -3,8 +3,8 @@ Absfuyu: Data Extension
|
|
|
3
3
|
-----------------------
|
|
4
4
|
int extension
|
|
5
5
|
|
|
6
|
-
Version: 5.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 5.1.0
|
|
7
|
+
Date updated: 10/03/2025 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
# Module Package
|
|
@@ -18,7 +18,7 @@ import math
|
|
|
18
18
|
from collections import Counter
|
|
19
19
|
from typing import Any, Self
|
|
20
20
|
|
|
21
|
-
from absfuyu.core import ShowAllMethodsMixin, versionchanged
|
|
21
|
+
from absfuyu.core import ShowAllMethodsMixin, versionadded, versionchanged
|
|
22
22
|
from absfuyu.dxt.dxt_support import DictBoolTrue
|
|
23
23
|
|
|
24
24
|
|
|
@@ -584,3 +584,31 @@ class IntExt(ShowAllMethodsMixin, int):
|
|
|
584
584
|
|
|
585
585
|
output["characteristic"] = characteristic
|
|
586
586
|
return output # type: ignore
|
|
587
|
+
|
|
588
|
+
@versionadded("5.1.0")
|
|
589
|
+
def split(self, parts: int) -> list[int]:
|
|
590
|
+
"""
|
|
591
|
+
Evenly split the number into ``parts`` parts
|
|
592
|
+
|
|
593
|
+
Parameters
|
|
594
|
+
----------
|
|
595
|
+
parts : int
|
|
596
|
+
Split by how many parts
|
|
597
|
+
|
|
598
|
+
Returns
|
|
599
|
+
-------
|
|
600
|
+
list[int]
|
|
601
|
+
List of evenly splitted numbers
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
Example:
|
|
605
|
+
--------
|
|
606
|
+
>>> IntExt(10).split(4)
|
|
607
|
+
[2, 2, 3, 3]
|
|
608
|
+
"""
|
|
609
|
+
p = max(1, parts)
|
|
610
|
+
if p == 1:
|
|
611
|
+
return [int(self)]
|
|
612
|
+
|
|
613
|
+
quotient, remainder = divmod(self, p)
|
|
614
|
+
return [quotient + (i >= (p - remainder)) for i in range(p)]
|
absfuyu/dxt/listext.py
CHANGED
|
@@ -3,8 +3,8 @@ Absfuyu: Data Extension
|
|
|
3
3
|
-----------------------
|
|
4
4
|
list extension
|
|
5
5
|
|
|
6
|
-
Version: 5.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 5.1.0
|
|
7
|
+
Date updated: 10/03/2025 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
# Module Package
|
|
@@ -22,6 +22,7 @@ from itertools import accumulate, chain, groupby
|
|
|
22
22
|
from typing import Any, Self
|
|
23
23
|
|
|
24
24
|
from absfuyu.core import ShowAllMethodsMixin, deprecated
|
|
25
|
+
from absfuyu.core.docstring import versionadded
|
|
25
26
|
from absfuyu.util import set_min, set_min_max
|
|
26
27
|
|
|
27
28
|
|
|
@@ -323,7 +324,7 @@ class ListExt(ShowAllMethodsMixin, list):
|
|
|
323
324
|
# logger.debug(out)
|
|
324
325
|
return out
|
|
325
326
|
|
|
326
|
-
def apply(self, func: Callable) -> Self:
|
|
327
|
+
def apply(self, func: Callable[[Any], Any]) -> Self:
|
|
327
328
|
"""
|
|
328
329
|
Apply function to each entry
|
|
329
330
|
|
|
@@ -490,6 +491,30 @@ class ListExt(ShowAllMethodsMixin, list):
|
|
|
490
491
|
start = int(set_min(start, min_value=0))
|
|
491
492
|
return self.__class__(enumerate(self, start=start))
|
|
492
493
|
|
|
494
|
+
@versionadded("5.1.0") # no test case yet
|
|
495
|
+
def split_chunk(self, chunk_size: int) -> list[list]:
|
|
496
|
+
"""
|
|
497
|
+
Split list into smaller chunks
|
|
498
|
+
|
|
499
|
+
Parameters
|
|
500
|
+
----------
|
|
501
|
+
chunk_size : int
|
|
502
|
+
Chunk size, minimum: ``1``
|
|
503
|
+
|
|
504
|
+
Returns
|
|
505
|
+
-------
|
|
506
|
+
list[list]
|
|
507
|
+
List of chunk
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
Example:
|
|
511
|
+
--------
|
|
512
|
+
>>> ListExt([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]).split_chunk(5)
|
|
513
|
+
[[1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], [1, 1]]
|
|
514
|
+
"""
|
|
515
|
+
slice_points = list(range(0, len(self), max(chunk_size, 1)))[1:]
|
|
516
|
+
return self.slice_points(slice_points)
|
|
517
|
+
|
|
493
518
|
@staticmethod
|
|
494
519
|
@deprecated("5.0.0")
|
|
495
520
|
def _group_by_unique(iterable: list) -> list[list]:
|
absfuyu/dxt/strext.py
CHANGED
|
@@ -3,8 +3,8 @@ Absfuyu: Data Extension
|
|
|
3
3
|
-----------------------
|
|
4
4
|
str extension
|
|
5
5
|
|
|
6
|
-
Version: 5.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 5.1.0
|
|
7
|
+
Date updated: 10/03/2025 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
# Module Package
|
|
@@ -18,8 +18,8 @@ import random
|
|
|
18
18
|
from typing import NotRequired, Self, TypedDict
|
|
19
19
|
|
|
20
20
|
from absfuyu.core import ShowAllMethodsMixin, deprecated, versionadded, versionchanged
|
|
21
|
-
from absfuyu.general.generator import Charset, Generator
|
|
22
21
|
from absfuyu.logger import logger
|
|
22
|
+
from absfuyu.tools.generator import Charset, Generator
|
|
23
23
|
from absfuyu.util import set_min_max
|
|
24
24
|
|
|
25
25
|
|
absfuyu/extra/__init__.py
CHANGED
absfuyu/extra/beautiful.py
CHANGED
|
@@ -3,8 +3,8 @@ Absfuyu: Beautiful
|
|
|
3
3
|
------------------
|
|
4
4
|
A decorator that makes output more beautiful
|
|
5
5
|
|
|
6
|
-
Version: 5.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 5.1.0
|
|
7
|
+
Date updated: 10/03/2025 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
# Module level
|
|
@@ -77,6 +77,7 @@ class PerformanceOutput(NamedTuple):
|
|
|
77
77
|
return out
|
|
78
78
|
|
|
79
79
|
|
|
80
|
+
# TODO: header and footer layout to 1,2,3 instead of true false
|
|
80
81
|
class BeautifulOutput:
|
|
81
82
|
"""A decorator that makes output more beautiful"""
|
|
82
83
|
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Absfuyu: Data Analysis
|
|
3
|
+
----------------------
|
|
4
|
+
Data Analyst
|
|
5
|
+
|
|
6
|
+
Version: 5.1.0
|
|
7
|
+
Date updated: 10/03/2025 (dd/mm/yyyy)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
# Module level
|
|
11
|
+
# ---------------------------------------------------------------------------
|
|
12
|
+
__all__ = ["MatplotlibFormatString", "DADF"]
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# Library
|
|
16
|
+
# ---------------------------------------------------------------------------
|
|
17
|
+
DA_MODE = False
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
import numpy as np
|
|
21
|
+
import pandas as pd
|
|
22
|
+
except ImportError:
|
|
23
|
+
from subprocess import run
|
|
24
|
+
|
|
25
|
+
from absfuyu.config import ABSFUYU_CONFIG
|
|
26
|
+
|
|
27
|
+
if ABSFUYU_CONFIG._get_setting("auto-install-extra").value:
|
|
28
|
+
cmd = "python -m pip install -U absfuyu[full]".split()
|
|
29
|
+
run(cmd)
|
|
30
|
+
else:
|
|
31
|
+
raise SystemExit("This feature is in absfuyu[full] package") # noqa: B904
|
|
32
|
+
else:
|
|
33
|
+
DA_MODE = True
|
|
34
|
+
|
|
35
|
+
from absfuyu.extra.da.dadf import DADF
|
|
36
|
+
from absfuyu.extra.da.mplt import MatplotlibFormatString
|