absfuyu 5.2.0__py3-none-any.whl → 5.4.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 +2 -2
- absfuyu/cli/config_group.py +2 -2
- absfuyu/cli/do_group.py +12 -2
- absfuyu/cli/game_group.py +2 -2
- absfuyu/cli/tool_group.py +2 -2
- absfuyu/config/__init__.py +2 -2
- absfuyu/core/__init__.py +2 -2
- absfuyu/core/baseclass.py +32 -2
- absfuyu/core/baseclass2.py +2 -2
- absfuyu/core/decorator.py +2 -2
- absfuyu/core/docstring.py +2 -2
- absfuyu/core/dummy_cli.py +2 -2
- absfuyu/core/dummy_func.py +2 -2
- absfuyu/dxt/__init__.py +2 -2
- absfuyu/dxt/dictext.py +15 -6
- absfuyu/dxt/dxt_support.py +2 -2
- absfuyu/dxt/intext.py +51 -33
- absfuyu/dxt/listext.py +138 -10
- absfuyu/dxt/strext.py +2 -2
- absfuyu/extra/__init__.py +2 -2
- absfuyu/extra/beautiful.py +2 -2
- absfuyu/extra/da/__init__.py +2 -2
- absfuyu/extra/da/dadf.py +57 -41
- absfuyu/extra/da/dadf_base.py +2 -2
- absfuyu/extra/da/df_func.py +2 -2
- absfuyu/extra/da/mplt.py +2 -2
- absfuyu/extra/data_analysis.py +2 -2
- absfuyu/fun/__init__.py +7 -2
- absfuyu/fun/rubik.py +442 -0
- 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 +2 -2
- 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 +4 -4
- absfuyu/tools/checksum.py +2 -2
- absfuyu/tools/converter.py +2 -2
- absfuyu/tools/generator.py +2 -2
- absfuyu/tools/inspector.py +41 -6
- absfuyu/tools/keygen.py +2 -2
- absfuyu/tools/obfuscator.py +2 -2
- absfuyu/tools/passwordlib.py +2 -2
- absfuyu/tools/shutdownizer.py +2 -2
- absfuyu/tools/web.py +2 -2
- absfuyu/typings.py +7 -2
- absfuyu/util/__init__.py +57 -3
- absfuyu/util/api.py +2 -2
- absfuyu/util/json_method.py +2 -2
- absfuyu/util/lunar.py +2 -2
- absfuyu/util/path.py +158 -4
- absfuyu/util/performance.py +2 -2
- absfuyu/util/shorten_number.py +2 -2
- absfuyu/util/text_table.py +220 -64
- absfuyu/util/zipped.py +2 -2
- absfuyu/version.py +2 -2
- {absfuyu-5.2.0.dist-info → absfuyu-5.4.0.dist-info}/METADATA +1 -1
- absfuyu-5.4.0.dist-info/RECORD +77 -0
- absfuyu-5.2.0.dist-info/RECORD +0 -76
- {absfuyu-5.2.0.dist-info → absfuyu-5.4.0.dist-info}/WHEEL +0 -0
- {absfuyu-5.2.0.dist-info → absfuyu-5.4.0.dist-info}/entry_points.txt +0 -0
- {absfuyu-5.2.0.dist-info → absfuyu-5.4.0.dist-info}/licenses/LICENSE +0 -0
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.4.0
|
|
7
|
+
Date updated: 21/03/2025 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
# Module Package
|
|
@@ -18,11 +18,12 @@ import operator
|
|
|
18
18
|
import random
|
|
19
19
|
from collections import Counter
|
|
20
20
|
from collections.abc import Callable, Iterable
|
|
21
|
-
from itertools import accumulate, chain, groupby
|
|
21
|
+
from itertools import accumulate, chain, groupby, zip_longest
|
|
22
22
|
from typing import Any, Literal, Self, cast, overload
|
|
23
23
|
|
|
24
24
|
from absfuyu.core.baseclass import ShowAllMethodsMixin
|
|
25
25
|
from absfuyu.core.docstring import deprecated, versionadded, versionchanged
|
|
26
|
+
from absfuyu.typings import T as _T
|
|
26
27
|
from absfuyu.util import set_min_max
|
|
27
28
|
|
|
28
29
|
|
|
@@ -71,6 +72,12 @@ class ListExt(ShowAllMethodsMixin, list):
|
|
|
71
72
|
-------
|
|
72
73
|
list
|
|
73
74
|
Filtered list
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
Example:
|
|
78
|
+
--------
|
|
79
|
+
>>> ListExt(range(10)).head(2)
|
|
80
|
+
[0, 1]
|
|
74
81
|
"""
|
|
75
82
|
number_of_items = int(
|
|
76
83
|
set_min_max(number_of_items, min_value=0, max_value=len(self))
|
|
@@ -91,6 +98,12 @@ class ListExt(ShowAllMethodsMixin, list):
|
|
|
91
98
|
-------
|
|
92
99
|
list
|
|
93
100
|
Filtered list
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
Example:
|
|
104
|
+
--------
|
|
105
|
+
>>> ListExt(range(10)).tail(2)
|
|
106
|
+
[8, 9]
|
|
94
107
|
"""
|
|
95
108
|
number_of_items = int(
|
|
96
109
|
set_min_max(number_of_items, min_value=0, max_value=len(self))
|
|
@@ -354,6 +367,40 @@ class ListExt(ShowAllMethodsMixin, list):
|
|
|
354
367
|
start = max(start, 0)
|
|
355
368
|
return self.__class__(enumerate(self, start=start))
|
|
356
369
|
|
|
370
|
+
@versionadded("5.3.0") # no test case yet
|
|
371
|
+
def transpose(self, fillvalue: _T | None = None, /) -> Self:
|
|
372
|
+
"""
|
|
373
|
+
Transpose a list of iterable.
|
|
374
|
+
|
|
375
|
+
Parameters
|
|
376
|
+
----------
|
|
377
|
+
fillvalue : Any, optional
|
|
378
|
+
A fill value, by default ``None``
|
|
379
|
+
|
|
380
|
+
Returns
|
|
381
|
+
-------
|
|
382
|
+
Self | list[list[T]]
|
|
383
|
+
Transposed list.
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
Example:
|
|
387
|
+
--------
|
|
388
|
+
>>> ListExt([1, 1, 1, 1]).transpose()
|
|
389
|
+
[(1, 1, 1, 1)]
|
|
390
|
+
|
|
391
|
+
>>> ListExt([[1, 1, 1, 1], [1, 1, 1, 1]]).transpose()
|
|
392
|
+
[(1, 1), (1, 1), (1, 1), (1, 1)]
|
|
393
|
+
|
|
394
|
+
>>> ListExt([[1, 1, 1, 1], [1, 1, 1, 1], [1]]).transpose()
|
|
395
|
+
[(1, 1, 1), (1, 1, None), (1, 1, None), (1, 1, None)]
|
|
396
|
+
"""
|
|
397
|
+
try:
|
|
398
|
+
return self.__class__(zip_longest(*self, fillvalue=fillvalue)).apply(list)
|
|
399
|
+
except TypeError: # Dimension of 1
|
|
400
|
+
mod_dat = self.apply(lambda x: [x])
|
|
401
|
+
# return self.__class__(zip_longest(*mod_dat, fillvalue=fillvalue)).apply(list)
|
|
402
|
+
return mod_dat
|
|
403
|
+
|
|
357
404
|
# Random
|
|
358
405
|
def pick_one(self) -> Any:
|
|
359
406
|
"""
|
|
@@ -620,7 +667,7 @@ class ListExt(ShowAllMethodsMixin, list):
|
|
|
620
667
|
return self.__class__(data[i1:i2] for i1, i2 in zip([0] + points[:-1], points))
|
|
621
668
|
|
|
622
669
|
@versionadded("5.1.0")
|
|
623
|
-
def split_chunk(self, chunk_size: int) -> Self:
|
|
670
|
+
def split_chunk(self, chunk_size: int, /) -> Self:
|
|
624
671
|
"""
|
|
625
672
|
Split list into smaller chunks
|
|
626
673
|
|
|
@@ -643,8 +690,75 @@ class ListExt(ShowAllMethodsMixin, list):
|
|
|
643
690
|
slice_points = list(range(0, len(self), max(chunk_size, 1)))[1:]
|
|
644
691
|
return self.slice_points(slice_points)
|
|
645
692
|
|
|
693
|
+
@versionadded("5.3.0") # no test case yet
|
|
694
|
+
def to_column(self, ncols: int, fillvalue: _T | None = None) -> Self:
|
|
695
|
+
"""
|
|
696
|
+
Smart convert 1 dimension list to 2 dimension list,
|
|
697
|
+
in which, number of columns = ``ncols``.
|
|
698
|
+
|
|
699
|
+
Parameters
|
|
700
|
+
----------
|
|
701
|
+
ncols : int
|
|
702
|
+
Number of columns
|
|
703
|
+
|
|
704
|
+
fillvalue : T | None, optional
|
|
705
|
+
Fill value, by default ``None``
|
|
706
|
+
|
|
707
|
+
Returns
|
|
708
|
+
-------
|
|
709
|
+
Self
|
|
710
|
+
Coulumned list.
|
|
711
|
+
|
|
712
|
+
|
|
713
|
+
Example:
|
|
714
|
+
--------
|
|
715
|
+
>>> ins = ListExt(range(1,20))
|
|
716
|
+
|
|
717
|
+
>>> # Normal split chunk
|
|
718
|
+
>>> ins.split_chunk(10)
|
|
719
|
+
[
|
|
720
|
+
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
|
|
721
|
+
[11, 12, 13, 14, 15, 16, 17, 18, 19]
|
|
722
|
+
]
|
|
723
|
+
|
|
724
|
+
>>> # Column split chunk
|
|
725
|
+
>>> ins.to_column(10)
|
|
726
|
+
[
|
|
727
|
+
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19],
|
|
728
|
+
[2, 4, 6, 8, 10, 12, 14, 16, 18, None]
|
|
729
|
+
]
|
|
730
|
+
"""
|
|
731
|
+
num_of_col = max(ncols, 1)
|
|
732
|
+
len_cols = len(self.split_chunk(num_of_col))
|
|
733
|
+
return self.split_chunk(len_cols).transpose(fillvalue)
|
|
734
|
+
|
|
735
|
+
@overload
|
|
736
|
+
def wrap_to_column(self, width: int, /) -> Self: ...
|
|
737
|
+
|
|
738
|
+
@overload
|
|
739
|
+
def wrap_to_column(
|
|
740
|
+
self,
|
|
741
|
+
width: int,
|
|
742
|
+
/,
|
|
743
|
+
*,
|
|
744
|
+
margin: int = 4,
|
|
745
|
+
sep: str = "",
|
|
746
|
+
fill: str = " ",
|
|
747
|
+
transpose: bool = False,
|
|
748
|
+
) -> Self: ...
|
|
749
|
+
|
|
750
|
+
@versionchanged("5.3.0", reason="New `sep`, `fill`, `transpose` parameters")
|
|
646
751
|
@versionadded("5.2.0") # no test case yet
|
|
647
|
-
def wrap_to_column(
|
|
752
|
+
def wrap_to_column(
|
|
753
|
+
self,
|
|
754
|
+
width: int,
|
|
755
|
+
/,
|
|
756
|
+
*,
|
|
757
|
+
margin: int = 4,
|
|
758
|
+
sep: str = "",
|
|
759
|
+
fill: str = " ",
|
|
760
|
+
transpose: bool = False,
|
|
761
|
+
) -> Self:
|
|
648
762
|
"""
|
|
649
763
|
Arrange list[str] items into aligned text columns (for printing)
|
|
650
764
|
with automatic column count calculation.
|
|
@@ -655,7 +769,16 @@ class ListExt(ShowAllMethodsMixin, list):
|
|
|
655
769
|
Total available display width (must be >= ``margin``)
|
|
656
770
|
|
|
657
771
|
margin : int, optional
|
|
658
|
-
Reserved space for borders/padding, by default ``4``
|
|
772
|
+
Reserved space for borders/padding, should be an even number, by default ``4``
|
|
773
|
+
|
|
774
|
+
sep : str, optional
|
|
775
|
+
Separator between each element, by default ``""``
|
|
776
|
+
|
|
777
|
+
fill : str, optional
|
|
778
|
+
Fill character for spacing, must have the length of 1, by default ``" "``
|
|
779
|
+
|
|
780
|
+
transpose : bool, optional
|
|
781
|
+
Smart transpose the columns, by default ``False``
|
|
659
782
|
|
|
660
783
|
Returns
|
|
661
784
|
-------
|
|
@@ -673,8 +796,10 @@ class ListExt(ShowAllMethodsMixin, list):
|
|
|
673
796
|
['apple ', 'banana ', 'cherry ', 'date ']
|
|
674
797
|
"""
|
|
675
798
|
|
|
676
|
-
max_item_length = self.max_item_len() +
|
|
677
|
-
available_width = max(width, 4) - max(margin,
|
|
799
|
+
max_item_length = self.max_item_len() + max(len(sep), 1)
|
|
800
|
+
available_width = max(width, 4) - max(margin, 0) # Set boundary
|
|
801
|
+
if len(fill) != 1:
|
|
802
|
+
fill = " "
|
|
678
803
|
|
|
679
804
|
# Calculate how many columns of text
|
|
680
805
|
column_count = (
|
|
@@ -688,8 +813,11 @@ class ListExt(ShowAllMethodsMixin, list):
|
|
|
688
813
|
|
|
689
814
|
def mod_item(item: list[str]) -> str:
|
|
690
815
|
# Set width for str item and join them together
|
|
691
|
-
return
|
|
816
|
+
return sep.join(x.ljust(max_item_length, fill) for x in item)
|
|
692
817
|
|
|
693
|
-
|
|
818
|
+
if transpose:
|
|
819
|
+
mod_chunk = self.to_column(column_count, fillvalue="").apply(mod_item)
|
|
820
|
+
else:
|
|
821
|
+
mod_chunk = self.split_chunk(column_count).apply(mod_item)
|
|
694
822
|
|
|
695
823
|
return mod_chunk
|
absfuyu/dxt/strext.py
CHANGED
absfuyu/extra/__init__.py
CHANGED
absfuyu/extra/beautiful.py
CHANGED
absfuyu/extra/da/__init__.py
CHANGED
absfuyu/extra/da/dadf.py
CHANGED
|
@@ -3,8 +3,8 @@ Absfuyu: Data Analysis
|
|
|
3
3
|
----------------------
|
|
4
4
|
Data Analyst DataFrame
|
|
5
5
|
|
|
6
|
-
Version: 5.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 5.4.0
|
|
7
|
+
Date updated: 21/03/2025 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
# Module level
|
|
@@ -58,6 +58,7 @@ class DataAnalystDataFrameColumnMethodMixin(DFBase):
|
|
|
58
58
|
- Drop columns
|
|
59
59
|
- Drop rightmost column
|
|
60
60
|
- Add blank column
|
|
61
|
+
- Split str column
|
|
61
62
|
"""
|
|
62
63
|
|
|
63
64
|
def rearrange_rightmost_column(
|
|
@@ -200,6 +201,59 @@ class DataAnalystDataFrameColumnMethodMixin(DFBase):
|
|
|
200
201
|
self[column_name] = [fill] * self.shape[0]
|
|
201
202
|
return self
|
|
202
203
|
|
|
204
|
+
@versionadded("5.2.0") # No test cases
|
|
205
|
+
def split_str_column(
|
|
206
|
+
self,
|
|
207
|
+
col: str,
|
|
208
|
+
pattern: str = " ",
|
|
209
|
+
*,
|
|
210
|
+
n: int | None = None,
|
|
211
|
+
regex: bool = False,
|
|
212
|
+
) -> Self:
|
|
213
|
+
"""
|
|
214
|
+
Split column with dtype[str] into other columns.
|
|
215
|
+
|
|
216
|
+
Parameters
|
|
217
|
+
----------
|
|
218
|
+
col : str
|
|
219
|
+
Column name
|
|
220
|
+
|
|
221
|
+
pattern : str, optional
|
|
222
|
+
Split pattern, by default ``" "``
|
|
223
|
+
|
|
224
|
+
n : int | None, optional
|
|
225
|
+
Split by how many times, by default ``None``
|
|
226
|
+
|
|
227
|
+
regex : bool, optional
|
|
228
|
+
Regex mode, by default ``False``
|
|
229
|
+
|
|
230
|
+
Returns
|
|
231
|
+
-------
|
|
232
|
+
Self
|
|
233
|
+
DataFrame
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
Example:
|
|
237
|
+
--------
|
|
238
|
+
>>> df = DADF(DADF.sample_df(5)[["text"]])
|
|
239
|
+
>>> df.split_str_column("text", "s"))
|
|
240
|
+
text text_0 text_1
|
|
241
|
+
0 uwfzbsgj uwfzb gj
|
|
242
|
+
1 lxlskayx lxl kayx
|
|
243
|
+
2 fzgpzjtp fzgpzjtp None
|
|
244
|
+
3 lxnytktz lxnytktz None
|
|
245
|
+
4 onryaxtt onryaxtt None
|
|
246
|
+
"""
|
|
247
|
+
if n is None:
|
|
248
|
+
pass
|
|
249
|
+
splited_data: pd.DataFrame = self[col].str.split(
|
|
250
|
+
pat=pattern, n=n, expand=True, regex=regex
|
|
251
|
+
)
|
|
252
|
+
num_of_splitted_cols = splited_data.shape[1]
|
|
253
|
+
new_col_names = [f"{col}_{x}" for x in range(num_of_splitted_cols)]
|
|
254
|
+
self[new_col_names] = splited_data
|
|
255
|
+
return self
|
|
256
|
+
|
|
203
257
|
|
|
204
258
|
# Row method
|
|
205
259
|
# ---------------------------------------------------------------------------
|
|
@@ -1136,42 +1190,4 @@ class DADF_WIP(DADF):
|
|
|
1136
1190
|
W.I.P - No test cases written
|
|
1137
1191
|
"""
|
|
1138
1192
|
|
|
1139
|
-
|
|
1140
|
-
self,
|
|
1141
|
-
col: str,
|
|
1142
|
-
pattern: str = " ",
|
|
1143
|
-
*,
|
|
1144
|
-
n: int | None = None,
|
|
1145
|
-
regex: bool = False,
|
|
1146
|
-
) -> Self:
|
|
1147
|
-
"""
|
|
1148
|
-
Split column with dtype[str] into other columns.
|
|
1149
|
-
|
|
1150
|
-
Parameters
|
|
1151
|
-
----------
|
|
1152
|
-
col : str
|
|
1153
|
-
Column name
|
|
1154
|
-
|
|
1155
|
-
pattern : str, optional
|
|
1156
|
-
Split pattern, by default ``" "``
|
|
1157
|
-
|
|
1158
|
-
n : int | None, optional
|
|
1159
|
-
Split by how many times, by default ``None``
|
|
1160
|
-
|
|
1161
|
-
regex : bool, optional
|
|
1162
|
-
Regex mode, by default ``False``
|
|
1163
|
-
|
|
1164
|
-
Returns
|
|
1165
|
-
-------
|
|
1166
|
-
Self
|
|
1167
|
-
DataFrame
|
|
1168
|
-
"""
|
|
1169
|
-
if n is None:
|
|
1170
|
-
pass
|
|
1171
|
-
splited_data: pd.DataFrame = self[col].str.split(
|
|
1172
|
-
pat=pattern, n=n, expand=True, regex=regex
|
|
1173
|
-
)
|
|
1174
|
-
num_of_splitted_cols = splited_data.shape[1]
|
|
1175
|
-
new_col_names = [f"{col}_{x}" for x in range(num_of_splitted_cols)]
|
|
1176
|
-
self[new_col_names] = splited_data
|
|
1177
|
-
return self
|
|
1193
|
+
pass
|
absfuyu/extra/da/dadf_base.py
CHANGED
absfuyu/extra/da/df_func.py
CHANGED
absfuyu/extra/da/mplt.py
CHANGED
absfuyu/extra/data_analysis.py
CHANGED
absfuyu/fun/__init__.py
CHANGED
|
@@ -3,10 +3,15 @@ Absfuyu: Fun
|
|
|
3
3
|
------------
|
|
4
4
|
Some fun or weird stuff
|
|
5
5
|
|
|
6
|
-
Version: 5.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 5.4.0
|
|
7
|
+
Date updated: 21/03/2025 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
|
+
# Module level
|
|
11
|
+
# ---------------------------------------------------------------------------
|
|
12
|
+
__all__ = ["zodiac_sign", "happy_new_year", "human_year_to_dog_year"]
|
|
13
|
+
|
|
14
|
+
|
|
10
15
|
# Library
|
|
11
16
|
# ---------------------------------------------------------------------------
|
|
12
17
|
from datetime import date
|