istr-python 1.1.7__tar.gz → 1.1.8.post0__tar.gz
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.
- {istr_python-1.1.7 → istr_python-1.1.8.post0}/PKG-INFO +21 -2
- {istr_python-1.1.7 → istr_python-1.1.8.post0}/README.md +19 -0
- {istr_python-1.1.7 → istr_python-1.1.8.post0}/istr/istr.py +55 -7
- {istr_python-1.1.7 → istr_python-1.1.8.post0}/istr_python.egg-info/PKG-INFO +21 -2
- {istr_python-1.1.7 → istr_python-1.1.8.post0}/pyproject.toml +2 -2
- {istr_python-1.1.7 → istr_python-1.1.8.post0}/tests/test_istr.py +37 -15
- {istr_python-1.1.7 → istr_python-1.1.8.post0}/istr/LICENSE.txt +0 -0
- {istr_python-1.1.7 → istr_python-1.1.8.post0}/istr/__init__.py +0 -0
- {istr_python-1.1.7 → istr_python-1.1.8.post0}/istr_python.egg-info/SOURCES.txt +0 -0
- {istr_python-1.1.7 → istr_python-1.1.8.post0}/istr_python.egg-info/dependency_links.txt +0 -0
- {istr_python-1.1.7 → istr_python-1.1.8.post0}/istr_python.egg-info/top_level.txt +0 -0
- {istr_python-1.1.7 → istr_python-1.1.8.post0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: istr-python
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.8.post0
|
|
4
4
|
Summary: istr - strings you can count on
|
|
5
5
|
Author-email: Ruud van der Ham <rt.van.der.ham@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/salabim/istr
|
|
@@ -8,7 +8,7 @@ Project-URL: Repository, https://github.com/salabim/istr
|
|
|
8
8
|
Classifier: Development Status :: 5 - Production/Stable
|
|
9
9
|
Classifier: License :: OSI Approved :: MIT License
|
|
10
10
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
11
|
-
Requires-Python: >=3.
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
|
|
14
14
|
<img src="https://www.salabim.org/istr/istr_logo.png" width=500>
|
|
@@ -556,6 +556,25 @@ list(istr.concat(istr.permutations(range(3),2))) ==>
|
|
|
556
556
|
[istr('01'), istr('02'), istr('10'), istr('12'), istr('20'), istr('21')]
|
|
557
557
|
```
|
|
558
558
|
|
|
559
|
+
#### prod to get product of an iterable
|
|
560
|
+
|
|
561
|
+
The method `prod` can be used to return the product of an iterable (including an istr), like `math.prod`, but as istr.
|
|
562
|
+
Thus, `istr.prod(range(1,5))` is `istr(24)`
|
|
563
|
+
And `istr("123", start=4)` is also `istr(24)`.
|
|
564
|
+
|
|
565
|
+
It is also possible to apply `prod` on an istr:
|
|
566
|
+
`istr(1234).prod()` is `istr(24)`
|
|
567
|
+
`istr("123").prod(start=4)` is `istr(24)`
|
|
568
|
+
|
|
569
|
+
#### sumprod to get the sum of products of iterables
|
|
570
|
+
|
|
571
|
+
The class method `istr.sumprod()`, is equivalent to `math.sumprod()`, but applies istr to both iterables.
|
|
572
|
+
Note that this method is available even in Python < 3.12 .
|
|
573
|
+
Thus, `istr.sumprod("12", (3,4))` is `istr(11)`
|
|
574
|
+
In contrast with `math.sumprod()`, `istr.sumprod()` supports a `strict` parameter (True by default)
|
|
575
|
+
Thus, `istr.sumprod("12", (3,4,5), strict=False)` is `istr(11)`, whereas `istr.sumprod("12", (3,4,5))`
|
|
576
|
+
raises a ValueError.
|
|
577
|
+
|
|
559
578
|
#### generate istr with digits
|
|
560
579
|
|
|
561
580
|
The class method `digits` can be used to return an istr of digits according to a given specification.
|
|
@@ -543,6 +543,25 @@ list(istr.concat(istr.permutations(range(3),2))) ==>
|
|
|
543
543
|
[istr('01'), istr('02'), istr('10'), istr('12'), istr('20'), istr('21')]
|
|
544
544
|
```
|
|
545
545
|
|
|
546
|
+
#### prod to get product of an iterable
|
|
547
|
+
|
|
548
|
+
The method `prod` can be used to return the product of an iterable (including an istr), like `math.prod`, but as istr.
|
|
549
|
+
Thus, `istr.prod(range(1,5))` is `istr(24)`
|
|
550
|
+
And `istr("123", start=4)` is also `istr(24)`.
|
|
551
|
+
|
|
552
|
+
It is also possible to apply `prod` on an istr:
|
|
553
|
+
`istr(1234).prod()` is `istr(24)`
|
|
554
|
+
`istr("123").prod(start=4)` is `istr(24)`
|
|
555
|
+
|
|
556
|
+
#### sumprod to get the sum of products of iterables
|
|
557
|
+
|
|
558
|
+
The class method `istr.sumprod()`, is equivalent to `math.sumprod()`, but applies istr to both iterables.
|
|
559
|
+
Note that this method is available even in Python < 3.12 .
|
|
560
|
+
Thus, `istr.sumprod("12", (3,4))` is `istr(11)`
|
|
561
|
+
In contrast with `math.sumprod()`, `istr.sumprod()` supports a `strict` parameter (True by default)
|
|
562
|
+
Thus, `istr.sumprod("12", (3,4,5), strict=False)` is `istr(11)`, whereas `istr.sumprod("12", (3,4,5))`
|
|
563
|
+
raises a ValueError.
|
|
564
|
+
|
|
546
565
|
#### generate istr with digits
|
|
547
566
|
|
|
548
567
|
The class method `digits` can be used to return an istr of digits according to a given specification.
|
|
@@ -5,12 +5,14 @@
|
|
|
5
5
|
# |_||___/ \__||_|
|
|
6
6
|
# strings you can count on
|
|
7
7
|
|
|
8
|
-
__version__ = "1.1.
|
|
8
|
+
__version__ = "1.1.8"
|
|
9
9
|
import functools
|
|
10
10
|
import itertools
|
|
11
11
|
import types
|
|
12
12
|
import sys
|
|
13
13
|
import inspect
|
|
14
|
+
import math
|
|
15
|
+
import operator
|
|
14
16
|
|
|
15
17
|
"""
|
|
16
18
|
Note: the changelog is now in changelog.md
|
|
@@ -230,7 +232,7 @@ class istr(str):
|
|
|
230
232
|
return int(value, cls._base)
|
|
231
233
|
else:
|
|
232
234
|
return int(value)
|
|
233
|
-
except:
|
|
235
|
+
except Exception:
|
|
234
236
|
return cls._nan
|
|
235
237
|
|
|
236
238
|
def __new__(cls, *value):
|
|
@@ -251,8 +253,8 @@ class istr(str):
|
|
|
251
253
|
return map(functools.partial(cls), value)
|
|
252
254
|
return type(value)(map(functools.partial(cls), value))
|
|
253
255
|
|
|
254
|
-
if isinstance(value, str) and value.startswith(
|
|
255
|
-
value=str(cls.compose(value[1:],inspect.currentframe().f_back.f_back.f_globals))
|
|
256
|
+
if isinstance(value, str) and value.startswith("="):
|
|
257
|
+
value = str(cls.compose(value[1:], inspect.currentframe().f_back.f_back.f_globals))
|
|
256
258
|
as_int = cls._to_int(value)
|
|
257
259
|
if isinstance(value, str):
|
|
258
260
|
as_str = value
|
|
@@ -349,10 +351,10 @@ class istr(str):
|
|
|
349
351
|
return int(self._as_int)
|
|
350
352
|
|
|
351
353
|
def is_even(self):
|
|
352
|
-
return istr.is_divisible_by(self,2)
|
|
354
|
+
return istr.is_divisible_by(self, 2)
|
|
353
355
|
|
|
354
356
|
def is_odd(self):
|
|
355
|
-
return not istr.is_divisible_by(self,2)
|
|
357
|
+
return not istr.is_divisible_by(self, 2)
|
|
356
358
|
|
|
357
359
|
def is_divisible_by(self, divisor):
|
|
358
360
|
return istr.interpret_as_int(self) % int(divisor) == 0
|
|
@@ -489,6 +491,17 @@ class istr(str):
|
|
|
489
491
|
def concat(cls, iterable):
|
|
490
492
|
return map(lambda x: istr("").join(x), istr(iterable))
|
|
491
493
|
|
|
494
|
+
|
|
495
|
+
def prod(self, *, start=1):
|
|
496
|
+
return math.prod(self, start=istr(start))
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
@classmethod
|
|
500
|
+
def sumprod(cls, p, q, /, strict=True):
|
|
501
|
+
if "sumprod" in math.__dict__ and strict:
|
|
502
|
+
return istr(math.sumprod(p, q))
|
|
503
|
+
return sum(_map(operator.__mul__, cls(p), cls(q), strict=strict))
|
|
504
|
+
|
|
492
505
|
@classmethod
|
|
493
506
|
def enumerate(cls, iterable, start=0):
|
|
494
507
|
for i, value in enumerate(iterable, start):
|
|
@@ -519,7 +532,7 @@ class istr(str):
|
|
|
519
532
|
def __new__(cls, cls_repr_mode, mode=None):
|
|
520
533
|
if mode is None:
|
|
521
534
|
return cls_repr_mode._repr_mode
|
|
522
|
-
if mode
|
|
535
|
+
if mode is int:
|
|
523
536
|
mode = "int"
|
|
524
537
|
if mode in ("istr", "str", "int"): # _istr is used only for TypeErrors
|
|
525
538
|
return super().__new__(cls)
|
|
@@ -628,6 +641,41 @@ class istr(str):
|
|
|
628
641
|
return result
|
|
629
642
|
|
|
630
643
|
|
|
644
|
+
def _map(func, *iterables, strict=False):
|
|
645
|
+
"""
|
|
646
|
+
like map, but with a strict parameter (also for Python < 3.14)
|
|
647
|
+
"""
|
|
648
|
+
if sys.version_info >= (3, 14):
|
|
649
|
+
yield from map(func, *iterables, strict=strict)
|
|
650
|
+
return
|
|
651
|
+
|
|
652
|
+
if not strict:
|
|
653
|
+
yield from map(func, *iterables)
|
|
654
|
+
return
|
|
655
|
+
|
|
656
|
+
iterators = [iter(it) for it in iterables]
|
|
657
|
+
|
|
658
|
+
while True:
|
|
659
|
+
values = []
|
|
660
|
+
exhausted = []
|
|
661
|
+
for it in iterators:
|
|
662
|
+
try:
|
|
663
|
+
v = next(it)
|
|
664
|
+
values.append(v)
|
|
665
|
+
exhausted.append(False)
|
|
666
|
+
except StopIteration:
|
|
667
|
+
values.append(None)
|
|
668
|
+
exhausted.append(True)
|
|
669
|
+
|
|
670
|
+
if all(exhausted):
|
|
671
|
+
return
|
|
672
|
+
|
|
673
|
+
if any(exhausted) and not all(exhausted):
|
|
674
|
+
raise ValueError("map_strict: iterables have different lengths")
|
|
675
|
+
|
|
676
|
+
yield func(*values)
|
|
677
|
+
|
|
678
|
+
|
|
631
679
|
istr.type = type(istr(0))
|
|
632
680
|
|
|
633
681
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: istr-python
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.8.post0
|
|
4
4
|
Summary: istr - strings you can count on
|
|
5
5
|
Author-email: Ruud van der Ham <rt.van.der.ham@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/salabim/istr
|
|
@@ -8,7 +8,7 @@ Project-URL: Repository, https://github.com/salabim/istr
|
|
|
8
8
|
Classifier: Development Status :: 5 - Production/Stable
|
|
9
9
|
Classifier: License :: OSI Approved :: MIT License
|
|
10
10
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
11
|
-
Requires-Python: >=3.
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
|
|
14
14
|
<img src="https://www.salabim.org/istr/istr_logo.png" width=500>
|
|
@@ -556,6 +556,25 @@ list(istr.concat(istr.permutations(range(3),2))) ==>
|
|
|
556
556
|
[istr('01'), istr('02'), istr('10'), istr('12'), istr('20'), istr('21')]
|
|
557
557
|
```
|
|
558
558
|
|
|
559
|
+
#### prod to get product of an iterable
|
|
560
|
+
|
|
561
|
+
The method `prod` can be used to return the product of an iterable (including an istr), like `math.prod`, but as istr.
|
|
562
|
+
Thus, `istr.prod(range(1,5))` is `istr(24)`
|
|
563
|
+
And `istr("123", start=4)` is also `istr(24)`.
|
|
564
|
+
|
|
565
|
+
It is also possible to apply `prod` on an istr:
|
|
566
|
+
`istr(1234).prod()` is `istr(24)`
|
|
567
|
+
`istr("123").prod(start=4)` is `istr(24)`
|
|
568
|
+
|
|
569
|
+
#### sumprod to get the sum of products of iterables
|
|
570
|
+
|
|
571
|
+
The class method `istr.sumprod()`, is equivalent to `math.sumprod()`, but applies istr to both iterables.
|
|
572
|
+
Note that this method is available even in Python < 3.12 .
|
|
573
|
+
Thus, `istr.sumprod("12", (3,4))` is `istr(11)`
|
|
574
|
+
In contrast with `math.sumprod()`, `istr.sumprod()` supports a `strict` parameter (True by default)
|
|
575
|
+
Thus, `istr.sumprod("12", (3,4,5), strict=False)` is `istr(11)`, whereas `istr.sumprod("12", (3,4,5))`
|
|
576
|
+
raises a ValueError.
|
|
577
|
+
|
|
559
578
|
#### generate istr with digits
|
|
560
579
|
|
|
561
580
|
The class method `digits` can be used to return an istr of digits according to a given specification.
|
|
@@ -10,9 +10,9 @@ authors = [
|
|
|
10
10
|
{ name = "Ruud van der Ham", email = "rt.van.der.ham@gmail.com" },
|
|
11
11
|
]
|
|
12
12
|
description = "istr - strings you can count on"
|
|
13
|
-
version = "1.1.
|
|
13
|
+
version = "1.1.8.post0"
|
|
14
14
|
readme = "README.md"
|
|
15
|
-
requires-python = ">=3.
|
|
15
|
+
requires-python = ">=3.8"
|
|
16
16
|
dependencies = []
|
|
17
17
|
classifiers = [
|
|
18
18
|
"Development Status :: 5 - Production/Stable",
|
|
@@ -313,7 +313,8 @@ def test_even_odd():
|
|
|
313
313
|
assert istr.is_even(12345678)
|
|
314
314
|
assert istr.is_odd(11111111)
|
|
315
315
|
|
|
316
|
-
|
|
316
|
+
|
|
317
|
+
def test_is_divisible_by():
|
|
317
318
|
assert istr(18).is_divisible_by(3)
|
|
318
319
|
assert istr(18).is_divisible_by(istr(3))
|
|
319
320
|
assert not istr(19).is_divisible_by(3)
|
|
@@ -323,6 +324,7 @@ def test_is_divisible():
|
|
|
323
324
|
assert istr.is_divisible_by(18, 3)
|
|
324
325
|
assert not istr.is_divisible_by(19, 3)
|
|
325
326
|
|
|
327
|
+
|
|
326
328
|
def test_is_square():
|
|
327
329
|
assert not istr(-1).is_square()
|
|
328
330
|
assert istr(0).is_square()
|
|
@@ -339,6 +341,7 @@ def test_is_square():
|
|
|
339
341
|
assert istr.is_square(4)
|
|
340
342
|
assert istr.is_square(16)
|
|
341
343
|
|
|
344
|
+
|
|
342
345
|
def test_is_cube():
|
|
343
346
|
assert not istr(-1).is_cube()
|
|
344
347
|
assert istr(0).is_cube()
|
|
@@ -366,16 +369,17 @@ def test_is_power_of():
|
|
|
366
369
|
assert not istr(99).is_power_of(3)
|
|
367
370
|
with pytest.raises(TypeError, match=re.escape(f"not interpretable as int")):
|
|
368
371
|
istr("a").is_power_of(3)
|
|
369
|
-
assert istr.is_power_of(0,3)
|
|
370
|
-
assert istr.is_power_of(1,3)
|
|
371
|
-
assert not istr.is_power_of(2,3)
|
|
372
|
-
assert istr.is_power_of(8,3)
|
|
373
|
-
assert istr.is_power_of(27,3)
|
|
372
|
+
assert istr.is_power_of(0, 3)
|
|
373
|
+
assert istr.is_power_of(1, 3)
|
|
374
|
+
assert not istr.is_power_of(2, 3)
|
|
375
|
+
assert istr.is_power_of(8, 3)
|
|
376
|
+
assert istr.is_power_of(27, 3)
|
|
374
377
|
with pytest.raises(TypeError):
|
|
375
378
|
istr(1).is_power_of(3.1)
|
|
376
379
|
with pytest.raises(ValueError):
|
|
377
380
|
istr(1).is_power_of(-1)
|
|
378
|
-
|
|
381
|
+
|
|
382
|
+
|
|
379
383
|
def test_is_prime():
|
|
380
384
|
assert not istr(0).is_prime()
|
|
381
385
|
assert not istr(1).is_prime()
|
|
@@ -553,12 +557,13 @@ def test_unpacking():
|
|
|
553
557
|
assert x.equals(istr(1))
|
|
554
558
|
assert y.equals(istr(2))
|
|
555
559
|
assert z.equals(istr(3))
|
|
556
|
-
del x,y,z
|
|
560
|
+
del x, y, z
|
|
557
561
|
|
|
558
562
|
x, y, z = a
|
|
559
563
|
assert x.equals(istr(1))
|
|
560
564
|
assert y.equals(istr(2))
|
|
561
|
-
assert z=="3"
|
|
565
|
+
assert z == "3"
|
|
566
|
+
|
|
562
567
|
|
|
563
568
|
def test_repr_mode():
|
|
564
569
|
hundred = istr(100)
|
|
@@ -649,9 +654,6 @@ def test_base():
|
|
|
649
654
|
assert a * a == 225
|
|
650
655
|
|
|
651
656
|
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
657
|
def test_digits():
|
|
656
658
|
assert istr.digits().equals(istr("0123456789"))
|
|
657
659
|
assert istr.digits("").equals(istr("0123456789"))
|
|
@@ -703,13 +705,16 @@ def test_itertools():
|
|
|
703
705
|
assert list(istr.dropwhile(lambda x: x < 5, [1, 4, 6, 4, 1])) == [istr("6"), istr("4"), istr("1")]
|
|
704
706
|
assert list(istr.filterfalse(lambda x: x % 2, range(10))) == [istr("0"), istr("2"), istr("4"), istr("6"), istr("8")]
|
|
705
707
|
assert list(istr.islice("123456", 2)) == [istr("1"), istr("2")]
|
|
706
|
-
assert list(istr.pairwise("1234")) == [(istr("1"), istr("2")), (istr("2"), istr("3")), (istr("3"), istr("4"))]
|
|
707
708
|
assert list(istr.permutations(range(5), 3)) == list(istr(itertools.permutations(range(5), 3)))
|
|
708
709
|
assert list(istr.product(range(5), range(4))) == list(istr(itertools.product(range(5), range(4))))
|
|
709
710
|
assert list100(istr.repeat(10)) == list100(istr(itertools.repeat(10)))
|
|
710
711
|
assert list(istr.starmap(pow, [(2, 5), (3, 2), (10, 3)])) == [istr("32"), istr("9"), istr("1000")]
|
|
711
712
|
assert list(istr.takewhile(lambda x: x < 5, [1, 4, 6, 3, 8])) == [istr("1"), istr("4")]
|
|
712
713
|
assert list(istr.zip_longest("123", "56", fillvalue="0")) == [(istr("1"), istr("5")), (istr("2"), istr("6")), (istr("3"), istr("0"))]
|
|
714
|
+
if sys.version_info >= (3, 10):
|
|
715
|
+
assert list(istr.pairwise("1234")) == [(istr("1"), istr("2")), (istr("2"), istr("3")), (istr("3"), istr("4"))]
|
|
716
|
+
if sys.version_info >= (3, 12):
|
|
717
|
+
assert list(istr.batched("12345", n=2)) == [(istr("1"), istr("2")), (istr("3"), istr("4")), (istr("5"),)]
|
|
713
718
|
|
|
714
719
|
|
|
715
720
|
def test_all_distinct():
|
|
@@ -718,6 +723,25 @@ def test_all_distinct():
|
|
|
718
723
|
assert istr("").all_distinct()
|
|
719
724
|
|
|
720
725
|
|
|
726
|
+
def test_prod():
|
|
727
|
+
assert istr.prod(range(1, 5)).equals(istr(24))
|
|
728
|
+
assert istr.prod((1, 2, 3), start=4).equals(istr(24))
|
|
729
|
+
assert istr("1234").prod().equals(istr(24))
|
|
730
|
+
assert istr("123").prod(start=4).equals(istr(24))
|
|
731
|
+
|
|
732
|
+
|
|
733
|
+
def test_sumprod():
|
|
734
|
+
assert istr.sumprod((1, 2), (3, 4)).equals(istr(11))
|
|
735
|
+
assert istr.sumprod(istr("12"), (3, 4)).equals(istr(11))
|
|
736
|
+
assert istr.sumprod(istr("12"), "34").equals(istr(11))
|
|
737
|
+
assert istr.sumprod(istr("12"), "34", strict=False).equals(istr(11))
|
|
738
|
+
assert istr.sumprod(istr("12"), "345", strict=False).equals(istr(11))
|
|
739
|
+
with pytest.raises(ValueError):
|
|
740
|
+
istr.sumprod((1, 2), (3, 4, 5))
|
|
741
|
+
with pytest.raises(ValueError):
|
|
742
|
+
istr.sumprod((1, 2), (3, 4, 5), strict=True)
|
|
743
|
+
|
|
744
|
+
|
|
721
745
|
def test_subclassing():
|
|
722
746
|
class jstr(istr.type): ...
|
|
723
747
|
|
|
@@ -750,8 +774,6 @@ def test_decompose():
|
|
|
750
774
|
istr(12).decompose("xyz")
|
|
751
775
|
with pytest.raises(ValueError):
|
|
752
776
|
istr(123).decompose("xy1")
|
|
753
|
-
|
|
754
|
-
|
|
755
777
|
|
|
756
778
|
|
|
757
779
|
def test_compose():
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|