absfuyu 3.3.3__tar.gz → 3.4.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-3.3.3 → absfuyu-3.4.0}/PKG-INFO +1 -1
- {absfuyu-3.3.3 → absfuyu-3.4.0}/pyproject.toml +2 -1
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/__init__.py +1 -1
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/cli/__init__.py +1 -1
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/cli/do_group.py +24 -2
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/general/data_extension.py +36 -23
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/general/human.py +77 -3
- absfuyu-3.4.0/tests/test_beautiful.py +13 -0
- absfuyu-3.4.0/tests/test_data_analysis.py +157 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/tests/test_everything.py +5 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/tests/test_passwordlib.py +7 -6
- absfuyu-3.3.3/tests/test_beautiful.py +0 -7
- absfuyu-3.3.3/tests/test_data_analysis.py +0 -159
- {absfuyu-3.3.3 → absfuyu-3.4.0}/.gitignore +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/LICENSE +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/README.md +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/dev_requirements.txt +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/docs/Makefile +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/docs/conf.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/docs/index.rst +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/docs/info.md +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/docs/make.bat +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/docs/modules.rst +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/images/repository-image-crop.png +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/images/repository-image-white.png +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/images/repository-image.png +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/__main__.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/cli/color.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/cli/config_group.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/cli/game_group.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/config/__init__.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/config/config.json +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/core.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/everything.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/extensions/__init__.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/extensions/beautiful.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/extensions/dev/__init__.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/extensions/dev/password_hash.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/extensions/dev/passwordlib.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/extensions/dev/project_starter.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/extensions/dev/shutdownizer.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/extensions/extra/__init__.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/extensions/extra/data_analysis.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/fun/WGS.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/fun/__init__.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/fun/tarot.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/game/__init__.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/game/game_stat.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/game/sudoku.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/game/tictactoe.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/game/wordle.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/general/__init__.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/general/content.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/general/generator.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/logger.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/pkg_data/__init__.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/pkg_data/chemistry.pkl +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/pkg_data/tarot.pkl +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/py.typed +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/sort.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/tools/__init__.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/tools/converter.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/tools/keygen.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/tools/obfuscator.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/tools/stats.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/tools/web.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/util/__init__.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/util/api.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/util/json_method.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/util/lunar.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/util/path.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/util/performance.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/util/pkl.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/util/zipped.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/src/absfuyu/version.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/tests/__init__.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/tests/conftest.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/tests/test_config.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/tests/test_data_extension.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/tests/test_extensions.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/tests/test_fun.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/tests/test_game.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/tests/test_generator.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/tests/test_logger.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/tests/test_pkg_data.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/tests/test_tarot.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/tests/test_tools.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/tests/test_util.py +0 -0
- {absfuyu-3.3.3 → absfuyu-3.4.0}/tests/test_version.py +0 -0
|
@@ -84,7 +84,6 @@ only-include = ["src", "tests", "docs", "images", "dev_requirements.txt"]
|
|
|
84
84
|
# Set up virtual env: use hatch env show
|
|
85
85
|
[tool.hatch.envs.default]
|
|
86
86
|
dependencies = ["coverage[toml]", "pytest-cov", "pytest"]
|
|
87
|
-
features = ["full"]
|
|
88
87
|
description = """
|
|
89
88
|
Default environment
|
|
90
89
|
|
|
@@ -102,6 +101,7 @@ cov = ["test-cov", "cov-report"] # use this
|
|
|
102
101
|
cov2 = "pytest --cov-report=term-missing --cov=absfuyu --cov=tests" # use this
|
|
103
102
|
|
|
104
103
|
[tool.hatch.envs.all]
|
|
104
|
+
features = ["full"]
|
|
105
105
|
description = """
|
|
106
106
|
All python version to test:
|
|
107
107
|
hatch run all:test
|
|
@@ -125,6 +125,7 @@ check = "mypy --install-types --non-interactive {args:src/absfuyu}"
|
|
|
125
125
|
# check = "mypy --install-types --non-interactive {args:src/absfuyu tests}"
|
|
126
126
|
|
|
127
127
|
[tool.hatch.envs.docs]
|
|
128
|
+
features = ["full"]
|
|
128
129
|
dependencies = [
|
|
129
130
|
"sphinx>=7.0.0",
|
|
130
131
|
"sphinx_rtd_theme",
|
|
@@ -3,8 +3,8 @@ ABSFUYU CLI
|
|
|
3
3
|
-----------
|
|
4
4
|
Do
|
|
5
5
|
|
|
6
|
-
Version: 1.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 1.1.0
|
|
7
|
+
Date updated: 15/08/2024 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
__all__ = ["do_group"]
|
|
@@ -16,6 +16,7 @@ import click
|
|
|
16
16
|
from absfuyu import __title__
|
|
17
17
|
from absfuyu.cli.color import COLOR
|
|
18
18
|
from absfuyu.core import __package_feature__
|
|
19
|
+
from absfuyu.general.human import Human2
|
|
19
20
|
from absfuyu.version import PkgVersion
|
|
20
21
|
|
|
21
22
|
|
|
@@ -65,6 +66,25 @@ def advice() -> None:
|
|
|
65
66
|
click.echo(f"{COLOR['green']}{im_bored()}")
|
|
66
67
|
|
|
67
68
|
|
|
69
|
+
@click.command(name="fs")
|
|
70
|
+
@click.argument("date", type=str)
|
|
71
|
+
@click.argument("number_string", type=str)
|
|
72
|
+
def fs(date: str, number_string: str) -> None:
|
|
73
|
+
"""Feng-shui W.I.P"""
|
|
74
|
+
|
|
75
|
+
instance = Human2(date)
|
|
76
|
+
print(instance.fs(number_string))
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@click.command(name="info")
|
|
80
|
+
@click.argument("date", type=str)
|
|
81
|
+
def info(date: str) -> None:
|
|
82
|
+
"""Day info"""
|
|
83
|
+
|
|
84
|
+
instance = Human2(date)
|
|
85
|
+
print(instance.info())
|
|
86
|
+
|
|
87
|
+
|
|
68
88
|
@click.group(name="do")
|
|
69
89
|
def do_group() -> None:
|
|
70
90
|
"""Perform functionalities"""
|
|
@@ -74,3 +94,5 @@ def do_group() -> None:
|
|
|
74
94
|
do_group.add_command(update)
|
|
75
95
|
do_group.add_command(install)
|
|
76
96
|
do_group.add_command(advice)
|
|
97
|
+
do_group.add_command(fs)
|
|
98
|
+
do_group.add_command(info)
|
|
@@ -3,8 +3,8 @@ Absfuyu: Data extension
|
|
|
3
3
|
-----------------------
|
|
4
4
|
Extension for data type such as ``list``, ``str``, ``dict``, ...
|
|
5
5
|
|
|
6
|
-
Version: 1.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 1.15.0
|
|
7
|
+
Date updated: 27/04/2024 (dd/mm/yyyy)
|
|
8
8
|
|
|
9
9
|
Features:
|
|
10
10
|
---------
|
|
@@ -61,9 +61,9 @@ from typing import (
|
|
|
61
61
|
)
|
|
62
62
|
|
|
63
63
|
if _python_version.minor >= 11:
|
|
64
|
-
from typing import NotRequired
|
|
64
|
+
from typing import NotRequired, Self
|
|
65
65
|
else:
|
|
66
|
-
from typing_extensions import NotRequired # type: ignore
|
|
66
|
+
from typing_extensions import NotRequired, Self # type: ignore
|
|
67
67
|
|
|
68
68
|
from deprecated.sphinx import versionadded, versionchanged
|
|
69
69
|
|
|
@@ -256,7 +256,7 @@ class Text(str):
|
|
|
256
256
|
split_size: int = 60,
|
|
257
257
|
split_var_len: int = 12,
|
|
258
258
|
custom_var_name: Optional[str] = None,
|
|
259
|
-
) ->
|
|
259
|
+
) -> List[str]:
|
|
260
260
|
"""
|
|
261
261
|
Divide long string into smaller size,
|
|
262
262
|
then assign a random variable to splited
|
|
@@ -277,7 +277,7 @@ class Text(str):
|
|
|
277
277
|
|
|
278
278
|
Returns
|
|
279
279
|
-------
|
|
280
|
-
list
|
|
280
|
+
list[str]
|
|
281
281
|
A list in which each item is a smaller
|
|
282
282
|
string with the size of ``split_size``
|
|
283
283
|
and a way to concaternate them (when using ``print()``)
|
|
@@ -398,7 +398,7 @@ class Text(str):
|
|
|
398
398
|
|
|
399
399
|
return detail
|
|
400
400
|
|
|
401
|
-
def reverse(self) ->
|
|
401
|
+
def reverse(self) -> Self:
|
|
402
402
|
"""
|
|
403
403
|
Reverse the string
|
|
404
404
|
|
|
@@ -489,7 +489,7 @@ class Text(str):
|
|
|
489
489
|
else:
|
|
490
490
|
return hex_str
|
|
491
491
|
|
|
492
|
-
def random_capslock(self, probability: int = 50) ->
|
|
492
|
+
def random_capslock(self, probability: int = 50) -> Self:
|
|
493
493
|
"""
|
|
494
494
|
Randomly capslock letter in string
|
|
495
495
|
|
|
@@ -522,7 +522,7 @@ class Text(str):
|
|
|
522
522
|
logger.debug(temp)
|
|
523
523
|
return self.__class__("".join(temp))
|
|
524
524
|
|
|
525
|
-
def reverse_capslock(self) ->
|
|
525
|
+
def reverse_capslock(self) -> Self:
|
|
526
526
|
"""
|
|
527
527
|
Reverse capslock in string
|
|
528
528
|
|
|
@@ -934,7 +934,7 @@ class IntNumber(int):
|
|
|
934
934
|
except Exception:
|
|
935
935
|
return False
|
|
936
936
|
|
|
937
|
-
def reverse(self) ->
|
|
937
|
+
def reverse(self) -> Self:
|
|
938
938
|
"""
|
|
939
939
|
Reverse a number. Reverse ``abs(number)`` if ``number < 0``
|
|
940
940
|
|
|
@@ -983,7 +983,7 @@ class IntNumber(int):
|
|
|
983
983
|
|
|
984
984
|
# calculation stuff
|
|
985
985
|
@versionchanged(version="3.3.0", reason="Fix bug")
|
|
986
|
-
def lcm(self, with_number: int) ->
|
|
986
|
+
def lcm(self, with_number: int) -> Self:
|
|
987
987
|
"""
|
|
988
988
|
Least common multiple of ``self`` and ``with_number``
|
|
989
989
|
|
|
@@ -1010,7 +1010,7 @@ class IntNumber(int):
|
|
|
1010
1010
|
return self.__class__((self * with_number) // math.gcd(self, with_number))
|
|
1011
1011
|
|
|
1012
1012
|
@versionchanged(version="3.3.0", reason="Fix bug")
|
|
1013
|
-
def gcd(self, with_number: int) ->
|
|
1013
|
+
def gcd(self, with_number: int) -> Self:
|
|
1014
1014
|
"""
|
|
1015
1015
|
Greatest common divisor of ``self`` and ``with_number``
|
|
1016
1016
|
|
|
@@ -1033,7 +1033,7 @@ class IntNumber(int):
|
|
|
1033
1033
|
"""
|
|
1034
1034
|
return self.__class__(math.gcd(self, with_number))
|
|
1035
1035
|
|
|
1036
|
-
def add_to_one_digit(self, master_number: bool = False) ->
|
|
1036
|
+
def add_to_one_digit(self, master_number: bool = False) -> Self:
|
|
1037
1037
|
"""
|
|
1038
1038
|
Convert ``self`` into 1-digit number
|
|
1039
1039
|
by adding all of the digits together
|
|
@@ -1220,7 +1220,7 @@ class ListExt(list):
|
|
|
1220
1220
|
``list`` extension
|
|
1221
1221
|
"""
|
|
1222
1222
|
|
|
1223
|
-
def stringify(self) ->
|
|
1223
|
+
def stringify(self) -> Self:
|
|
1224
1224
|
"""
|
|
1225
1225
|
Convert all item in ``list`` into string
|
|
1226
1226
|
|
|
@@ -1278,7 +1278,7 @@ class ListExt(list):
|
|
|
1278
1278
|
)
|
|
1279
1279
|
return self[::-1][:number_of_items][::-1]
|
|
1280
1280
|
|
|
1281
|
-
def sorts(self, reverse: bool = False) ->
|
|
1281
|
+
def sorts(self, reverse: bool = False) -> Self:
|
|
1282
1282
|
"""
|
|
1283
1283
|
Sort all items (with different type) in ``list``
|
|
1284
1284
|
|
|
@@ -1458,7 +1458,7 @@ class ListExt(list):
|
|
|
1458
1458
|
"""
|
|
1459
1459
|
return [self.pick_one() for _ in range(number_of_items)]
|
|
1460
1460
|
|
|
1461
|
-
def len_items(self) ->
|
|
1461
|
+
def len_items(self) -> Self:
|
|
1462
1462
|
"""
|
|
1463
1463
|
``len()`` for every item in ``list[str]``
|
|
1464
1464
|
|
|
@@ -1499,7 +1499,7 @@ class ListExt(list):
|
|
|
1499
1499
|
logger.debug(out)
|
|
1500
1500
|
return out
|
|
1501
1501
|
|
|
1502
|
-
def apply(self, func: Callable) ->
|
|
1502
|
+
def apply(self, func: Callable) -> Self:
|
|
1503
1503
|
"""
|
|
1504
1504
|
Apply function to each entry
|
|
1505
1505
|
|
|
@@ -1523,7 +1523,7 @@ class ListExt(list):
|
|
|
1523
1523
|
# return __class__(func(x) for x in self)
|
|
1524
1524
|
return self.__class__(map(func, self))
|
|
1525
1525
|
|
|
1526
|
-
def unique(self) ->
|
|
1526
|
+
def unique(self) -> Self:
|
|
1527
1527
|
"""
|
|
1528
1528
|
Remove duplicates
|
|
1529
1529
|
|
|
@@ -1541,7 +1541,7 @@ class ListExt(list):
|
|
|
1541
1541
|
"""
|
|
1542
1542
|
return self.__class__(set(self))
|
|
1543
1543
|
|
|
1544
|
-
def group_by_unique(self) ->
|
|
1544
|
+
def group_by_unique(self) -> Self:
|
|
1545
1545
|
"""
|
|
1546
1546
|
Group duplicated elements into list
|
|
1547
1547
|
|
|
@@ -1624,7 +1624,7 @@ class ListExt(list):
|
|
|
1624
1624
|
|
|
1625
1625
|
return list(x for x, _ in groupby(iter))
|
|
1626
1626
|
|
|
1627
|
-
def flatten(self) ->
|
|
1627
|
+
def flatten(self) -> Self:
|
|
1628
1628
|
"""
|
|
1629
1629
|
Flatten the list
|
|
1630
1630
|
|
|
@@ -1646,7 +1646,7 @@ class ListExt(list):
|
|
|
1646
1646
|
temp = list(map(lambda x: x if isinstance(x, list) else [x], self))
|
|
1647
1647
|
return ListExt(chain(*temp))
|
|
1648
1648
|
|
|
1649
|
-
def numbering(self, start: int = 0) ->
|
|
1649
|
+
def numbering(self, start: int = 0) -> Self:
|
|
1650
1650
|
"""
|
|
1651
1651
|
Number the item in list
|
|
1652
1652
|
(``enumerate`` wrapper)
|
|
@@ -1744,7 +1744,7 @@ class DictExt(dict):
|
|
|
1744
1744
|
logger.error(err_msg)
|
|
1745
1745
|
raise ValueError(err_msg) # noqa: B904
|
|
1746
1746
|
|
|
1747
|
-
def swap_items(self) ->
|
|
1747
|
+
def swap_items(self) -> Self:
|
|
1748
1748
|
"""
|
|
1749
1749
|
Swap ``dict.keys()`` with ``dict.values()``
|
|
1750
1750
|
|
|
@@ -1762,7 +1762,7 @@ class DictExt(dict):
|
|
|
1762
1762
|
"""
|
|
1763
1763
|
return self.__class__(zip(self.values(), self.keys()))
|
|
1764
1764
|
|
|
1765
|
-
def apply(self, func: Callable, apply_to_value: bool = True) ->
|
|
1765
|
+
def apply(self, func: Callable, apply_to_value: bool = True) -> Self:
|
|
1766
1766
|
"""
|
|
1767
1767
|
Apply function to ``DictExt.keys()`` or ``DictExt.values()``
|
|
1768
1768
|
|
|
@@ -1795,6 +1795,19 @@ class DictExt(dict):
|
|
|
1795
1795
|
v = self.values() # type: ignore
|
|
1796
1796
|
return self.__class__(zip(k, v))
|
|
1797
1797
|
|
|
1798
|
+
@versionadded(version="3.4.0")
|
|
1799
|
+
def aggregate(
|
|
1800
|
+
self,
|
|
1801
|
+
other_dict: Dict[Any, Union[int, float]],
|
|
1802
|
+
default_value: Union[int, float] = 0,
|
|
1803
|
+
) -> Self:
|
|
1804
|
+
"""Dict with value type int or float"""
|
|
1805
|
+
out = {
|
|
1806
|
+
k: self.get(k, default_value) + other_dict.get(k, default_value)
|
|
1807
|
+
for k in set(self | other_dict)
|
|
1808
|
+
}
|
|
1809
|
+
return self.__class__(out)
|
|
1810
|
+
|
|
1798
1811
|
|
|
1799
1812
|
# Run
|
|
1800
1813
|
###########################################################################
|
|
@@ -3,8 +3,8 @@ Absfuyu: Human
|
|
|
3
3
|
--------------
|
|
4
4
|
Human related stuff
|
|
5
5
|
|
|
6
|
-
Version: 1.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 1.4.0
|
|
7
|
+
Date updated: 15/08/2024 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
# Module level
|
|
@@ -14,13 +14,16 @@ __all__ = ["Human", "Person"]
|
|
|
14
14
|
|
|
15
15
|
# Library
|
|
16
16
|
###########################################################################
|
|
17
|
+
import re
|
|
17
18
|
from datetime import datetime, time
|
|
18
19
|
from typing import Optional, Union
|
|
20
|
+
from urllib.parse import urlencode
|
|
19
21
|
|
|
20
22
|
from dateutil.relativedelta import relativedelta
|
|
21
23
|
|
|
22
24
|
from absfuyu.fun import zodiac_sign
|
|
23
25
|
from absfuyu.general.data_extension import IntNumber
|
|
26
|
+
from absfuyu.tools.web import soup_link
|
|
24
27
|
from absfuyu.version import Version # type: ignore
|
|
25
28
|
|
|
26
29
|
|
|
@@ -349,7 +352,78 @@ class Person(Human):
|
|
|
349
352
|
return IntNumber(temp).add_to_one_digit(master_number=True)
|
|
350
353
|
|
|
351
354
|
|
|
355
|
+
class Human2:
|
|
356
|
+
"""W.I.P for cli"""
|
|
357
|
+
|
|
358
|
+
def __init__(self, birthday_string: str, is_male: bool = True) -> None:
|
|
359
|
+
"""
|
|
360
|
+
:param birthday_string: Format ``<yyyymmddhhmm>`` or ``<yyyymmdd>``
|
|
361
|
+
"""
|
|
362
|
+
if len(birthday_string) == 12:
|
|
363
|
+
day = datetime(
|
|
364
|
+
year=int(birthday_string[:4]),
|
|
365
|
+
month=int(birthday_string[4:6]),
|
|
366
|
+
day=int(birthday_string[6:8]),
|
|
367
|
+
hour=int(birthday_string[8:10]),
|
|
368
|
+
minute=int(birthday_string[10:]),
|
|
369
|
+
)
|
|
370
|
+
else:
|
|
371
|
+
day = datetime(
|
|
372
|
+
year=int(birthday_string[:4]),
|
|
373
|
+
month=int(birthday_string[4:6]),
|
|
374
|
+
day=int(birthday_string[6:]),
|
|
375
|
+
)
|
|
376
|
+
self._date_str = birthday_string[:8]
|
|
377
|
+
self.day = day
|
|
378
|
+
self.is_male = is_male
|
|
379
|
+
|
|
380
|
+
def __str__(self) -> str:
|
|
381
|
+
class_name = self.__class__.__name__
|
|
382
|
+
return f"{class_name}({str(self.day)})"
|
|
383
|
+
|
|
384
|
+
def __repr__(self) -> str:
|
|
385
|
+
class_name = self.__class__.__name__
|
|
386
|
+
return f"{class_name}({str(self.day)})"
|
|
387
|
+
|
|
388
|
+
def numerology(self) -> int:
|
|
389
|
+
# numerology
|
|
390
|
+
return IntNumber(self._date_str).add_to_one_digit(master_number=True)
|
|
391
|
+
|
|
392
|
+
def _make_fengshui_check_query(self) -> str:
|
|
393
|
+
"""
|
|
394
|
+
Generate query to check Feng-shui
|
|
395
|
+
"""
|
|
396
|
+
params = {
|
|
397
|
+
"ngay": self.day.day.__str__().rjust(2, "0"),
|
|
398
|
+
"thang": self.day.month.__str__().rjust(2, "0"),
|
|
399
|
+
"nam": self.day.year,
|
|
400
|
+
"gio": self.day.hour.__str__().rjust(2, "0"),
|
|
401
|
+
"phut": self.day.minute.__str__().rjust(2, "0"),
|
|
402
|
+
"gioitinh": "nam" if self.is_male else "nu",
|
|
403
|
+
}
|
|
404
|
+
output = urlencode(params)
|
|
405
|
+
return output
|
|
406
|
+
|
|
407
|
+
def fs(self, number_string: str) -> float:
|
|
408
|
+
# fengshui
|
|
409
|
+
base = "https://thanglongdaoquan.vn/boi-so-tai-khoan/?taikhoan="
|
|
410
|
+
link = f"{base}{number_string}&{self._make_fengshui_check_query()}"
|
|
411
|
+
soup = soup_link(link)
|
|
412
|
+
val = soup.find_all(class_="total_point")[0].get_text()
|
|
413
|
+
pattern = r"([0-9.]{1,3})/10"
|
|
414
|
+
res = re.findall(pattern, val)[0]
|
|
415
|
+
return float(res)
|
|
416
|
+
|
|
417
|
+
def info(self) -> dict:
|
|
418
|
+
out = {
|
|
419
|
+
"numerology": self.numerology(),
|
|
420
|
+
"zodiac": zodiac_sign(self.day.day, self.day.month),
|
|
421
|
+
}
|
|
422
|
+
return out
|
|
423
|
+
|
|
424
|
+
|
|
352
425
|
# Run
|
|
353
426
|
###########################################################################
|
|
354
427
|
if __name__ == "__main__":
|
|
355
|
-
print(Person.JohnDoe().__dict__)
|
|
428
|
+
# print(Person.JohnDoe().__dict__)
|
|
429
|
+
pass
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
try: # [beautiful] feature
|
|
4
|
+
import rich # type: ignore
|
|
5
|
+
except ImportError:
|
|
6
|
+
rich = pytest.importorskip("rich")
|
|
7
|
+
|
|
8
|
+
from absfuyu.extensions import beautiful as bu
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class TestBeautiful:
|
|
12
|
+
def test_beau(self):
|
|
13
|
+
assert bu.demo() is None
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Test: Data Analysis
|
|
3
|
+
|
|
4
|
+
Version: 1.2.1
|
|
5
|
+
Date updated: 19/04/2024 (dd/mm/yyyy)
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import random
|
|
9
|
+
|
|
10
|
+
import pytest
|
|
11
|
+
|
|
12
|
+
try: # [extra] feature
|
|
13
|
+
import numpy as np
|
|
14
|
+
import pandas as pd
|
|
15
|
+
except ImportError:
|
|
16
|
+
np = pytest.importorskip("numpy")
|
|
17
|
+
pd = pytest.importorskip("pandas")
|
|
18
|
+
|
|
19
|
+
from absfuyu.extensions.extra.data_analysis import DADF, CityData, SplittedDF
|
|
20
|
+
from absfuyu.general.generator import Charset, Generator
|
|
21
|
+
|
|
22
|
+
SAMPLE_SIZE = 100
|
|
23
|
+
sample_city_data = CityData._sample_city_data(size=SAMPLE_SIZE)
|
|
24
|
+
|
|
25
|
+
# MARK: fixture
|
|
26
|
+
@pytest.fixture
|
|
27
|
+
def sample_df() -> DADF:
|
|
28
|
+
# Number of columns generated
|
|
29
|
+
num_of_cols: int = random.randint(5, 10)
|
|
30
|
+
# List of column name
|
|
31
|
+
col_name: list = Generator.generate_string(
|
|
32
|
+
Charset.LOWERCASE, unique=True, times=num_of_cols
|
|
33
|
+
)
|
|
34
|
+
# Create DataFrame
|
|
35
|
+
df = pd.DataFrame(
|
|
36
|
+
np.random.randn(random.randint(5, 100), num_of_cols), columns=col_name
|
|
37
|
+
)
|
|
38
|
+
out = DADF(df)
|
|
39
|
+
return out
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@pytest.fixture
|
|
43
|
+
def sample_df_2() -> DADF:
|
|
44
|
+
return DADF.sample_df()
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@pytest.fixture
|
|
48
|
+
def sample_df_3():
|
|
49
|
+
sample = DADF.sample_df(size=SAMPLE_SIZE)
|
|
50
|
+
sample["city"] = [x.city for x in sample_city_data]
|
|
51
|
+
return sample
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
# MARK: test
|
|
55
|
+
class TestDADF:
|
|
56
|
+
"""absfuyu.extensions.extra.data_analysis.DADF"""
|
|
57
|
+
|
|
58
|
+
# Drop cols
|
|
59
|
+
def test_drop_rightmost(self, sample_df: DADF) -> None:
|
|
60
|
+
num_of_cols_drop = random.randint(1, 4)
|
|
61
|
+
|
|
62
|
+
num_of_cols_current = sample_df.shape[1]
|
|
63
|
+
sample_df.drop_rightmost(num_of_cols_drop)
|
|
64
|
+
num_of_cols_modified = sample_df.shape[1]
|
|
65
|
+
|
|
66
|
+
condition = (num_of_cols_current - num_of_cols_modified) == num_of_cols_drop
|
|
67
|
+
assert condition
|
|
68
|
+
|
|
69
|
+
# Add blank column
|
|
70
|
+
def test_add_blank_column(self, sample_df: DADF) -> None:
|
|
71
|
+
original_num_of_cols = sample_df.shape[1]
|
|
72
|
+
sample_df.add_blank_column("new_col", 0)
|
|
73
|
+
new_num_of_cols = sample_df.shape[1]
|
|
74
|
+
|
|
75
|
+
condition = (new_num_of_cols - original_num_of_cols) == 1 and sum(
|
|
76
|
+
sample_df["new_col"]
|
|
77
|
+
) == 0
|
|
78
|
+
assert condition
|
|
79
|
+
|
|
80
|
+
# Add date column
|
|
81
|
+
def test_add_date_from_month(self, sample_df_2: DADF) -> None:
|
|
82
|
+
sample_df_2.add_detail_date("date", mode="m")
|
|
83
|
+
original_num_of_cols = sample_df_2.shape[1]
|
|
84
|
+
sample_df_2.add_date_from_month("month", col_name="mod_date")
|
|
85
|
+
new_num_of_cols = sample_df_2.shape[1]
|
|
86
|
+
|
|
87
|
+
original_month = sample_df_2["month"][0]
|
|
88
|
+
modified_month = sample_df_2["mod_date"][0].month
|
|
89
|
+
|
|
90
|
+
# assert original_month == modified_month
|
|
91
|
+
condition = (
|
|
92
|
+
new_num_of_cols - original_num_of_cols
|
|
93
|
+
) == 1 and original_month == modified_month
|
|
94
|
+
assert condition
|
|
95
|
+
|
|
96
|
+
def test_add_date_column(self, sample_df_2: DADF) -> None:
|
|
97
|
+
# Get random mode
|
|
98
|
+
mode_list = ["d", "w", "m", "y"]
|
|
99
|
+
test_mode = list(
|
|
100
|
+
map(lambda x: "".join(x), Generator.combinations_range(mode_list))
|
|
101
|
+
)
|
|
102
|
+
random_mode = random.choice(test_mode)
|
|
103
|
+
num_of_new_cols = len(random_mode)
|
|
104
|
+
|
|
105
|
+
# Convert
|
|
106
|
+
original_num_of_cols = sample_df_2.shape[1]
|
|
107
|
+
sample_df_2.add_detail_date("date", mode=random_mode)
|
|
108
|
+
new_num_of_cols = sample_df_2.shape[1]
|
|
109
|
+
assert (new_num_of_cols - original_num_of_cols) == num_of_new_cols
|
|
110
|
+
|
|
111
|
+
# Join and split
|
|
112
|
+
def test_split_df(self, sample_df_2: DADF) -> None:
|
|
113
|
+
test = sample_df_2.split_na("missing_value")
|
|
114
|
+
assert len(test) > 1
|
|
115
|
+
|
|
116
|
+
def test_split_df_2(self, sample_df_2: DADF) -> None:
|
|
117
|
+
test = SplittedDF.divide_dataframe(sample_df_2, "number_range")
|
|
118
|
+
assert len(test) > 1
|
|
119
|
+
|
|
120
|
+
def test_join_df(self, sample_df_2: DADF) -> None:
|
|
121
|
+
test = sample_df_2.split_na("missing_value")
|
|
122
|
+
out = test.concat()
|
|
123
|
+
assert out.shape[0] == 100
|
|
124
|
+
|
|
125
|
+
def test_join_df_2(self, sample_df_2: DADF) -> None:
|
|
126
|
+
"""This test static method"""
|
|
127
|
+
test = SplittedDF.divide_dataframe(sample_df_2, "number_range")
|
|
128
|
+
out = SplittedDF.concat_df(test)
|
|
129
|
+
assert out.shape[0] == 100
|
|
130
|
+
|
|
131
|
+
# Threshold filter
|
|
132
|
+
def test_threshold_filter(self, sample_df_2: DADF) -> None:
|
|
133
|
+
original_num_of_cols = sample_df_2.shape[1]
|
|
134
|
+
sample_df_2.threshold_filter("number_range", 11)
|
|
135
|
+
new_num_of_cols = sample_df_2.shape[1]
|
|
136
|
+
|
|
137
|
+
# Check new column
|
|
138
|
+
assert (new_num_of_cols - original_num_of_cols) == 1
|
|
139
|
+
|
|
140
|
+
# Check filler value
|
|
141
|
+
test: list = sample_df_2["number_range_filtered"].unique().tolist()
|
|
142
|
+
try:
|
|
143
|
+
test.index("Other")
|
|
144
|
+
assert True
|
|
145
|
+
except Exception:
|
|
146
|
+
pass
|
|
147
|
+
|
|
148
|
+
# Check len
|
|
149
|
+
test1 = sample_df_2["number_range"].unique().tolist()
|
|
150
|
+
assert (len(test1) - len(test)) >= 1
|
|
151
|
+
|
|
152
|
+
# Convert city
|
|
153
|
+
def test_convert_city(self, sample_df_3: DADF) -> None:
|
|
154
|
+
original_num_of_cols = sample_df_3.shape[1]
|
|
155
|
+
sample_df_3.convert_city("city", city_list=sample_city_data)
|
|
156
|
+
new_num_of_cols = sample_df_3.shape[1]
|
|
157
|
+
assert (new_num_of_cols - original_num_of_cols) == 2
|
|
@@ -9,6 +9,11 @@ Date updated: 14/04/2024 (dd/mm/yyyy)
|
|
|
9
9
|
###########################################################################
|
|
10
10
|
import pytest
|
|
11
11
|
|
|
12
|
+
try: # [beautiful] feature
|
|
13
|
+
import rich # type: ignore
|
|
14
|
+
except ImportError:
|
|
15
|
+
rich = pytest.importorskip("rich")
|
|
16
|
+
|
|
12
17
|
from absfuyu import __author__, __license__, __title__, __version__
|
|
13
18
|
from absfuyu import everything as ab
|
|
14
19
|
from absfuyu.config import (
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Test: Passwordlib
|
|
3
3
|
|
|
4
|
-
Version: 1.1.
|
|
5
|
-
Date updated:
|
|
4
|
+
Version: 1.1.1
|
|
5
|
+
Date updated: 19/04/2024 (dd/mm/yyyy)
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
# Library
|
|
9
|
-
###########################################################################
|
|
10
8
|
from itertools import combinations_with_replacement
|
|
11
9
|
|
|
12
10
|
import pytest
|
|
13
11
|
|
|
12
|
+
try: # [res] feature
|
|
13
|
+
import absfuyu_res
|
|
14
|
+
except ImportError:
|
|
15
|
+
absfuyu_res = pytest.importorskip("absfuyu_res")
|
|
16
|
+
|
|
14
17
|
from absfuyu.extensions.dev.passwordlib import Password
|
|
15
18
|
from absfuyu.general.data_extension import Text
|
|
16
19
|
|
|
17
|
-
# Test
|
|
18
|
-
###########################################################################
|
|
19
20
|
# def test_generate_password():
|
|
20
21
|
# test = [password_check(Password.generate_password()) for _ in range(100)]
|
|
21
22
|
# assert all(test)
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Test: Data Analysis
|
|
3
|
-
|
|
4
|
-
Version: 1.2.0
|
|
5
|
-
Date updated: 08/03/2024 (dd/mm/yyyy)
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
# Library
|
|
9
|
-
###########################################################################
|
|
10
|
-
import random
|
|
11
|
-
|
|
12
|
-
import numpy as np
|
|
13
|
-
import pandas as pd
|
|
14
|
-
import pytest
|
|
15
|
-
|
|
16
|
-
from absfuyu.extensions.extra.data_analysis import DADF, CityData, SplittedDF
|
|
17
|
-
from absfuyu.general.generator import Charset, Generator
|
|
18
|
-
|
|
19
|
-
# Test
|
|
20
|
-
###########################################################################
|
|
21
|
-
SAMPLE_SIZE = 100
|
|
22
|
-
sample_city_data = CityData._sample_city_data(size=SAMPLE_SIZE)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
@pytest.fixture
|
|
26
|
-
def sample_df() -> DADF:
|
|
27
|
-
# Number of columns generated
|
|
28
|
-
num_of_cols: int = random.randint(5, 10)
|
|
29
|
-
# List of column name
|
|
30
|
-
col_name: list = Generator.generate_string(
|
|
31
|
-
Charset.LOWERCASE, unique=True, times=num_of_cols
|
|
32
|
-
)
|
|
33
|
-
# Create DataFrame
|
|
34
|
-
df = pd.DataFrame(
|
|
35
|
-
np.random.randn(random.randint(5, 100), num_of_cols), columns=col_name
|
|
36
|
-
)
|
|
37
|
-
out = DADF(df)
|
|
38
|
-
return out
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
@pytest.fixture
|
|
42
|
-
def sample_df_2() -> DADF:
|
|
43
|
-
return DADF.sample_df()
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
@pytest.fixture
|
|
47
|
-
def sample_df_3():
|
|
48
|
-
sample = DADF.sample_df(size=SAMPLE_SIZE)
|
|
49
|
-
sample["city"] = [x.city for x in sample_city_data]
|
|
50
|
-
return sample
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
# Drop cols
|
|
54
|
-
def test_drop_rightmost(sample_df: DADF):
|
|
55
|
-
num_of_cols_drop = random.randint(1, 4)
|
|
56
|
-
|
|
57
|
-
num_of_cols_current = sample_df.shape[1]
|
|
58
|
-
sample_df.drop_rightmost(num_of_cols_drop)
|
|
59
|
-
num_of_cols_modified = sample_df.shape[1]
|
|
60
|
-
|
|
61
|
-
condition = (num_of_cols_current - num_of_cols_modified) == num_of_cols_drop
|
|
62
|
-
assert condition
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
# Add blank column
|
|
66
|
-
def test_add_blank_column(sample_df: DADF):
|
|
67
|
-
original_num_of_cols = sample_df.shape[1]
|
|
68
|
-
sample_df.add_blank_column("new_col", 0)
|
|
69
|
-
new_num_of_cols = sample_df.shape[1]
|
|
70
|
-
|
|
71
|
-
condition = (new_num_of_cols - original_num_of_cols) == 1 and sum(
|
|
72
|
-
sample_df["new_col"]
|
|
73
|
-
) == 0
|
|
74
|
-
assert condition
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
# Add date column
|
|
78
|
-
def test_add_date_from_month(sample_df_2: DADF):
|
|
79
|
-
sample_df_2.add_detail_date("date", mode="m")
|
|
80
|
-
original_num_of_cols = sample_df_2.shape[1]
|
|
81
|
-
sample_df_2.add_date_from_month("month", col_name="mod_date")
|
|
82
|
-
new_num_of_cols = sample_df_2.shape[1]
|
|
83
|
-
|
|
84
|
-
original_month = sample_df_2["month"][0]
|
|
85
|
-
modified_month = sample_df_2["mod_date"][0].month
|
|
86
|
-
|
|
87
|
-
# assert original_month == modified_month
|
|
88
|
-
condition = (
|
|
89
|
-
new_num_of_cols - original_num_of_cols
|
|
90
|
-
) == 1 and original_month == modified_month
|
|
91
|
-
assert condition
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
def test_add_date_column(sample_df_2: DADF):
|
|
95
|
-
# Get random mode
|
|
96
|
-
mode_list = ["d", "w", "m", "y"]
|
|
97
|
-
test_mode = list(map(lambda x: "".join(x), Generator.combinations_range(mode_list)))
|
|
98
|
-
random_mode = random.choice(test_mode)
|
|
99
|
-
num_of_new_cols = len(random_mode)
|
|
100
|
-
|
|
101
|
-
# Convert
|
|
102
|
-
original_num_of_cols = sample_df_2.shape[1]
|
|
103
|
-
sample_df_2.add_detail_date("date", mode=random_mode)
|
|
104
|
-
new_num_of_cols = sample_df_2.shape[1]
|
|
105
|
-
assert (new_num_of_cols - original_num_of_cols) == num_of_new_cols
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
# Join and split
|
|
109
|
-
def test_split_df(sample_df_2: DADF):
|
|
110
|
-
test = sample_df_2.split_na("missing_value")
|
|
111
|
-
assert len(test) > 1
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
def test_split_df_2(sample_df_2: DADF):
|
|
115
|
-
test = SplittedDF.divide_dataframe(sample_df_2, "number_range")
|
|
116
|
-
assert len(test) > 1
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
def test_join_df(sample_df_2: DADF):
|
|
120
|
-
test = sample_df_2.split_na("missing_value")
|
|
121
|
-
out = test.concat()
|
|
122
|
-
assert out.shape[0] == 100
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
def test_join_df_2(sample_df_2: DADF):
|
|
126
|
-
"""This test static method"""
|
|
127
|
-
test = SplittedDF.divide_dataframe(sample_df_2, "number_range")
|
|
128
|
-
out = SplittedDF.concat_df(test)
|
|
129
|
-
assert out.shape[0] == 100
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
# Threshold filter
|
|
133
|
-
def test_threshold_filter(sample_df_2: DADF):
|
|
134
|
-
original_num_of_cols = sample_df_2.shape[1]
|
|
135
|
-
sample_df_2.threshold_filter("number_range", 11)
|
|
136
|
-
new_num_of_cols = sample_df_2.shape[1]
|
|
137
|
-
|
|
138
|
-
# Check new column
|
|
139
|
-
assert (new_num_of_cols - original_num_of_cols) == 1
|
|
140
|
-
|
|
141
|
-
# Check filler value
|
|
142
|
-
test: list = sample_df_2["number_range_filtered"].unique().tolist()
|
|
143
|
-
try:
|
|
144
|
-
test.index("Other")
|
|
145
|
-
assert True
|
|
146
|
-
except Exception:
|
|
147
|
-
pass
|
|
148
|
-
|
|
149
|
-
# Check len
|
|
150
|
-
test1 = sample_df_2["number_range"].unique().tolist()
|
|
151
|
-
assert (len(test1) - len(test)) >= 1
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
# Convert city
|
|
155
|
-
def test_convert_city(sample_df_3: DADF):
|
|
156
|
-
original_num_of_cols = sample_df_3.shape[1]
|
|
157
|
-
sample_df_3.convert_city("city", city_list=sample_city_data)
|
|
158
|
-
new_num_of_cols = sample_df_3.shape[1]
|
|
159
|
-
assert (new_num_of_cols - original_num_of_cols) == 2
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|