absfuyu 3.3.3__py3-none-any.whl → 4.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of absfuyu might be problematic. Click here for more details.

absfuyu/game/tictactoe.py CHANGED
@@ -2,8 +2,8 @@
2
2
  Game: Tic Tac Toe
3
3
  -----------------
4
4
 
5
- Version: 2.0.3
6
- Date updated: 05/04/2024 (mm/dd/yyyy)
5
+ Version: 2.0.4
6
+ Date updated: 15/11/2024 (dd/mm/yyyy)
7
7
  """
8
8
 
9
9
  __all__ = ["TicTacToe", "GameMode"]
@@ -11,11 +11,11 @@ __all__ = ["TicTacToe", "GameMode"]
11
11
 
12
12
  import random
13
13
  import time
14
- from typing import List, Literal, NamedTuple
14
+ from typing import Literal, NamedTuple
15
15
 
16
16
  from absfuyu.core import CLITextColor
17
17
 
18
- BoardGame = List[List[str]]
18
+ BoardGame = list[list[str]]
19
19
 
20
20
 
21
21
  class Pos(NamedTuple):
@@ -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.14.3
7
- Date updated: 05/04/2024 (dd/mm/yyyy)
6
+ Version: 1.15.2
7
+ Date updated: 06/01/2025 (dd/mm/yyyy)
8
8
 
9
9
  Features:
10
10
  ---------
@@ -47,23 +47,7 @@ import operator
47
47
  import random
48
48
  from collections import Counter
49
49
  from itertools import accumulate, chain, groupby
50
- from sys import version_info as _python_version
51
- from typing import (
52
- Any,
53
- Callable,
54
- Dict,
55
- List,
56
- NamedTuple,
57
- Optional,
58
- Tuple,
59
- TypedDict,
60
- Union,
61
- )
62
-
63
- if _python_version.minor >= 11:
64
- from typing import NotRequired
65
- else:
66
- from typing_extensions import NotRequired # type: ignore
50
+ from typing import Any, Callable, NamedTuple, NotRequired, Self, TypedDict, Union
67
51
 
68
52
  from deprecated.sphinx import versionadded, versionchanged
69
53
 
@@ -74,7 +58,7 @@ from absfuyu.util import set_min, set_min_max
74
58
 
75
59
  # Function
76
60
  ###########################################################################
77
- def _dict_bool(dict_object: dict, option: bool) -> Optional[dict]:
61
+ def _dict_bool(dict_object: dict, option: bool) -> dict | None:
78
62
  """
79
63
  Support function DictBool class
80
64
  """
@@ -93,7 +77,7 @@ def _dict_bool(dict_object: dict, option: bool) -> Optional[dict]:
93
77
  class Pow:
94
78
  """Number power by a number"""
95
79
 
96
- def __init__(self, number: Union[int, float], power_by: Union[int, float]) -> None:
80
+ def __init__(self, number: int | float, power_by: int | float) -> None:
97
81
  self.number = number
98
82
  self.power_by = power_by
99
83
 
@@ -107,7 +91,7 @@ class Pow:
107
91
  def __repr__(self) -> str:
108
92
  return self.__str__()
109
93
 
110
- def to_list(self) -> List[Union[int, float]]:
94
+ def to_list(self) -> list[int | float]:
111
95
  """
112
96
  Convert into list
113
97
 
@@ -132,7 +116,7 @@ class ListREPR(list):
132
116
  return _compress_list_for_print(self, 9)
133
117
 
134
118
 
135
- class ListNoDunder(List[str]):
119
+ class ListNoDunder(list[str]):
136
120
  """Use with ``object.__dir__()``"""
137
121
 
138
122
  def __repr__(self) -> str:
@@ -140,7 +124,7 @@ class ListNoDunder(List[str]):
140
124
  return out.__repr__()
141
125
 
142
126
 
143
- class DictBoolTrue(Dict[Any, bool]):
127
+ class DictBoolTrue(dict[Any, bool]):
144
128
  """Only show items when ``values == True`` in ``__repr__()``"""
145
129
 
146
130
  def __repr__(self) -> str:
@@ -148,7 +132,7 @@ class DictBoolTrue(Dict[Any, bool]):
148
132
  return _dict_bool(temp, True).__repr__()
149
133
 
150
134
 
