relib 1.2.9__py3-none-any.whl → 1.2.11__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.
- relib/system.py +2 -1
- relib/utils.py +59 -20
- {relib-1.2.9.dist-info → relib-1.2.11.dist-info}/METADATA +1 -1
- relib-1.2.11.dist-info/RECORD +9 -0
- relib-1.2.9.dist-info/RECORD +0 -9
- {relib-1.2.9.dist-info → relib-1.2.11.dist-info}/WHEEL +0 -0
- {relib-1.2.9.dist-info → relib-1.2.11.dist-info}/licenses/LICENSE +0 -0
relib/system.py
CHANGED
@@ -31,7 +31,8 @@ def read_json(path: Path, default=default_sentinel) -> Any:
|
|
31
31
|
|
32
32
|
def write_json(path: Path, obj: object, indent: None | int = None) -> None:
|
33
33
|
with path.open("w") as f:
|
34
|
-
|
34
|
+
separators = (",", ":") if indent is None else None
|
35
|
+
return json.dump(obj, f, indent=indent, separators=separators)
|
35
36
|
|
36
37
|
def clear_console() -> None:
|
37
38
|
os.system("cls" if os.name == "nt" else "clear")
|
relib/utils.py
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
import re
|
2
2
|
from itertools import chain
|
3
|
-
from typing import Any, Callable, Iterable, overload
|
3
|
+
from typing import Any, Callable, Iterable, Literal, overload
|
4
4
|
|
5
5
|
__all__ = [
|
6
6
|
"noop",
|
7
|
+
"clamp",
|
7
8
|
"non_none",
|
8
9
|
"as_any",
|
9
10
|
"list_split",
|
@@ -11,6 +12,7 @@ __all__ = [
|
|
11
12
|
"distinct",
|
12
13
|
"dict_firsts",
|
13
14
|
"distinct_by",
|
15
|
+
"sort_by",
|
14
16
|
"first",
|
15
17
|
"move_value",
|
16
18
|
"transpose_dict",
|
@@ -43,6 +45,13 @@ __all__ = [
|
|
43
45
|
def noop() -> None:
|
44
46
|
pass
|
45
47
|
|
48
|
+
@overload
|
49
|
+
def clamp(value: int, low: int, high: int) -> int: ...
|
50
|
+
@overload
|
51
|
+
def clamp(value: float, low: float, high: float) -> float: ...
|
52
|
+
def clamp(value: float, low: float, high: float) -> float:
|
53
|
+
return max(low, min(value, high))
|
54
|
+
|
46
55
|
def non_none[T](obj: T | None) -> T:
|
47
56
|
assert obj is not None
|
48
57
|
return obj
|
@@ -50,38 +59,42 @@ def non_none[T](obj: T | None) -> T:
|
|
50
59
|
def as_any(obj: Any) -> Any:
|
51
60
|
return obj
|
52
61
|
|
53
|
-
def list_split[T](
|
54
|
-
|
55
|
-
split_at = [i for i, x in enumerate(
|
62
|
+
def list_split[T](iterable: Iterable[T], sep: T) -> list[list[T]]:
|
63
|
+
values = [sep, *iterable, sep]
|
64
|
+
split_at = [i for i, x in enumerate(values) if x is sep]
|
56
65
|
ranges = list(zip(split_at[0:-1], split_at[1:]))
|
57
66
|
return [
|
58
|
-
|
67
|
+
values[start + 1:end]
|
59
68
|
for start, end in ranges
|
60
69
|
]
|
61
70
|
|
62
71
|
def drop_none[T](iterable: Iterable[T | None]) -> list[T]:
|
63
72
|
return [x for x in iterable if x is not None]
|
64
73
|
|
65
|
-
def distinct[T](
|
66
|
-
return list(dict.fromkeys(
|
74
|
+
def distinct[T](iterable: Iterable[T]) -> list[T]:
|
75
|
+
return list(dict.fromkeys(iterable))
|
67
76
|
|
68
|
-
def dict_firsts[T, K](
|
77
|
+
def dict_firsts[T, K](pairs: Iterable[tuple[K, T]]) -> dict[K, T]:
|
69
78
|
result: dict[K, T] = {}
|
70
|
-
for key, item in
|
79
|
+
for key, item in pairs:
|
71
80
|
if key not in result:
|
72
81
|
result[key] = item
|
73
82
|
return result
|
74
83
|
|
75
|
-
def distinct_by[T](
|
76
|
-
return list(dict_firsts(
|
84
|
+
def distinct_by[T](pairs: Iterable[tuple[object, T]]) -> list[T]:
|
85
|
+
return list(dict_firsts(pairs).values())
|
86
|
+
|
87
|
+
def sort_by[T](pairs: Iterable[tuple[Any, T]]) -> list[T]:
|
88
|
+
pairs = sorted(pairs, key=lambda p: p[0])
|
89
|
+
return [v for _, v in pairs]
|
77
90
|
|
78
91
|
def first[T](iterable: Iterable[T]) -> T | None:
|
79
92
|
return next(iter(iterable), None)
|
80
93
|
|
81
94
|
def move_value[T](iterable: Iterable[T], from_i: int, to_i: int) -> list[T]:
|
82
|
-
|
83
|
-
|
84
|
-
return
|
95
|
+
values = list(iterable)
|
96
|
+
values.insert(to_i, values.pop(from_i))
|
97
|
+
return values
|
85
98
|
|
86
99
|
def transpose_dict(des):
|
87
100
|
if isinstance(des, list):
|
@@ -101,7 +114,7 @@ def transpose_dict(des):
|
|
101
114
|
raise ValueError("transpose_dict only accepts dict or list")
|
102
115
|
|
103
116
|
def make_combinations_by_dict(des, keys=None, pairs=[]):
|
104
|
-
keys = sorted(des.keys()) if keys
|
117
|
+
keys = sorted(des.keys()) if keys is None else keys
|
105
118
|
if len(keys) == 0:
|
106
119
|
return [dict(pairs)]
|
107
120
|
key = keys[0]
|
@@ -145,10 +158,36 @@ def dict_by[T, K](keys: Iterable[K], values: Iterable[T]) -> dict[K, T]:
|
|
145
158
|
def tuple_by[T, K](d: dict[K, T], keys: Iterable[K]) -> tuple[T, ...]:
|
146
159
|
return tuple(d[key] for key in keys)
|
147
160
|
|
148
|
-
|
149
|
-
|
161
|
+
@overload
|
162
|
+
def flatten[T](iterable: Iterable[T], depth: Literal[0]) -> list[T]: ...
|
163
|
+
@overload
|
164
|
+
def flatten[T](iterable: Iterable[Iterable[T]], depth: Literal[1] = 1) -> list[T]: ...
|
165
|
+
@overload
|
166
|
+
def flatten[T](iterable: Iterable[Iterable[Iterable[T]]], depth: Literal[2]) -> list[T]: ...
|
167
|
+
@overload
|
168
|
+
def flatten[T](iterable: Iterable[Iterable[Iterable[Iterable[T]]]], depth: Literal[3]) -> list[T]: ...
|
169
|
+
@overload
|
170
|
+
def flatten[T](iterable: Iterable[Iterable[Iterable[Iterable[Iterable[T]]]]], depth: Literal[4]) -> list[T]: ...
|
171
|
+
@overload
|
172
|
+
def flatten(iterable: Iterable, depth: int) -> list: ...
|
173
|
+
|
174
|
+
def flatten(iterable: Iterable, depth: int = 1) -> list:
|
175
|
+
for _ in range(depth):
|
176
|
+
iterable = chain.from_iterable(iterable)
|
177
|
+
return list(iterable)
|
178
|
+
|
179
|
+
@overload
|
180
|
+
def transpose[T1, T2](tuples: Iterable[tuple[T1, T2]], default_num_returns: int = 0) -> tuple[list[T1], list[T2]]: ...
|
181
|
+
@overload
|
182
|
+
def transpose[T1, T2, T3](tuples: Iterable[tuple[T1, T2, T3]], default_num_returns: int = 0) -> tuple[list[T1], list[T2], list[T3]]: ...
|
183
|
+
@overload
|
184
|
+
def transpose[T1, T2, T3, T4](tuples: Iterable[tuple[T1, T2, T3, T4]], default_num_returns: int = 0) -> tuple[list[T1], list[T2], list[T3], list[T4]]: ...
|
185
|
+
@overload
|
186
|
+
def transpose[T1, T2, T3, T4, T5](tuples: Iterable[tuple[T1, T2, T3, T4, T5]], default_num_returns: int = 0) -> tuple[list[T1], list[T2], list[T3], list[T4], list[T5]]: ...
|
187
|
+
@overload
|
188
|
+
def transpose(tuples: Iterable[tuple], default_num_returns: int = 0) -> tuple[list, ...]: ...
|
150
189
|
|
151
|
-
def transpose(tuples, default_num_returns=0):
|
190
|
+
def transpose(tuples: Iterable[tuple], default_num_returns=0) -> tuple[list, ...]:
|
152
191
|
output = tuple(zip(*tuples))
|
153
192
|
if not output:
|
154
193
|
return ([],) * default_num_returns
|
@@ -196,8 +235,8 @@ def group[T, K](pairs: Iterable[tuple[K, T]]) -> dict[K, list[T]]:
|
|
196
235
|
values_by_key.setdefault(key, []).append(value)
|
197
236
|
return values_by_key
|
198
237
|
|
199
|
-
def reversed_enumerate[T](
|
200
|
-
return zip(reversed(range(len(
|
238
|
+
def reversed_enumerate[T](values: list[T] | tuple[T, ...]) -> Iterable[tuple[int, T]]:
|
239
|
+
return zip(reversed(range(len(values))), reversed(values))
|
201
240
|
|
202
241
|
def get_at[T](d: dict, keys: Iterable[Any], default: T) -> T:
|
203
242
|
try:
|
@@ -0,0 +1,9 @@
|
|
1
|
+
relib/__init__.py,sha256=4_nmex7mRhCwdtLF8k0XLbxxPs-UeN2sP-EEImm5JGs,126
|
2
|
+
relib/hashing.py,sha256=DB_fnkj0ls01FgZbf4nPFHl4EBU8X_0OrmDvty4HlRE,6020
|
3
|
+
relib/measure_duration.py,sha256=LCTo_D_qReNprD3fhtJ0daeWycS6xQE_cwxeg2_h0xo,456
|
4
|
+
relib/system.py,sha256=3RWmSweTCQtB1wzsgpUqcAsMo6TIhVRq2oSt28Ul_1E,2733
|
5
|
+
relib/utils.py,sha256=bwOJXfsNx5nZf1fZxWtT_hLwjTbWo2cP9qfsqca1aHI,9680
|
6
|
+
relib-1.2.11.dist-info/METADATA,sha256=WxEfPUA2Ox2t1ulJZFIXX5ynIOf1jw1u6iWbvtcx9HI,1296
|
7
|
+
relib-1.2.11.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
8
|
+
relib-1.2.11.dist-info/licenses/LICENSE,sha256=9xVsdtv_-uSyY9Xl9yujwAPm4-mjcCLeVy-ljwXEWbo,1059
|
9
|
+
relib-1.2.11.dist-info/RECORD,,
|
relib-1.2.9.dist-info/RECORD
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
relib/__init__.py,sha256=4_nmex7mRhCwdtLF8k0XLbxxPs-UeN2sP-EEImm5JGs,126
|
2
|
-
relib/hashing.py,sha256=DB_fnkj0ls01FgZbf4nPFHl4EBU8X_0OrmDvty4HlRE,6020
|
3
|
-
relib/measure_duration.py,sha256=LCTo_D_qReNprD3fhtJ0daeWycS6xQE_cwxeg2_h0xo,456
|
4
|
-
relib/system.py,sha256=JOqH4oBM8XMzCfG65um9gQz9CHhEQ4JOaTwywIRgS8Q,2654
|
5
|
-
relib/utils.py,sha256=QGAse1K_K9qaRyL7AOdkpNmATcUSNOcHECLiJKuMxgo,7803
|
6
|
-
relib-1.2.9.dist-info/METADATA,sha256=idOhfbgIelWndDu3mSpUINq5EOag0O18WbDDJy2d8rc,1295
|
7
|
-
relib-1.2.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
8
|
-
relib-1.2.9.dist-info/licenses/LICENSE,sha256=9xVsdtv_-uSyY9Xl9yujwAPm4-mjcCLeVy-ljwXEWbo,1059
|
9
|
-
relib-1.2.9.dist-info/RECORD,,
|
File without changes
|
File without changes
|