dycw-utilities 0.125.9__py3-none-any.whl → 0.125.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.125.9
3
+ Version: 0.125.10
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -174,7 +174,7 @@ Requires-Dist: scipy<1.16,>=1.15.3; extra == 'zzz-test-scipy'
174
174
  Provides-Extra: zzz-test-sentinel
175
175
  Provides-Extra: zzz-test-shelve
176
176
  Provides-Extra: zzz-test-slack-sdk
177
- Requires-Dist: aiohttp<3.12.1,>=3.12.0; extra == 'zzz-test-slack-sdk'
177
+ Requires-Dist: aiohttp<3.12.3,>=3.12.2; extra == 'zzz-test-slack-sdk'
178
178
  Requires-Dist: slack-sdk<3.36,>=3.35.0; extra == 'zzz-test-slack-sdk'
179
179
  Provides-Extra: zzz-test-socket
180
180
  Provides-Extra: zzz-test-sqlalchemy
@@ -1,4 +1,4 @@
1
- utilities/__init__.py,sha256=sL0f7a9_XSj0OxG9E_04onbu2cDKar7GrU1t0jU_9So,60
1
+ utilities/__init__.py,sha256=hCotYGEOz7s5mhsPf8wWq526AJNjwEkUazmqfzo-lkU,61
2
2
  utilities/altair.py,sha256=Gpja-flOo-Db0PIPJLJsgzAlXWoKUjPU1qY-DQ829ek,9156
3
3
  utilities/asyncio.py,sha256=3OVbJKTYCucrIkM7WSMMkQA9jYJFCQMnGNM4H5rBNgA,29154
4
4
  utilities/atomicwrites.py,sha256=geFjn9Pwn-tTrtoGjDDxWli9NqbYfy3gGL6ZBctiqSo,5393
@@ -26,7 +26,7 @@ utilities/http.py,sha256=WcahTcKYRtZ04WXQoWt5EGCgFPcyHD3EJdlMfxvDt-0,946
26
26
  utilities/hypothesis.py,sha256=a75izXg9aCBhhDkj_ZgK3TDzlzk38evP8TO7JbYYQvg,46264
27
27
  utilities/importlib.py,sha256=mV1xT_O_zt_GnZZ36tl3xOmMaN_3jErDWY54fX39F6Y,429
28
28
  utilities/ipython.py,sha256=V2oMYHvEKvlNBzxDXdLvKi48oUq2SclRg5xasjaXStw,763
29
- utilities/iterables.py,sha256=wqq2lKfEAq1qncE-lR848DHX627aerFaq4BXmLen-NE,43589
29
+ utilities/iterables.py,sha256=mDqw2_0MUVp-P8FklgcaVTi2TXduH0MxbhTDzzhSBho,44915
30
30
  utilities/jupyter.py,sha256=ft5JA7fBxXKzP-L9W8f2-wbF0QeYc_2uLQNFDVk4Z-M,2917
31
31
  utilities/libcst.py,sha256=L0IkwAWXPuNpYyceeJGOC8CAwHdVPRpbXC8MQphCXh4,4954
32
32
  utilities/lightweight_charts.py,sha256=0xNfcsrgFI0R9xL25LtSm-W5yhfBI93qQNT6HyaXAhg,2769
@@ -88,7 +88,7 @@ utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
88
88
  utilities/whenever.py,sha256=jS31ZAY5OMxFxLja_Yo5Fidi87Pd-GoVZ7Vi_teqVDA,16743
89
89
  utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
90
90
  utilities/zoneinfo.py,sha256=-5j7IQ9nb7gR43rdgA7ms05im-XuqhAk9EJnQBXxCoQ,1874
91
- dycw_utilities-0.125.9.dist-info/METADATA,sha256=Lr7FuRGFVTmBQl5RfJRKVA44Nz5TGMHeIKBv4Y4S5eY,12851
92
- dycw_utilities-0.125.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
93
- dycw_utilities-0.125.9.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
94
- dycw_utilities-0.125.9.dist-info/RECORD,,
91
+ dycw_utilities-0.125.10.dist-info/METADATA,sha256=TOOerRTXo6msfA1IIjYMyh-7-i0CR54HRLZc1GTpZdE,12852
92
+ dycw_utilities-0.125.10.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
93
+ dycw_utilities-0.125.10.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
94
+ dycw_utilities-0.125.10.dist-info/RECORD,,
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.125.9"
3
+ __version__ = "0.125.10"
utilities/iterables.py CHANGED
@@ -1190,6 +1190,56 @@ def product_dicts(mapping: Mapping[_K, Iterable[_V]], /) -> Iterator[Mapping[_K,
1190
1190
  ##
1191
1191
 
1192
1192
 
1193
+ def range_partitions(stop: int, num: int, total: int, /) -> range:
1194
+ """Partition a range."""
1195
+ if stop <= 0:
1196
+ raise _RangePartitionsStopError(stop=stop)
1197
+ if not (1 <= total <= stop):
1198
+ raise _RangePartitionsTotalError(stop=stop, total=total)
1199
+ if not (0 <= num < total):
1200
+ raise _RangePartitionsNumError(num=num, total=total)
1201
+ q, r = divmod(stop, total)
1202
+ start = num * q + min(num, r)
1203
+ end = start + q + (1 if num < r else 0)
1204
+ return range(start, end)
1205
+
1206
+
1207
+ @dataclass(kw_only=True, slots=True)
1208
+ class RangePartitionsError(Exception): ...
1209
+
1210
+
1211
+ @dataclass(kw_only=True, slots=True)
1212
+ class _RangePartitionsStopError(RangePartitionsError):
1213
+ stop: int
1214
+
1215
+ @override
1216
+ def __str__(self) -> str:
1217
+ return f"'stop' must be positive; got {self.stop}"
1218
+
1219
+
1220
+ @dataclass(kw_only=True, slots=True)
1221
+ class _RangePartitionsTotalError(RangePartitionsError):
1222
+ stop: int
1223
+ total: int
1224
+
1225
+ @override
1226
+ def __str__(self) -> str:
1227
+ return f"'total' must be in [1, {self.stop}]; got {self.total}"
1228
+
1229
+
1230
+ @dataclass(kw_only=True, slots=True)
1231
+ class _RangePartitionsNumError(RangePartitionsError):
1232
+ num: int
1233
+ total: int
1234
+
1235
+ @override
1236
+ def __str__(self) -> str:
1237
+ return f"'num' must be in [0, {self.total - 1}]; got {self.num}"
1238
+
1239
+
1240
+ ##
1241
+
1242
+
1193
1243
  @overload
1194
1244
  def reduce_mappings(
1195
1245
  func: Callable[[_V, _V], _V], sequence: Iterable[Mapping[_K, _V]], /
@@ -1458,6 +1508,7 @@ __all__ = [
1458
1508
  "OneUniqueEmptyError",
1459
1509
  "OneUniqueError",
1460
1510
  "OneUniqueNonUniqueError",
1511
+ "RangePartitionsError",
1461
1512
  "ResolveIncludeAndExcludeError",
1462
1513
  "SortIterableError",
1463
1514
  "always_iterable",
@@ -1502,6 +1553,7 @@ __all__ = [
1502
1553
  "one_unique",
1503
1554
  "pairwise_tail",
1504
1555
  "product_dicts",
1556
+ "range_partitions",
1505
1557
  "reduce_mappings",
1506
1558
  "resolve_include_and_exclude",
1507
1559
  "sort_iterable",