relib 1.2.9__py3-none-any.whl → 1.2.10__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 +32 -16
- {relib-1.2.9.dist-info → relib-1.2.10.dist-info}/METADATA +1 -1
- relib-1.2.10.dist-info/RECORD +9 -0
- relib-1.2.9.dist-info/RECORD +0 -9
- {relib-1.2.9.dist-info → relib-1.2.10.dist-info}/WHEEL +0 -0
- {relib-1.2.9.dist-info → relib-1.2.10.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
@@ -4,6 +4,7 @@ from typing import Any, Callable, Iterable, 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,45 @@ 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[object, T]]) -> list[T]:
|
88
|
+
pair_list: list[Any] = list(pairs)
|
89
|
+
pair_list.sort(key=lambda p: p[0])
|
90
|
+
for i in range(len(pair_list)):
|
91
|
+
pair_list[i] = pair_list[i][1]
|
92
|
+
return pair_list
|
77
93
|
|
78
94
|
def first[T](iterable: Iterable[T]) -> T | None:
|
79
95
|
return next(iter(iterable), None)
|
80
96
|
|
81
97
|
def move_value[T](iterable: Iterable[T], from_i: int, to_i: int) -> list[T]:
|
82
|
-
|
83
|
-
|
84
|
-
return
|
98
|
+
values = list(iterable)
|
99
|
+
values.insert(to_i, values.pop(from_i))
|
100
|
+
return values
|
85
101
|
|
86
102
|
def transpose_dict(des):
|
87
103
|
if isinstance(des, list):
|
@@ -101,7 +117,7 @@ def transpose_dict(des):
|
|
101
117
|
raise ValueError("transpose_dict only accepts dict or list")
|
102
118
|
|
103
119
|
def make_combinations_by_dict(des, keys=None, pairs=[]):
|
104
|
-
keys = sorted(des.keys()) if keys
|
120
|
+
keys = sorted(des.keys()) if keys is None else keys
|
105
121
|
if len(keys) == 0:
|
106
122
|
return [dict(pairs)]
|
107
123
|
key = keys[0]
|
@@ -196,8 +212,8 @@ def group[T, K](pairs: Iterable[tuple[K, T]]) -> dict[K, list[T]]:
|
|
196
212
|
values_by_key.setdefault(key, []).append(value)
|
197
213
|
return values_by_key
|
198
214
|
|
199
|
-
def reversed_enumerate[T](
|
200
|
-
return zip(reversed(range(len(
|
215
|
+
def reversed_enumerate[T](values: list[T] | tuple[T, ...]) -> Iterable[tuple[int, T]]:
|
216
|
+
return zip(reversed(range(len(values))), reversed(values))
|
201
217
|
|
202
218
|
def get_at[T](d: dict, keys: Iterable[Any], default: T) -> T:
|
203
219
|
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=A6GenRxjzI-1R80QD3G8Xq-E72LezIbItuHeBSaYnHg,8362
|
6
|
+
relib-1.2.10.dist-info/METADATA,sha256=q2wmDYkUk7f_D3WxRQloVtqjOpI6_Z3h5AFt9qXFEto,1296
|
7
|
+
relib-1.2.10.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
8
|
+
relib-1.2.10.dist-info/licenses/LICENSE,sha256=9xVsdtv_-uSyY9Xl9yujwAPm4-mjcCLeVy-ljwXEWbo,1059
|
9
|
+
relib-1.2.10.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
|