absfuyu 3.2.0__py3-none-any.whl → 3.3.3__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 +3 -10
- absfuyu/__main__.py +5 -250
- absfuyu/cli/__init__.py +51 -0
- absfuyu/cli/color.py +24 -0
- absfuyu/cli/config_group.py +56 -0
- absfuyu/cli/do_group.py +76 -0
- absfuyu/cli/game_group.py +109 -0
- absfuyu/config/__init__.py +55 -94
- absfuyu/config/config.json +0 -7
- absfuyu/core.py +5 -66
- absfuyu/everything.py +7 -9
- absfuyu/extensions/beautiful.py +30 -23
- absfuyu/extensions/dev/__init__.py +11 -8
- absfuyu/extensions/dev/password_hash.py +4 -2
- absfuyu/extensions/dev/passwordlib.py +7 -5
- absfuyu/extensions/dev/project_starter.py +4 -2
- absfuyu/extensions/dev/shutdownizer.py +148 -0
- absfuyu/extensions/extra/__init__.py +1 -2
- absfuyu/extensions/extra/data_analysis.py +110 -58
- absfuyu/fun/WGS.py +50 -26
- absfuyu/fun/__init__.py +6 -7
- absfuyu/fun/tarot.py +1 -1
- absfuyu/game/__init__.py +75 -81
- absfuyu/game/game_stat.py +36 -0
- absfuyu/game/sudoku.py +41 -48
- absfuyu/game/tictactoe.py +303 -548
- absfuyu/game/wordle.py +56 -47
- absfuyu/general/__init__.py +17 -7
- absfuyu/general/content.py +16 -15
- absfuyu/general/data_extension.py +282 -90
- absfuyu/general/generator.py +67 -67
- absfuyu/general/human.py +74 -78
- absfuyu/logger.py +94 -68
- absfuyu/pkg_data/__init__.py +29 -25
- absfuyu/py.typed +0 -0
- absfuyu/sort.py +61 -47
- absfuyu/tools/__init__.py +0 -1
- absfuyu/tools/converter.py +80 -62
- absfuyu/tools/keygen.py +62 -67
- absfuyu/tools/obfuscator.py +57 -53
- absfuyu/tools/stats.py +24 -24
- absfuyu/tools/web.py +10 -9
- absfuyu/util/__init__.py +38 -40
- absfuyu/util/api.py +53 -43
- absfuyu/util/json_method.py +25 -27
- absfuyu/util/lunar.py +20 -24
- absfuyu/util/path.py +362 -241
- absfuyu/util/performance.py +36 -98
- absfuyu/util/pkl.py +8 -8
- absfuyu/util/zipped.py +17 -19
- absfuyu/version.py +137 -148
- absfuyu-3.3.3.dist-info/METADATA +124 -0
- absfuyu-3.3.3.dist-info/RECORD +59 -0
- {absfuyu-3.2.0.dist-info → absfuyu-3.3.3.dist-info}/WHEEL +1 -2
- {absfuyu-3.2.0.dist-info → absfuyu-3.3.3.dist-info}/entry_points.txt +1 -0
- {absfuyu-3.2.0.dist-info → absfuyu-3.3.3.dist-info/licenses}/LICENSE +1 -1
- absfuyu/extensions/dev/pkglib.py +0 -98
- absfuyu/game/tictactoe2.py +0 -318
- absfuyu-3.2.0.dist-info/METADATA +0 -216
- absfuyu-3.2.0.dist-info/RECORD +0 -55
- absfuyu-3.2.0.dist-info/top_level.txt +0 -1
absfuyu/general/generator.py
CHANGED
|
@@ -3,8 +3,8 @@ Absfuyu: Generator
|
|
|
3
3
|
------------------
|
|
4
4
|
This generate stuff (Not python's ``generator``)
|
|
5
5
|
|
|
6
|
-
Version: 1.1.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 1.1.1
|
|
7
|
+
Date updated: 05/04/2024 (dd/mm/yyyy)
|
|
8
8
|
|
|
9
9
|
Features:
|
|
10
10
|
---------
|
|
@@ -14,20 +14,17 @@ Features:
|
|
|
14
14
|
- Generate combinations of list in range
|
|
15
15
|
"""
|
|
16
16
|
|
|
17
|
-
|
|
18
17
|
# Module level
|
|
19
18
|
###########################################################################
|
|
20
|
-
__all__ = [
|
|
21
|
-
"Charset",
|
|
22
|
-
"Generator"
|
|
23
|
-
]
|
|
19
|
+
__all__ = ["Charset", "Generator"]
|
|
24
20
|
|
|
25
21
|
|
|
26
22
|
# Library
|
|
27
23
|
###########################################################################
|
|
24
|
+
import string
|
|
28
25
|
from itertools import chain, combinations
|
|
29
26
|
from random import choice
|
|
30
|
-
|
|
27
|
+
|
|
31
28
|
# from string import (
|
|
32
29
|
# ascii_letters as _ascii_letters,
|
|
33
30
|
# ascii_uppercase as _ascii_uppercase,
|
|
@@ -48,6 +45,7 @@ class Charset:
|
|
|
48
45
|
"""
|
|
49
46
|
Character set data class
|
|
50
47
|
"""
|
|
48
|
+
|
|
51
49
|
DEFAULT = string.ascii_letters + string.digits
|
|
52
50
|
ALPHABET = string.ascii_letters
|
|
53
51
|
FULL = string.ascii_letters + string.digits + string.punctuation
|
|
@@ -56,7 +54,7 @@ class Charset:
|
|
|
56
54
|
DIGIT = string.digits
|
|
57
55
|
SPECIAL = string.punctuation
|
|
58
56
|
ALL = string.printable
|
|
59
|
-
PRODUCT_KEY = "BCDFGHJKMNPQRTVWXY2346789"
|
|
57
|
+
PRODUCT_KEY = "BCDFGHJKMNPQRTVWXY2346789" # Charset that various key makers use
|
|
60
58
|
# DEFAULT = _ascii_letters + _digits
|
|
61
59
|
# ALPHABET = _ascii_letters
|
|
62
60
|
# FULL = _ascii_letters + _digits + _punctuation
|
|
@@ -67,7 +65,7 @@ class Charset:
|
|
|
67
65
|
# ALL = _printable
|
|
68
66
|
|
|
69
67
|
def __str__(self) -> str:
|
|
70
|
-
charset = [x for x in __class__.__dict__.keys() if not x.startswith("__")]
|
|
68
|
+
charset = [x for x in self.__class__.__dict__.keys() if not x.startswith("__")]
|
|
71
69
|
return f"List of Character set: {charset}"
|
|
72
70
|
|
|
73
71
|
def __repr__(self) -> str:
|
|
@@ -78,24 +76,27 @@ class Generator:
|
|
|
78
76
|
"""
|
|
79
77
|
Generator that generate stuffs
|
|
80
78
|
"""
|
|
79
|
+
|
|
81
80
|
def __init__(self) -> None:
|
|
82
81
|
logger.debug("Class initiated!")
|
|
82
|
+
|
|
83
83
|
def __str__(self) -> str:
|
|
84
84
|
return f"{self.__class__.__name__}()"
|
|
85
|
+
|
|
85
86
|
def __repr__(self) -> str:
|
|
86
87
|
return self.__str__()
|
|
87
88
|
|
|
88
89
|
@staticmethod
|
|
89
90
|
def generate_string(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
91
|
+
charset: str = Charset.DEFAULT,
|
|
92
|
+
size: int = 8,
|
|
93
|
+
times: int = 1,
|
|
94
|
+
unique: bool = False,
|
|
95
|
+
string_type_if_1: bool = False,
|
|
96
|
+
):
|
|
96
97
|
"""
|
|
97
98
|
Generate a list of random string from character set (Random string generator)
|
|
98
|
-
|
|
99
|
+
|
|
99
100
|
Parameters
|
|
100
101
|
----------
|
|
101
102
|
charset : str
|
|
@@ -108,31 +109,31 @@ class Generator:
|
|
|
108
109
|
- ``Charset.DIGIT``: character in [0-9]
|
|
109
110
|
- ``Charset.SPECIAL``: character in [!@#$%^&*()_+=-]
|
|
110
111
|
- ``Charset.ALL``: character in every printable character
|
|
111
|
-
|
|
112
|
+
|
|
112
113
|
size : int
|
|
113
|
-
Length of each string in list
|
|
114
|
+
Length of each string in list
|
|
114
115
|
(Default: ``8``)
|
|
115
|
-
|
|
116
|
+
|
|
116
117
|
times : int
|
|
117
|
-
How many random string generated
|
|
118
|
+
How many random string generated
|
|
118
119
|
(Default: ``1``)
|
|
119
|
-
|
|
120
|
+
|
|
120
121
|
unique : bool
|
|
121
|
-
Each generated text is unique
|
|
122
|
+
Each generated text is unique
|
|
122
123
|
(Default: ``False``)
|
|
123
|
-
|
|
124
|
+
|
|
124
125
|
string_type_if_1 : bool
|
|
125
|
-
Return a ``str`` type result if ``times == 1``
|
|
126
|
+
Return a ``str`` type result if ``times == 1``
|
|
126
127
|
(Default: ``False``)
|
|
127
|
-
|
|
128
|
+
|
|
128
129
|
Returns
|
|
129
130
|
-------
|
|
130
131
|
list
|
|
131
132
|
List of random string generated
|
|
132
|
-
|
|
133
|
+
|
|
133
134
|
str
|
|
134
135
|
When ``string_type_if_1`` is ``True``
|
|
135
|
-
|
|
136
|
+
|
|
136
137
|
None
|
|
137
138
|
When invalid option
|
|
138
139
|
|
|
@@ -145,15 +146,15 @@ class Generator:
|
|
|
145
146
|
|
|
146
147
|
try:
|
|
147
148
|
char_lst = list(charset)
|
|
148
|
-
except:
|
|
149
|
-
char_lst = charset
|
|
149
|
+
except Exception:
|
|
150
|
+
char_lst = charset # type: ignore # ! review this sometime
|
|
150
151
|
# logger.debug(char_lst)
|
|
151
152
|
|
|
152
153
|
unique_string = []
|
|
153
154
|
count = 0
|
|
154
155
|
logger.debug(f"Unique generated text: {unique}")
|
|
155
156
|
|
|
156
|
-
while
|
|
157
|
+
while count < times:
|
|
157
158
|
s = "".join(choice(char_lst) for _ in range(size))
|
|
158
159
|
logger.debug(f"Time generated: {count+1}. Remaining: {times-count-1}. {s}")
|
|
159
160
|
if not unique:
|
|
@@ -163,39 +164,39 @@ class Generator:
|
|
|
163
164
|
if s not in unique_string:
|
|
164
165
|
unique_string.append(s)
|
|
165
166
|
count += 1
|
|
166
|
-
|
|
167
|
+
|
|
167
168
|
logger.debug(unique_string)
|
|
168
169
|
if string_type_if_1 and times == 1:
|
|
169
170
|
return unique_string[0]
|
|
170
171
|
else:
|
|
171
172
|
return unique_string
|
|
172
|
-
|
|
173
|
+
|
|
173
174
|
@staticmethod
|
|
174
175
|
def generate_key(
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
176
|
+
charset: str = Charset.PRODUCT_KEY,
|
|
177
|
+
letter_per_block: int = 5,
|
|
178
|
+
number_of_block: int = 5,
|
|
179
|
+
sep: str = "-",
|
|
180
|
+
) -> str:
|
|
180
181
|
"""
|
|
181
182
|
Generate custom key
|
|
182
183
|
|
|
183
184
|
Parameters
|
|
184
185
|
----------
|
|
185
186
|
charset : str
|
|
186
|
-
Character set
|
|
187
|
+
Character set
|
|
187
188
|
(Default: ``Charset.PRODUCT_KEY``)
|
|
188
|
-
|
|
189
|
+
|
|
189
190
|
letter_per_block : int
|
|
190
|
-
Number of letter per key block
|
|
191
|
+
Number of letter per key block
|
|
191
192
|
(Default: ``5``)
|
|
192
|
-
|
|
193
|
+
|
|
193
194
|
number_of_block : int
|
|
194
|
-
Number of key block
|
|
195
|
+
Number of key block
|
|
195
196
|
(Default: ``5``)
|
|
196
|
-
|
|
197
|
+
|
|
197
198
|
sep : str
|
|
198
|
-
Key block separator
|
|
199
|
+
Key block separator
|
|
199
200
|
(Default: ``-``)
|
|
200
201
|
|
|
201
202
|
Returns
|
|
@@ -210,12 +211,12 @@ class Generator:
|
|
|
210
211
|
'VKKPJVYD2H-M7R687QCV2'
|
|
211
212
|
"""
|
|
212
213
|
out = sep.join(
|
|
213
|
-
__class__.generate_string(
|
|
214
|
+
__class__.generate_string( # type: ignore
|
|
214
215
|
charset,
|
|
215
216
|
size=letter_per_block,
|
|
216
217
|
times=number_of_block,
|
|
217
218
|
unique=False,
|
|
218
|
-
string_type_if_1=False
|
|
219
|
+
string_type_if_1=False,
|
|
219
220
|
)
|
|
220
221
|
)
|
|
221
222
|
logger.debug(out)
|
|
@@ -225,7 +226,7 @@ class Generator:
|
|
|
225
226
|
def generate_check_digit(number: int) -> int:
|
|
226
227
|
"""
|
|
227
228
|
Check digit generator
|
|
228
|
-
|
|
229
|
+
|
|
229
230
|
"A check digit is a form of redundancy check used for
|
|
230
231
|
error detection on identification numbers, such as
|
|
231
232
|
bank account numbers, which are used in an application
|
|
@@ -238,20 +239,20 @@ class Generator:
|
|
|
238
239
|
the input of a series of characters (usually digits)
|
|
239
240
|
such as a single mistyped digit or some permutations
|
|
240
241
|
of two successive digits." (Wikipedia)
|
|
241
|
-
|
|
242
|
+
|
|
242
243
|
This function use Luhn's algorithm to calculate
|
|
243
|
-
|
|
244
|
+
|
|
244
245
|
Parameters
|
|
245
246
|
----------
|
|
246
247
|
number : int
|
|
247
248
|
Number to calculate check digit
|
|
248
|
-
|
|
249
|
+
|
|
249
250
|
Returns
|
|
250
251
|
-------
|
|
251
252
|
int
|
|
252
253
|
Check digit
|
|
253
|
-
|
|
254
|
-
|
|
254
|
+
|
|
255
|
+
|
|
255
256
|
Example:
|
|
256
257
|
--------
|
|
257
258
|
>>> Generator.generate_check_digit("4129984562545")
|
|
@@ -265,22 +266,24 @@ class Generator:
|
|
|
265
266
|
logger.debug(f"Reversed: {''.join(num)}")
|
|
266
267
|
for i in range(len(num)):
|
|
267
268
|
# convert back into integer
|
|
268
|
-
num[i] = int(num[i])
|
|
269
|
-
if i%2 == 0:
|
|
269
|
+
num[i] = int(num[i]) # type: ignore
|
|
270
|
+
if i % 2 == 0:
|
|
270
271
|
# double value of the even-th digit
|
|
271
272
|
num[i] *= 2
|
|
272
273
|
# sum the character of digit if it's >= 10
|
|
273
|
-
if num[i] >= 10:
|
|
274
|
-
num[i] -= 9
|
|
275
|
-
sum += num[i]
|
|
274
|
+
if num[i] >= 10: # type: ignore
|
|
275
|
+
num[i] -= 9 # type: ignore
|
|
276
|
+
sum += num[i] # type: ignore
|
|
276
277
|
logger.debug(f"Loop {i+1}: {num[i]}, {sum}")
|
|
277
|
-
|
|
278
|
+
|
|
278
279
|
out = (10 - (sum % 10)) % 10
|
|
279
280
|
logger.debug(f"Output: {out}")
|
|
280
281
|
return out
|
|
281
282
|
|
|
282
283
|
@staticmethod
|
|
283
|
-
def combinations_range(
|
|
284
|
+
def combinations_range(
|
|
285
|
+
sequence: list, *, min_len: int = 1, max_len: int = 0
|
|
286
|
+
) -> List[tuple]:
|
|
284
287
|
"""
|
|
285
288
|
Generate all combinations of a ``sequence`` from ``min_len`` to ``max_len``
|
|
286
289
|
|
|
@@ -305,17 +308,14 @@ class Generator:
|
|
|
305
308
|
# Restrain
|
|
306
309
|
if max_len < 1:
|
|
307
310
|
max_len = len(sequence)
|
|
308
|
-
max_len = set_max(max_len, max_value=len(sequence))
|
|
309
|
-
min_len = set_min_max(min_len, min_value=1, max_value=max_len)
|
|
311
|
+
max_len = int(set_max(max_len, max_value=len(sequence)))
|
|
312
|
+
min_len = int(set_min_max(min_len, min_value=1, max_value=max_len))
|
|
310
313
|
logger.debug(f"Combination range: [{min_len}, {max_len}]")
|
|
311
314
|
|
|
312
315
|
# Return
|
|
313
316
|
return list(
|
|
314
317
|
chain.from_iterable(
|
|
315
|
-
[
|
|
316
|
-
list(combinations(sequence, i))
|
|
317
|
-
for i in range(min_len, max_len + 1)
|
|
318
|
-
]
|
|
318
|
+
[list(combinations(sequence, i)) for i in range(min_len, max_len + 1)]
|
|
319
319
|
)
|
|
320
320
|
)
|
|
321
321
|
|
|
@@ -323,4 +323,4 @@ class Generator:
|
|
|
323
323
|
# Run
|
|
324
324
|
###########################################################################
|
|
325
325
|
if __name__ == "__main__":
|
|
326
|
-
logger.setLevel(10)
|
|
326
|
+
logger.setLevel(10) # DEBUG
|
absfuyu/general/human.py
CHANGED
|
@@ -3,16 +3,13 @@ Absfuyu: Human
|
|
|
3
3
|
--------------
|
|
4
4
|
Human related stuff
|
|
5
5
|
|
|
6
|
-
Version: 1.3.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 1.3.1
|
|
7
|
+
Date updated: 05/04/2024 (dd/mm/yyyy)
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
|
-
|
|
11
10
|
# Module level
|
|
12
11
|
###########################################################################
|
|
13
|
-
__all__ = [
|
|
14
|
-
"Human", "Person"
|
|
15
|
-
]
|
|
12
|
+
__all__ = ["Human", "Person"]
|
|
16
13
|
|
|
17
14
|
|
|
18
15
|
# Library
|
|
@@ -22,10 +19,9 @@ from typing import Optional, Union
|
|
|
22
19
|
|
|
23
20
|
from dateutil.relativedelta import relativedelta
|
|
24
21
|
|
|
25
|
-
from absfuyu.general.data_extension import IntNumber
|
|
26
22
|
from absfuyu.fun import zodiac_sign
|
|
27
|
-
|
|
28
|
-
from absfuyu.version import Version
|
|
23
|
+
from absfuyu.general.data_extension import IntNumber
|
|
24
|
+
from absfuyu.version import Version # type: ignore
|
|
29
25
|
|
|
30
26
|
|
|
31
27
|
# Sub-Class
|
|
@@ -77,17 +73,17 @@ class Human:
|
|
|
77
73
|
Basic human data
|
|
78
74
|
"""
|
|
79
75
|
|
|
80
|
-
__MEASUREMENT = "m|kg"
|
|
81
|
-
__VERSION = Version(1, 1, 1)
|
|
76
|
+
__MEASUREMENT = "m|kg" # Metric system
|
|
77
|
+
__VERSION = Version(1, 1, 1) # Internal version class check
|
|
82
78
|
|
|
83
79
|
def __init__(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
80
|
+
self,
|
|
81
|
+
first_name: str,
|
|
82
|
+
last_name: Optional[str] = None,
|
|
83
|
+
birthday: Union[str, datetime, None] = None,
|
|
84
|
+
birth_time: Optional[str] = None,
|
|
85
|
+
gender: Union[bool, None] = None,
|
|
86
|
+
) -> None:
|
|
91
87
|
"""
|
|
92
88
|
:param first_name: First name
|
|
93
89
|
:param last_name: Last name
|
|
@@ -98,16 +94,22 @@ class Human:
|
|
|
98
94
|
# Name
|
|
99
95
|
self.first_name = first_name
|
|
100
96
|
self.last_name = last_name
|
|
101
|
-
self.name =
|
|
97
|
+
self.name = (
|
|
98
|
+
f"{self.last_name}, {self.first_name}"
|
|
99
|
+
if self.last_name is not None
|
|
100
|
+
else self.first_name
|
|
101
|
+
)
|
|
102
102
|
|
|
103
103
|
# Birthday
|
|
104
104
|
now = datetime.now()
|
|
105
105
|
if birthday is None:
|
|
106
106
|
modified_birthday = now.date()
|
|
107
|
-
|
|
107
|
+
elif isinstance(birthday, str):
|
|
108
108
|
for x in ["/", "-"]:
|
|
109
109
|
birthday = birthday.replace(x, "/")
|
|
110
110
|
modified_birthday = datetime.strptime(birthday, "%Y/%m/%d")
|
|
111
|
+
else:
|
|
112
|
+
modified_birthday = birthday
|
|
111
113
|
# birthday = list(map(int, birthday.split("/")))
|
|
112
114
|
# modified_birthday = date(*birthday)
|
|
113
115
|
# modified_birthday = date(birthday[0], birthday[1], birthday[2])
|
|
@@ -115,11 +117,11 @@ class Human:
|
|
|
115
117
|
if birth_time is None:
|
|
116
118
|
modified_birthtime = now.time()
|
|
117
119
|
else:
|
|
118
|
-
birth_time = list(map(int, birth_time.split(":")))
|
|
120
|
+
birth_time = list(map(int, birth_time.split(":"))) # type: ignore
|
|
119
121
|
modified_birthtime = time(*birth_time)
|
|
120
122
|
# modified_birthtime = time(birth_time[0], birth_time[1])
|
|
121
|
-
|
|
122
|
-
self.birthday = modified_birthday.date()
|
|
123
|
+
|
|
124
|
+
self.birthday = modified_birthday.date() # type: ignore
|
|
123
125
|
self.birth_time = modified_birthtime
|
|
124
126
|
|
|
125
127
|
self.birth = datetime(
|
|
@@ -127,15 +129,15 @@ class Human:
|
|
|
127
129
|
modified_birthday.month,
|
|
128
130
|
modified_birthday.day,
|
|
129
131
|
modified_birthtime.hour,
|
|
130
|
-
modified_birthtime.minute
|
|
132
|
+
modified_birthtime.minute,
|
|
131
133
|
)
|
|
132
134
|
|
|
133
135
|
# Others
|
|
134
|
-
self.gender: bool = gender # True: Male; False: Female
|
|
135
|
-
self.height: float = None # centimeter
|
|
136
|
-
self.weight: float = None # kilogram
|
|
137
|
-
self.blood_type: Union[str, BloodType] = BloodType.OTHER
|
|
138
|
-
|
|
136
|
+
self.gender: bool = gender # type: ignore # True: Male; False: Female
|
|
137
|
+
self.height: float = None # type: ignore # centimeter
|
|
138
|
+
self.weight: float = None # type: ignore # kilogram
|
|
139
|
+
self.blood_type: Union[str, BloodType] = BloodType.OTHER # type: ignore
|
|
140
|
+
|
|
139
141
|
def __str__(self) -> str:
|
|
140
142
|
class_name = self.__class__.__name__
|
|
141
143
|
return f"{class_name}({str(self.name)})"
|
|
@@ -145,7 +147,7 @@ class Human:
|
|
|
145
147
|
name = str(self.name)
|
|
146
148
|
gender = "M" if self.is_male else "F"
|
|
147
149
|
return f"{class_name}({name} ({self.age}|{gender}))"
|
|
148
|
-
|
|
150
|
+
|
|
149
151
|
@classmethod
|
|
150
152
|
def JohnDoe(cls):
|
|
151
153
|
"""
|
|
@@ -159,7 +161,7 @@ class Human:
|
|
|
159
161
|
temp = cls("John", "Doe", "1980/01/01", "00:00")
|
|
160
162
|
temp.update({"gender": True, "height": 180, "weight": 80, "blood_type": "O+"})
|
|
161
163
|
return temp
|
|
162
|
-
|
|
164
|
+
|
|
163
165
|
@property
|
|
164
166
|
def is_male(self) -> bool:
|
|
165
167
|
"""
|
|
@@ -172,7 +174,7 @@ class Human:
|
|
|
172
174
|
| ``False``: Female
|
|
173
175
|
"""
|
|
174
176
|
return self.gender
|
|
175
|
-
|
|
177
|
+
|
|
176
178
|
@property
|
|
177
179
|
def age(self):
|
|
178
180
|
"""
|
|
@@ -182,7 +184,7 @@ class Human:
|
|
|
182
184
|
-------
|
|
183
185
|
float
|
|
184
186
|
Age
|
|
185
|
-
|
|
187
|
+
|
|
186
188
|
None
|
|
187
189
|
When unable to get ``self.birthday``
|
|
188
190
|
"""
|
|
@@ -191,7 +193,7 @@ class Human:
|
|
|
191
193
|
# age = now - self.birthday
|
|
192
194
|
try:
|
|
193
195
|
rdelta = relativedelta(now, self.birthday)
|
|
194
|
-
except:
|
|
196
|
+
except Exception:
|
|
195
197
|
date_str = self.birthday
|
|
196
198
|
if date_str is None:
|
|
197
199
|
self.birthday = datetime.now().date()
|
|
@@ -201,19 +203,19 @@ class Human:
|
|
|
201
203
|
date = datetime.strptime(date_str, "%Y/%m/%d")
|
|
202
204
|
self.birthday = date
|
|
203
205
|
rdelta = relativedelta(now, self.birthday)
|
|
204
|
-
return round(rdelta.years + rdelta.months/12, 2)
|
|
206
|
+
return round(rdelta.years + rdelta.months / 12, 2)
|
|
205
207
|
else:
|
|
206
208
|
return None
|
|
207
|
-
|
|
209
|
+
|
|
208
210
|
@property
|
|
209
211
|
def is_adult(self):
|
|
210
212
|
"""
|
|
211
213
|
Check if ``self.age`` >= ``18``
|
|
212
|
-
|
|
214
|
+
|
|
213
215
|
:rtype: bool
|
|
214
216
|
"""
|
|
215
217
|
return self.age >= 18
|
|
216
|
-
|
|
218
|
+
|
|
217
219
|
@property
|
|
218
220
|
def bmi(self):
|
|
219
221
|
r"""
|
|
@@ -229,7 +231,7 @@ class Human:
|
|
|
229
231
|
-------
|
|
230
232
|
float
|
|
231
233
|
BMI value
|
|
232
|
-
|
|
234
|
+
|
|
233
235
|
None
|
|
234
236
|
When unable to get ``self.height`` and ``self.weight``
|
|
235
237
|
"""
|
|
@@ -237,9 +239,9 @@ class Human:
|
|
|
237
239
|
temp = self.height / 100
|
|
238
240
|
bmi = self.weight / (temp * temp)
|
|
239
241
|
return round(bmi, 2)
|
|
240
|
-
except:
|
|
242
|
+
except Exception:
|
|
241
243
|
return None
|
|
242
|
-
|
|
244
|
+
|
|
243
245
|
# @property
|
|
244
246
|
def dir_(self) -> list:
|
|
245
247
|
"""
|
|
@@ -251,7 +253,7 @@ class Human:
|
|
|
251
253
|
List of available properties
|
|
252
254
|
"""
|
|
253
255
|
return [x for x in self.__dir__() if not x.startswith("_")]
|
|
254
|
-
|
|
256
|
+
|
|
255
257
|
def update(self, data: dict) -> None:
|
|
256
258
|
"""
|
|
257
259
|
Update Human data
|
|
@@ -260,7 +262,7 @@ class Human:
|
|
|
260
262
|
----------
|
|
261
263
|
data : dict
|
|
262
264
|
Data
|
|
263
|
-
|
|
265
|
+
|
|
264
266
|
Returns
|
|
265
267
|
-------
|
|
266
268
|
None
|
|
@@ -274,29 +276,29 @@ class Person(Human):
|
|
|
274
276
|
More detailed ``Human`` data
|
|
275
277
|
"""
|
|
276
278
|
|
|
277
|
-
__VERSION = Version(1, 1, 1)
|
|
279
|
+
__VERSION = Version(1, 1, 1) # Internal version class check
|
|
278
280
|
|
|
279
281
|
def __init__(
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
282
|
+
self,
|
|
283
|
+
first_name: str,
|
|
284
|
+
last_name: Optional[str] = None,
|
|
285
|
+
birthday: Union[str, datetime, None] = None,
|
|
286
|
+
birth_time: Optional[str] = None,
|
|
287
|
+
gender: Union[bool, None] = None,
|
|
288
|
+
) -> None:
|
|
287
289
|
super().__init__(first_name, last_name, birthday, birth_time, gender)
|
|
288
|
-
self.address: str = None
|
|
289
|
-
self.hometown: str = None
|
|
290
|
-
self.email: str = None
|
|
291
|
-
self.phone_number: str = None
|
|
292
|
-
self.nationality = None
|
|
293
|
-
self.likes: list = None
|
|
294
|
-
self.hates: list = None
|
|
295
|
-
self.education = None
|
|
296
|
-
self.occupation: str = None
|
|
297
|
-
self.personality = None
|
|
298
|
-
self.note: str = None
|
|
299
|
-
|
|
290
|
+
self.address: str = None # type: ignore
|
|
291
|
+
self.hometown: str = None # type: ignore
|
|
292
|
+
self.email: str = None # type: ignore
|
|
293
|
+
self.phone_number: str = None # type: ignore
|
|
294
|
+
self.nationality = None # type: ignore
|
|
295
|
+
self.likes: list = None # type: ignore
|
|
296
|
+
self.hates: list = None # type: ignore
|
|
297
|
+
self.education = None # type: ignore
|
|
298
|
+
self.occupation: str = None # type: ignore
|
|
299
|
+
self.personality = None # type: ignore
|
|
300
|
+
self.note: str = None # type: ignore
|
|
301
|
+
|
|
300
302
|
@property
|
|
301
303
|
def zodiac_sign(self):
|
|
302
304
|
"""
|
|
@@ -306,15 +308,15 @@ class Person(Human):
|
|
|
306
308
|
-------
|
|
307
309
|
str
|
|
308
310
|
Zodiac sign
|
|
309
|
-
|
|
311
|
+
|
|
310
312
|
None
|
|
311
313
|
When unable to get ``self.birthday``
|
|
312
314
|
"""
|
|
313
315
|
try:
|
|
314
316
|
return zodiac_sign(self.birthday.day, self.birthday.month)
|
|
315
|
-
except:
|
|
317
|
+
except Exception:
|
|
316
318
|
return None
|
|
317
|
-
|
|
319
|
+
|
|
318
320
|
@property
|
|
319
321
|
def zodiac_sign_13(self):
|
|
320
322
|
"""
|
|
@@ -324,15 +326,15 @@ class Person(Human):
|
|
|
324
326
|
-------
|
|
325
327
|
str
|
|
326
328
|
Zodiac sign
|
|
327
|
-
|
|
329
|
+
|
|
328
330
|
None
|
|
329
331
|
When unable to get ``self.birthday``
|
|
330
332
|
"""
|
|
331
333
|
try:
|
|
332
334
|
return zodiac_sign(self.birthday.day, self.birthday.month, zodiac13=True)
|
|
333
|
-
except:
|
|
335
|
+
except Exception:
|
|
334
336
|
return None
|
|
335
|
-
|
|
337
|
+
|
|
336
338
|
@property
|
|
337
339
|
def numerology(self) -> int:
|
|
338
340
|
"""
|
|
@@ -342,18 +344,12 @@ class Person(Human):
|
|
|
342
344
|
-------
|
|
343
345
|
int
|
|
344
346
|
Numerology number
|
|
345
|
-
|
|
346
|
-
None
|
|
347
|
-
When unable to get ``self.birthday``
|
|
348
347
|
"""
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
return IntNumber(temp).add_to_one_digit(master_number=True)
|
|
352
|
-
except:
|
|
353
|
-
return None
|
|
348
|
+
temp = f"{self.birthday.year}{self.birthday.month}{self.birthday.day}"
|
|
349
|
+
return IntNumber(temp).add_to_one_digit(master_number=True)
|
|
354
350
|
|
|
355
351
|
|
|
356
352
|
# Run
|
|
357
353
|
###########################################################################
|
|
358
354
|
if __name__ == "__main__":
|
|
359
|
-
print(Person.JohnDoe().__dict__)
|
|
355
|
+
print(Person.JohnDoe().__dict__)
|