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/sort.py
CHANGED
|
@@ -1,32 +1,39 @@
|
|
|
1
|
-
#
|
|
1
|
+
# type: ignore
|
|
2
2
|
"""
|
|
3
3
|
Absfuyu: Sort
|
|
4
4
|
-------------
|
|
5
5
|
Sort Module
|
|
6
6
|
|
|
7
|
-
Version: 1.2.
|
|
8
|
-
Date updated:
|
|
7
|
+
Version: 1.2.4
|
|
8
|
+
Date updated: 20/03/2024 (mm/dd/yyyy)
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
|
-
|
|
12
11
|
# Module level
|
|
13
12
|
###########################################################################
|
|
14
13
|
__all__ = [
|
|
15
14
|
# Sort
|
|
16
|
-
"selection_sort",
|
|
15
|
+
"selection_sort",
|
|
16
|
+
"insertion_sort",
|
|
17
17
|
# Alphabet
|
|
18
|
-
"alphabetAppear",
|
|
18
|
+
"alphabetAppear",
|
|
19
|
+
"AlphabetAppearResult",
|
|
19
20
|
# Search
|
|
20
|
-
"linear_search",
|
|
21
|
+
"linear_search",
|
|
22
|
+
"binary_search",
|
|
21
23
|
]
|
|
22
24
|
|
|
23
25
|
|
|
24
26
|
# Library
|
|
25
27
|
###########################################################################
|
|
26
|
-
from collections import Counter, namedtuple
|
|
27
|
-
from itertools import accumulate
|
|
28
28
|
import operator
|
|
29
|
-
from
|
|
29
|
+
from collections import Counter
|
|
30
|
+
from itertools import accumulate
|
|
31
|
+
from typing import Any, Dict, List, NamedTuple, Union
|
|
32
|
+
|
|
33
|
+
from deprecated import deprecated
|
|
34
|
+
from deprecated.sphinx import (
|
|
35
|
+
deprecated as sphinx_deprecated, # versionadded,; versionchanged,
|
|
36
|
+
)
|
|
30
37
|
|
|
31
38
|
from absfuyu.logger import logger
|
|
32
39
|
|
|
@@ -36,12 +43,12 @@ from absfuyu.logger import logger
|
|
|
36
43
|
def selection_sort(iterable: list, reverse: bool = False) -> list:
|
|
37
44
|
"""
|
|
38
45
|
Sort the list with selection sort (bubble sort) algorithm
|
|
39
|
-
|
|
46
|
+
|
|
40
47
|
Parameters
|
|
41
48
|
----------
|
|
42
49
|
iterable : list
|
|
43
50
|
List that want to be sorted
|
|
44
|
-
|
|
51
|
+
|
|
45
52
|
reverse : bool
|
|
46
53
|
| if ``True``: sort in descending order
|
|
47
54
|
| if ``False``: sort in ascending order
|
|
@@ -53,65 +60,67 @@ def selection_sort(iterable: list, reverse: bool = False) -> list:
|
|
|
53
60
|
sorted list
|
|
54
61
|
"""
|
|
55
62
|
|
|
56
|
-
if reverse:
|
|
63
|
+
if reverse: # descending order
|
|
57
64
|
for i in range(len(iterable)):
|
|
58
|
-
for j in range(i+1, len(iterable)):
|
|
65
|
+
for j in range(i + 1, len(iterable)):
|
|
59
66
|
if iterable[i] < iterable[j]:
|
|
60
67
|
iterable[i], iterable[j] = iterable[j], iterable[i]
|
|
61
68
|
return iterable
|
|
62
|
-
|
|
63
|
-
else:
|
|
69
|
+
|
|
70
|
+
else: # ascending order
|
|
64
71
|
for i in range(len(iterable)):
|
|
65
|
-
for j in range(i+1, len(iterable)):
|
|
72
|
+
for j in range(i + 1, len(iterable)):
|
|
66
73
|
if iterable[i] > iterable[j]:
|
|
67
74
|
iterable[i], iterable[j] = iterable[j], iterable[i]
|
|
68
75
|
return iterable
|
|
69
76
|
|
|
77
|
+
|
|
70
78
|
def insertion_sort(iterable: list) -> list:
|
|
71
79
|
"""
|
|
72
80
|
Sort the list with insertion sort algorithm
|
|
73
|
-
|
|
81
|
+
|
|
74
82
|
Parameters
|
|
75
83
|
----------
|
|
76
84
|
iterable : list
|
|
77
85
|
List that want to be sorted
|
|
78
|
-
|
|
86
|
+
|
|
79
87
|
Returns
|
|
80
88
|
-------
|
|
81
89
|
list
|
|
82
90
|
sorted list (ascending order)
|
|
83
91
|
"""
|
|
84
92
|
|
|
85
|
-
for i in range
|
|
93
|
+
for i in range(1, len(iterable)):
|
|
86
94
|
key = iterable[i]
|
|
87
|
-
j = i-1
|
|
88
|
-
while j>=0 and key < iterable[j]:
|
|
89
|
-
iterable[j+1] = iterable[j]
|
|
95
|
+
j = i - 1
|
|
96
|
+
while j >= 0 and key < iterable[j]:
|
|
97
|
+
iterable[j + 1] = iterable[j]
|
|
90
98
|
j -= 1
|
|
91
|
-
iterable[j+1] = key
|
|
99
|
+
iterable[j + 1] = key
|
|
92
100
|
return iterable
|
|
93
101
|
|
|
94
102
|
|
|
95
|
-
def
|
|
96
|
-
|
|
103
|
+
def _alphabetAppear_old(
|
|
104
|
+
lst: List[str],
|
|
105
|
+
) -> List[Union[Dict[str, int], List[int]]]:
|
|
97
106
|
r"""
|
|
98
107
|
Summary
|
|
99
108
|
-------
|
|
100
109
|
Make a dict that show the frequency of
|
|
101
110
|
item name's first character in list
|
|
102
111
|
in alphabet order
|
|
103
|
-
|
|
112
|
+
|
|
104
113
|
For example:
|
|
105
114
|
|
|
106
115
|
>>> ["apple","bee","book"]
|
|
107
116
|
|
|
108
117
|
freq = {"a": 1, "b": 2}
|
|
109
|
-
|
|
118
|
+
|
|
110
119
|
Parameters
|
|
111
120
|
----------
|
|
112
121
|
lst : list
|
|
113
122
|
list that want to be analyzed
|
|
114
|
-
|
|
123
|
+
|
|
115
124
|
Returns
|
|
116
125
|
-------
|
|
117
126
|
list
|
|
@@ -126,7 +135,7 @@ def alphabetAppear_old(lst: List[str],
|
|
|
126
135
|
times_appear[x] += 1
|
|
127
136
|
else:
|
|
128
137
|
times_appear[x] = 1
|
|
129
|
-
|
|
138
|
+
|
|
130
139
|
times_appear_increment = []
|
|
131
140
|
total = 0
|
|
132
141
|
for x in times_appear.values():
|
|
@@ -137,36 +146,40 @@ def alphabetAppear_old(lst: List[str],
|
|
|
137
146
|
# second item is incremental index list
|
|
138
147
|
return [times_appear, times_appear_increment]
|
|
139
148
|
|
|
140
|
-
AlphabetAppearResult = namedtuple("AlphabetAppearResult", ["times_appear", "times_appear_increment"])
|
|
141
149
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
150
|
+
class AlphabetAppearResult(NamedTuple):
|
|
151
|
+
times_appear: Dict[str, int]
|
|
152
|
+
times_appear_increment: List[int]
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
@deprecated(version="3.0.0", reason="In absfuyu ``ListExt``")
|
|
156
|
+
@sphinx_deprecated(version="3.0.0", reason="In absfuyu ``ListExt``")
|
|
157
|
+
def alphabetAppear(iterable: list, num_of_char_sorted: int = 1) -> AlphabetAppearResult:
|
|
146
158
|
"""
|
|
147
159
|
Make a dict that show the frequency of
|
|
148
160
|
item name's first character in list
|
|
149
161
|
in alphabet order
|
|
150
|
-
|
|
151
|
-
For example:
|
|
152
162
|
|
|
153
|
-
>>> ["apple","bee","book"]
|
|
154
|
-
freq = {"a": 1, "b": 2}
|
|
155
|
-
|
|
156
163
|
Parameters
|
|
157
164
|
----------
|
|
158
165
|
iterable : list
|
|
159
166
|
List that want to be analyzed
|
|
160
|
-
|
|
167
|
+
|
|
161
168
|
num_of_char_sorted : int
|
|
162
169
|
Number of first character taken into account to sort
|
|
163
170
|
(default: ``1`` - first character in each item)
|
|
164
|
-
|
|
171
|
+
|
|
165
172
|
Returns
|
|
166
173
|
-------
|
|
167
174
|
AlphabetAppearResult
|
|
168
175
|
| Analyzed list (``AlphabetAppearResult.times_appear``)
|
|
169
176
|
| Apperance incremental value index (``AlphabetAppearResult.times_appear_increment``)
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
Example:
|
|
180
|
+
--------
|
|
181
|
+
>>> alphabetAppear(["apple", "bee", "book"])
|
|
182
|
+
AlphabetAppearResult(times_appear={'a': 1, 'b': 2}, times_appear_increment=[1, 3])
|
|
170
183
|
"""
|
|
171
184
|
|
|
172
185
|
if not isinstance(num_of_char_sorted, int):
|
|
@@ -181,9 +194,9 @@ def alphabetAppear(
|
|
|
181
194
|
temp = Counter([str(x)[:num_of_char_sorted] for x in iterable])
|
|
182
195
|
times_appear = dict(sorted(temp.items()))
|
|
183
196
|
logger.debug(times_appear)
|
|
184
|
-
|
|
197
|
+
|
|
185
198
|
temp = accumulate(times_appear.values(), operator.add)
|
|
186
|
-
times_appear_increment = list(temp)
|
|
199
|
+
times_appear_increment: List[int] = list(temp)
|
|
187
200
|
logger.debug(times_appear_increment)
|
|
188
201
|
|
|
189
202
|
# first item is character frequency
|
|
@@ -199,7 +212,7 @@ def linear_search(iterable: list, key: Any) -> int:
|
|
|
199
212
|
----------
|
|
200
213
|
iterable : list
|
|
201
214
|
List want to search
|
|
202
|
-
|
|
215
|
+
|
|
203
216
|
key: Any
|
|
204
217
|
Item want to find
|
|
205
218
|
|
|
@@ -213,6 +226,7 @@ def linear_search(iterable: list, key: Any) -> int:
|
|
|
213
226
|
return i
|
|
214
227
|
return -1
|
|
215
228
|
|
|
229
|
+
|
|
216
230
|
def binary_search(iterable: list, key: Any) -> int:
|
|
217
231
|
"""
|
|
218
232
|
Returns the position of ``key`` in the list (list must be sorted)
|
|
@@ -221,7 +235,7 @@ def binary_search(iterable: list, key: Any) -> int:
|
|
|
221
235
|
----------
|
|
222
236
|
iterable : list
|
|
223
237
|
List want to search
|
|
224
|
-
|
|
238
|
+
|
|
225
239
|
key: Any
|
|
226
240
|
Item want to find
|
|
227
241
|
|
|
@@ -234,7 +248,7 @@ def binary_search(iterable: list, key: Any) -> int:
|
|
|
234
248
|
right = len(iterable) - 1
|
|
235
249
|
while left <= right:
|
|
236
250
|
middle = (left + right) // 2
|
|
237
|
-
|
|
251
|
+
|
|
238
252
|
if iterable[middle] == key:
|
|
239
253
|
return middle
|
|
240
254
|
if iterable[middle] > key:
|
absfuyu/tools/__init__.py
CHANGED
absfuyu/tools/converter.py
CHANGED
|
@@ -3,8 +3,8 @@ Absufyu: Converter
|
|
|
3
3
|
------------------
|
|
4
4
|
Convert stuff
|
|
5
5
|
|
|
6
|
-
Version: 1.2.
|
|
7
|
-
Date updated:
|
|
6
|
+
Version: 1.2.2
|
|
7
|
+
Date updated: 05/04/2024 (dd/mm/yyyy)
|
|
8
8
|
|
|
9
9
|
Feature:
|
|
10
10
|
--------
|
|
@@ -13,21 +13,18 @@ Feature:
|
|
|
13
13
|
- Base64EncodeDecode
|
|
14
14
|
"""
|
|
15
15
|
|
|
16
|
-
|
|
17
16
|
# Module level
|
|
18
17
|
###########################################################################
|
|
19
|
-
__all__ = [
|
|
20
|
-
"Text2Chemistry", "Str2Pixel", "Base64EncodeDecode"
|
|
21
|
-
]
|
|
18
|
+
__all__ = ["Text2Chemistry", "Str2Pixel", "Base64EncodeDecode"]
|
|
22
19
|
|
|
23
20
|
|
|
24
21
|
# Library
|
|
25
22
|
###########################################################################
|
|
26
23
|
import base64
|
|
27
|
-
from itertools import combinations, chain
|
|
28
24
|
import math
|
|
29
25
|
import re
|
|
30
26
|
import string
|
|
27
|
+
from itertools import chain, combinations
|
|
31
28
|
from typing import Dict, List, Union
|
|
32
29
|
|
|
33
30
|
from absfuyu.core import CLITextColor
|
|
@@ -43,6 +40,7 @@ class Base64EncodeDecode:
|
|
|
43
40
|
"""
|
|
44
41
|
Encode and decode base64
|
|
45
42
|
"""
|
|
43
|
+
|
|
46
44
|
@staticmethod
|
|
47
45
|
def encode(data: str) -> str:
|
|
48
46
|
return base64.b64encode(data.encode()).decode()
|
|
@@ -54,14 +52,10 @@ class Base64EncodeDecode:
|
|
|
54
52
|
|
|
55
53
|
class ChemistryElement:
|
|
56
54
|
"""Chemistry Element"""
|
|
55
|
+
|
|
57
56
|
_VERSION = (1, 1, 0)
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
name: str,
|
|
61
|
-
number: int,
|
|
62
|
-
symbol: str,
|
|
63
|
-
atomic_mass: float
|
|
64
|
-
) -> None:
|
|
57
|
+
|
|
58
|
+
def __init__(self, name: str, number: int, symbol: str, atomic_mass: float) -> None:
|
|
65
59
|
"""
|
|
66
60
|
name: element name
|
|
67
61
|
number: order in periodic table
|
|
@@ -72,69 +66,76 @@ class ChemistryElement:
|
|
|
72
66
|
self.number = number
|
|
73
67
|
self.symbol = symbol
|
|
74
68
|
self.atomic_mass = atomic_mass
|
|
69
|
+
|
|
75
70
|
def __str__(self) -> str:
|
|
76
71
|
return self.symbol
|
|
72
|
+
|
|
77
73
|
def __repr__(self) -> str:
|
|
78
74
|
# return self.symbol
|
|
79
75
|
return f"{self.__class__.__name__}({self.symbol})"
|
|
80
|
-
|
|
76
|
+
|
|
81
77
|
def to_dict(self) -> Dict[str, Union[str, int, float]]:
|
|
82
78
|
"""
|
|
83
79
|
Output content to dict
|
|
84
|
-
|
|
80
|
+
|
|
85
81
|
:rtype: dict[str, str | int | float]
|
|
86
82
|
"""
|
|
87
83
|
return {
|
|
88
84
|
"name": self.name,
|
|
89
85
|
"number": self.number,
|
|
90
86
|
"symbol": self.symbol,
|
|
91
|
-
"atomic_mass": self.atomic_mass
|
|
87
|
+
"atomic_mass": self.atomic_mass,
|
|
92
88
|
}
|
|
93
|
-
|
|
89
|
+
|
|
94
90
|
@classmethod
|
|
95
91
|
def from_dict(cls, data: Dict[str, Union[str, int, float]]) -> "ChemistryElement":
|
|
96
92
|
"""
|
|
97
93
|
Convert from ``dict`` data
|
|
98
|
-
|
|
94
|
+
|
|
99
95
|
:param data: Dict data
|
|
100
96
|
:type data: dict[str, str | int | float]
|
|
101
97
|
:rtype: ChemistryElement
|
|
102
98
|
"""
|
|
103
99
|
return cls(
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
100
|
+
name=data["name"], # type: ignore
|
|
101
|
+
number=int(data["number"]),
|
|
102
|
+
symbol=data["symbol"], # type: ignore
|
|
103
|
+
atomic_mass=float(data["atomic_mass"]),
|
|
108
104
|
)
|
|
109
105
|
|
|
106
|
+
|
|
110
107
|
class Text2Chemistry:
|
|
111
108
|
def __init__(self) -> None:
|
|
112
109
|
self.data_location = DataList.CHEMISTRY
|
|
110
|
+
|
|
113
111
|
def __str__(self) -> str:
|
|
114
112
|
return f"{self.__class__.__name__}()"
|
|
113
|
+
|
|
115
114
|
def __repr__(self) -> str:
|
|
116
115
|
return self.__str__()
|
|
117
|
-
|
|
116
|
+
|
|
118
117
|
def _load_chemistry_data(self) -> List[ChemistryElement]:
|
|
119
118
|
"""
|
|
120
119
|
Load chemistry pickle data
|
|
121
120
|
"""
|
|
122
|
-
data: List[dict] = Pickler.load(self.data_location)
|
|
121
|
+
data: List[dict] = Pickler.load(self.data_location) # type: ignore
|
|
123
122
|
return [ChemistryElement.from_dict(x) for x in data]
|
|
124
|
-
|
|
123
|
+
|
|
125
124
|
@property
|
|
126
125
|
def unvailable_characters(self):
|
|
127
126
|
"""
|
|
128
127
|
Characters that can not be converted (unvailable chemistry symbol)
|
|
129
|
-
|
|
128
|
+
|
|
130
129
|
:rtype: set[str]
|
|
131
130
|
"""
|
|
132
131
|
base = set(string.ascii_lowercase)
|
|
133
|
-
available = set(
|
|
132
|
+
available = set(
|
|
133
|
+
"".join(map(lambda x: x.symbol.lower(), self._load_chemistry_data()))
|
|
134
|
+
)
|
|
134
135
|
# logger.debug(base)
|
|
135
136
|
# logger.debug(available)
|
|
136
137
|
return base.difference(available)
|
|
137
|
-
|
|
138
|
+
|
|
138
139
|
def convert(self, text: str) -> List[List[ChemistryElement]]:
|
|
139
140
|
"""
|
|
140
141
|
Convert text to chemistry symbol
|
|
@@ -151,27 +152,33 @@ class Text2Chemistry:
|
|
|
151
152
|
raise ValueError("Convert Failed. Word Only!")
|
|
152
153
|
for x in self.unvailable_characters:
|
|
153
154
|
if text.find(x) != -1:
|
|
154
|
-
logger.debug(
|
|
155
|
+
logger.debug(
|
|
156
|
+
f"{text} contains unvailable characters: {self.unvailable_characters}"
|
|
157
|
+
)
|
|
155
158
|
# raise ValueError(f"Text contains {self.unvailable_character}")
|
|
156
159
|
return []
|
|
157
|
-
|
|
160
|
+
|
|
158
161
|
# Setup
|
|
159
162
|
text_lower = text.lower()
|
|
160
163
|
data = self._load_chemistry_data()
|
|
161
|
-
|
|
164
|
+
|
|
162
165
|
# List possible elements
|
|
163
166
|
possible_elements: List[ChemistryElement] = []
|
|
164
167
|
for i, letter in enumerate(text_lower):
|
|
165
168
|
for element in data:
|
|
166
|
-
if element.symbol.lower().startswith(
|
|
169
|
+
if element.symbol.lower().startswith(
|
|
170
|
+
letter
|
|
171
|
+
): # Check for `element.symbol` starts with `letter`
|
|
167
172
|
# logger.debug(f"{letter} {element}")
|
|
168
|
-
if element.symbol.lower().startswith(
|
|
173
|
+
if element.symbol.lower().startswith(
|
|
174
|
+
text_lower[i : i + len(element.symbol)]
|
|
175
|
+
): # Check for `element.symbol` with len > 1 starts with `letter` of len(element.symbol)
|
|
169
176
|
possible_elements.append(element)
|
|
170
177
|
# Break when reach last letter in text
|
|
171
178
|
if letter == text_lower[-1]:
|
|
172
179
|
break
|
|
173
180
|
logger.debug(possible_elements)
|
|
174
|
-
if len(possible_elements) < 1:
|
|
181
|
+
if len(possible_elements) < 1: # No possible elements
|
|
175
182
|
return []
|
|
176
183
|
|
|
177
184
|
# temp = []
|
|
@@ -179,12 +186,19 @@ class Text2Chemistry:
|
|
|
179
186
|
# comb = combinations(possible_elements, i)
|
|
180
187
|
# temp.append(comb)
|
|
181
188
|
# possible_combinations = chain(*temp)
|
|
182
|
-
max_symbol_len = max(
|
|
189
|
+
max_symbol_len = max(
|
|
190
|
+
map(lambda x: len(x.symbol), possible_elements)
|
|
191
|
+
) # Max len of `element.symbol`
|
|
183
192
|
min_combination_range = math.ceil(len(text_lower) / max_symbol_len)
|
|
184
193
|
logger.debug(f"Combination range: [{min_combination_range}, {len(text_lower)}]")
|
|
185
|
-
possible_combinations = chain(
|
|
194
|
+
possible_combinations = chain(
|
|
195
|
+
*(
|
|
196
|
+
combinations(possible_elements, i)
|
|
197
|
+
for i in range(min_combination_range, len(text_lower) + 1)
|
|
198
|
+
)
|
|
199
|
+
)
|
|
186
200
|
# logger.debug(list(possible_combinations))
|
|
187
|
-
|
|
201
|
+
|
|
188
202
|
output = []
|
|
189
203
|
for comb in possible_combinations:
|
|
190
204
|
merged = "".join(map(lambda x: x.symbol, comb))
|
|
@@ -197,14 +211,16 @@ class Text2Chemistry:
|
|
|
197
211
|
|
|
198
212
|
class Str2Pixel:
|
|
199
213
|
"""Convert str into pixel"""
|
|
200
|
-
|
|
214
|
+
|
|
215
|
+
PIXEL = "\u2588"
|
|
216
|
+
|
|
201
217
|
def __init__(
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
218
|
+
self,
|
|
219
|
+
str_data: str,
|
|
220
|
+
*,
|
|
221
|
+
pixel_size: int = 2,
|
|
222
|
+
pixel_symbol_overwrite: Union[str, None] = None,
|
|
223
|
+
) -> None:
|
|
208
224
|
"""
|
|
209
225
|
str_data: Pixel string data (Format: <number_of_pixel><color_code>)
|
|
210
226
|
pixel_size: Pixel size (Default: 2)
|
|
@@ -214,27 +230,29 @@ class Str2Pixel:
|
|
|
214
230
|
"""
|
|
215
231
|
self.data = str_data
|
|
216
232
|
if pixel_symbol_overwrite is None:
|
|
217
|
-
self.pixel = self.PIXEL * set_min(pixel_size, min_value=1)
|
|
233
|
+
self.pixel = self.PIXEL * int(set_min(pixel_size, min_value=1))
|
|
218
234
|
else:
|
|
219
235
|
self.pixel = pixel_symbol_overwrite
|
|
236
|
+
|
|
220
237
|
def __str__(self) -> str:
|
|
221
238
|
return f"{self.__class__.__name__}(pixel={self.pixel})"
|
|
239
|
+
|
|
222
240
|
def __repr__(self) -> str:
|
|
223
241
|
return self.__str__()
|
|
224
|
-
|
|
242
|
+
|
|
225
243
|
def _extract_pixel(self):
|
|
226
244
|
"""Split str_data into corresponding int and str"""
|
|
227
|
-
num = re.split("[a-zA-Z]", self.data)
|
|
228
|
-
num = filter(lambda x: x != "", num) # Clean "" in list
|
|
229
|
-
num = list(map(int, num))
|
|
245
|
+
num = re.split("[a-zA-Z]", self.data) # type: ignore
|
|
246
|
+
num = filter(lambda x: x != "", num) # type: ignore # Clean "" in list
|
|
247
|
+
num = list(map(int, num)) # type: ignore
|
|
230
248
|
char = re.split("[0-9]", self.data)
|
|
231
|
-
char = filter(lambda x: x != "", char)
|
|
249
|
+
char = filter(lambda x: x != "", char) # type: ignore
|
|
232
250
|
return [x for y in zip(num, char) for x in y]
|
|
233
251
|
|
|
234
252
|
def convert(self, line_break: bool = True) -> str:
|
|
235
253
|
"""
|
|
236
254
|
Convert data into pixel
|
|
237
|
-
|
|
255
|
+
|
|
238
256
|
:param line_break: add ``\\n`` at the end of line (Default: ``False``)
|
|
239
257
|
:type line_break: bool
|
|
240
258
|
:returns: Converted colored pixels
|
|
@@ -246,16 +264,16 @@ class Str2Pixel:
|
|
|
246
264
|
# Translation to color
|
|
247
265
|
translate = {
|
|
248
266
|
"w": CLITextColor.WHITE,
|
|
249
|
-
"b": CLITextColor.BLACK,
|
|
250
|
-
"B": CLITextColor.BLUE,
|
|
251
|
-
"g": CLITextColor.GRAY,
|
|
252
|
-
"G": CLITextColor.GREEN,
|
|
253
|
-
"r": CLITextColor.RED,
|
|
254
|
-
"R": CLITextColor.DARK_RED,
|
|
255
|
-
"m": CLITextColor.MAGENTA,
|
|
256
|
-
"y": CLITextColor.YELLOW,
|
|
267
|
+
"b": CLITextColor.BLACK,
|
|
268
|
+
"B": CLITextColor.BLUE,
|
|
269
|
+
"g": CLITextColor.GRAY,
|
|
270
|
+
"G": CLITextColor.GREEN,
|
|
271
|
+
"r": CLITextColor.RED,
|
|
272
|
+
"R": CLITextColor.DARK_RED,
|
|
273
|
+
"m": CLITextColor.MAGENTA,
|
|
274
|
+
"y": CLITextColor.YELLOW,
|
|
257
275
|
"E": CLITextColor.RESET,
|
|
258
|
-
"N": "\n"
|
|
276
|
+
"N": "\n", # New line
|
|
259
277
|
}
|
|
260
278
|
|
|
261
279
|
# import colorama
|
|
@@ -277,7 +295,7 @@ class Str2Pixel:
|
|
|
277
295
|
out = ""
|
|
278
296
|
for i, x in enumerate(pixel_map):
|
|
279
297
|
if isinstance(x, str):
|
|
280
|
-
temp = self.pixel * pixel_map[i-1]
|
|
298
|
+
temp = self.pixel * pixel_map[i - 1]
|
|
281
299
|
out += f"{translate[x]}{temp}{translate['E']}"
|
|
282
300
|
if line_break:
|
|
283
301
|
return out + "\n"
|