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/__init__.py CHANGED
@@ -22,7 +22,7 @@ Using in cmd (`absfuyu[cli]` required):
22
22
  __title__ = "absfuyu"
23
23
  __author__ = "AbsoluteWinter"
24
24
  __license__ = "MIT License"
25
- __version__ = "3.3.3"
25
+ __version__ = "4.0.0"
26
26
  __all__ = [
27
27
  "core",
28
28
  "config",
absfuyu/cli/__init__.py CHANGED
@@ -26,7 +26,7 @@ colorama.init(autoreset=True)
26
26
 
27
27
  @click.command()
28
28
  def version() -> None:
29
- """Check current version"""
29
+ """Show current version"""
30
30
  ver_msg = f"{__title__} v{__version__}"
31
31
  click.echo(
32
32
  f"{COLOR['green']}{ver_msg}{COLOR['reset']}\n"
absfuyu/cli/do_group.py CHANGED
@@ -3,8 +3,8 @@ ABSFUYU CLI
3
3
  -----------
4
4
  Do
5
5
 
6
- Version: 1.0.0
7
- Date updated: 14/04/2024 (dd/mm/yyyy)
6
+ Version: 1.2.0
7
+ Date updated: 07/01/2025 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  __all__ = ["do_group"]
@@ -16,6 +16,8 @@ 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
20
+ from absfuyu.util.zipped import Zipper
19
21
  from absfuyu.version import PkgVersion
20
22
 
21
23
 
@@ -65,6 +67,35 @@ def advice() -> None:
65
67
  click.echo(f"{COLOR['green']}{im_bored()}")
66
68
 
67
69
 
70
+ @click.command(name="fs")
71
+ @click.argument("date", type=str)
72
+ @click.argument("number_string", type=str)
73
+ def fs(date: str, number_string: str) -> None:
74
+ """Feng-shui W.I.P"""
75
+
76
+ instance = Human2(date)
77
+ print(instance.fs(number_string))
78
+
79
+
80
+ @click.command(name="info")
81
+ @click.argument("date", type=str)
82
+ def info(date: str) -> None:
83
+ """Day info"""
84
+
85
+ instance = Human2(date)
86
+ print(instance.info())
87
+
88
+
89
+ @click.command(name="unzip")
90
+ @click.argument("dir", type=str)
91
+ def unzip_files_in_dir(dir: str) -> None:
92
+ """Unzip every files in directory"""
93
+
94
+ engine = Zipper(dir)
95
+ engine.unzip()
96
+ print("Done")
97
+
98
+
68
99
  @click.group(name="do")
69
100
  def do_group() -> None:
70
101
  """Perform functionalities"""
@@ -74,3 +105,6 @@ def do_group() -> None:
74
105
  do_group.add_command(update)
75
106
  do_group.add_command(install)
76
107
  do_group.add_command(advice)
108
+ do_group.add_command(fs)
109
+ do_group.add_command(info)
110
+ do_group.add_command(unzip_files_in_dir)
@@ -3,8 +3,8 @@ Absfuyu: Configuration
3
3
  ----------------------
4
4
  Package configuration module
5
5
 
6
- Version: 2.0.4
7
- Date updated: 06/04/2024 (dd/mm/yyyy)
6
+ Version: 2.0.5
7
+ Date updated: 14/11/2024 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module level
@@ -19,7 +19,7 @@ __all__ = [
19
19
  # Library
20
20
  ###########################################################################
21
21
  from pathlib import Path
22
- from typing import Any, Dict, List, Optional, TypedDict
22
+ from typing import Any, TypedDict
23
23
 
24
24
  from absfuyu.core import CONFIG_PATH
25
25
  from absfuyu.util.json_method import JsonFile
@@ -55,7 +55,7 @@ class ConfigFormat(TypedDict):
55
55
  :type version: VersionDictFormat
56
56
  """
57
57
 
58
- setting: Dict[str, SettingDictFormat]
58
+ setting: dict[str, SettingDictFormat]
59
59
 
60
60
 
61
61
  # Class
@@ -82,7 +82,7 @@ class Setting:
82
82
  return self.__str__()
83
83
 
84
84
  @classmethod
85
- def from_dict(cls, dict_data: Dict[str, SettingDictFormat]):
85
+ def from_dict(cls, dict_data: dict[str, SettingDictFormat]):
86
86
  """
87
87
  Convert ``dict`` into ``Setting`` (``len==1`` only)
88
88
  """
@@ -104,11 +104,11 @@ class Setting:
104
104
  """Update current value"""
105
105
  self.value = value
106
106
 
107
- def to_dict(self) -> Dict[str, SettingDictFormat]:
107
+ def to_dict(self) -> dict[str, SettingDictFormat]:
108
108
  """
109
109
  Convert ``Setting`` into ``dict``
110
110
  """
111
- output: Dict[str, SettingDictFormat] = {
111
+ output: dict[str, SettingDictFormat] = {
112
112
  self.name: {"default": self.default, "help": self.help, "value": self.value}
113
113
  }
114
114
  return output
@@ -119,7 +119,7 @@ class Config:
119
119
  Config handling
120
120
  """
121
121
 
122
- def __init__(self, config_file: Path, name: Optional[str] = None) -> None:
122
+ def __init__(self, config_file: Path, name: str | None = None) -> None:
123
123
  """
124
124
  config_file: Path to `.json` config file
125
125
  """
@@ -132,7 +132,7 @@ class Config:
132
132
  self.name = self.config_path.name
133
133
 
134
134
  # Data
135
- self.settings: List[Setting] = None # type: ignore
135
+ self.settings: list[Setting] = None # type: ignore
136
136
  self._fetch_data() # Load data
137
137
 
138
138
  def __str__(self) -> str:
@@ -145,7 +145,7 @@ class Config:
145
145
  def _fetch_data(self) -> None:
146
146
  """Load data from ``self.config_file`` file"""
147
147
  data: dict = self.json_engine.load_json()
148
- settings: Dict[str, SettingDictFormat] = data.get("setting") # type: ignore
148
+ settings: dict[str, SettingDictFormat] = data.get("setting") # type: ignore
149
149
  self.settings = [Setting.from_dict({k: v}) for k, v in settings.items()]
150
150
 
151
151
  def _prepare_data(self) -> ConfigFormat:
@@ -164,7 +164,7 @@ class Config:
164
164
 
165
165
  # Setting method
166
166
  @property
167
- def setting_list(self) -> List[str]:
167
+ def setting_list(self) -> list[str]:
168
168
  """List of name of available settings"""
169
169
  return [setting.name for setting in self.settings]
170
170
 
@@ -183,7 +183,7 @@ class Config:
183
183
  [setting.reset() for setting in self.settings] # type: ignore
184
184
  self.save()
185
185
 
186
- def show_settings(self) -> List[Setting]:
186
+ def show_settings(self) -> list[Setting]:
187
187
  """
188
188
  Returns a list of available settings
189
189
  (wrapper for ``Config.settings``)
@@ -276,7 +276,7 @@ class Config:
276
276
 
277
277
  # Init
278
278
  ###########################################################################
279
- ABSFUYU_CONFIG = Config(CONFIG_PATH)
279
+ ABSFUYU_CONFIG = Config(CONFIG_PATH) # type: ignore
280
280
 
281
281
  # TODO: Create a config file when not available [W.I.P]
282
282
  # _settings = [
absfuyu/core.py CHANGED
@@ -3,8 +3,8 @@ Absfuyu: Core
3
3
  -------------
4
4
  Contain type hints and other stuffs
5
5
 
6
- Version: 2.2.0
7
- Date updated: 14/04/2024 (dd/mm/yyyy)
6
+ Version: 2.2.1
7
+ Date updated: 14/11/2024 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module Package
@@ -21,18 +21,7 @@ __all__ = [
21
21
  __package_feature__ = ["beautiful", "extra", "res", "full", "dev"]
22
22
 
23
23
 
24
- from pathlib import Path
25
-
26
- # import sys
27
- # from sys import version_info as _python_version
28
-
29
- # if sys.version_info.minor >= 10:
30
- # from importlib.resources import files
31
- # else:
32
- # try:
33
- # from importlib_resources import files
34
- # except:
35
- # raise ImportError("Please install importlib-resources")
24
+ from importlib.resources import files
36
25
 
37
26
 
38
27
  class CLITextColor:
@@ -50,7 +39,7 @@ class CLITextColor:
50
39
  RESET = "\x1b[39m"
51
40
 
52
41
 
53
- CORE_PATH = Path(__file__).parent.absolute()
54
- # CORE_PATH = files("absfuyu")
42
+ # CORE_PATH = Path(__file__).parent.absolute()
43
+ CORE_PATH = files("absfuyu")
55
44
  CONFIG_PATH = CORE_PATH.joinpath("config", "config.json")
56
45
  DATA_PATH = CORE_PATH.joinpath("pkg_data")
@@ -3,8 +3,8 @@ Absfuyu: Data Analysis [W.I.P]
3
3
  ------------------------------
4
4
  Extension for ``pd.DataFrame``
5
5
 
6
- Version: 2.1.3
7
- Date updated: 20/03/2024 (dd/mm/yyyy)
6
+ Version: 2.2.0
7
+ Date updated: 29/11/2024 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Module level
@@ -30,7 +30,7 @@ import string
30
30
  from collections import deque
31
31
  from datetime import datetime
32
32
  from itertools import chain, product
33
- from typing import Any, Dict, List, NamedTuple, Optional, Union
33
+ from typing import Any, Literal, NamedTuple, Self
34
34
 
35
35
  # import matplotlib.pyplot as plt
36
36
  # from scipy import stats
@@ -49,7 +49,7 @@ from absfuyu.util import set_min, set_min_max
49
49
  ###########################################################################
50
50
  @deprecated(reason="Not needed", version="3.1.0")
51
51
  @sphinx_deprecated(reason="Not needed", version="3.1.0")
52
- def summary(data: Union[list, np.ndarray]): # del this
52
+ def summary(data: list | np.ndarray): # del this
53
53
  """
54
54
  Quick summary of data
55
55
 
@@ -78,7 +78,7 @@ def summary(data: Union[list, np.ndarray]): # del this
78
78
  return output
79
79
 
80
80
 
81
- def equalize_df(data: Dict[str, list], fillna=np.nan) -> Dict[str, list]:
81
+ def equalize_df(data: dict[str, list], fillna=np.nan) -> dict[str, list]:
82
82
  """
83
83
  Make all list in dict have equal length to make pd.DataFrame
84
84
 
@@ -182,14 +182,14 @@ class CityData(NamedTuple):
182
182
  area: str
183
183
 
184
184
  @staticmethod
185
- def _sample_city_data(size: int = 100) -> List["CityData"]:
185
+ def _sample_city_data(size: int = 100) -> list["CityData"]:
186
186
  """
187
187
  Generate sample city data (testing purpose)
188
188
  """
189
189
  sample_range = 10 ** len(str(size))
190
190
 
191
191
  # Serial list
192
- serials: List[str] = []
192
+ serials: list[str] = []
193
193
  while len(serials) != size: # Unique serial
194
194
  serial = random.randint(0, sample_range - 1)
195
195
  serial = str(serial).rjust(len(str(size)), "0") # type: ignore
@@ -232,7 +232,9 @@ class SplittedDF(NamedTuple):
232
232
  df_na: pd.DataFrame
233
233
 
234
234
  @staticmethod
235
- def concat_df(df_list: List[pd.DataFrame], join: str = "inner"):
235
+ def concat_df(
236
+ df_list: list[pd.DataFrame], join: Literal["inner", "outer"] = "inner"
237
+ ) -> pd.DataFrame:
236
238
  """
237
239
  Concat the list of DataFrame (static method)
238
240
 
@@ -254,7 +256,7 @@ class SplittedDF(NamedTuple):
254
256
  df.drop(columns=["index"], inplace=True)
255
257
  return df
256
258
 
257
- def concat(self, join: str = "inner"):
259
+ def concat(self, join: Literal["inner", "outer"] = "inner") -> pd.DataFrame:
258
260
  """
259
261
  Concat the splitted DataFrame
260
262
 
@@ -272,7 +274,7 @@ class SplittedDF(NamedTuple):
272
274
  return self.concat_df(self, join=join) # type: ignore
273
275
 
274
276
  @staticmethod
275
- def divide_dataframe(df: pd.DataFrame, by_column: str) -> List[pd.DataFrame]:
277
+ def divide_dataframe(df: pd.DataFrame, by_column: str) -> list[pd.DataFrame]:
276
278
  """
277
279
  Divide DataFrame into a list of DataFrame
278
280
 
@@ -400,7 +402,7 @@ class MatplotlibFormatString:
400
402
  Color = _DictToAtrr(COLOR_LIST, key_as_atrribute=False)
401
403
 
402
404
  @staticmethod
403
- def all_format_string() -> List[PLTFormatString]:
405
+ def all_format_string() -> list[PLTFormatString]:
404
406
  fmt_str = [
405
407
  __class__.MARKER_LIST, # type: ignore
406
408
  __class__.LINE_STYLE_LIST, # type: ignore
@@ -427,7 +429,7 @@ class DataAnalystDataFrame(pd.DataFrame):
427
429
  # Support
428
430
  # ================================================================
429
431
  # Rearrange column
430
- def rearrange_column(self, insert_to_col: str, num_of_cols: int = 1):
432
+ def rearrange_column(self, insert_to_col: str, num_of_cols: int = 1) -> Self:
431
433
  """
432
434
  Move right-most columns to selected position
433
435
 
@@ -456,7 +458,7 @@ class DataAnalystDataFrame(pd.DataFrame):
456
458
  return self
457
459
 
458
460
  # Drop a list of column
459
- def drop_columns(self, columns: List[str]):
461
+ def drop_columns(self, columns: list[str]) -> Self:
460
462
  """
461
463
  Drop columns in DataFrame
462
464
 
@@ -479,7 +481,7 @@ class DataAnalystDataFrame(pd.DataFrame):
479
481
  return self
480
482
 
481
483
  # Drop right-most columns
482
- def drop_rightmost(self, num_of_cols: int = 1):
484
+ def drop_rightmost(self, num_of_cols: int = 1) -> Self:
483
485
  """
484
486
  Drop ``num_of_cols`` right-most columns
485
487
 
@@ -508,7 +510,7 @@ class DataAnalystDataFrame(pd.DataFrame):
508
510
  return self
509
511
 
510
512
  # Add blank column
511
- def add_blank_column(self, column_name: str, fill: Any):
513
+ def add_blank_column(self, column_name: str, fill: Any) -> Self:
512
514
  """
513
515
  Add a blank column
514
516
 
@@ -534,10 +536,10 @@ class DataAnalystDataFrame(pd.DataFrame):
534
536
  def convert_city(
535
537
  self,
536
538
  city_column: str,
537
- city_list: List[CityData],
539
+ city_list: list[CityData],
538
540
  *,
539
541
  mode: str = "ra",
540
- ):
542
+ ) -> Self:
541
543
  """
542
544
  Get ``region`` and ``area`` of a city
543
545
 
@@ -588,7 +590,7 @@ class DataAnalystDataFrame(pd.DataFrame):
588
590
  return self.rearrange_column(city_column, col_counter)
589
591
 
590
592
  # Date related
591
- def add_date_from_month(self, month_column: str, *, col_name: str = "date"):
593
+ def add_date_from_month(self, month_column: str, *, col_name: str = "date") -> Self:
592
594
  """
593
595
  Add dummy ``date`` column from ``month`` column
594
596
 
@@ -614,7 +616,7 @@ class DataAnalystDataFrame(pd.DataFrame):
614
616
  # Rearrange
615
617
  return self.rearrange_column(month_column)
616
618
 
617
- def add_detail_date(self, date_column: str, mode: str = "dwmy"):
619
+ def add_detail_date(self, date_column: str, mode: str = "dwmy") -> Self:
618
620
  """
619
621
  Add these columns from ``date_column``:
620
622
  - ``date`` (won't add if ``date_column`` value is ``"date"``)
@@ -668,8 +670,12 @@ class DataAnalystDataFrame(pd.DataFrame):
668
670
  return self.rearrange_column(date_column, col_counter)
669
671
 
670
672
  def delta_date(
671
- self, date_column: str, mode: str = "now", *, col_name: str = "delta_date"
672
- ):
673
+ self,
674
+ date_column: str,
675
+ mode: Literal["now", "between_row"] = "now",
676
+ *,
677
+ col_name: str = "delta_date",
678
+ ) -> Self:
673
679
  """
674
680
  Calculate date interval
675
681
 
@@ -682,7 +688,7 @@ class DataAnalystDataFrame(pd.DataFrame):
682
688
  | Mode to calculate
683
689
  | ``"between_row"``: Calculate date interval between each row
684
690
  | ``"now"``: Calculate date interval to current date
685
- | (Default: ``"between_row"``)
691
+ | (Default: ``"now"``)
686
692
 
687
693
  col_name : str
688
694
  | New delta date column name
@@ -714,7 +720,7 @@ class DataAnalystDataFrame(pd.DataFrame):
714
720
  # Fill missing value
715
721
  def fill_missing_values(
716
722
  self, column_name: str, fill: Any = np.nan, *, fill_when_not_exist: Any = np.nan
717
- ):
723
+ ) -> Self:
718
724
  """
719
725
  Fill missing values in specified column
720
726
 
@@ -771,11 +777,11 @@ class DataAnalystDataFrame(pd.DataFrame):
771
777
  def threshold_filter(
772
778
  self,
773
779
  destination_column: str,
774
- threshold: Union[int, float] = 10,
780
+ threshold: int | float = 10,
775
781
  *,
776
- top: Optional[int] = None,
782
+ top: int | None = None,
777
783
  replace_with: Any = "Other",
778
- ):
784
+ ) -> Self:
779
785
  """
780
786
  Filter out percentage of data that smaller than the ``threshold``,
781
787
  replace all of the smaller data to ``replace_with``.
@@ -972,7 +978,7 @@ class DataAnalystDataFrame(pd.DataFrame):
972
978
 
973
979
  # Help
974
980
  @staticmethod
975
- def dadf_help() -> List[str]:
981
+ def dadf_help() -> list[str]:
976
982
  """
977
983
  Show all available method of DataAnalystDataFrame
978
984
  """
@@ -981,7 +987,7 @@ class DataAnalystDataFrame(pd.DataFrame):
981
987
 
982
988
  # Sample DataFrame
983
989
  @classmethod
984
- def sample_df(cls, size: int = 100):
990
+ def sample_df(cls, size: int = 100) -> Self:
985
991
  """
986
992
  Create sample DataFrame
987
993
 
@@ -1057,6 +1063,46 @@ class DADF(DataAnalystDataFrame):
1057
1063
  pass
1058
1064
 
1059
1065
 
1066
+ class DADF_WIP(DADF):
1067
+ """W.I.P"""
1068
+
1069
+ @versionadded(version="4.0.0")
1070
+ def subtract_df(self, other: Self | pd.DataFrame) -> Self:
1071
+ """
1072
+ Subtract DF to find the different rows
1073
+ """
1074
+ temp = self.copy()
1075
+ out = (
1076
+ temp.merge(other, indicator=True, how="right")
1077
+ .query("_merge=='right_only'")
1078
+ .drop("_merge", axis=1)
1079
+ )
1080
+ return self.__class__(out)
1081
+
1082
+ @versionadded(version="4.0.0")
1083
+ def merge_left(
1084
+ self,
1085
+ other: Self | pd.DataFrame,
1086
+ on: str,
1087
+ columns: list[str] | None = None,
1088
+ ) -> Self:
1089
+ """
1090
+ Merge left of 2 dfs
1091
+
1092
+ :param columns: Columns to take from df2
1093
+ """
1094
+
1095
+ if columns:
1096
+ current_col = [on]
1097
+ current_col.extend(columns)
1098
+ col = other.columns.to_list()
1099
+ cols = list(set(col) - set(current_col))
1100
+ self.drop_columns(cols)
1101
+
1102
+ out = self.merge(other, how="left", on=on)
1103
+ return self.__class__(out)
1104
+
1105
+
1060
1106
  # Run
1061
1107
  ###########################################################################
1062
1108
  if __name__ == "__main__":
absfuyu/fun/__init__.py CHANGED
@@ -3,8 +3,8 @@ Absfuyu: Fun
3
3
  ------------
4
4
  Some fun or weird stuff
5
5
 
6
- Version: 1.0.6
7
- Date updated: 05/04/2023 (dd/mm/yyyy)
6
+ Version: 1.0.7
7
+ Date updated: 16/08/2024 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  # Library
@@ -24,7 +24,7 @@ def zodiac_sign(
24
24
  day: int,
25
25
  month: int,
26
26
  zodiac13: bool = False,
27
- ):
27
+ ) -> str:
28
28
  """
29
29
  Calculate zodiac sign
30
30
 
@@ -43,9 +43,6 @@ def zodiac_sign(
43
43
  -------
44
44
  str
45
45
  Zodiac sign
46
-
47
- None
48
- When failed
49
46
  """
50
47
 
51
48
  # Condition check
@@ -57,34 +54,40 @@ def zodiac_sign(
57
54
  raise ValueError("Value out of range")
58
55
 
59
56
  zodiac = {
60
- "Aquarius": any(
57
+ "Aquarius (A)": any(
61
58
  [month == 1 and day >= 20, month == 2 and day <= 18]
62
59
  ), # 20/1-18/2
63
- "Pisces": any(
60
+ "Pisces (W)": any(
64
61
  [month == 2 and day >= 19, month == 3 and day <= 20]
65
62
  ), # 19/2-20/3
66
- "Aries": any([month == 3 and day >= 21, month == 4 and day <= 19]), # 21/3-19/4
67
- "Taurus": any(
63
+ "Aries (F)": any(
64
+ [month == 3 and day >= 21, month == 4 and day <= 19]
65
+ ), # 21/3-19/4
66
+ "Taurus (E)": any(
68
67
  [month == 4 and day >= 20, month == 5 and day <= 20]
69
68
  ), # 20/4-20/5
70
- "Gemini": any(
69
+ "Gemini (A)": any(
71
70
  [month == 5 and day >= 21, month == 6 and day <= 20]
72
71
  ), # 21/5-20/6
73
- "Cancer": any(
72
+ "Cancer (W)": any(
74
73
  [month == 6 and day >= 21, month == 7 and day <= 22]
75
74
  ), # 21/6-22/7
76
- "Leo": any([month == 7 and day >= 23, month == 8 and day <= 22]), # 23/7-22/8
77
- "Virgo": any([month == 8 and day >= 23, month == 9 and day <= 22]), # 23/8-22/9
78
- "Libra": any(
75
+ "Leo (F)": any(
76
+ [month == 7 and day >= 23, month == 8 and day <= 22]
77
+ ), # 23/7-22/8
78
+ "Virgo (E)": any(
79
+ [month == 8 and day >= 23, month == 9 and day <= 22]
80
+ ), # 23/8-22/9
81
+ "Libra (A)": any(
79
82
  [month == 9 and day >= 23, month == 10 and day <= 22]
80
83
  ), # 23/9-22/10
81
- "Scorpio": any(
84
+ "Scorpio (W)": any(
82
85
  [month == 10 and day >= 23, month == 11 and day <= 21]
83
86
  ), # 23/10-21/11
84
- "Sagittarius": any(
87
+ "Sagittarius (F)": any(
85
88
  [month == 11 and day >= 22, month == 12 and day <= 21]
86
89
  ), # 22/11-21/12
87
- "Capricorn": any(
90
+ "Capricorn (E)": any(
88
91
  [month == 12 and day >= 22, month == 1 and day <= 19]
89
92
  ), # 22/12-19/1
90
93
  }
@@ -132,11 +135,9 @@ def zodiac_sign(
132
135
  ), # 21/1-16/2
133
136
  }
134
137
 
135
- logger.debug(zodiac)
136
-
137
- for k, v in zodiac.items():
138
- if v is True:
139
- return k
138
+ # logger.debug(zodiac)
139
+ temp = dict(zip(zodiac.values(), zodiac.keys()))
140
+ return temp[True]
140
141
 
141
142
 
142
143
  def im_bored() -> str:
absfuyu/fun/tarot.py CHANGED
@@ -4,8 +4,8 @@ Absfuyu: Tarot
4
4
  Tarot stuff
5
5
 
6
6
 
7
- Version: 1.0.3
8
- Date updated: 01/01/2024 (dd/mm/yyyy)
7
+ Version: 1.0.4
8
+ Date updated: 14/11/2024 (dd/mm/yyyy)
9
9
 
10
10
  Usage:
11
11
  ------
@@ -21,7 +21,6 @@ __all__ = ["Tarot", "TarotCard"]
21
21
  # Library
22
22
  ###########################################################################
23
23
  import random
24
- from typing import Dict, List
25
24
 
26
25
  from absfuyu.logger import logger
27
26
  from absfuyu.pkg_data import DataList
@@ -38,9 +37,9 @@ class TarotCard:
38
37
  name: str,
39
38
  rank: int,
40
39
  suit: str,
41
- meanings: Dict[str, List[str]],
42
- keywords: List[str],
43
- fortune_telling: List[str],
40
+ meanings: dict[str, list[str]],
41
+ keywords: list[str],
42
+ fortune_telling: list[str],
44
43
  ) -> None:
45
44
  self.name = name.title()
46
45
  self.rank = rank
@@ -69,7 +68,7 @@ class Tarot:
69
68
  return self.__str__()
70
69
 
71
70
  @property
72
- def tarot_deck(self) -> List[TarotCard]:
71
+ def tarot_deck(self) -> list[TarotCard]:
73
72
  """
74
73
  Load pickled tarot data
75
74
 
absfuyu/game/__init__.py CHANGED
@@ -4,7 +4,7 @@ Absfuyu: Game
4
4
  Contain some game that can be played on terminal
5
5
 
6
6
  Version: 1.1.0
7
- Date updated: 14/04/2024 (mm/dd/yyyy)
7
+ Date updated: 14/04/2024 (dd/mm/yyyy)
8
8
  """
9
9
 
10
10
  __all__ = [
absfuyu/game/sudoku.py CHANGED
@@ -3,8 +3,8 @@ Game: Sudoku
3
3
  ------------
4
4
  Sudoku 9x9 Solver
5
5
 
6
- Version: 1.0.2
7
- Date updated: 24/11/2023 (mm/dd/yyyy)
6
+ Version: 1.0.3
7
+ Date updated: 15/11/2024 (dd/mm/yyyy)
8
8
 
9
9
  Credit:
10
10
  -------
@@ -15,11 +15,12 @@ Credit:
15
15
  __all__ = ["Sudoku"]
16
16
 
17
17
 
18
- from typing import List, Literal, Tuple
18
+ from typing import Literal
19
19
 
20
20
 
21
21
  class Sudoku:
22
- def __init__(self, sudoku_data: List[List[int]]) -> None:
22
+
23
+ def __init__(self, sudoku_data: list[list[int]]) -> None:
23
24
  self.data = sudoku_data
24
25
  # self._original = sudoku_data # Make backup
25
26
  self._row_len = len(self.data)
@@ -194,7 +195,7 @@ class Sudoku:
194
195
  # Return None when there is no empty cell
195
196
  return None
196
197
 
197
- def _is_valid(self, number: int, position: Tuple[int, int]) -> bool:
198
+ def _is_valid(self, number: int, position: tuple[int, int]) -> bool:
198
199
  """
199
200
  Check valid number value in row, column, box
200
201
  """