absfuyu 4.2.0__py3-none-any.whl → 5.0.1__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.

Files changed (72) hide show
  1. absfuyu/__init__.py +4 -4
  2. absfuyu/__main__.py +13 -1
  3. absfuyu/cli/__init__.py +2 -2
  4. absfuyu/cli/color.py +9 -2
  5. absfuyu/cli/config_group.py +2 -2
  6. absfuyu/cli/do_group.py +2 -37
  7. absfuyu/cli/game_group.py +2 -2
  8. absfuyu/cli/tool_group.py +7 -7
  9. absfuyu/config/__init__.py +17 -34
  10. absfuyu/core/__init__.py +49 -0
  11. absfuyu/core/baseclass.py +299 -0
  12. absfuyu/core/baseclass2.py +165 -0
  13. absfuyu/core/decorator.py +67 -0
  14. absfuyu/core/docstring.py +166 -0
  15. absfuyu/core/dummy_cli.py +67 -0
  16. absfuyu/core/dummy_func.py +49 -0
  17. absfuyu/dxt/__init__.py +42 -0
  18. absfuyu/dxt/dictext.py +201 -0
  19. absfuyu/dxt/dxt_support.py +79 -0
  20. absfuyu/dxt/intext.py +586 -0
  21. absfuyu/dxt/listext.py +508 -0
  22. absfuyu/dxt/strext.py +530 -0
  23. absfuyu/extra/__init__.py +12 -0
  24. absfuyu/extra/beautiful.py +252 -0
  25. absfuyu/{extensions → extra}/data_analysis.py +51 -82
  26. absfuyu/fun/__init__.py +110 -135
  27. absfuyu/fun/tarot.py +11 -19
  28. absfuyu/game/__init__.py +8 -2
  29. absfuyu/game/game_stat.py +8 -2
  30. absfuyu/game/sudoku.py +9 -3
  31. absfuyu/game/tictactoe.py +14 -7
  32. absfuyu/game/wordle.py +16 -10
  33. absfuyu/general/__init__.py +8 -81
  34. absfuyu/general/content.py +24 -38
  35. absfuyu/general/human.py +108 -228
  36. absfuyu/general/shape.py +1334 -0
  37. absfuyu/logger.py +10 -15
  38. absfuyu/pkg_data/__init__.py +137 -100
  39. absfuyu/pkg_data/deprecated.py +133 -0
  40. absfuyu/sort.py +6 -130
  41. absfuyu/tools/__init__.py +2 -2
  42. absfuyu/tools/checksum.py +33 -22
  43. absfuyu/tools/converter.py +51 -48
  44. absfuyu/{general → tools}/generator.py +17 -42
  45. absfuyu/tools/keygen.py +25 -30
  46. absfuyu/tools/obfuscator.py +246 -112
  47. absfuyu/tools/passwordlib.py +100 -30
  48. absfuyu/tools/shutdownizer.py +68 -47
  49. absfuyu/tools/web.py +4 -11
  50. absfuyu/util/__init__.py +17 -17
  51. absfuyu/util/api.py +10 -15
  52. absfuyu/util/json_method.py +7 -24
  53. absfuyu/util/lunar.py +5 -11
  54. absfuyu/util/path.py +22 -27
  55. absfuyu/util/performance.py +43 -67
  56. absfuyu/util/shorten_number.py +65 -14
  57. absfuyu/util/zipped.py +11 -17
  58. absfuyu/version.py +59 -42
  59. {absfuyu-4.2.0.dist-info → absfuyu-5.0.1.dist-info}/METADATA +41 -14
  60. absfuyu-5.0.1.dist-info/RECORD +68 -0
  61. absfuyu/core.py +0 -57
  62. absfuyu/everything.py +0 -32
  63. absfuyu/extensions/__init__.py +0 -12
  64. absfuyu/extensions/beautiful.py +0 -188
  65. absfuyu/fun/WGS.py +0 -134
  66. absfuyu/general/data_extension.py +0 -1796
  67. absfuyu/tools/stats.py +0 -226
  68. absfuyu/util/pkl.py +0 -67
  69. absfuyu-4.2.0.dist-info/RECORD +0 -59
  70. {absfuyu-4.2.0.dist-info → absfuyu-5.0.1.dist-info}/WHEEL +0 -0
  71. {absfuyu-4.2.0.dist-info → absfuyu-5.0.1.dist-info}/entry_points.txt +0 -0
  72. {absfuyu-4.2.0.dist-info → absfuyu-5.0.1.dist-info}/licenses/LICENSE +0 -0
