absfuyu 5.0.1__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.

Files changed (72) hide show
  1. absfuyu/__init__.py +1 -1
  2. absfuyu/__main__.py +2 -2
  3. absfuyu/cli/__init__.py +2 -2
  4. absfuyu/cli/color.py +30 -14
  5. absfuyu/cli/config_group.py +9 -2
  6. absfuyu/cli/do_group.py +13 -6
  7. absfuyu/cli/game_group.py +9 -2
  8. absfuyu/cli/tool_group.py +16 -9
  9. absfuyu/config/__init__.py +2 -2
  10. absfuyu/core/__init__.py +2 -2
  11. absfuyu/core/baseclass.py +448 -79
  12. absfuyu/core/baseclass2.py +2 -2
  13. absfuyu/core/decorator.py +69 -3
  14. absfuyu/core/docstring.py +2 -2
  15. absfuyu/core/dummy_cli.py +2 -2
  16. absfuyu/core/dummy_func.py +13 -2
  17. absfuyu/core/typings.py +40 -0
  18. absfuyu/dxt/__init__.py +2 -2
  19. absfuyu/dxt/dictext.py +2 -2
  20. absfuyu/dxt/dxt_support.py +2 -2
  21. absfuyu/dxt/intext.py +31 -3
  22. absfuyu/dxt/listext.py +28 -3
  23. absfuyu/dxt/strext.py +2 -2
  24. absfuyu/extra/__init__.py +2 -2
  25. absfuyu/extra/beautiful.py +2 -2
  26. absfuyu/extra/da/__init__.py +36 -0
  27. absfuyu/extra/da/dadf.py +1138 -0
  28. absfuyu/extra/da/dadf_base.py +186 -0
  29. absfuyu/extra/da/df_func.py +97 -0
  30. absfuyu/extra/da/mplt.py +219 -0
  31. absfuyu/extra/data_analysis.py +10 -1067
  32. absfuyu/fun/__init__.py +2 -2
  33. absfuyu/fun/tarot.py +2 -2
  34. absfuyu/game/__init__.py +2 -2
  35. absfuyu/game/game_stat.py +2 -2
  36. absfuyu/game/sudoku.py +2 -2
  37. absfuyu/game/tictactoe.py +2 -2
  38. absfuyu/game/wordle.py +2 -2
  39. absfuyu/general/__init__.py +2 -2
  40. absfuyu/general/content.py +2 -2
  41. absfuyu/general/human.py +2 -2
  42. absfuyu/general/shape.py +2 -2
  43. absfuyu/logger.py +2 -2
  44. absfuyu/pkg_data/__init__.py +2 -2
  45. absfuyu/pkg_data/deprecated.py +2 -2
  46. absfuyu/sort.py +2 -2
  47. absfuyu/tools/__init__.py +25 -2
  48. absfuyu/tools/checksum.py +27 -7
  49. absfuyu/tools/converter.py +93 -28
  50. absfuyu/tools/generator.py +2 -2
  51. absfuyu/tools/inspector.py +433 -0
  52. absfuyu/tools/keygen.py +2 -2
  53. absfuyu/tools/obfuscator.py +45 -7
  54. absfuyu/tools/passwordlib.py +87 -22
  55. absfuyu/tools/shutdownizer.py +2 -2
  56. absfuyu/tools/web.py +2 -2
  57. absfuyu/util/__init__.py +2 -2
  58. absfuyu/util/api.py +2 -2
  59. absfuyu/util/json_method.py +2 -2
  60. absfuyu/util/lunar.py +2 -2
  61. absfuyu/util/path.py +190 -82
  62. absfuyu/util/performance.py +4 -4
  63. absfuyu/util/shorten_number.py +40 -10
  64. absfuyu/util/text_table.py +272 -0
  65. absfuyu/util/zipped.py +6 -6
  66. absfuyu/version.py +2 -2
  67. {absfuyu-5.0.1.dist-info → absfuyu-5.1.0.dist-info}/METADATA +9 -2
  68. absfuyu-5.1.0.dist-info/RECORD +76 -0
  69. absfuyu-5.0.1.dist-info/RECORD +0 -68
  70. {absfuyu-5.0.1.dist-info → absfuyu-5.1.0.dist-info}/WHEEL +0 -0
  71. {absfuyu-5.0.1.dist-info → absfuyu-5.1.0.dist-info}/entry_points.txt +0 -0
  72. {absfuyu-5.0.1.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.0.0
7
- Date updated: 22/02/2025 (dd/mm/yyyy)
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__ = ["dummy_decorator", "dummy_decorator_with_args"]
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.0.0
7
- Date updated: 23/02/2025 (dd/mm/yyyy)
6
+ Version: 5.1.0
7
+ Date updated: 10/03/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module Package
absfuyu/core/dummy_cli.py CHANGED
@@ -3,8 +3,8 @@ Absfuyu: Core
3
3
  -------------
4
4
  Dummy cli
5
5
 
6
- Version: 5.0.0
7
- Date updated: 25/02/2025 (dd/mm/yyyy)
6
+ Version: 5.1.0
7
+ Date updated: 10/03/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module Package
@@ -3,8 +3,8 @@ Absfuyu: Core
3
3
  -------------
4
4
  Dummy functions when other libraries are unvailable
5
5
 
6
- Version: 5.0.0
7
- Date updated: 22/02/2025 (dd/mm/yyyy)
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: 22/02/2025 (dd/mm/yyyy)
12
12
  __all__ = [
13
13
  "tqdm",
14
14
  "unidecode",
15
+ "dummy_function",
15
16
  ]
16
17
 
17
18
 
@@ -47,3 +48,13 @@ except (ModuleNotFoundError, AttributeError):
47
48
  install package ``unidecode`` to fully use this feature
48
49
  """
49
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
@@ -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
@@ -3,8 +3,8 @@ Absfuyu: Data Extension
3
3
  -----------------------
4
4
  Extension for data type such as ``list``, ``str``, ``dict``, ...
5
5
 
6
- Version: 5.0.0
7
- Date updated: 22/02/2025 (dd/mm/yyyy)
6
+ Version: 5.1.0
7
+ Date updated: 10/03/2025 (dd/mm/yyyy)
8
8
 
9
9
  Features:
10
10
  ---------
absfuyu/dxt/dictext.py CHANGED
@@ -3,8 +3,8 @@ Absfuyu: Data Extension
3
3
  -----------------------
4
4
  dict extension
5
5
 
6
- Version: 5.0.0
7
- Date updated: 25/02/2025 (dd/mm/yyyy)
6
+ Version: 5.1.0
7
+ Date updated: 10/03/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module Package
@@ -3,8 +3,8 @@ Absfuyu: Data Extension
3
3
  -----------------------
4
4
  Support classes
5
5
 
6
- Version: 5.0.0
7
- Date updated: 22/02/2025 (dd/mm/yyyy)
6
+ Version: 5.1.0
7
+ Date updated: 10/03/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module Package
absfuyu/dxt/intext.py CHANGED
@@ -3,8 +3,8 @@ Absfuyu: Data Extension
3
3
  -----------------------
4
4
  int extension
5
5
 
6
- Version: 5.0.0
7
- Date updated: 25/02/2025 (dd/mm/yyyy)
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.0.0
7
- Date updated: 25/02/2025 (dd/mm/yyyy)
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.0.0
7
- Date updated: 25/02/2025 (dd/mm/yyyy)
6
+ Version: 5.1.0
7
+ Date updated: 10/03/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module Package
absfuyu/extra/__init__.py CHANGED
@@ -3,8 +3,8 @@ Absfuyu: Extra
3
3
  --------------
4
4
  Features that require additional libraries
5
5
 
6
- Version: 5.0.0
7
- Date updated: 22/02/2025 (dd/mm/yyyy)
6
+ Version: 5.1.0
7
+ Date updated: 10/03/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
 
@@ -3,8 +3,8 @@ Absfuyu: Beautiful
3
3
  ------------------
4
4
  A decorator that makes output more beautiful
5
5
 
6
- Version: 5.0.0
7
- Date updated: 22/02/2025 (dd/mm/yyyy)
6
+ Version: 5.1.0
7
+ Date updated: 10/03/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module level
@@ -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