absfuyu 5.2.0__tar.gz → 5.3.0__tar.gz
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-5.2.0 → absfuyu-5.3.0}/PKG-INFO +1 -1
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/__init__.py +1 -1
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/cli/do_group.py +10 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/core/baseclass.py +30 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/dxt/listext.py +124 -8
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/extra/da/dadf.py +13 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/tools/__init__.py +2 -2
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/tools/inspector.py +17 -3
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/util/path.py +156 -2
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/util/text_table.py +218 -62
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/test_everything.py +22 -9
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/test_listext.py +1 -1
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/test_text_table.py +7 -7
- {absfuyu-5.2.0 → absfuyu-5.3.0}/.gitignore +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/LICENSE +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/README.md +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/dev_requirements.txt +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/docs/Makefile +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/docs/_template/versioning.html +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/docs/conf.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/docs/index.rst +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/docs/info.md +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/docs/make.bat +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/docs/modules.rst +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/images/Logo Full.png +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/images/Logo Square.png +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/images/Logo White.png +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/images/repository-image-crop.png +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/images/repository-image-white.png +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/images/repository-image.png +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/pyproject.toml +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/__main__.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/cli/__init__.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/cli/color.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/cli/config_group.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/cli/game_group.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/cli/tool_group.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/config/__init__.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/config/config.json +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/core/__init__.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/core/baseclass2.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/core/decorator.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/core/docstring.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/core/dummy_cli.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/core/dummy_func.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/dxt/__init__.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/dxt/dictext.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/dxt/dxt_support.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/dxt/intext.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/dxt/strext.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/extra/__init__.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/extra/beautiful.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/extra/da/__init__.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/extra/da/dadf_base.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/extra/da/df_func.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/extra/da/mplt.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/extra/data_analysis.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/fun/__init__.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/fun/tarot.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/game/__init__.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/game/game_stat.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/game/sudoku.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/game/tictactoe.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/game/wordle.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/general/__init__.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/general/content.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/general/human.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/general/shape.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/logger.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/pkg_data/__init__.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/pkg_data/chemistry.pkl +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/pkg_data/deprecated.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/pkg_data/passwordlib_lzma.pkl +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/pkg_data/tarot.pkl +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/py.typed +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/sort.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/tools/checksum.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/tools/converter.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/tools/generator.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/tools/keygen.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/tools/obfuscator.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/tools/passwordlib.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/tools/shutdownizer.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/tools/web.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/typings.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/util/__init__.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/util/api.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/util/json_method.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/util/lunar.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/util/performance.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/util/shorten_number.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/util/zipped.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/src/absfuyu/version.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/__init__.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/conftest.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/test_api.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/test_beautiful.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/test_config.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/test_converter.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/test_core.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/test_data_analysis.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/test_dictext.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/test_extra.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/test_fun.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/test_game.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/test_generator.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/test_inspector.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/test_intext.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/test_logger.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/test_obfuscator.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/test_passwordlib.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/test_performance.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/test_pkg_data.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/test_shape.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/test_shorten_number.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/test_strext.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/test_tools.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/test_util.py +0 -0
- {absfuyu-5.2.0 → absfuyu-5.3.0}/tests/test_version.py +0 -0
|
@@ -83,6 +83,15 @@ def os_shutdown() -> None:
|
|
|
83
83
|
engine.shutdown()
|
|
84
84
|
|
|
85
85
|
|
|
86
|
+
@click.command(name="organize")
|
|
87
|
+
@click.argument("dir", type=str)
|
|
88
|
+
def organize_directory(dir: str) -> None:
|
|
89
|
+
"""Organize a directory"""
|
|
90
|
+
engine = Directory(dir)
|
|
91
|
+
engine.organize()
|
|
92
|
+
click.echo(f"{COLOR['green']}Done!")
|
|
93
|
+
|
|
94
|
+
|
|
86
95
|
@click.group(name="do")
|
|
87
96
|
def do_group() -> None:
|
|
88
97
|
"""Perform functionalities"""
|
|
@@ -93,3 +102,4 @@ do_group.add_command(update)
|
|
|
93
102
|
do_group.add_command(install)
|
|
94
103
|
do_group.add_command(unzip_files_in_dir)
|
|
95
104
|
do_group.add_command(os_shutdown)
|
|
105
|
+
do_group.add_command(organize_directory)
|
|
@@ -162,6 +162,36 @@ class MethodNPropertyList(NamedTuple):
|
|
|
162
162
|
|
|
163
163
|
return self.__class__(new_methods_list, [], [], self.properties)
|
|
164
164
|
|
|
165
|
+
def sort(self, reverse: bool = False) -> Self:
|
|
166
|
+
"""
|
|
167
|
+
Sorts every element in each method list.
|
|
168
|
+
|
|
169
|
+
Parameters
|
|
170
|
+
----------
|
|
171
|
+
reverse : bool, optional
|
|
172
|
+
Descending order, by default ``False``
|
|
173
|
+
|
|
174
|
+
Returns
|
|
175
|
+
-------
|
|
176
|
+
Self
|
|
177
|
+
Sorted.
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
Example:
|
|
181
|
+
--------
|
|
182
|
+
>>> test = MethodNPropertyList(["b", "a"], ["d", "c"], ["f", "e"], ["h", "g"])
|
|
183
|
+
>>> test.sort()
|
|
184
|
+
MethodNPropertyList(methods=['a', 'b'], classmethods=['c', 'd'], staticmethods=['e', 'f'], properties=['g', 'h'])
|
|
185
|
+
|
|
186
|
+
>>> test.pack().sort()
|
|
187
|
+
MethodNPropertyList(methods=['a', 'b', 'c <classmethod>', 'd <classmethod>', 'e <staticmethod>', 'f <staticmethod>'], properties=['g', 'h'])
|
|
188
|
+
"""
|
|
189
|
+
sorted_vals = [
|
|
190
|
+
sorted(getattr(self, field), reverse=reverse) for field in self._fields
|
|
191
|
+
]
|
|
192
|
+
# return self._make(sorted_vals)
|
|
193
|
+
return self.__class__(*sorted_vals)
|
|
194
|
+
|
|
165
195
|
|
|
166
196
|
# @versionadded("5.1.0")
|
|
167
197
|
class MethodNPropertyResult(dict[str, MethodNPropertyList]):
|
|
@@ -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
|
|
|
@@ -354,6 +355,40 @@ class ListExt(ShowAllMethodsMixin, list):
|
|
|
354
355
|
start = max(start, 0)
|
|
355
356
|
return self.__class__(enumerate(self, start=start))
|
|
356
357
|
|
|
358
|
+
@versionadded("5.3.0") # no test case yet
|
|
359
|
+
def transpose(self, fillvalue: _T | None = None, /) -> Self:
|
|
360
|
+
"""
|
|
361
|
+
Transpose a list of iterable.
|
|
362
|
+
|
|
363
|
+
Parameters
|
|
364
|
+
----------
|
|
365
|
+
fillvalue : Any, optional
|
|
366
|
+
A fill value, by default ``None``
|
|
367
|
+
|
|
368
|
+
Returns
|
|
369
|
+
-------
|
|
370
|
+
Self | list[list[T]]
|
|
371
|
+
Transposed list.
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
Example:
|
|
375
|
+
--------
|
|
376
|
+
>>> ListExt([1, 1, 1, 1]).transpose()
|
|
377
|
+
[(1, 1, 1, 1)]
|
|
378
|
+
|
|
379
|
+
>>> ListExt([[1, 1, 1, 1], [1, 1, 1, 1]]).transpose()
|
|
380
|
+
[(1, 1), (1, 1), (1, 1), (1, 1)]
|
|
381
|
+
|
|
382
|
+
>>> ListExt([[1, 1, 1, 1], [1, 1, 1, 1], [1]]).transpose()
|
|
383
|
+
[(1, 1, 1), (1, 1, None), (1, 1, None), (1, 1, None)]
|
|
384
|
+
"""
|
|
385
|
+
try:
|
|
386
|
+
return self.__class__(zip_longest(*self, fillvalue=fillvalue)).apply(list)
|
|
387
|
+
except TypeError: # Dimension of 1
|
|
388
|
+
mod_dat = self.apply(lambda x: [x])
|
|
389
|
+
# return self.__class__(zip_longest(*mod_dat, fillvalue=fillvalue)).apply(list)
|
|
390
|
+
return mod_dat
|
|
391
|
+
|
|
357
392
|
# Random
|
|
358
393
|
def pick_one(self) -> Any:
|
|
359
394
|
"""
|
|
@@ -620,7 +655,7 @@ class ListExt(ShowAllMethodsMixin, list):
|
|
|
620
655
|
return self.__class__(data[i1:i2] for i1, i2 in zip([0] + points[:-1], points))
|
|
621
656
|
|
|
622
657
|
@versionadded("5.1.0")
|
|
623
|
-
def split_chunk(self, chunk_size: int) -> Self:
|
|
658
|
+
def split_chunk(self, chunk_size: int, /) -> Self:
|
|
624
659
|
"""
|
|
625
660
|
Split list into smaller chunks
|
|
626
661
|
|
|
@@ -643,8 +678,75 @@ class ListExt(ShowAllMethodsMixin, list):
|
|
|
643
678
|
slice_points = list(range(0, len(self), max(chunk_size, 1)))[1:]
|
|
644
679
|
return self.slice_points(slice_points)
|
|
645
680
|
|
|
681
|
+
@versionadded("5.3.0") # no test case yet
|
|
682
|
+
def to_column(self, ncols: int, fillvalue: _T | None = None) -> Self:
|
|
683
|
+
"""
|
|
684
|
+
Smart convert 1 dimension list to 2 dimension list,
|
|
685
|
+
in which, number of columns = ``ncols``.
|
|
686
|
+
|
|
687
|
+
Parameters
|
|
688
|
+
----------
|
|
689
|
+
ncols : int
|
|
690
|
+
Number of columns
|
|
691
|
+
|
|
692
|
+
fillvalue : T | None, optional
|
|
693
|
+
Fill value, by default ``None``
|
|
694
|
+
|
|
695
|
+
Returns
|
|
696
|
+
-------
|
|
697
|
+
Self
|
|
698
|
+
Coulumned list.
|
|
699
|
+
|
|
700
|
+
|
|
701
|
+
Example:
|
|
702
|
+
--------
|
|
703
|
+
>>> ins = ListExt(range(1,20))
|
|
704
|
+
|
|
705
|
+
>>> # Normal split chunk
|
|
706
|
+
>>> ins.split_chunk(10)
|
|
707
|
+
[
|
|
708
|
+
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
|
|
709
|
+
[11, 12, 13, 14, 15, 16, 17, 18, 19]
|
|
710
|
+
]
|
|
711
|
+
|
|
712
|
+
>>> # Column split chunk
|
|
713
|
+
>>> ins.to_column(10)
|
|
714
|
+
[
|
|
715
|
+
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19],
|
|
716
|
+
[2, 4, 6, 8, 10, 12, 14, 16, 18, None]
|
|
717
|
+
]
|
|
718
|
+
"""
|
|
719
|
+
num_of_col = max(ncols, 1)
|
|
720
|
+
len_cols = len(self.split_chunk(num_of_col))
|
|
721
|
+
return self.split_chunk(len_cols).transpose(fillvalue)
|
|
722
|
+
|
|
723
|
+
@overload
|
|
724
|
+
def wrap_to_column(self, width: int, /) -> Self: ...
|
|
725
|
+
|
|
726
|
+
@overload
|
|
727
|
+
def wrap_to_column(
|
|
728
|
+
self,
|
|
729
|
+
width: int,
|
|
730
|
+
/,
|
|
731
|
+
*,
|
|
732
|
+
margin: int = 4,
|
|
733
|
+
sep: str = "",
|
|
734
|
+
fill: str = " ",
|
|
735
|
+
transpose: bool = False,
|
|
736
|
+
) -> Self: ...
|
|
737
|
+
|
|
738
|
+
@versionchanged("5.3.0", reason="New `sep`, `fill`, `transpose` parameters")
|
|
646
739
|
@versionadded("5.2.0") # no test case yet
|
|
647
|
-
def wrap_to_column(
|
|
740
|
+
def wrap_to_column(
|
|
741
|
+
self,
|
|
742
|
+
width: int,
|
|
743
|
+
/,
|
|
744
|
+
*,
|
|
745
|
+
margin: int = 4,
|
|
746
|
+
sep: str = "",
|
|
747
|
+
fill: str = " ",
|
|
748
|
+
transpose: bool = False,
|
|
749
|
+
) -> Self:
|
|
648
750
|
"""
|
|
649
751
|
Arrange list[str] items into aligned text columns (for printing)
|
|
650
752
|
with automatic column count calculation.
|
|
@@ -655,7 +757,16 @@ class ListExt(ShowAllMethodsMixin, list):
|
|
|
655
757
|
Total available display width (must be >= ``margin``)
|
|
656
758
|
|
|
657
759
|
margin : int, optional
|
|
658
|
-
Reserved space for borders/padding, by default ``4``
|
|
760
|
+
Reserved space for borders/padding, should be an even number, by default ``4``
|
|
761
|
+
|
|
762
|
+
sep : str, optional
|
|
763
|
+
Separator between each element, by default ``""``
|
|
764
|
+
|
|
765
|
+
fill : str, optional
|
|
766
|
+
Fill character for spacing, must have the length of 1, by default ``" "``
|
|
767
|
+
|
|
768
|
+
transpose : bool, optional
|
|
769
|
+
Smart transpose the columns, by default ``False``
|
|
659
770
|
|
|
660
771
|
Returns
|
|
661
772
|
-------
|
|
@@ -673,8 +784,10 @@ class ListExt(ShowAllMethodsMixin, list):
|
|
|
673
784
|
['apple ', 'banana ', 'cherry ', 'date ']
|
|
674
785
|
"""
|
|
675
786
|
|
|
676
|
-
max_item_length = self.max_item_len() +
|
|
677
|
-
available_width = max(width, 4) - max(margin,
|
|
787
|
+
max_item_length = self.max_item_len() + max(len(sep), 1)
|
|
788
|
+
available_width = max(width, 4) - max(margin, 0) # Set boundary
|
|
789
|
+
if len(fill) != 1:
|
|
790
|
+
fill = " "
|
|
678
791
|
|
|
679
792
|
# Calculate how many columns of text
|
|
680
793
|
column_count = (
|
|
@@ -688,8 +801,11 @@ class ListExt(ShowAllMethodsMixin, list):
|
|
|
688
801
|
|
|
689
802
|
def mod_item(item: list[str]) -> str:
|
|
690
803
|
# Set width for str item and join them together
|
|
691
|
-
return
|
|
804
|
+
return sep.join(x.ljust(max_item_length, fill) for x in item)
|
|
692
805
|
|
|
693
|
-
|
|
806
|
+
if transpose:
|
|
807
|
+
mod_chunk = self.to_column(column_count, fillvalue="").apply(mod_item)
|
|
808
|
+
else:
|
|
809
|
+
mod_chunk = self.split_chunk(column_count).apply(mod_item)
|
|
694
810
|
|
|
695
811
|
return mod_chunk
|
|
@@ -1136,6 +1136,7 @@ class DADF_WIP(DADF):
|
|
|
1136
1136
|
W.I.P - No test cases written
|
|
1137
1137
|
"""
|
|
1138
1138
|
|
|
1139
|
+
@versionadded("5.2.0")
|
|
1139
1140
|
def split_str_column(
|
|
1140
1141
|
self,
|
|
1141
1142
|
col: str,
|
|
@@ -1165,6 +1166,18 @@ class DADF_WIP(DADF):
|
|
|
1165
1166
|
-------
|
|
1166
1167
|
Self
|
|
1167
1168
|
DataFrame
|
|
1169
|
+
|
|
1170
|
+
|
|
1171
|
+
Example:
|
|
1172
|
+
--------
|
|
1173
|
+
>>> df = DADF(DADF.sample_df(5)[["text"]])
|
|
1174
|
+
>>> df.split_str_column("text", "s"))
|
|
1175
|
+
text text_0 text_1
|
|
1176
|
+
0 uwfzbsgj uwfzb gj
|
|
1177
|
+
1 lxlskayx lxl kayx
|
|
1178
|
+
2 fzgpzjtp fzgpzjtp None
|
|
1179
|
+
3 lxnytktz lxnytktz None
|
|
1180
|
+
4 onryaxtt onryaxtt None
|
|
1168
1181
|
"""
|
|
1169
1182
|
if n is None:
|
|
1170
1183
|
pass
|
|
@@ -12,7 +12,7 @@ Date updated: 16/03/2025 (dd/mm/yyyy)
|
|
|
12
12
|
__all__ = [
|
|
13
13
|
# # Main
|
|
14
14
|
"Checksum",
|
|
15
|
-
"
|
|
15
|
+
"B64",
|
|
16
16
|
"T2C",
|
|
17
17
|
# "Charset",
|
|
18
18
|
# "Generator",
|
|
@@ -26,7 +26,7 @@ __all__ = [
|
|
|
26
26
|
# Library
|
|
27
27
|
# ---------------------------------------------------------------------------
|
|
28
28
|
from absfuyu.tools.checksum import Checksum
|
|
29
|
-
from absfuyu.tools.converter import Base64EncodeDecode as
|
|
29
|
+
from absfuyu.tools.converter import Base64EncodeDecode as B64
|
|
30
30
|
from absfuyu.tools.converter import Text2Chemistry as T2C
|
|
31
31
|
from absfuyu.tools.inspector import Inspector, inspect_all
|
|
32
32
|
|
|
@@ -71,6 +71,9 @@ class Inspector(AutoREPRMixin):
|
|
|
71
71
|
Maximum lines for the output's header (class, signature, repr).
|
|
72
72
|
Must be >= 1, by default ``8``
|
|
73
73
|
|
|
74
|
+
style : Literal["normal", "bold", "dashed", "double", "rounded"], optional
|
|
75
|
+
Style for the table, by default ``"normal"``
|
|
76
|
+
|
|
74
77
|
|
|
75
78
|
Example:
|
|
76
79
|
--------
|
|
@@ -96,6 +99,7 @@ class Inspector(AutoREPRMixin):
|
|
|
96
99
|
include_attribute: bool = True,
|
|
97
100
|
include_private: bool = False,
|
|
98
101
|
max_textwrap_lines: int = 8,
|
|
102
|
+
style: Literal["normal", "bold", "dashed", "double", "rounded"] = "normal",
|
|
99
103
|
) -> None: ...
|
|
100
104
|
|
|
101
105
|
def __init__(
|
|
@@ -114,6 +118,8 @@ class Inspector(AutoREPRMixin):
|
|
|
114
118
|
include_attribute: bool = True,
|
|
115
119
|
include_private: bool = False,
|
|
116
120
|
include_all: bool = False,
|
|
121
|
+
# Style
|
|
122
|
+
style: Literal["normal", "bold", "dashed", "double", "rounded"] = "normal",
|
|
117
123
|
) -> None:
|
|
118
124
|
"""
|
|
119
125
|
Inspect an object.
|
|
@@ -153,6 +159,9 @@ class Inspector(AutoREPRMixin):
|
|
|
153
159
|
Maximum lines for the output's header (class, signature, repr).
|
|
154
160
|
Must be >= 1, by default ``8``
|
|
155
161
|
|
|
162
|
+
style : Literal["normal", "bold", "dashed", "double", "rounded"], optional
|
|
163
|
+
Style for the table, by default ``"normal"``
|
|
164
|
+
|
|
156
165
|
|
|
157
166
|
Example:
|
|
158
167
|
--------
|
|
@@ -165,6 +174,7 @@ class Inspector(AutoREPRMixin):
|
|
|
165
174
|
self.include_property = include_property
|
|
166
175
|
self.include_attribute = include_attribute
|
|
167
176
|
self.include_private = include_private
|
|
177
|
+
self._style = style
|
|
168
178
|
|
|
169
179
|
if include_all:
|
|
170
180
|
self.include_docs = True
|
|
@@ -203,7 +213,9 @@ class Inspector(AutoREPRMixin):
|
|
|
203
213
|
|
|
204
214
|
# Support
|
|
205
215
|
def _long_list_terminal_size(self, long_list: list) -> list:
|
|
206
|
-
ll = ListExt(long_list).wrap_to_column(
|
|
216
|
+
ll = ListExt(long_list).wrap_to_column(
|
|
217
|
+
self._linelength, margin=4, transpose=True
|
|
218
|
+
)
|
|
207
219
|
return list(ll)
|
|
208
220
|
|
|
209
221
|
# Signature
|
|
@@ -392,7 +404,7 @@ class Inspector(AutoREPRMixin):
|
|
|
392
404
|
|
|
393
405
|
# Output
|
|
394
406
|
def _make_output(self) -> OneColumnTableMaker:
|
|
395
|
-
table = OneColumnTableMaker(self._linelength)
|
|
407
|
+
table = OneColumnTableMaker(self._linelength, style=self._style)
|
|
396
408
|
body: list[str] = []
|
|
397
409
|
|
|
398
410
|
# Signature
|
|
@@ -419,7 +431,9 @@ class Inspector(AutoREPRMixin):
|
|
|
419
431
|
|
|
420
432
|
# Method & Property
|
|
421
433
|
try:
|
|
422
|
-
method_n_properties =
|
|
434
|
+
method_n_properties = (
|
|
435
|
+
self._get_method_property().flatten_value().pack().sort()
|
|
436
|
+
)
|
|
423
437
|
if self.include_method:
|
|
424
438
|
ml = [
|
|
425
439
|
text_shorten(f"- {x}", self._linelength - 4)
|
|
@@ -46,6 +46,128 @@ from absfuyu.core.decorator import add_subclass_methods_decorator
|
|
|
46
46
|
from absfuyu.core.docstring import deprecated, versionadded, versionchanged
|
|
47
47
|
from absfuyu.logger import logger
|
|
48
48
|
|
|
49
|
+
# Template
|
|
50
|
+
# ---------------------------------------------------------------------------
|
|
51
|
+
ORGANIZE_TEMPLATE: dict[str, list[str]] = {
|
|
52
|
+
"Code": [".ps1", ".py", ".rs", ".js", ".c", ".h", ".cpp", ".r", ".cmd", ".bat"],
|
|
53
|
+
"Comic": [".cbz", ".cbr", ".cb7", ".cbt", ".cba"],
|
|
54
|
+
"Compressed": [
|
|
55
|
+
".7z",
|
|
56
|
+
".zip",
|
|
57
|
+
".rar",
|
|
58
|
+
".apk",
|
|
59
|
+
".cab",
|
|
60
|
+
".tar",
|
|
61
|
+
".tgz",
|
|
62
|
+
".txz",
|
|
63
|
+
".bz2",
|
|
64
|
+
".gz",
|
|
65
|
+
".lz",
|
|
66
|
+
".lz4",
|
|
67
|
+
".lzma",
|
|
68
|
+
".xz",
|
|
69
|
+
".zipx",
|
|
70
|
+
".zst",
|
|
71
|
+
],
|
|
72
|
+
"Documents": [".docx", ".doc", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt"],
|
|
73
|
+
"Ebook": [
|
|
74
|
+
".epub",
|
|
75
|
+
".mobi",
|
|
76
|
+
".prc",
|
|
77
|
+
".lrf",
|
|
78
|
+
".lrx",
|
|
79
|
+
".pdb",
|
|
80
|
+
".azw",
|
|
81
|
+
".azw3",
|
|
82
|
+
".kf8",
|
|
83
|
+
".kfx",
|
|
84
|
+
".opf",
|
|
85
|
+
],
|
|
86
|
+
"Music": [".mp3", ".flac", ".wav", ".m4a", ".wma", ".aac", ".alac", ".aiff"],
|
|
87
|
+
"OS": [".iso", ".dmg", ".wim"],
|
|
88
|
+
"Pictures": [
|
|
89
|
+
".jpg",
|
|
90
|
+
".jpeg",
|
|
91
|
+
".png",
|
|
92
|
+
".apng",
|
|
93
|
+
".avif",
|
|
94
|
+
".bmp",
|
|
95
|
+
".gif",
|
|
96
|
+
".jfif",
|
|
97
|
+
".pjpeg",
|
|
98
|
+
".pjp",
|
|
99
|
+
".svg",
|
|
100
|
+
".ico",
|
|
101
|
+
".cur",
|
|
102
|
+
".tif",
|
|
103
|
+
".tiff",
|
|
104
|
+
".webp",
|
|
105
|
+
],
|
|
106
|
+
"Programs": [".exe", ".msi"],
|
|
107
|
+
"Video": [
|
|
108
|
+
".3g2",
|
|
109
|
+
".3gp",
|
|
110
|
+
".avi",
|
|
111
|
+
".flv",
|
|
112
|
+
".m2ts",
|
|
113
|
+
".m4v",
|
|
114
|
+
".mkv",
|
|
115
|
+
".mov",
|
|
116
|
+
".mp4",
|
|
117
|
+
".mpeg",
|
|
118
|
+
".mpv",
|
|
119
|
+
".mts",
|
|
120
|
+
".ts",
|
|
121
|
+
".vob",
|
|
122
|
+
".webm",
|
|
123
|
+
],
|
|
124
|
+
"Raw pictures": [
|
|
125
|
+
".3fr",
|
|
126
|
+
".ari",
|
|
127
|
+
".arw",
|
|
128
|
+
".bay",
|
|
129
|
+
".braw",
|
|
130
|
+
".crw",
|
|
131
|
+
".cr2",
|
|
132
|
+
".cr3",
|
|
133
|
+
".cap",
|
|
134
|
+
".data",
|
|
135
|
+
".dcs",
|
|
136
|
+
".dcr",
|
|
137
|
+
".dng",
|
|
138
|
+
".drf",
|
|
139
|
+
".eip",
|
|
140
|
+
".erf",
|
|
141
|
+
".fff",
|
|
142
|
+
".gpr",
|
|
143
|
+
".iiq",
|
|
144
|
+
".k25",
|
|
145
|
+
".kdc",
|
|
146
|
+
".mdc",
|
|
147
|
+
".mef",
|
|
148
|
+
".mos",
|
|
149
|
+
".mrw",
|
|
150
|
+
".nef",
|
|
151
|
+
".nrw",
|
|
152
|
+
".obm",
|
|
153
|
+
".orf",
|
|
154
|
+
".pef",
|
|
155
|
+
".ptx",
|
|
156
|
+
".pxn",
|
|
157
|
+
".r3d",
|
|
158
|
+
".raf",
|
|
159
|
+
".raw",
|
|
160
|
+
".rwl",
|
|
161
|
+
".rw2",
|
|
162
|
+
".rwz",
|
|
163
|
+
".sr2",
|
|
164
|
+
".srf",
|
|
165
|
+
".srw",
|
|
166
|
+
".tif",
|
|
167
|
+
".x3f",
|
|
168
|
+
],
|
|
169
|
+
}
|
|
170
|
+
|
|
49
171
|
|
|
50
172
|
# Support Class
|
|
51
173
|
# ---------------------------------------------------------------------------
|
|
@@ -444,10 +566,42 @@ class DirectoryArchiverMixin(DirectoryBase):
|
|
|
444
566
|
|
|
445
567
|
class DirectoryOrganizerMixin(DirectoryBase):
|
|
446
568
|
"""
|
|
447
|
-
Directory - File organizer
|
|
569
|
+
Directory - File organizer
|
|
570
|
+
|
|
571
|
+
- Organize
|
|
448
572
|
"""
|
|
449
573
|
|
|
450
|
-
|
|
574
|
+
@versionadded("5.3.0")
|
|
575
|
+
def organize(self, dirtemplate: dict[str, list[str]] | None = None) -> None:
|
|
576
|
+
"""
|
|
577
|
+
Organize a directory.
|
|
578
|
+
|
|
579
|
+
Parameters
|
|
580
|
+
----------
|
|
581
|
+
dirtemplate : dict[str, Collection[str]] | None, optional
|
|
582
|
+
| Template to move file to, by default ``None``.
|
|
583
|
+
| Example: {"Documents": [".txt", ".pdf", ...]}
|
|
584
|
+
"""
|
|
585
|
+
if dirtemplate is None:
|
|
586
|
+
template = ORGANIZE_TEMPLATE
|
|
587
|
+
else:
|
|
588
|
+
template = dirtemplate
|
|
589
|
+
|
|
590
|
+
other_dir = self.source_path.joinpath("Others")
|
|
591
|
+
other_dir.mkdir(parents=True, exist_ok=True)
|
|
592
|
+
|
|
593
|
+
for path in self.source_path.iterdir():
|
|
594
|
+
if path.is_dir():
|
|
595
|
+
continue
|
|
596
|
+
|
|
597
|
+
for dir_name, suffixes in template.items():
|
|
598
|
+
if path.suffix.lower() in suffixes:
|
|
599
|
+
move_path = self.source_path.joinpath(dir_name)
|
|
600
|
+
move_path.mkdir(parents=True, exist_ok=True)
|
|
601
|
+
path.rename(move_path.joinpath(path.name))
|
|
602
|
+
break
|
|
603
|
+
else:
|
|
604
|
+
path.rename(other_dir.joinpath(path.name))
|
|
451
605
|
|
|
452
606
|
|
|
453
607
|
class DirectoryTreeMixin(DirectoryBase):
|