absfuyu/dxt/intext.py ADDED
@@ -0,0 +1,586 @@
1
+ """
2
+ Absfuyu: Data Extension
3
+ -----------------------
4
+ int extension
5
+
6
+ Version: 5.0.0
7
+ Date updated: 25/02/2025 (dd/mm/yyyy)
8
+ """
9
+
10
+ # Module Package
11
+ # ---------------------------------------------------------------------------
12
+ __all__ = ["IntExt", "Pow"]
13
+
14
+
15
+ # Library
16
+ # ---------------------------------------------------------------------------
17
+ import math
18
+ from collections import Counter
19
+ from typing import Any, Self
20
+
21
+ from absfuyu.core import ShowAllMethodsMixin, versionchanged
22
+ from absfuyu.dxt.dxt_support import DictBoolTrue
23
+
24
+
25
+ # Class
26
+ # ---------------------------------------------------------------------------
27
+ class Pow:
28
+ """Number power by a number"""
29
+
30
+ def __init__(self, number: int | float, power_by: int) -> None:
31
+ self.number = number
32
+ self.power_by = power_by
33
+
34
+ def __str__(self) -> str:
35
+ if self.power_by == 1:
36
+ return str(self.number)
37
+ else:
38
+ return f"{self.number}^{self.power_by}"
39
+ # return f"{self.__class__.__name__}({self.number}, {self.power_by})"
40
+
41
+ def __repr__(self) -> str:
42
+ return self.__str__()
43
+
44
+ def to_list(self) -> list[int]:
45
+ """
46
+ Convert into list
47
+
48
+ :rtype: list[int | float]
49
+ """
50
+ return [self.number] * self.power_by # type: ignore
51
+
52
+ def calculate(self) -> float:
53
+ """
54
+ Calculate the ``self.number`` to the power of ``self.power_by``
55
+
56
+ :rtype: float
57
+ """
58
+ # return self.number**self.power_by
59
+ return math.pow(self.number, self.power_by)
60
+
61
+
62
+ class IntExt(ShowAllMethodsMixin, int):
63
+ """
64
+ ``int`` extension
65
+ """
66
+
67
+ # convert stuff
68
+ def to_binary(self) -> str:
69
+ """
70
+ Convert to binary number
71
+
72
+ Returns
73
+ -------
74
+ str
75
+ Binary number
76
+
77
+
78
+ Example:
79
+ --------
80
+ >>> test = IntNumber(10)
81
+ >>> test.to_binary()
82
+ '1010'
83
+ """
84
+ return format(self, "b")
85
+
86
+ def to_celcius_degree(self) -> float:
87
+ """
88
+ Convert into Celcius degree as if ``self`` is Fahrenheit degree
89
+
90
+ Returns
91
+ -------
92
+ float
93
+ Celcius degree
94
+
95
+
96
+ Example:
97
+ --------
98
+ >>> test = IntNumber(10)
99
+ >>> test.to_celcius_degree()
100
+ -12.222222222222221
101
+ """
102
+ c_degree = (self - 32) / 1.8
103
+ return c_degree
104
+
105
+ def to_fahrenheit_degree(self) -> float:
106
+ """
107
+ Convert into Fahrenheit degree as if ``self`` is Celcius degree
108
+
109
+ Returns
110
+ -------
111
+ float
112
+ Fahrenheit degree
113
+
114
+
115
+ Example:
116
+ --------
117
+ >>> test = IntNumber(10)
118
+ >>> test.to_fahrenheit_degree()
119
+ 50.0
120
+ """
121
+ f_degree = (self * 1.8) + 32
122
+ return f_degree
123
+
124
+ def reverse(self) -> Self:
125
+ """
126
+ Reverse a number. Reverse ``abs(number)`` if ``number < 0``
127
+
128
+ Returns
129
+ -------
130
+ IntNumber
131
+ Reversed number
132
+
133
+
134
+ Example:
135
+ --------
136
+ >>> test = IntNumber(102)
137
+ >>> test.reverse()
138
+ 201
139
+ """
140
+ number = int(self)
141
+ if number <= 1:
142
+ number *= -1
143
+ return self.__class__(str(number)[::-1])
144
+
145
+ # is_stuff
146
+ def is_even(self) -> bool:
147
+ """
148
+ An even number is a number which divisible by 2
149
+
150
+ Returns
151
+ -------
152
+ bool
153
+ | ``True`` if an even number
154
+ | ``False`` if not an even number
155
+ """
156
+ return self % 2 == 0
157
+
158
+ def is_prime(self) -> bool:
159
+ """
160
+ Check if the integer is a prime number or not
161
+
162
+ A prime number is a natural number greater than ``1``
163
+ that is not a product of two smaller natural numbers.
164
+ A natural number greater than ``1`` that is not prime
165
+ is called a composite number.
166
+
167
+ Returns
168
+ -------
169
+ bool
170
+ | ``True`` if a prime number
171
+ | ``False`` if not a prime number
172
+ """
173
+ number = self
174
+
175
+ if number <= 1:
176
+ return False
177
+ for i in range(2, int(math.sqrt(number)) + 1): # divisor range
178
+ if number % i == 0:
179
+ return False
180
+ return True
181
+
182
+ def is_twisted_prime(self) -> bool:
183
+ """
184
+ A number is said to be twisted prime if
185
+ it is a prime number and
186
+ reverse of the number is also a prime number
187
+
188
+ Returns
189
+ -------
190
+ bool
191
+ | ``True`` if a twisted prime number
192
+ | ``False`` if not a twisted prime number
193
+ """
194
+ prime = self.is_prime()
195
+ rev = self.reverse().is_prime()
196
+ return prime and rev
197
+
198
+ def is_perfect(self) -> bool:
199
+ """
200
+ Check if integer is perfect number
201
+
202
+ Perfect number: a positive integer that is
203
+ equal to the sum of its proper divisors.
204
+ The smallest perfect number is ``6``, which is
205
+ the sum of ``1``, ``2``, and ``3``.
206
+ Other perfect numbers are ``28``, ``496``, and ``8,128``.
207
+
208
+ Returns
209
+ -------
210
+ bool
211
+ | ``True`` if a perfect number
212
+ | ``False`` if not a perfect number
213
+ """
214
+ # ---
215
+ """
216
+ # List of known perfect number
217
+ # Source: https://en.wikipedia.org/wiki/List_of_Mersenne_primes_and_perfect_numbers
218
+ perfect_number_index = [
219
+ 2, 3, 5, 7,
220
+ 13, 17, 19, 31, 61, 89,
221
+ 107, 127, 521, 607,
222
+ 1279, 2203, 2281, 3217, 4253, 4423, 9689, 9941,
223
+ 11_213, 19_937, 21_701, 23_209, 44_497, 86_243,
224
+ 110_503, 132_049, 216_091, 756_839, 859_433,
225
+ # 1_257_787, 1_398_269, 2_976_221, 3_021_377, 6_972_593,
226
+ # 13_466_917, 20_996_011, 24_036_583, 25_964_951,
227
+ # 30_402_457, 32_582_657, 37_156_667, 42_643_801,
228
+ # 43_112_609, 57_885_161,
229
+ ## 74_207_281, 77_232_917, 82_589_933
230
+ ]
231
+ perfect_number = []
232
+ for x in perfect_number_index:
233
+ # a perfect number have a form of (2**(n-1))*((2**n)-1)
234
+ perfect_number.append((2**(x-1))*((2**x)-1))
235
+ """
236
+ number = int(self)
237
+
238
+ perfect_number = [
239
+ 6,
240
+ 28,
241
+ 496,
242
+ 8128,
243
+ 33_550_336,
244
+ 8_589_869_056,
245
+ 137_438_691_328,
246
+ 2_305_843_008_139_952_128,
247
+ ]
248
+
249
+ if number in perfect_number:
250
+ return True
251
+
252
+ elif number < perfect_number[-1]:
253
+ return False
254
+
255
+ else:
256
+ # Faster way to check
257
+ perfect_number_index: list[int] = [
258
+ 61,
259
+ 89,
260
+ 107,
261
+ 127,
262
+ 521,
263
+ 607,
264
+ 1279,
265
+ 2203,
266
+ 2281,
267
+ 3217,
268
+ 4253,
269
+ 4423,
270
+ 9689,
271
+ 9941,
272
+ 11_213,
273
+ 19_937,
274
+ 21_701,
275
+ 23_209,
276
+ 44_497,
277
+ 86_243,
278
+ 110_503,
279
+ 132_049,
280
+ 216_091,
281
+ 756_839,
282
+ 859_433,
283
+ 1_257_787,
284
+ # 1_398_269,
285
+ # 2_976_221,
286
+ # 3_021_377,
287
+ # 6_972_593,
288
+ # 13_466_917,
289
+ # 20_996_011,
290
+ # 24_036_583,
291
+ # 25_964_951,
292
+ # 30_402_457,
293
+ # 32_582_657,
294
+ # 37_156_667,
295
+ # 42_643_801,
296
+ # 43_112_609,
297
+ # 57_885_161,
298
+ ## 74_207_281,
299
+ ## 77_232_917,
300
+ ## 82_589_933
301
+ ]
302
+ for x in perfect_number_index:
303
+ # a perfect number have a form of (2**(n-1))*((2**n)-1)
304
+ perfect_number = (2 ** (x - 1)) * ((2**x) - 1)
305
+ if number < perfect_number: # type: ignore
306
+ return False
307
+ elif number == perfect_number: # type: ignore
308
+ return True
309
+
310
+ # Manual way when above method not working
311
+ # sum
312
+ s = 1
313
+ # add all divisors
314
+ i = 2
315
+ while i * i <= number:
316
+ if number % i == 0:
317
+ s += +i + number / i # type: ignore
318
+ i += 1
319
+ # s == number -> perfect
320
+ return True if s == number and number != 1 else False
321
+
322
+ def is_narcissistic(self) -> bool:
323
+ """
324
+ Check if a narcissistic number
325
+
326
+ In number theory, a narcissistic number
327
+ (also known as a pluperfect digital invariant (PPDI),
328
+ an Armstrong number (after Michael F. Armstrong)
329
+ or a plus perfect number) in a given number base ``b``
330
+ is a number that is the sum of its own digits
331
+ each raised to the power of the number of digits.
332
+
333
+ Returns
334
+ -------
335
+ bool
336
+ | ``True`` if a narcissistic number
337
+ | ``False`` if not a narcissistic number
338
+ """
339
+ try:
340
+ check = sum([int(x) ** len(str(self)) for x in str(self)])
341
+ res = int(self) == check
342
+ return res # type: ignore
343
+ except Exception:
344
+ return False
345
+
346
+ def is_palindromic(self) -> bool:
347
+ """
348
+ A palindromic number (also known as a numeral palindrome
349
+ or a numeric palindrome) is a number (such as ``16461``)
350
+ that remains the same when its digits are reversed.
351
+
352
+ Returns
353
+ -------
354
+ bool
355
+ | ``True`` if a palindromic number
356
+ | ``False`` if not a palindromic number
357
+ """
358
+ return self == self.reverse()
359
+
360
+ def is_palindromic_prime(self) -> bool:
361
+ """
362
+ A palindormic prime is a number which is both palindromic and prime
363
+
364
+ Returns
365
+ -------
366
+ bool
367
+ | ``True`` if a palindormic prime number
368
+ | ``False`` if not a palindormic prime number
369
+ """
370
+ return self.is_palindromic() and self.is_prime()
371
+
372
+ # calculation stuff
373
+ def lcm(self, with_number: int) -> Self:
374
+ """
375
+ Least common multiple of ``self`` and ``with_number``
376
+
377
+ Parameters
378
+ ----------
379
+ with_number : int
380
+ The number that want to find LCM with
381
+
382
+ Returns
383
+ -------
384
+ IntNumber
385
+ Least common multiple
386
+
387
+
388
+ Example:
389
+ --------
390
+ >>> test = IntNumber(102)
391
+ >>> test.lcm(5)
392
+ 510
393
+ """
394
+ return self.__class__(math.lcm(self, with_number))
395
+
396
+ @versionchanged("3.3.0", reason="Updated functionality")
397
+ def gcd(self, with_number: int) -> Self:
398
+ """
399
+ Greatest common divisor of ``self`` and ``with_number``
400
+
401
+ Parameters
402
+ ----------
403
+ with_number : int
404
+ The number that want to find GCD with
405
+
406
+ Returns
407
+ -------
408
+ IntNumber
409
+ Greatest common divisor
410
+
411
+
412
+ Example:
413
+ --------
414
+ >>> test = IntNumber(1024)
415
+ >>> test.gcd(8)
416
+ 8
417
+ """
418
+ return self.__class__(math.gcd(self, with_number))
419
+
420
+ def add_to_one_digit(self, master_number: bool = False) -> Self:
421
+ """
422
+ Convert ``self`` into 1-digit number
423
+ by adding all of the digits together
424
+
425
+ Parameters
426
+ ----------
427
+ master_number : bool
428
+ | Break when sum = ``22`` or ``11`` (numerology)
429
+ | (Default: ``False``)
430
+
431
+ Returns
432
+ -------
433
+ IntNumber
434
+ IntNumber
435
+
436
+
437
+ Example:
438
+ --------
439
+ >>> test = IntNumber(119)
440
+ >>> test.add_to_one_digit()
441
+ 2
442
+
443
+ >>> test = IntNumber(119)
444
+ >>> test.add_to_one_digit(master_number=True)
445
+ 11
446
+ """
447
+ number = int(self)
448
+ if number < 0:
449
+ number *= -1
450
+ while len(str(number)) != 1:
451
+ number = sum(map(int, str(number)))
452
+ if master_number:
453
+ if number == 22 or number == 11:
454
+ break # Master number
455
+ return self.__class__(number)
456
+
457
+ @versionchanged("5.0.0", reason="Removed ``short_form`` parameter")
458
+ def divisible_list(self) -> list[int]:
459
+ """
460
+ A list of divisible number
461
+
462
+ Returns
463
+ -------
464
+ list[int]
465
+ A list of divisible number
466
+
467
+
468
+ Example:
469
+ --------
470
+ >>> test = IntNumber(1024)
471
+ >>> test.divisible_list()
472
+ [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
473
+ """
474
+
475
+ if self <= 1:
476
+ return [1]
477
+ divi_list = [x for x in range(1, int(self / 2) + 1) if self % x == 0] + [self]
478
+
479
+ return divi_list
480
+
481
+ def prime_factor(self, short_form: bool = True) -> list[int] | list[Pow]:
482
+ """
483
+ Prime factor
484
+
485
+ Parameters
486
+ ----------
487
+ short_form : bool
488
+ | Show prime list in short form
489
+ | Normal example: ``[2, 2, 2, 3, 3]``
490
+ | Short form example: ``[2^3, 3^2]``
491
+ | (Default: ``True``)
492
+
493
+ Returns
494
+ -------
495
+ list[int] | list[Pow]
496
+ | List of prime number that when multiplied together == ``self``
497
+ | list[int]: Long form
498
+ | list[Pow]: Short form
499
+
500
+
501
+ Example:
502
+ --------
503
+ >>> test = IntNumber(1024)
504
+ >>> test.prime_factor()
505
+ [2^10]
506
+
507
+ >>> test = IntNumber(1024)
508
+ >>> test.prime_factor(short_form=False)
509
+ [2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
510
+ """
511
+ # Generate list
512
+ factors = []
513
+ divisor = 2
514
+ number = int(self)
515
+ if number <= 1:
516
+ return [number]
517
+ while divisor <= number:
518
+ if number % divisor == 0:
519
+ factors.append(divisor)
520
+ number //= divisor # number = number // divisor
521
+ else:
522
+ divisor += 1
523
+
524
+ # Output
525
+ if short_form:
526
+ temp = dict(Counter(factors))
527
+ return [Pow(k, v) for k, v in temp.items()]
528
+ return factors
529
+
530
+ # analyze
531
+ def analyze(self, short_form: bool = True) -> dict[str, dict[str, Any]]:
532
+ """
533
+ Analyze the number with almost all ``IntNumber`` method
534
+
535
+ Parameters
536
+ ----------
537
+ short_form : bool
538
+ | Enable short form for some items
539
+ | (Default: ``True``)
540
+
541
+ Returns
542
+ -------
543
+ dict[str, dict[str, Any]]
544
+ Detailed analysis
545
+
546
+
547
+ Example:
548
+ --------
549
+ >>> test = IntNumber(1024)
550
+ >>> test.analyze()
551
+ {
552
+ 'summary': {'number': 1024, 'length': 4, 'even': True, 'prime factor': [2^10], 'divisible': [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]},
553
+ 'convert': {'binary': '10000000000', 'octa': '2000', 'hex': '400', 'reverse': 4201, 'add to one': 7},
554
+ 'characteristic': {'prime': False, 'twisted prime': False, 'perfect': False, 'narcissistic': False, 'palindromic': False, 'palindromic prime': False}
555
+ }
556
+ """
557
+ output = {
558
+ "summary": {
559
+ "number": self,
560
+ "length": len(str(self)),
561
+ "even": self.is_even(),
562
+ "prime factor": self.prime_factor(short_form=short_form),
563
+ "divisible": self.divisible_list(),
564
+ },
565
+ "convert": {
566
+ "binary": bin(self)[2:],
567
+ "octa": oct(self)[2:],
568
+ "hex": hex(self)[2:],
569
+ # "hash": hash(self),
570
+ "reverse": self.reverse(),
571
+ "add to one": self.add_to_one_digit(),
572
+ },
573
+ }
574
+ characteristic = {
575
+ "prime": self.is_prime(),
576
+ "twisted prime": self.is_twisted_prime(),
577
+ "perfect": self.is_perfect(),
578
+ "narcissistic": self.is_narcissistic(),
579
+ "palindromic": self.is_palindromic(),
580
+ "palindromic prime": self.is_palindromic_prime(),
581
+ }
582
+ if short_form:
583
+ characteristic = DictBoolTrue(characteristic)
584
+
585
+ output["characteristic"] = characteristic
586
+ return output # type: ignore