absfuyu 5.6.1__py3-none-any.whl → 6.1.2__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 +5 -3
- absfuyu/__main__.py +2 -2
- absfuyu/cli/__init__.py +13 -2
- absfuyu/cli/audio_group.py +98 -0
- absfuyu/cli/color.py +2 -2
- absfuyu/cli/config_group.py +2 -2
- absfuyu/cli/do_group.py +2 -2
- absfuyu/cli/game_group.py +20 -2
- absfuyu/cli/tool_group.py +68 -4
- absfuyu/config/__init__.py +3 -3
- absfuyu/core/__init__.py +10 -6
- absfuyu/core/baseclass.py +104 -34
- absfuyu/core/baseclass2.py +43 -2
- absfuyu/core/decorator.py +2 -2
- absfuyu/core/docstring.py +4 -2
- absfuyu/core/dummy_cli.py +3 -3
- absfuyu/core/dummy_func.py +2 -2
- absfuyu/dxt/__init__.py +2 -2
- absfuyu/dxt/base_type.py +93 -0
- absfuyu/dxt/dictext.py +188 -6
- absfuyu/dxt/dxt_support.py +2 -2
- absfuyu/dxt/intext.py +72 -4
- absfuyu/dxt/listext.py +495 -23
- absfuyu/dxt/strext.py +2 -2
- absfuyu/extra/__init__.py +2 -2
- absfuyu/extra/audio/__init__.py +8 -0
- absfuyu/extra/audio/_util.py +57 -0
- absfuyu/extra/audio/convert.py +192 -0
- absfuyu/extra/audio/lossless.py +281 -0
- absfuyu/extra/beautiful.py +2 -2
- absfuyu/extra/da/__init__.py +39 -3
- absfuyu/extra/da/dadf.py +436 -29
- absfuyu/extra/da/dadf_base.py +2 -2
- absfuyu/extra/da/df_func.py +89 -5
- absfuyu/extra/da/mplt.py +2 -2
- absfuyu/extra/ggapi/__init__.py +8 -0
- absfuyu/extra/ggapi/gdrive.py +223 -0
- absfuyu/extra/ggapi/glicense.py +148 -0
- absfuyu/extra/ggapi/glicense_df.py +186 -0
- absfuyu/extra/ggapi/gsheet.py +88 -0
- absfuyu/extra/img/__init__.py +30 -0
- absfuyu/extra/img/converter.py +402 -0
- absfuyu/extra/img/dup_check.py +291 -0
- absfuyu/extra/pdf.py +4 -6
- absfuyu/extra/rclone.py +253 -0
- absfuyu/extra/xml.py +90 -0
- absfuyu/fun/__init__.py +2 -20
- absfuyu/fun/rubik.py +2 -2
- absfuyu/fun/tarot.py +2 -2
- absfuyu/game/__init__.py +2 -2
- absfuyu/game/game_stat.py +2 -2
- absfuyu/game/schulte.py +78 -0
- absfuyu/game/sudoku.py +2 -2
- absfuyu/game/tictactoe.py +2 -2
- absfuyu/game/wordle.py +6 -4
- absfuyu/general/__init__.py +2 -2
- absfuyu/general/content.py +2 -2
- absfuyu/general/human.py +2 -2
- absfuyu/general/resrel.py +213 -0
- absfuyu/general/shape.py +3 -8
- absfuyu/general/tax.py +344 -0
- absfuyu/logger.py +806 -59
- absfuyu/numbers/__init__.py +13 -0
- absfuyu/numbers/number_to_word.py +321 -0
- absfuyu/numbers/shorten_number.py +303 -0
- absfuyu/numbers/time_duration.py +217 -0
- absfuyu/pkg_data/__init__.py +2 -2
- absfuyu/pkg_data/deprecated.py +2 -2
- absfuyu/pkg_data/logo.py +1462 -0
- absfuyu/sort.py +4 -4
- absfuyu/tools/__init__.py +2 -2
- absfuyu/tools/checksum.py +119 -4
- absfuyu/tools/converter.py +2 -2
- absfuyu/tools/generator.py +24 -7
- absfuyu/tools/inspector.py +2 -2
- absfuyu/tools/keygen.py +2 -2
- absfuyu/tools/obfuscator.py +2 -2
- absfuyu/tools/passwordlib.py +2 -2
- absfuyu/tools/shutdownizer.py +3 -8
- absfuyu/tools/sw.py +213 -10
- absfuyu/tools/web.py +10 -13
- absfuyu/typings.py +5 -8
- absfuyu/util/__init__.py +31 -2
- absfuyu/util/api.py +7 -4
- absfuyu/util/cli.py +119 -0
- absfuyu/util/gui.py +91 -0
- absfuyu/util/json_method.py +2 -2
- absfuyu/util/lunar.py +2 -2
- absfuyu/util/package.py +124 -0
- absfuyu/util/path.py +313 -4
- absfuyu/util/performance.py +2 -2
- absfuyu/util/shorten_number.py +206 -13
- absfuyu/util/text_table.py +2 -2
- absfuyu/util/zipped.py +2 -2
- absfuyu/version.py +22 -19
- {absfuyu-5.6.1.dist-info → absfuyu-6.1.2.dist-info}/METADATA +37 -8
- absfuyu-6.1.2.dist-info/RECORD +105 -0
- {absfuyu-5.6.1.dist-info → absfuyu-6.1.2.dist-info}/WHEEL +1 -1
- absfuyu/extra/data_analysis.py +0 -21
- absfuyu-5.6.1.dist-info/RECORD +0 -79
- {absfuyu-5.6.1.dist-info → absfuyu-6.1.2.dist-info}/entry_points.txt +0 -0
- {absfuyu-5.6.1.dist-info → absfuyu-6.1.2.dist-info}/licenses/LICENSE +0 -0
absfuyu/fun/rubik.py
CHANGED
absfuyu/fun/tarot.py
CHANGED
absfuyu/game/__init__.py
CHANGED
absfuyu/game/game_stat.py
CHANGED
absfuyu/game/schulte.py
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Game: Schulte
|
|
3
|
+
-------------
|
|
4
|
+
|
|
5
|
+
Version: 6.1.1
|
|
6
|
+
Date updated: 30/12/2025 (dd/mm/yyyy)
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
# Module level
|
|
10
|
+
# ---------------------------------------------------------------------------
|
|
11
|
+
__all__ = ["SchulteTable"]
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# Library
|
|
15
|
+
# ---------------------------------------------------------------------------
|
|
16
|
+
from absfuyu.core.baseclass import BaseClass
|
|
17
|
+
from absfuyu.dxt import ListExt
|
|
18
|
+
from absfuyu.util.text_table import BoxStyle, get_box_drawing_character
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# Function
|
|
22
|
+
# ---------------------------------------------------------------------------
|
|
23
|
+
def draw_grid(data: list[list[int]], style: BoxStyle = "normal"):
|
|
24
|
+
chars = get_box_drawing_character(style=style)
|
|
25
|
+
rows = len(data)
|
|
26
|
+
cols = len(data[0])
|
|
27
|
+
|
|
28
|
+
# find max width for padding
|
|
29
|
+
cell_width = max(len(str(x)) for row in data for x in row) + 2
|
|
30
|
+
|
|
31
|
+
def horizontal_border(left: str, middle: str, right: str) -> str:
|
|
32
|
+
return left + (chars.HORIZONTAL * cell_width + middle) * (cols - 1) + chars.HORIZONTAL * cell_width + right
|
|
33
|
+
|
|
34
|
+
# top border
|
|
35
|
+
print(horizontal_border(chars.UPPER_LEFT_CORNER, chars.HORIZONTAL_DOWN, chars.UPPER_RIGHT_CORNER))
|
|
36
|
+
|
|
37
|
+
for i, row in enumerate(data):
|
|
38
|
+
# content line
|
|
39
|
+
line = chars.VERTICAL + "".join(f"{str(val):^{cell_width}}" + chars.VERTICAL for val in row)
|
|
40
|
+
print(line)
|
|
41
|
+
|
|
42
|
+
# middle or bottom border
|
|
43
|
+
if i < rows - 1:
|
|
44
|
+
print(horizontal_border(chars.VERTICAL_RIGHT, chars.CROSS, chars.VERTICAL_LEFT))
|
|
45
|
+
else:
|
|
46
|
+
print(horizontal_border(chars.LOWER_LEFT_CORNER, chars.HORIZONTAL_UP, chars.LOWER_RIGHT_CORNER))
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# Class
|
|
50
|
+
# ---------------------------------------------------------------------------
|
|
51
|
+
class SchulteTable(BaseClass):
|
|
52
|
+
"""
|
|
53
|
+
A Schulte Table is a cognitive training tool consisting of a grid filled
|
|
54
|
+
with randomly placed numbers. The task is to find and select all the numbers
|
|
55
|
+
in ascending order as quickly as possible. This exercise helps improve
|
|
56
|
+
visual attention, focus, processing speed, mental flexibility,
|
|
57
|
+
and peripheral vision.
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
def __init__(self, size: int = 5) -> None:
|
|
61
|
+
self.size = max(size, 1)
|
|
62
|
+
|
|
63
|
+
def make_table(self) -> None:
|
|
64
|
+
data = ListExt(range(1, self.size**2 + 1)).shuffle().split_chunk(self.size)
|
|
65
|
+
draw_grid(data)
|
|
66
|
+
|
|
67
|
+
# def play(self):
|
|
68
|
+
# """GUI"""
|
|
69
|
+
# from absfuyu.util.gui import CustomTkinterApp
|
|
70
|
+
|
|
71
|
+
# class Schulte(CustomTkinterApp):
|
|
72
|
+
# def __init__(self, title: str | None = None, size: tuple[int, int] | None = None) -> None:
|
|
73
|
+
# super().__init__(title=title, size=size)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
if __name__ == "__main__":
|
|
77
|
+
t = SchulteTable(5)
|
|
78
|
+
print(t)
|
absfuyu/game/sudoku.py
CHANGED
absfuyu/game/tictactoe.py
CHANGED
absfuyu/game/wordle.py
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Game: Wordle Solver
|
|
3
3
|
-------------------
|
|
4
4
|
|
|
5
|
-
Version:
|
|
6
|
-
Date updated: 12/
|
|
5
|
+
Version: 6.1.1
|
|
6
|
+
Date updated: 30/12/2025 (dd/mm/yyyy)
|
|
7
7
|
|
|
8
8
|
Usage:
|
|
9
9
|
------
|
|
@@ -27,8 +27,6 @@ import string
|
|
|
27
27
|
from collections import Counter
|
|
28
28
|
from itertools import chain
|
|
29
29
|
|
|
30
|
-
import requests
|
|
31
|
-
|
|
32
30
|
# Class
|
|
33
31
|
# ---------------------------------------------------------------------------
|
|
34
32
|
OFFLINE_WORDS = """\
|
|
@@ -123,6 +121,8 @@ class Wordle:
|
|
|
123
121
|
Try to fetch words list from online source
|
|
124
122
|
"""
|
|
125
123
|
try:
|
|
124
|
+
import requests
|
|
125
|
+
|
|
126
126
|
dict_link = "https://raw.githubusercontent.com/dwyl/english-words/master/words_dictionary.json"
|
|
127
127
|
res = requests.get(dict_link)
|
|
128
128
|
word_list: list[str] = list(res.json().keys())
|
|
@@ -134,6 +134,8 @@ class Wordle:
|
|
|
134
134
|
and set(word) < self._ALLOWABLE_CHARACTERS
|
|
135
135
|
}
|
|
136
136
|
)
|
|
137
|
+
except ImportError:
|
|
138
|
+
raise ImportError("Please install requests package")
|
|
137
139
|
except Exception:
|
|
138
140
|
pass
|
|
139
141
|
|
absfuyu/general/__init__.py
CHANGED
absfuyu/general/content.py
CHANGED
absfuyu/general/human.py
CHANGED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Absfuyu: Relative resolution
|
|
3
|
+
----------------------------
|
|
4
|
+
Relative resolution
|
|
5
|
+
|
|
6
|
+
Use with screen resolution getter like ``tkinter``, ``ctypes``, ``screeninfo`` is recommended
|
|
7
|
+
|
|
8
|
+
Version: 6.1.1
|
|
9
|
+
Date updated: 30/12/2025 (dd/mm/yyyy)
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
# Module level
|
|
13
|
+
# ---------------------------------------------------------------------------
|
|
14
|
+
__all__ = ["RelativeResoluton", "RelativeResolutonTranslater"]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# Library
|
|
18
|
+
# ---------------------------------------------------------------------------
|
|
19
|
+
from fractions import Fraction
|
|
20
|
+
from typing import Self, overload
|
|
21
|
+
|
|
22
|
+
from absfuyu.core.baseclass import BaseClass
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# Class
|
|
26
|
+
# ---------------------------------------------------------------------------
|
|
27
|
+
class RelativeResoluton(BaseClass):
|
|
28
|
+
def __init__(self, x: int, y: int) -> None:
|
|
29
|
+
"""
|
|
30
|
+
Resolution
|
|
31
|
+
|
|
32
|
+
Parameters
|
|
33
|
+
----------
|
|
34
|
+
x : int
|
|
35
|
+
Normally width
|
|
36
|
+
|
|
37
|
+
y : int
|
|
38
|
+
Normally height
|
|
39
|
+
|
|
40
|
+
Raises
|
|
41
|
+
------
|
|
42
|
+
ValueError
|
|
43
|
+
When x or y < 1
|
|
44
|
+
"""
|
|
45
|
+
if x < 1 or y < 1:
|
|
46
|
+
raise ValueError("Resolution must be >= 1")
|
|
47
|
+
|
|
48
|
+
self.x = x
|
|
49
|
+
self.y = y
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def ratio(self) -> Fraction:
|
|
53
|
+
"""
|
|
54
|
+
Ratio of the resolution
|
|
55
|
+
"""
|
|
56
|
+
return Fraction(self.x, self.y)
|
|
57
|
+
|
|
58
|
+
def scale_by(self, by: int | float | Fraction, /) -> Self:
|
|
59
|
+
"""
|
|
60
|
+
Scale the resolution by an amount
|
|
61
|
+
|
|
62
|
+
Parameters
|
|
63
|
+
----------
|
|
64
|
+
by : int | float | Fraction
|
|
65
|
+
Amount to scale
|
|
66
|
+
|
|
67
|
+
Returns
|
|
68
|
+
-------
|
|
69
|
+
Self
|
|
70
|
+
New scaled resolution
|
|
71
|
+
"""
|
|
72
|
+
if isinstance(by, Fraction):
|
|
73
|
+
x = int(self.x * by.numerator / by.denominator)
|
|
74
|
+
y = int(self.y * by.numerator / by.denominator)
|
|
75
|
+
else:
|
|
76
|
+
x = int(self.x * by)
|
|
77
|
+
y = int(self.y * by)
|
|
78
|
+
return self.__class__(x, y)
|
|
79
|
+
|
|
80
|
+
@overload
|
|
81
|
+
def get_point_relative(self, x: int, y: int, /) -> tuple[Fraction, Fraction]: ...
|
|
82
|
+
@overload
|
|
83
|
+
def get_point_relative(self, x: int, y: int, /, *, strict: bool = True) -> tuple[Fraction, Fraction]: ...
|
|
84
|
+
def get_point_relative(self, x: int, y: int, /, *, strict: bool = True) -> tuple[Fraction, Fraction]:
|
|
85
|
+
"""
|
|
86
|
+
Get relative point from fixed point.
|
|
87
|
+
|
|
88
|
+
Parameters
|
|
89
|
+
----------
|
|
90
|
+
x : int
|
|
91
|
+
Normally width
|
|
92
|
+
|
|
93
|
+
y : int
|
|
94
|
+
Normally height
|
|
95
|
+
|
|
96
|
+
strict : bool, optional
|
|
97
|
+
Convert ``x`` and ``y`` into type int first, by default ``True``
|
|
98
|
+
|
|
99
|
+
Returns
|
|
100
|
+
-------
|
|
101
|
+
tuple[Fraction, Fraction]
|
|
102
|
+
Relative point
|
|
103
|
+
"""
|
|
104
|
+
if strict:
|
|
105
|
+
x = int(x)
|
|
106
|
+
y = int(y)
|
|
107
|
+
x_rel = Fraction(x, self.x)
|
|
108
|
+
y_rel = Fraction(y, self.y)
|
|
109
|
+
return x_rel, y_rel
|
|
110
|
+
|
|
111
|
+
def get_fixed_point(self, x_rel: Fraction, y_rel: Fraction, /) -> tuple[int, int]:
|
|
112
|
+
"""
|
|
113
|
+
Get fixed point from relative point.
|
|
114
|
+
|
|
115
|
+
Parameters
|
|
116
|
+
----------
|
|
117
|
+
x_rel : Fraction
|
|
118
|
+
Normally width
|
|
119
|
+
|
|
120
|
+
y_rel : Fraction
|
|
121
|
+
Normally height
|
|
122
|
+
|
|
123
|
+
Returns
|
|
124
|
+
-------
|
|
125
|
+
tuple[int, int]
|
|
126
|
+
Fixed point
|
|
127
|
+
"""
|
|
128
|
+
x = int(self.x * x_rel.numerator / x_rel.denominator)
|
|
129
|
+
y = int(self.y * y_rel.numerator / y_rel.denominator)
|
|
130
|
+
return x, y
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class RelativeResolutonTranslater(RelativeResoluton):
|
|
134
|
+
"""
|
|
135
|
+
Relative resolution translater
|
|
136
|
+
|
|
137
|
+
It is recommended to use with screen resolution getter like
|
|
138
|
+
``tkinter``, ``ctypes``, ``screeninfo``, ``pyautogui``
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
Example:
|
|
142
|
+
--------
|
|
143
|
+
>>> import tkinter as tk
|
|
144
|
+
>>> root = tk.Tk()
|
|
145
|
+
>>> width, height = root.winfo_screenwidth(), root.winfo_screenheight()
|
|
146
|
+
>>> rr = RelativeResolutonTranslater(width, height)
|
|
147
|
+
>>> rr.add_target_scale((1920, 1080))
|
|
148
|
+
>>> rr.t(1280, 720)
|
|
149
|
+
|
|
150
|
+
>>> import tkinter as tk
|
|
151
|
+
>>> root = tk.Tk()
|
|
152
|
+
>>> width, height = root.winfo_screenwidth(), root.winfo_screenheight()
|
|
153
|
+
>>> rr = RelativeResolutonTranslater(1920, 1080)
|
|
154
|
+
>>> rr.add_target_scale((width, height))
|
|
155
|
+
>>> rr.t(1280, 720)
|
|
156
|
+
"""
|
|
157
|
+
|
|
158
|
+
def __init__(self, x: int, y: int) -> None:
|
|
159
|
+
super().__init__(x, y)
|
|
160
|
+
self._target_scale = Fraction(1, 1)
|
|
161
|
+
|
|
162
|
+
@overload
|
|
163
|
+
def add_target_scale(self, target: int | float, /) -> None: ...
|
|
164
|
+
@overload
|
|
165
|
+
def add_target_scale(self, target: Fraction, /) -> None: ...
|
|
166
|
+
@overload
|
|
167
|
+
def add_target_scale(self, target: tuple[int, int], /) -> None: ...
|
|
168
|
+
def add_target_scale(self, target: tuple[int, int] | Fraction | int | float, /) -> None:
|
|
169
|
+
"""
|
|
170
|
+
Add target scale to scale resolution to
|
|
171
|
+
|
|
172
|
+
Parameters
|
|
173
|
+
----------
|
|
174
|
+
target : tuple[int, int] | Fraction | int | float
|
|
175
|
+
Target scale (tuple[int, int] for desire resolution)
|
|
176
|
+
|
|
177
|
+
Raises
|
|
178
|
+
------
|
|
179
|
+
NotImplementedError
|
|
180
|
+
When ratio of new and old resolution is not equal
|
|
181
|
+
"""
|
|
182
|
+
if isinstance(target, tuple): # Resolution
|
|
183
|
+
if self.ratio == Fraction(*target): # Same ratio
|
|
184
|
+
self._target_scale = Fraction(target[0] / self.x)
|
|
185
|
+
else:
|
|
186
|
+
raise NotImplementedError("Resolution's ratio conversion not supported")
|
|
187
|
+
else:
|
|
188
|
+
self._target_scale = Fraction(target)
|
|
189
|
+
|
|
190
|
+
def translate_point(self, x: int, y: int, /) -> tuple[int, int]:
|
|
191
|
+
"""
|
|
192
|
+
Translate point(x, y) to target_scale fixed point through relative point.
|
|
193
|
+
|
|
194
|
+
Parameters
|
|
195
|
+
----------
|
|
196
|
+
x : int
|
|
197
|
+
Normally width
|
|
198
|
+
|
|
199
|
+
y : int
|
|
200
|
+
Normally height
|
|
201
|
+
|
|
202
|
+
Returns
|
|
203
|
+
-------
|
|
204
|
+
tuple[int, int]
|
|
205
|
+
Translated point
|
|
206
|
+
"""
|
|
207
|
+
x_rel, y_rel = self.get_point_relative(x, y)
|
|
208
|
+
fixed_point = self.scale_by(self._target_scale).get_fixed_point(x_rel, y_rel)
|
|
209
|
+
return fixed_point
|
|
210
|
+
|
|
211
|
+
def t(self, x: int, y: int, /) -> tuple[int, int]:
|
|
212
|
+
"""Wrapper for self.translate_point"""
|
|
213
|
+
return self.translate_point(x, y)
|
absfuyu/general/shape.py
CHANGED
|
@@ -3,8 +3,8 @@ Absfuyu: Shape
|
|
|
3
3
|
--------------
|
|
4
4
|
Shapes
|
|
5
5
|
|
|
6
|
-
Version:
|
|
7
|
-
Date updated: 12/
|
|
6
|
+
Version: 6.1.1
|
|
7
|
+
Date updated: 30/12/2025 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
# Module level
|
|
@@ -33,12 +33,7 @@ __all__ = [
|
|
|
33
33
|
# ---------------------------------------------------------------------------
|
|
34
34
|
import math
|
|
35
35
|
from abc import ABC, abstractmethod
|
|
36
|
-
from typing import ClassVar, Self
|
|
37
|
-
|
|
38
|
-
try:
|
|
39
|
-
from typing import override # type: ignore
|
|
40
|
-
except ImportError:
|
|
41
|
-
from absfuyu.core.decorator import dummy_decorator as override
|
|
36
|
+
from typing import ClassVar, Self, override
|
|
42
37
|
|
|
43
38
|
from absfuyu.core import BaseClass
|
|
44
39
|
|