absfuyu 5.7.0__tar.gz → 5.9.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.7.0 → absfuyu-5.9.0}/PKG-INFO +13 -1
- {absfuyu-5.7.0 → absfuyu-5.9.0}/pyproject.toml +16 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/__init__.py +1 -1
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/__main__.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/cli/__init__.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/cli/color.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/cli/config_group.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/cli/do_group.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/cli/game_group.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/cli/tool_group.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/config/__init__.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/core/__init__.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/core/baseclass.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/core/baseclass2.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/core/decorator.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/core/docstring.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/core/dummy_cli.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/core/dummy_func.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/dxt/__init__.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/dxt/dictext.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/dxt/dxt_support.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/dxt/intext.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/dxt/listext.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/dxt/strext.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/extra/__init__.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/extra/beautiful.py +2 -2
- absfuyu-5.9.0/src/absfuyu/extra/da/__init__.py +72 -0
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/extra/da/dadf.py +58 -21
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/extra/da/dadf_base.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/extra/da/df_func.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/extra/da/mplt.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/extra/data_analysis.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/extra/pdf.py +2 -2
- absfuyu-5.9.0/src/absfuyu/extra/rclone.py +253 -0
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/extra/xml.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/fun/__init__.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/fun/rubik.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/fun/tarot.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/game/__init__.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/game/game_stat.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/game/sudoku.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/game/tictactoe.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/game/wordle.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/general/__init__.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/general/content.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/general/human.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/general/shape.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/logger.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/pkg_data/__init__.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/pkg_data/deprecated.py +2 -2
- absfuyu-5.9.0/src/absfuyu/pkg_data/logo.py +1462 -0
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/sort.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/tools/__init__.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/tools/checksum.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/tools/converter.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/tools/generator.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/tools/inspector.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/tools/keygen.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/tools/obfuscator.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/tools/passwordlib.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/tools/shutdownizer.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/tools/sw.py +76 -5
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/tools/web.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/typings.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/util/__init__.py +31 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/util/api.py +2 -2
- absfuyu-5.9.0/src/absfuyu/util/gui.py +32 -0
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/util/json_method.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/util/lunar.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/util/path.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/util/performance.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/util/shorten_number.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/util/text_table.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/util/zipped.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/version.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/conftest.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/test_api.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/test_beautiful.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/test_config.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/test_converter.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/test_core.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/test_data_analysis.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/test_dictext.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/test_everything.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/test_extra.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/test_fun.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/test_game.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/test_generator.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/test_inspector.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/test_intext.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/test_listext.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/test_logger.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/test_obfuscator.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/test_passwordlib.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/test_performance.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/test_pkg_data.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/test_shape.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/test_shorten_number.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/test_strext.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/test_text_table.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/test_tools.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/test_util.py +2 -2
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/test_version.py +2 -2
- absfuyu-5.7.0/src/absfuyu/extra/da/__init__.py +0 -38
- {absfuyu-5.7.0 → absfuyu-5.9.0}/.gitignore +0 -0
- {absfuyu-5.7.0 → absfuyu-5.9.0}/LICENSE +0 -0
- {absfuyu-5.7.0 → absfuyu-5.9.0}/README.md +0 -0
- {absfuyu-5.7.0 → absfuyu-5.9.0}/dev_requirements.txt +0 -0
- {absfuyu-5.7.0 → absfuyu-5.9.0}/docs/Makefile +0 -0
- {absfuyu-5.7.0 → absfuyu-5.9.0}/docs/_template/versioning.html +0 -0
- {absfuyu-5.7.0 → absfuyu-5.9.0}/docs/conf.py +0 -0
- {absfuyu-5.7.0 → absfuyu-5.9.0}/docs/index.rst +0 -0
- {absfuyu-5.7.0 → absfuyu-5.9.0}/docs/info.md +0 -0
- {absfuyu-5.7.0 → absfuyu-5.9.0}/docs/make.bat +0 -0
- {absfuyu-5.7.0 → absfuyu-5.9.0}/docs/modules.rst +0 -0
- {absfuyu-5.7.0 → absfuyu-5.9.0}/images/Logo Full.png +0 -0
- {absfuyu-5.7.0 → absfuyu-5.9.0}/images/Logo Square.png +0 -0
- {absfuyu-5.7.0 → absfuyu-5.9.0}/images/Logo White.png +0 -0
- {absfuyu-5.7.0 → absfuyu-5.9.0}/images/repository-image-crop.png +0 -0
- {absfuyu-5.7.0 → absfuyu-5.9.0}/images/repository-image-white.png +0 -0
- {absfuyu-5.7.0 → absfuyu-5.9.0}/images/repository-image.png +0 -0
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/config/config.json +0 -0
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/pkg_data/chemistry.pkl +0 -0
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/pkg_data/passwordlib_lzma.pkl +0 -0
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/pkg_data/tarot.pkl +0 -0
- {absfuyu-5.7.0 → absfuyu-5.9.0}/src/absfuyu/py.typed +0 -0
- {absfuyu-5.7.0 → absfuyu-5.9.0}/tests/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: absfuyu
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.9.0
|
|
4
4
|
Summary: A small collection of code
|
|
5
5
|
Project-URL: Homepage, https://github.com/AbsoluteWinter/absfuyu-public
|
|
6
6
|
Project-URL: Documentation, https://absolutewinter.github.io/absfuyu-docs/
|
|
@@ -31,6 +31,11 @@ Requires-Dist: colorama
|
|
|
31
31
|
Requires-Dist: requests
|
|
32
32
|
Provides-Extra: beautiful
|
|
33
33
|
Requires-Dist: rich; extra == 'beautiful'
|
|
34
|
+
Provides-Extra: dadf
|
|
35
|
+
Requires-Dist: numpy; extra == 'dadf'
|
|
36
|
+
Requires-Dist: openpyxl; extra == 'dadf'
|
|
37
|
+
Requires-Dist: pandas; extra == 'dadf'
|
|
38
|
+
Requires-Dist: xlsxwriter; extra == 'dadf'
|
|
34
39
|
Provides-Extra: docs
|
|
35
40
|
Requires-Dist: numpy; extra == 'docs'
|
|
36
41
|
Requires-Dist: pandas; extra == 'docs'
|
|
@@ -47,12 +52,19 @@ Provides-Extra: full
|
|
|
47
52
|
Requires-Dist: numpy; extra == 'full'
|
|
48
53
|
Requires-Dist: openpyxl; extra == 'full'
|
|
49
54
|
Requires-Dist: pandas; extra == 'full'
|
|
55
|
+
Requires-Dist: rclone-crypt; extra == 'full'
|
|
50
56
|
Requires-Dist: rich; extra == 'full'
|
|
51
57
|
Requires-Dist: spire-pdf; extra == 'full'
|
|
52
58
|
Requires-Dist: tqdm; extra == 'full'
|
|
53
59
|
Requires-Dist: unidecode; extra == 'full'
|
|
54
60
|
Requires-Dist: xlsxwriter; extra == 'full'
|
|
55
61
|
Requires-Dist: xmltodict; extra == 'full'
|
|
62
|
+
Provides-Extra: pdf
|
|
63
|
+
Requires-Dist: spire-pdf; extra == 'pdf'
|
|
64
|
+
Provides-Extra: rclone
|
|
65
|
+
Requires-Dist: rclone-crypt; extra == 'rclone'
|
|
66
|
+
Provides-Extra: xml
|
|
67
|
+
Requires-Dist: xmltodict; extra == 'xml'
|
|
56
68
|
Description-Content-Type: text/markdown
|
|
57
69
|
|
|
58
70
|
<div align="center">
|
|
@@ -67,11 +67,16 @@ full = [
|
|
|
67
67
|
"xlsxwriter",
|
|
68
68
|
"spire-pdf",
|
|
69
69
|
"xmltodict",
|
|
70
|
+
"rclone-crypt",
|
|
70
71
|
# "jinja2"
|
|
71
72
|
]
|
|
72
73
|
docs = ["numpy", "pandas", "rich", "spire-pdf"]
|
|
73
74
|
beautiful = ["rich"]
|
|
74
75
|
extra = ["numpy", "pandas", "openpyxl", "xlsxwriter", "spire-pdf", "xmltodict"]
|
|
76
|
+
pdf = ["spire-pdf"]
|
|
77
|
+
dadf = ["numpy", "pandas", "openpyxl", "xlsxwriter"]
|
|
78
|
+
xml = ["xmltodict"]
|
|
79
|
+
rclone = ["rclone-crypt"]
|
|
75
80
|
|
|
76
81
|
|
|
77
82
|
[project.scripts]
|
|
@@ -231,7 +236,7 @@ test = [
|
|
|
231
236
|
"qa",
|
|
232
237
|
"hatch run all:test", # Test
|
|
233
238
|
]
|
|
234
|
-
|
|
239
|
+
build_no_docs = [
|
|
235
240
|
# Update license year - Convert to hex due to unable to run multiple lines
|
|
236
241
|
# Source code:
|
|
237
242
|
# import re;from datetime import datetime;from pathlib import Path
|
|
@@ -260,6 +265,9 @@ build = [
|
|
|
260
265
|
""",
|
|
261
266
|
"hatch clean", # Clean dist/ folder
|
|
262
267
|
"hatch -v build", # Build package
|
|
268
|
+
]
|
|
269
|
+
build = [
|
|
270
|
+
"build_no_docs",
|
|
263
271
|
"hatch run docs:build", # Build docs
|
|
264
272
|
]
|
|
265
273
|
patch = [
|
|
@@ -373,7 +381,13 @@ line-length = 120
|
|
|
373
381
|
[tool.uv]
|
|
374
382
|
required-version = ">=0.5.0"
|
|
375
383
|
cache-dir = "./.uv_cache"
|
|
376
|
-
dev-dependencies = [
|
|
384
|
+
dev-dependencies = [
|
|
385
|
+
"ruff",
|
|
386
|
+
"mypy>=1.18.0",
|
|
387
|
+
"pytest>=8.4.0",
|
|
388
|
+
"hatch>=1.14.1",
|
|
389
|
+
"python-dotenv",
|
|
390
|
+
]
|
|
377
391
|
|
|
378
392
|
[tool.uv.build-backend]
|
|
379
393
|
source-include = ["tests/**"]
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Absfuyu: Data Analysis
|
|
3
|
+
----------------------
|
|
4
|
+
Data Analyst
|
|
5
|
+
|
|
6
|
+
Version: 5.9.0
|
|
7
|
+
Date updated: 23/09/2025 (dd/mm/yyyy)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
# Module level
|
|
11
|
+
# ---------------------------------------------------------------------------
|
|
12
|
+
__all__ = [
|
|
13
|
+
"MatplotlibFormatString",
|
|
14
|
+
"DADF",
|
|
15
|
+
# Function
|
|
16
|
+
"custom_pandas_settings",
|
|
17
|
+
"reset_custom_pandas_settings",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# Library
|
|
22
|
+
# ---------------------------------------------------------------------------
|
|
23
|
+
DA_MODE = False
|
|
24
|
+
|
|
25
|
+
try:
|
|
26
|
+
import numpy as np
|
|
27
|
+
import openpyxl
|
|
28
|
+
import pandas as pd
|
|
29
|
+
import xlsxwriter
|
|
30
|
+
except ImportError:
|
|
31
|
+
from subprocess import run
|
|
32
|
+
|
|
33
|
+
from absfuyu.config import ABSFUYU_CONFIG
|
|
34
|
+
|
|
35
|
+
if ABSFUYU_CONFIG._get_setting("auto-install-extra").value: # type: ignore
|
|
36
|
+
cmd = "python -m pip install -U absfuyu[full]".split()
|
|
37
|
+
run(cmd)
|
|
38
|
+
else:
|
|
39
|
+
raise SystemExit("This feature is in absfuyu[full] package") # noqa: B904
|
|
40
|
+
else:
|
|
41
|
+
DA_MODE = True
|
|
42
|
+
|
|
43
|
+
from absfuyu.extra.da.dadf import DADF
|
|
44
|
+
from absfuyu.extra.da.mplt import MatplotlibFormatString
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
# Function
|
|
48
|
+
# ---------------------------------------------------------------------------
|
|
49
|
+
def custom_pandas_settings(*, show_all_rows: bool = False) -> None:
|
|
50
|
+
"""
|
|
51
|
+
Custom pandas settings. Currently only show all cols/rows
|
|
52
|
+
|
|
53
|
+
Parameters
|
|
54
|
+
----------
|
|
55
|
+
show_all_rows : bool, optional
|
|
56
|
+
Show all rows, by default False
|
|
57
|
+
"""
|
|
58
|
+
# Shows all columns
|
|
59
|
+
pd.set_option("display.max_columns", None) # type: ignore
|
|
60
|
+
|
|
61
|
+
if show_all_rows:
|
|
62
|
+
# (optional) also show all rows if needed
|
|
63
|
+
pd.set_option("display.max_rows", None) # type: ignore
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def reset_custom_pandas_settings() -> None:
|
|
67
|
+
"""
|
|
68
|
+
Reset custom pandas settings
|
|
69
|
+
"""
|
|
70
|
+
settings = ["display.max_columns", "display.max_rows"]
|
|
71
|
+
for x in settings:
|
|
72
|
+
pd.reset_option(x) # type: ignore
|
|
@@ -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.9.0
|
|
7
|
+
Date updated: 23/09/2025 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
# Module level
|
|
@@ -41,7 +41,7 @@ except ImportError:
|
|
|
41
41
|
from absfuyu.core.decorator import dummy_decorator as override
|
|
42
42
|
|
|
43
43
|
from absfuyu.core.baseclass import GetClassMembersMixin
|
|
44
|
-
from absfuyu.core.docstring import deprecated, versionadded
|
|
44
|
+
from absfuyu.core.docstring import deprecated, versionadded, versionchanged
|
|
45
45
|
from absfuyu.extra.da.dadf_base import CityData
|
|
46
46
|
from absfuyu.extra.da.dadf_base import DataAnalystDataFrameBase as DFBase
|
|
47
47
|
from absfuyu.extra.da.dadf_base import SplittedDF
|
|
@@ -366,7 +366,7 @@ class DataAnalystDataFrameInfoMixin(DFBase):
|
|
|
366
366
|
return info
|
|
367
367
|
|
|
368
368
|
@override
|
|
369
|
-
def describe(self, percentiles=None, include=None, exclude=None) -> Self:
|
|
369
|
+
def describe(self, percentiles=None, include=None, exclude=None) -> Self: # type: ignore
|
|
370
370
|
"""pd.DataFrame.describe() override"""
|
|
371
371
|
return self.__class__(super().describe(percentiles, include, exclude)) # type: ignore [no-any-return]
|
|
372
372
|
|
|
@@ -1051,7 +1051,17 @@ class DataAnalystDataFrameExportMixin(DFBase):
|
|
|
1051
1051
|
- da_export
|
|
1052
1052
|
"""
|
|
1053
1053
|
|
|
1054
|
-
|
|
1054
|
+
@versionchanged("5.8.0", "New parameter")
|
|
1055
|
+
def da_export(
|
|
1056
|
+
self,
|
|
1057
|
+
path: str,
|
|
1058
|
+
sheet_name: str = "Sheet1",
|
|
1059
|
+
*,
|
|
1060
|
+
auto_width: bool = True,
|
|
1061
|
+
cols_contain_centered_text: list[str] | None = None,
|
|
1062
|
+
cols_contain_number: list[str] | None = None,
|
|
1063
|
+
cols_contain_percentage: list[str] | None = None,
|
|
1064
|
+
) -> None:
|
|
1055
1065
|
"""
|
|
1056
1066
|
Export DataFrame with `xlsxwriter` engine
|
|
1057
1067
|
|
|
@@ -1060,12 +1070,22 @@ class DataAnalystDataFrameExportMixin(DFBase):
|
|
|
1060
1070
|
path : Path | str
|
|
1061
1071
|
Path to export
|
|
1062
1072
|
|
|
1063
|
-
sheet_name : str
|
|
1064
|
-
Sheet name
|
|
1073
|
+
sheet_name : str, optional
|
|
1074
|
+
Sheet name, by default "Sheet1"
|
|
1075
|
+
|
|
1076
|
+
auto_width : bool, optional
|
|
1077
|
+
Auto resize column width, by default ``True``
|
|
1078
|
+
|
|
1079
|
+
cols_contain_centered_text : list[str] | None, optional
|
|
1080
|
+
Columns that contain centered text (Align center), by default None
|
|
1065
1081
|
|
|
1066
|
-
cols_contain_number : list[str]
|
|
1067
|
-
Columns that contain number value (to format as number)
|
|
1082
|
+
cols_contain_number : list[str] | None, optional
|
|
1083
|
+
Columns that contain number value (to format as number - int), by default None
|
|
1084
|
+
|
|
1085
|
+
cols_contain_percentage : list[str] | None, optional
|
|
1086
|
+
Columns that contain percentage value (to format as percentage), by default None
|
|
1068
1087
|
"""
|
|
1088
|
+
|
|
1069
1089
|
# Using xlsxwriter engine
|
|
1070
1090
|
with pd.ExcelWriter(path, engine="xlsxwriter") as writer:
|
|
1071
1091
|
self.to_excel(writer, sheet_name=sheet_name, index=False, float_format="%.2f", na_rep="")
|
|
@@ -1083,12 +1103,9 @@ class DataAnalystDataFrameExportMixin(DFBase):
|
|
|
1083
1103
|
}
|
|
1084
1104
|
)
|
|
1085
1105
|
number_fmt = workbook.add_format(
|
|
1086
|
-
{
|
|
1087
|
-
"num_format": "#,##0",
|
|
1088
|
-
"align": "center",
|
|
1089
|
-
"valign": "vcenter",
|
|
1090
|
-
}
|
|
1106
|
+
{"num_format": "#,##0", "align": "center", "valign": "vcenter"}
|
|
1091
1107
|
) # 1,000,000
|
|
1108
|
+
percent_fmt = workbook.add_format({"num_format": "0.00%", "align": "center", "valign": "vcenter"}) # 1.00%
|
|
1092
1109
|
text_fmt = workbook.add_format({"valign": "vcenter"})
|
|
1093
1110
|
text_center_fmt = workbook.add_format({"align": "center", "valign": "vcenter"})
|
|
1094
1111
|
|
|
@@ -1099,20 +1116,29 @@ class DataAnalystDataFrameExportMixin(DFBase):
|
|
|
1099
1116
|
for col_num, value in enumerate(self.columns.values):
|
|
1100
1117
|
worksheet.write(0, col_num, value, header_fmt)
|
|
1101
1118
|
|
|
1119
|
+
rules = [
|
|
1120
|
+
(cols_contain_number, number_fmt),
|
|
1121
|
+
(cols_contain_percentage, percent_fmt),
|
|
1122
|
+
(cols_contain_centered_text, text_center_fmt),
|
|
1123
|
+
]
|
|
1124
|
+
|
|
1102
1125
|
# Auto width + col format
|
|
1103
1126
|
for i, col in enumerate(self.columns):
|
|
1104
1127
|
# Max str len of each column
|
|
1105
|
-
max_len = max(self[col].astype(str).map(len).max(), len(col)) + 2
|
|
1128
|
+
max_len = None if auto_width is None else max(self[col].astype(str).map(len).max(), len(col)) + 2
|
|
1106
1129
|
worksheet.set_column(i, i, max_len) # Set width
|
|
1107
1130
|
|
|
1108
1131
|
# Format style
|
|
1109
|
-
|
|
1110
|
-
|
|
1132
|
+
fmt = text_fmt # default
|
|
1133
|
+
for cols, f in rules:
|
|
1134
|
+
if cols is not None and col in cols:
|
|
1135
|
+
fmt = f
|
|
1136
|
+
break
|
|
1137
|
+
worksheet.set_column(i, i, max_len, fmt)
|
|
1111
1138
|
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
worksheet.set_column(i, i, max_len, text_fmt)
|
|
1139
|
+
# if cols_contain_number is not None:
|
|
1140
|
+
# for x in cols_contain_number:
|
|
1141
|
+
# self[x] = pd.to_numeric(self[x], errors="coerce")
|
|
1116
1142
|
|
|
1117
1143
|
|
|
1118
1144
|
# City
|
|
@@ -1289,3 +1315,14 @@ class DADF_WIP(DADF):
|
|
|
1289
1315
|
"""
|
|
1290
1316
|
|
|
1291
1317
|
pass
|
|
1318
|
+
|
|
1319
|
+
if __name__ == "__main__":
|
|
1320
|
+
from pathlib import Path
|
|
1321
|
+
|
|
1322
|
+
t = DADF.sample_df().show_distribution("number_range", show_percentage=False)
|
|
1323
|
+
t.da_export(
|
|
1324
|
+
Path(__file__).parent.joinpath("a.xlsx").resolve().__str__(),
|
|
1325
|
+
cols_contain_number=["number_range"],
|
|
1326
|
+
cols_contain_percentage=["percentage"],
|
|
1327
|
+
)
|
|
1328
|
+
print(t)
|