151
- class DictBoolFalse(Dict[Any, bool]):
135
+ class DictBoolFalse(dict[Any, bool]):
152
136
  """Only show items when ``values == False`` in ``__repr__()``"""
153
137
 
154
138
  def __repr__(self) -> str:
@@ -206,8 +190,8 @@ class DictAnalyzeResult(NamedTuple):
206
190
  Result for ``DictExt.analyze()``
207
191
  """
208
192
 
209
- max_value: Union[int, float]
210
- min_value: Union[int, float]
193
+ max_value: int | float
194
+ min_value: int | float
211
195
  max_list: list
212
196
  min_list: list
213
197
 
@@ -220,7 +204,7 @@ class Text(str):
220
204
  ``str`` extension
221
205
  """
222
206
 
223
- def divide(self, string_split_size: int = 60) -> List[str]:
207
+ def divide(self, string_split_size: int = 60) -> list[str]:
224
208
  """
225
209
  Divide long string into smaller size
226
210
 
@@ -255,8 +239,8 @@ class Text(str):
255
239
  self,
256
240
  split_size: int = 60,
257
241
  split_var_len: int = 12,
258
- custom_var_name: Optional[str] = None,
259
- ) -> list:
242
+ custom_var_name: str | None = None,
243
+ ) -> list[str]:
260
244
  """
261
245
  Divide long string into smaller size,
262
246
  then assign a random variable to splited
@@ -277,7 +261,7 @@ class Text(str):
277
261
 
278
262
  Returns
279
263
  -------
280
- list
264
+ list[str]
281
265
  A list in which each item is a smaller
282
266
  string with the size of ``split_size``
283
267
  and a way to concaternate them (when using ``print()``)
@@ -398,7 +382,7 @@ class Text(str):
398
382
 
399
383
  return detail
400
384
 
401
- def reverse(self) -> "Text":
385
+ def reverse(self) -> Self:
402
386
  """
403
387
  Reverse the string
404
388
 
@@ -489,7 +473,7 @@ class Text(str):
489
473
  else:
490
474
  return hex_str
491
475
 
492
- def random_capslock(self, probability: int = 50) -> "Text":
476
+ def random_capslock(self, probability: int = 50) -> Self:
493
477
  """
494
478
  Randomly capslock letter in string
495
479
 
@@ -522,7 +506,7 @@ class Text(str):
522
506
  logger.debug(temp)
523
507
  return self.__class__("".join(temp))
524
508
 
525
- def reverse_capslock(self) -> "Text":
509
+ def reverse_capslock(self) -> Self:
526
510
  """
527
511
  Reverse capslock in string
528
512
 
@@ -546,7 +530,7 @@ class Text(str):
546
530
  temp[i] = x.upper()
547
531
  return self.__class__("".join(temp))
548
532
 
549
- def to_list(self) -> List[str]:
533
+ def to_list(self) -> list[str]:
550
534
  """
551
535
  Convert into list
552
536
 
@@ -625,7 +609,7 @@ class Text(str):
625
609
  return sum(out)
626
610
 
627
611
  @versionadded(version="3.3.0")
628
- def hapax(self, strict: bool = False) -> List[str]:
612
+ def hapax(self, strict: bool = False) -> list[str]:
629
613
  """
630
614
  A hapax legomenon (often abbreviated to hapax)
631
615
  is a word which occurs only once in either
@@ -656,9 +640,9 @@ class Text(str):
656
640
  >>> test.hapax(strict=True)
657
641
  ['b']
658
642
  """
659
- word_list: List[str] = self.lower().split()
643
+ word_list: list[str] = self.lower().split()
660
644
  if strict:
661
- remove_characters: List[str] = list(r"\"'.,:;|()[]{}\/!@#$%^&*-_=+?<>`~")
645
+ remove_characters: list[str] = list(r"\"'.,:;|()[]{}\/!@#$%^&*-_=+?<>`~")
662
646
  temp = str(self)
663
647
  for x in remove_characters:
664
648
  temp = temp.replace(x, "")
@@ -845,7 +829,7 @@ class IntNumber(int):
845
829
 
846
830
  else:
847
831
  # Faster way to check
848
- perfect_number_index: List[int] = [
832
+ perfect_number_index: list[int] = [
849
833
  61,
850
834
  89,
851
835
  107,
@@ -934,7 +918,7 @@ class IntNumber(int):
934
918
  except Exception:
935
919
  return False
936
920
 
937
- def reverse(self) -> "IntNumber":
921
+ def reverse(self) -> Self:
938
922
  """
939
923
  Reverse a number. Reverse ``abs(number)`` if ``number < 0``
940
924
 
@@ -982,8 +966,8 @@ class IntNumber(int):
982
966
  return self.is_palindromic() and self.is_prime()
983
967
 
984
968
  # calculation stuff
985
- @versionchanged(version="3.3.0", reason="Fix bug")
986
- def lcm(self, with_number: int) -> "IntNumber":
969
+ @versionchanged(version="4.0.0", reason="Update")
970
+ def lcm(self, with_number: int) -> Self:
987
971
  """
988
972
  Least common multiple of ``self`` and ``with_number``
989
973
 
@@ -1004,13 +988,10 @@ class IntNumber(int):
1004
988
  >>> test.lcm(5)
1005
989
  510
1006
990
  """
1007
- try:
1008
- return self.__class__(math.lcm(self, with_number))
1009
- except AttributeError: # Python < 3.9
1010
- return self.__class__((self * with_number) // math.gcd(self, with_number))
991
+ return self.__class__(math.lcm(self, with_number))
1011
992
 
1012
993
  @versionchanged(version="3.3.0", reason="Fix bug")
1013
- def gcd(self, with_number: int) -> "IntNumber":
994
+ def gcd(self, with_number: int) -> Self:
1014
995
  """
1015
996
  Greatest common divisor of ``self`` and ``with_number``
1016
997
 
@@ -1033,7 +1014,7 @@ class IntNumber(int):
1033
1014
  """
1034
1015
  return self.__class__(math.gcd(self, with_number))
1035
1016
 
1036
- def add_to_one_digit(self, master_number: bool = False) -> "IntNumber":
1017
+ def add_to_one_digit(self, master_number: bool = False) -> Self:
1037
1018
  """
1038
1019
  Convert ``self`` into 1-digit number
1039
1020
  by adding all of the digits together
@@ -1072,7 +1053,7 @@ class IntNumber(int):
1072
1053
  logger.debug(f"Sum after loop: {number}")
1073
1054
  return self.__class__(number)
1074
1055
 
1075
- def divisible_list(self, short_form: bool = True) -> List[int]:
1056
+ def divisible_list(self, short_form: bool = True) -> list[int]:
1076
1057
  """
1077
1058
  A list of divisible number
1078
1059
 
@@ -1106,7 +1087,7 @@ class IntNumber(int):
1106
1087
  # return ListREPR(divi_list) ## FIX LATER
1107
1088
  return divi_list
1108
1089
 
1109
- def prime_factor(self, short_form: bool = True) -> Union[List[int], List[Pow]]:
1090
+ def prime_factor(self, short_form: bool = True) -> Union[list[int], list[Pow]]:
1110
1091
  """
1111
1092
  Prime factor
1112
1093
 
@@ -1156,7 +1137,7 @@ class IntNumber(int):
1156
1137
  return factors
1157
1138
 
1158
1139
  # analyze
1159
- def analyze(self, short_form: bool = True) -> Dict[str, Dict[str, Any]]:
1140
+ def analyze(self, short_form: bool = True) -> dict[str, dict[str, Any]]:
1160
1141
  """
1161
1142
  Analyze the number with almost all ``IntNumber`` method
1162
1143
 
@@ -1220,7 +1201,7 @@ class ListExt(list):
1220
1201
  ``list`` extension
1221
1202
  """
1222
1203
 
1223
- def stringify(self) -> "ListExt":
1204
+ def stringify(self) -> Self:
1224
1205
  """
1225
1206
  Convert all item in ``list`` into string
1226
1207
 
@@ -1236,7 +1217,7 @@ class ListExt(list):
1236
1217
  >>> test.stringify()
1237
1218
  ['1', '1', '1', '2', '2', '3']
1238
1219
  """
1239
- return ListExt(map(str, self))
1220
+ return self.__class__(map(str, self))
1240
1221
 
1241
1222
  def head(self, number_of_items: int = 5) -> list:
1242
1223
  """
@@ -1278,7 +1259,7 @@ class ListExt(list):
1278
1259
  )
1279
1260
  return self[::-1][:number_of_items][::-1]
1280
1261
 
1281
- def sorts(self, reverse: bool = False) -> "ListExt":
1262
+ def sorts(self, reverse: bool = False) -> Self:
1282
1263
  """
1283
1264
  Sort all items (with different type) in ``list``
1284
1265
 
@@ -1318,9 +1299,9 @@ class ListExt(list):
1318
1299
  def freq(
1319
1300
  self,
1320
1301
  sort: bool = False,
1321
- num_of_first_char: Optional[int] = None,
1302
+ num_of_first_char: int | None = None,
1322
1303
  appear_increment: bool = False,
1323
- ) -> Union[dict, List[int]]:
1304
+ ) -> Union[dict, list[int]]:
1324
1305
  """
1325
1306
  Find frequency of each item in list
1326
1307
 
@@ -1383,7 +1364,7 @@ class ListExt(list):
1383
1364
  logger.debug(times_appear)
1384
1365
 
1385
1366
  if appear_increment:
1386
- times_appear_increment: List[int] = list(
1367
+ times_appear_increment: list[int] = list(
1387
1368
  accumulate(times_appear.values(), operator.add)
1388
1369
  )
1389
1370
  logger.debug(times_appear_increment)
@@ -1391,7 +1372,7 @@ class ListExt(list):
1391
1372
  else:
1392
1373
  return times_appear
1393
1374
 
1394
- def slice_points(self, points: list) -> List[list]:
1375
+ def slice_points(self, points: list) -> list[list]:
1395
1376
  """
1396
1377
  Slices a list at specific indices into constituent lists.
1397
1378
 
@@ -1458,7 +1439,7 @@ class ListExt(list):
1458
1439
  """
1459
1440
  return [self.pick_one() for _ in range(number_of_items)]
1460
1441
 
1461
- def len_items(self) -> "ListExt":
1442
+ def len_items(self) -> Self:
1462
1443
  """
1463
1444
  ``len()`` for every item in ``list[str]``
1464
1445
 
@@ -1474,7 +1455,7 @@ class ListExt(list):
1474
1455
  >>> test.len_items()
1475
1456
  [3, 3, 5]
1476
1457
  """
1477
- out = ListExt([len(str(x)) for x in self])
1458
+ out = self.__class__([len(str(x)) for x in self])
1478
1459
  # out = ListExt(map(lambda x: len(str(x)), self))
1479
1460
  logger.debug(out)
1480
1461
  return out
@@ -1499,7 +1480,7 @@ class ListExt(list):
1499
1480
  logger.debug(out)
1500
1481
  return out
1501
1482
 
1502
- def apply(self, func: Callable) -> "ListExt":
1483
+ def apply(self, func: Callable) -> Self:
1503
1484
  """
1504
1485
  Apply function to each entry
1505
1486
 
@@ -1523,7 +1504,7 @@ class ListExt(list):
1523
1504
  # return __class__(func(x) for x in self)
1524
1505
  return self.__class__(map(func, self))
1525
1506
 
1526
- def unique(self) -> "ListExt":
1507
+ def unique(self) -> Self:
1527
1508
  """
1528
1509
  Remove duplicates
1529
1510
 
@@ -1541,7 +1522,7 @@ class ListExt(list):
1541
1522
  """
1542
1523
  return self.__class__(set(self))
1543
1524
 
1544
- def group_by_unique(self) -> "ListExt":
1525
+ def group_by_unique(self) -> Self:
1545
1526
  """
1546
1527
  Group duplicated elements into list
1547
1528
 
@@ -1566,13 +1547,13 @@ class ListExt(list):
1566
1547
  return self.__class__([list(g) for _, g in temp])
1567
1548
 
1568
1549
  @staticmethod
1569
- def _group_by_unique(iterable: list) -> List[list]:
1550
+ def _group_by_unique(iterable: list) -> list[list]:
1570
1551
  """
1571
1552
  Static method for ``group_by_unique``
1572
1553
  """
1573
1554
  return list([list(g) for _, g in groupby(iterable)])
1574
1555
 
1575
- def group_by_pair_value(self, max_loop: int = 3) -> List[list]:
1556
+ def group_by_pair_value(self, max_loop: int = 3) -> list[list]:
1576
1557
  """
1577
1558
  Assume each ``list`` in ``list`` is a pair value,
1578
1559
  returns a ``list`` contain all paired value
@@ -1607,7 +1588,7 @@ class ListExt(list):
1607
1588
 
1608
1589
  # Init loop
1609
1590
  for _ in range(int(set_min(max_loop, min_value=3))):
1610
- temp: Dict[Any, list] = {}
1591
+ temp: dict[Any, list] = {}
1611
1592
  # Make dict{key: all `item` that contains `key`}
1612
1593
  for item in iter:
1613
1594
  for x in item:
@@ -1624,7 +1605,7 @@ class ListExt(list):
1624
1605
 
1625
1606
  return list(x for x, _ in groupby(iter))
1626
1607
 
1627
- def flatten(self) -> "ListExt":
1608
+ def flatten(self) -> Self:
1628
1609
  """
1629
1610
  Flatten the list
1630
1611
 
@@ -1641,12 +1622,12 @@ class ListExt(list):
1641
1622
  ['test', 'test', 'test', 'test']
1642
1623
  """
1643
1624
  try:
1644
- return ListExt(chain(*self))
1625
+ return self.__class__(chain(*self))
1645
1626
  except Exception:
1646
1627
  temp = list(map(lambda x: x if isinstance(x, list) else [x], self))
1647
- return ListExt(chain(*temp))
1628
+ return self.__class__(chain(*temp))
1648
1629
 
1649
- def numbering(self, start: int = 0) -> "ListExt":
1630
+ def numbering(self, start: int = 0) -> Self:
1650
1631
  """
1651
1632
  Number the item in list
1652
1633
  (``enumerate`` wrapper)
@@ -1670,10 +1651,10 @@ class ListExt(list):
1670
1651
  [(0, 9), (1, 9), (2, 9)]
1671
1652
  """
1672
1653
  start = int(set_min(start, min_value=0))
1673
- return ListExt(enumerate(self, start=start))
1654
+ return self.__class__(enumerate(self, start=start))
1674
1655
 
1675
1656
  @staticmethod
1676
- def _numbering(iterable: list, start: int = 0) -> List[Tuple[int, Any]]:
1657
+ def _numbering(iterable: list, start: int = 0) -> list[tuple[int, Any]]:
1677
1658
  """
1678
1659
  Static method for ``numbering``
1679
1660
  """
@@ -1717,8 +1698,8 @@ class DictExt(dict):
1717
1698
  try:
1718
1699
  dct: dict = self.copy()
1719
1700
 
1720
- max_val: Union[int, float] = max(list(dct.values()))
1721
- min_val: Union[int, float] = min(list(dct.values()))
1701
+ max_val: int | float = max(list(dct.values()))
1702
+ min_val: int | float = min(list(dct.values()))
1722
1703
  max_list = []
1723
1704
  min_list = []
1724
1705
 
@@ -1744,7 +1725,7 @@ class DictExt(dict):
1744
1725
  logger.error(err_msg)
1745
1726
  raise ValueError(err_msg) # noqa: B904
1746
1727
 
1747
- def swap_items(self) -> "DictExt":
1728
+ def swap_items(self) -> Self:
1748
1729
  """
1749
1730
  Swap ``dict.keys()`` with ``dict.values()``
1750
1731
 
@@ -1762,7 +1743,7 @@ class DictExt(dict):
1762
1743
  """
1763
1744
  return self.__class__(zip(self.values(), self.keys()))
1764
1745
 
1765
- def apply(self, func: Callable, apply_to_value: bool = True) -> "DictExt":
1746
+ def apply(self, func: Callable, apply_to_value: bool = True) -> Self:
1766
1747
  """
1767
1748
  Apply function to ``DictExt.keys()`` or ``DictExt.values()``
1768
1749
 
@@ -1795,6 +1776,19 @@ class DictExt(dict):
1795
1776
  v = self.values() # type: ignore
1796
1777
  return self.__class__(zip(k, v))
1797
1778
 
1779
+ @versionadded(version="3.4.0")
1780
+ def aggregate(
1781
+ self,
1782
+ other_dict: dict[Any, int | float],
1783
+ default_value: int | float = 0,
1784
+ ) -> Self:
1785
+ """Dict with value type int or float"""
1786
+ out = {
1787
+ k: self.get(k, default_value) + other_dict.get(k, default_value)
1788
+ for k in set(self | other_dict)
1789
+ }
1790
+ return self.__class__(out)
1791
+
1798
1792
 
1799
1793
  # Run
1800
1794
  ###########################################################################
absfuyu/general/human.py CHANGED
@@ -3,8 +3,8 @@ Absfuyu: Human
3
3
  --------------
4
4
  Human related stuff
5
5
 
6
- Version: 1.3.1
7
- Date updated: 05/04/2024 (dd/mm/yyyy)
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
@@ -3,8 +3,8 @@ Absfuyu: Package data
3
3
  ---------------------
4
4
  Load package data
5
5
 
6
- Version: 2.2.2
7
- Date updated: 30/11/2023 (dd/mm/yyyy)
6
+ Version: 2.2.3
7
+ Date updated: 14/11/2024 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module level
@@ -16,18 +16,8 @@ __all__ = ["PkgData"]
16
16
  ###########################################################################
17
17
  import zlib
18
18
  from ast import literal_eval
19
- from importlib.resources import read_binary
19
+ from importlib.resources import files, read_binary
20
20
  from pathlib import Path
21
- from sys import version_info as _python_version
22
- from typing import List, Union
23
-
24
- if _python_version.minor >= 10:
25
- from importlib.resources import files
26
- else:
27
- try:
28
- from importlib_resources import files # type: ignore
29
- except Exception:
30
- raise ImportError("Please install importlib-resources") # noqa: B904
31
21
 
32
22
  from absfuyu.core import DATA_PATH
33
23
  from absfuyu.logger import logger
@@ -61,7 +51,7 @@ class PkgData:
61
51
  def __repr__(self) -> str:
62
52
  return self.__str__()
63
53
 
64
- def _make_dat(self, data: str, name: Union[str, Path]):
54
+ def _make_dat(self, data: str, name: str | Path):
65
55
  """
66
56
  data: string data
67
57
  name: name and location of the data
@@ -90,14 +80,14 @@ class PkgData:
90
80
 
91
81
  :param new_data: Data to be updated
92
82
  """
93
- self._make_dat(data=new_data, name=DATA_PATH.joinpath(self.name))
83
+ self._make_dat(data=new_data, name=DATA_PATH.joinpath(self.name)) # type:ignore
94
84
  logger.debug("Data updated")
95
85
 
96
86
 
97
87
  class _ManagePkgData:
98
88
  """Manage this package data"""
99
89
 
100
- def __init__(self, pkg_data_loc: Union[str, Path]) -> None:
90
+ def __init__(self, pkg_data_loc: str | Path) -> None:
101
91
  """
102
92
  pkg_data_loc: Package data location
103
93
  """
@@ -109,7 +99,7 @@ class _ManagePkgData:
109
99
  def __repr__(self) -> str:
110
100
  return self.__str__()
111
101
 
112
- def get_data_list(self, *, pattern: str = "*") -> List[Path]:
102
+ def get_data_list(self, *, pattern: str = "*") -> list[Path]:
113
103
  """Get a list of data available"""
114
104
  excludes = [
115
105
  x for x in self.data_loc.glob("*.[pP][yY]")
@@ -119,7 +109,7 @@ class _ManagePkgData:
119
109
  ]
120
110
 
121
111
  @property
122
- def data_list(self) -> List[str]:
112
+ def data_list(self) -> list[str]:
123
113
  """List of available data"""
124
114
  return [x.name for x in self.get_data_list()]
125
115
 
@@ -135,7 +125,10 @@ class _ManagePkgData:
135
125
  for data_name, data_link in _EXTERNAL_DATA.items():
136
126
  logger.debug(f"Downloading {data_name}...")
137
127
  data = APIRequest(data_link, encoding="utf-8")
138
- data.fetch_data(update=True, json_cache=DATA_PATH.joinpath(data_name))
128
+ data.fetch_data(
129
+ update=True,
130
+ json_cache=DATA_PATH.joinpath(data_name), # type:ignore
131
+ )
139
132
  logger.debug(f"Downloading {data_name}...DONE")
140
133
  logger.debug("Downloading data...DONE")
141
134
  except Exception:
@@ -147,7 +140,7 @@ class _ManagePkgData:
147
140
  x.unlink()
148
141
 
149
142
 
150
- PACKAGE_DATA = _ManagePkgData(DATA_PATH)
143
+ PACKAGE_DATA = _ManagePkgData(DATA_PATH) # type:ignore
151
144
 
152
145
 
153
146
  # Run