istr-python 1.1.27__tar.gz → 1.1.29__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.27 → istr_python-1.1.29}/PKG-INFO +52 -34
- {istr_python-1.1.27 → istr_python-1.1.29}/README.md +51 -33
- {istr_python-1.1.27 → istr_python-1.1.29}/istr/istr.py +34 -9
- {istr_python-1.1.27 → istr_python-1.1.29}/istr_python.egg-info/PKG-INFO +52 -34
- {istr_python-1.1.27 → istr_python-1.1.29}/pyproject.toml +1 -1
- {istr_python-1.1.27 → istr_python-1.1.29}/tests/test_istr.py +86 -56
- {istr_python-1.1.27 → istr_python-1.1.29}/istr/LICENSE.txt +0 -0
- {istr_python-1.1.27 → istr_python-1.1.29}/istr/__init__.py +0 -0
- {istr_python-1.1.27 → istr_python-1.1.29}/istr_python.egg-info/SOURCES.txt +0 -0
- {istr_python-1.1.27 → istr_python-1.1.29}/istr_python.egg-info/dependency_links.txt +0 -0
- {istr_python-1.1.27 → istr_python-1.1.29}/istr_python.egg-info/top_level.txt +0 -0
- {istr_python-1.1.27 → istr_python-1.1.29}/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.29
|
|
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
|
|
@@ -335,7 +335,7 @@ several other types:
|
|
|
335
335
|
```
|
|
336
336
|
istr([0, 1, 4]) ==> [istr('0'), istr('1'), istr('4')]
|
|
337
337
|
istr((0, 1, 4)) ==> (istr('0'), istr('1'), istr('4'))
|
|
338
|
-
istr({0, 1, 4}) ==>
|
|
338
|
+
istr({0, 1, 4}) ==> {istr('4'), istr('0'), istr('1')} # or similar
|
|
339
339
|
```
|
|
340
340
|
|
|
341
341
|
- if a range, an istr.range instance will be returned
|
|
@@ -395,6 +395,20 @@ istr.is_palindrome('no devil lived on') ==> True
|
|
|
395
395
|
istr.is_palindrome(min) ==> False
|
|
396
396
|
```
|
|
397
397
|
|
|
398
|
+
#### test for increasing, decreasing, non-decreasing and non-increasing
|
|
399
|
+
|
|
400
|
+
It is possible to test whether the characters of an istr are increasing, decreasing, non-decreasing or non-increasing, like
|
|
401
|
+
```
|
|
402
|
+
istr(1223).is_increasing() ==> False
|
|
403
|
+
istr(1223).is_non_decreasing() ==> True
|
|
404
|
+
istr(3221).is_decreasing() ==> False
|
|
405
|
+
istr(3221).is_non_increasing ==> True
|
|
406
|
+
```
|
|
407
|
+
It is also possible to test for 'increasingness' and friends for anything that can be converted to a str:
|
|
408
|
+
```
|
|
409
|
+
istr.is_increasing(123) ==> True
|
|
410
|
+
```
|
|
411
|
+
|
|
398
412
|
#### test for divisibility
|
|
399
413
|
|
|
400
414
|
It is possible to test whether an istr is divisible by a given value with the `is_divisible_by method,` e.g.
|
|
@@ -416,7 +430,7 @@ unless the *fallback* (last argument) is given, in which case *fallback* will be
|
|
|
416
430
|
istr(18).divided_by(3) ==> 6 (actually istr("6"))
|
|
417
431
|
istr(18).divided_by(istr(3)) ==> 6
|
|
418
432
|
istr(19).divided_by(3) ==> None
|
|
419
|
-
istr(19).divided_by(3, 0) ==>
|
|
433
|
+
istr(19).divided_by(3, 0) ==> 0
|
|
420
434
|
istr(19).divided_by(3) ==> None
|
|
421
435
|
istr(19).divided_by(istr(3)) ==> None
|
|
422
436
|
istr.divided_by(18, 3) ==> 6
|
|
@@ -447,7 +461,7 @@ istr(28).is_cube()) ==> False
|
|
|
447
461
|
It is also possible to test for cube of an ordinary int:
|
|
448
462
|
```
|
|
449
463
|
istr.is_cube(27) ==> True
|
|
450
|
-
istr.is_cube(28 ==> False
|
|
464
|
+
istr.is_cube(28) ==> False
|
|
451
465
|
```
|
|
452
466
|
|
|
453
467
|
#### test for power of
|
|
@@ -530,6 +544,7 @@ istr('0456')[::-1] ==> istr('6540')
|
|
|
530
544
|
> It is possible to reverse a negative istr, but the result can't be interpreted as an int anymore.
|
|
531
545
|
>
|
|
532
546
|
> ```
|
|
547
|
+
> istr(-456).reversed() ==> istr('654-')
|
|
533
548
|
> istr(-456).reversed() + 3 ==> TypeError
|
|
534
549
|
> ```
|
|
535
550
|
|
|
@@ -723,7 +738,7 @@ To decompose an istr into individual variables, it is arguably easier and safer
|
|
|
723
738
|
a, b, c = istr(485)
|
|
724
739
|
```
|
|
725
740
|
|
|
726
|
-
With `istr.compose()`, an istr can be constructed from individual (global) variables and
|
|
741
|
+
With `istr.compose()`, an istr can be constructed from individual (global) variables and letters that can't be identifiers.
|
|
727
742
|
E.g.
|
|
728
743
|
|
|
729
744
|
```
|
|
@@ -732,17 +747,19 @@ y = 9
|
|
|
732
747
|
z = 6
|
|
733
748
|
test1 = istr.compose("xyz")
|
|
734
749
|
test2 = istr.compose("xyz0")
|
|
750
|
+
test3 = istr.compose("(xyz)")
|
|
735
751
|
```
|
|
736
|
-
Now, `test1` will be `istr(396)` and `
|
|
752
|
+
Now, `test1` will be `istr(396)`, `test2` will be `istr(3960)` and `test3` will be `istr("(396)")`.
|
|
737
753
|
|
|
738
|
-
Composing can also be done by prefixing a string with
|
|
754
|
+
Composing can also be done by prefixing a string with `=`, like:
|
|
739
755
|
|
|
740
756
|
```
|
|
741
757
|
test1 = istr("=xyz")
|
|
742
758
|
test2 = istr("=xyz0")
|
|
743
|
-
|
|
744
|
-
Now, `test1` will be `istr(396)` and `test2` will be `istr(3960)`.
|
|
759
|
+
test3 = istr("=(xyz)")
|
|
745
760
|
```
|
|
761
|
+
Now, `test1` will be `istr(396)`, `test2` will be `istr(3960)` and `test3` will be `istr("(396)")`.
|
|
762
|
+
|
|
746
763
|
Note that `str(istr("="))` is "=".
|
|
747
764
|
|
|
748
765
|
Composing and assignment can be done by prefixing a string with ':=', like:
|
|
@@ -933,31 +950,32 @@ operator/function int str Example
|
|
|
933
950
|
+ x istr(20) + 3 ==> istr('23')
|
|
934
951
|
_ x istr(20) - 3 ==> istr('17')
|
|
935
952
|
* x istr(20) * 3 ==> istr('60')
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
953
|
+
/ x istr(20) / 3 ==> istr('6')
|
|
954
|
+
// x istr(20) // 3 ==> istr('6')
|
|
955
|
+
% x istr(20) % 3 ==> istr('2')
|
|
956
|
+
divmod x divmod(istr(20), 3) ==> (istr('6'), istr('2'))
|
|
957
|
+
** x istr(2) ** 3 ==> istr('8')
|
|
958
|
+
<=, <, >, >= x istr('100') > istr('2') ==> True
|
|
959
|
+
abs x abs(istr(-20)) ==> istr('20')
|
|
960
|
+
int x int(istr("20")) ==> 20
|
|
961
|
+
float x float(istr("20")) ==> 20.0
|
|
962
|
+
complex x complex(istr("20")) ==> (20+0j)
|
|
963
|
+
== x x istr(20) == 20 ==> True | istr(20) == '20' ==> True
|
|
964
|
+
bool x x *) bool(istr(' 0 ')) ==> False | bool(istr('')) ==> False
|
|
965
|
+
@ x istr(20) @ 3 ==> istr('202020')
|
|
966
|
+
| x istr(20) | '5' ==> istr('205')
|
|
967
|
+
slicing x istr(12345)[1:3] ==> istr('23')
|
|
968
|
+
iterate x [x for x in istr(20)] ==> [istr('2'), istr('0')]
|
|
969
|
+
len x len(istr(' 20 ')) ==> 4
|
|
970
|
+
count x istr(100).count(0) ==> 2
|
|
971
|
+
istr.count(100) ==> istr('100'), istr('101'). istr('102'), ...
|
|
972
|
+
index x istr(' 100 ').index('0') ==> 2
|
|
973
|
+
split x istr('1 2').split() ==> (istr('1'), istr('2'))
|
|
974
|
+
string format x f"|{istr(1234):6}|" ==> '|1234 |'
|
|
975
|
+
other string methods x istr('aAbBcC').lower() ==> istr('aabbcc')
|
|
976
|
+
istr('aAbBcC').islower() ==> False
|
|
977
|
+
istr(' abc ').strip() ==> istr('abc')
|
|
978
|
+
...
|
|
961
979
|
-----------------------------------------------------------------------------------------
|
|
962
980
|
*) str is applied if is_int() is False
|
|
963
981
|
```
|
|
@@ -322,7 +322,7 @@ several other types:
|
|
|
322
322
|
```
|
|
323
323
|
istr([0, 1, 4]) ==> [istr('0'), istr('1'), istr('4')]
|
|
324
324
|
istr((0, 1, 4)) ==> (istr('0'), istr('1'), istr('4'))
|
|
325
|
-
istr({0, 1, 4}) ==>
|
|
325
|
+
istr({0, 1, 4}) ==> {istr('4'), istr('0'), istr('1')} # or similar
|
|
326
326
|
```
|
|
327
327
|
|
|
328
328
|
- if a range, an istr.range instance will be returned
|
|
@@ -382,6 +382,20 @@ istr.is_palindrome('no devil lived on') ==> True
|
|
|
382
382
|
istr.is_palindrome(min) ==> False
|
|
383
383
|
```
|
|
384
384
|
|
|
385
|
+
#### test for increasing, decreasing, non-decreasing and non-increasing
|
|
386
|
+
|
|
387
|
+
It is possible to test whether the characters of an istr are increasing, decreasing, non-decreasing or non-increasing, like
|
|
388
|
+
```
|
|
389
|
+
istr(1223).is_increasing() ==> False
|
|
390
|
+
istr(1223).is_non_decreasing() ==> True
|
|
391
|
+
istr(3221).is_decreasing() ==> False
|
|
392
|
+
istr(3221).is_non_increasing ==> True
|
|
393
|
+
```
|
|
394
|
+
It is also possible to test for 'increasingness' and friends for anything that can be converted to a str:
|
|
395
|
+
```
|
|
396
|
+
istr.is_increasing(123) ==> True
|
|
397
|
+
```
|
|
398
|
+
|
|
385
399
|
#### test for divisibility
|
|
386
400
|
|
|
387
401
|
It is possible to test whether an istr is divisible by a given value with the `is_divisible_by method,` e.g.
|
|
@@ -403,7 +417,7 @@ unless the *fallback* (last argument) is given, in which case *fallback* will be
|
|
|
403
417
|
istr(18).divided_by(3) ==> 6 (actually istr("6"))
|
|
404
418
|
istr(18).divided_by(istr(3)) ==> 6
|
|
405
419
|
istr(19).divided_by(3) ==> None
|
|
406
|
-
istr(19).divided_by(3, 0) ==>
|
|
420
|
+
istr(19).divided_by(3, 0) ==> 0
|
|
407
421
|
istr(19).divided_by(3) ==> None
|
|
408
422
|
istr(19).divided_by(istr(3)) ==> None
|
|
409
423
|
istr.divided_by(18, 3) ==> 6
|
|
@@ -434,7 +448,7 @@ istr(28).is_cube()) ==> False
|
|
|
434
448
|
It is also possible to test for cube of an ordinary int:
|
|
435
449
|
```
|
|
436
450
|
istr.is_cube(27) ==> True
|
|
437
|
-
istr.is_cube(28 ==> False
|
|
451
|
+
istr.is_cube(28) ==> False
|
|
438
452
|
```
|
|
439
453
|
|
|
440
454
|
#### test for power of
|
|
@@ -517,6 +531,7 @@ istr('0456')[::-1] ==> istr('6540')
|
|
|
517
531
|
> It is possible to reverse a negative istr, but the result can't be interpreted as an int anymore.
|
|
518
532
|
>
|
|
519
533
|
> ```
|
|
534
|
+
> istr(-456).reversed() ==> istr('654-')
|
|
520
535
|
> istr(-456).reversed() + 3 ==> TypeError
|
|
521
536
|
> ```
|
|
522
537
|
|
|
@@ -710,7 +725,7 @@ To decompose an istr into individual variables, it is arguably easier and safer
|
|
|
710
725
|
a, b, c = istr(485)
|
|
711
726
|
```
|
|
712
727
|
|
|
713
|
-
With `istr.compose()`, an istr can be constructed from individual (global) variables and
|
|
728
|
+
With `istr.compose()`, an istr can be constructed from individual (global) variables and letters that can't be identifiers.
|
|
714
729
|
E.g.
|
|
715
730
|
|
|
716
731
|
```
|
|
@@ -719,17 +734,19 @@ y = 9
|
|
|
719
734
|
z = 6
|
|
720
735
|
test1 = istr.compose("xyz")
|
|
721
736
|
test2 = istr.compose("xyz0")
|
|
737
|
+
test3 = istr.compose("(xyz)")
|
|
722
738
|
```
|
|
723
|
-
Now, `test1` will be `istr(396)` and `
|
|
739
|
+
Now, `test1` will be `istr(396)`, `test2` will be `istr(3960)` and `test3` will be `istr("(396)")`.
|
|
724
740
|
|
|
725
|
-
Composing can also be done by prefixing a string with
|
|
741
|
+
Composing can also be done by prefixing a string with `=`, like:
|
|
726
742
|
|
|
727
743
|
```
|
|
728
744
|
test1 = istr("=xyz")
|
|
729
745
|
test2 = istr("=xyz0")
|
|
730
|
-
|
|
731
|
-
Now, `test1` will be `istr(396)` and `test2` will be `istr(3960)`.
|
|
746
|
+
test3 = istr("=(xyz)")
|
|
732
747
|
```
|
|
748
|
+
Now, `test1` will be `istr(396)`, `test2` will be `istr(3960)` and `test3` will be `istr("(396)")`.
|
|
749
|
+
|
|
733
750
|
Note that `str(istr("="))` is "=".
|
|
734
751
|
|
|
735
752
|
Composing and assignment can be done by prefixing a string with ':=', like:
|
|
@@ -920,31 +937,32 @@ operator/function int str Example
|
|
|
920
937
|
+ x istr(20) + 3 ==> istr('23')
|
|
921
938
|
_ x istr(20) - 3 ==> istr('17')
|
|
922
939
|
* x istr(20) * 3 ==> istr('60')
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
940
|
+
/ x istr(20) / 3 ==> istr('6')
|
|
941
|
+
// x istr(20) // 3 ==> istr('6')
|
|
942
|
+
% x istr(20) % 3 ==> istr('2')
|
|
943
|
+
divmod x divmod(istr(20), 3) ==> (istr('6'), istr('2'))
|
|
944
|
+
** x istr(2) ** 3 ==> istr('8')
|
|
945
|
+
<=, <, >, >= x istr('100') > istr('2') ==> True
|
|
946
|
+
abs x abs(istr(-20)) ==> istr('20')
|
|
947
|
+
int x int(istr("20")) ==> 20
|
|
948
|
+
float x float(istr("20")) ==> 20.0
|
|
949
|
+
complex x complex(istr("20")) ==> (20+0j)
|
|
950
|
+
== x x istr(20) == 20 ==> True | istr(20) == '20' ==> True
|
|
951
|
+
bool x x *) bool(istr(' 0 ')) ==> False | bool(istr('')) ==> False
|
|
952
|
+
@ x istr(20) @ 3 ==> istr('202020')
|
|
953
|
+
| x istr(20) | '5' ==> istr('205')
|
|
954
|
+
slicing x istr(12345)[1:3] ==> istr('23')
|
|
955
|
+
iterate x [x for x in istr(20)] ==> [istr('2'), istr('0')]
|
|
956
|
+
len x len(istr(' 20 ')) ==> 4
|
|
957
|
+
count x istr(100).count(0) ==> 2
|
|
958
|
+
istr.count(100) ==> istr('100'), istr('101'). istr('102'), ...
|
|
959
|
+
index x istr(' 100 ').index('0') ==> 2
|
|
960
|
+
split x istr('1 2').split() ==> (istr('1'), istr('2'))
|
|
961
|
+
string format x f"|{istr(1234):6}|" ==> '|1234 |'
|
|
962
|
+
other string methods x istr('aAbBcC').lower() ==> istr('aabbcc')
|
|
963
|
+
istr('aAbBcC').islower() ==> False
|
|
964
|
+
istr(' abc ').strip() ==> istr('abc')
|
|
965
|
+
...
|
|
948
966
|
-----------------------------------------------------------------------------------------
|
|
949
967
|
*) str is applied if is_int() is False
|
|
950
968
|
```
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# |_||___/ \__||_|
|
|
6
6
|
# strings you can count on
|
|
7
7
|
|
|
8
|
-
__version__ = "1.1.
|
|
8
|
+
__version__ = "1.1.29"
|
|
9
9
|
import functools
|
|
10
10
|
import itertools
|
|
11
11
|
import types
|
|
@@ -407,6 +407,22 @@ class istr(str):
|
|
|
407
407
|
self_as_str = str(self)
|
|
408
408
|
return self_as_str == self_as_str[::-1]
|
|
409
409
|
|
|
410
|
+
def is_non_decreasing(self):
|
|
411
|
+
self_as_str = str(self)
|
|
412
|
+
return all(i0 <= i1 for i0, i1 in zip(self_as_str, self_as_str[1:]))
|
|
413
|
+
|
|
414
|
+
def is_non_increasing(self):
|
|
415
|
+
self_as_str = str(self)
|
|
416
|
+
return all(i0 >= i1 for i0, i1 in zip(self_as_str, self_as_str[1:]))
|
|
417
|
+
|
|
418
|
+
def is_increasing(self):
|
|
419
|
+
self_as_str = str(self)
|
|
420
|
+
return all(i0 < i1 for i0, i1 in zip(self_as_str, self_as_str[1:]))
|
|
421
|
+
|
|
422
|
+
def is_decreasing(self):
|
|
423
|
+
self_as_str = str(self)
|
|
424
|
+
return all(i0 > i1 for i0, i1 in zip(self_as_str, self_as_str[1:]))
|
|
425
|
+
|
|
410
426
|
def is_divisible_by(self, divisor):
|
|
411
427
|
return istr.divided_by(self, divisor) is not None
|
|
412
428
|
|
|
@@ -584,14 +600,16 @@ class istr(str):
|
|
|
584
600
|
namespace = get_namespace(namespace)
|
|
585
601
|
|
|
586
602
|
lookup = {}
|
|
603
|
+
|
|
604
|
+
if len(letters) != len(self):
|
|
605
|
+
raise ValueError(f"incorrect number of variables {len(letters)}; should be {len(self)}")
|
|
606
|
+
|
|
587
607
|
for letter, ch in zip(letters, self):
|
|
588
608
|
if letter in lookup and lookup[letter] != ch:
|
|
589
609
|
raise ValueError(f"multiple values found for variable {letter}")
|
|
590
610
|
if not letter.isidentifier():
|
|
591
611
|
raise ValueError(f"{repr(letter)} cannot be used as a variable")
|
|
592
612
|
lookup[str(letter)] = ch
|
|
593
|
-
if len(letters) != len(self):
|
|
594
|
-
raise ValueError(f"incorrect number of variables {len(letters)}; should be {len(self)}")
|
|
595
613
|
namespace.update(lookup)
|
|
596
614
|
|
|
597
615
|
@classmethod
|
|
@@ -599,13 +617,16 @@ class istr(str):
|
|
|
599
617
|
"""
|
|
600
618
|
compose an istr from individual letter variables
|
|
601
619
|
"""
|
|
602
|
-
namespace = get_namespace(namespace)
|
|
620
|
+
namespace = get_namespace(namespace)
|
|
621
|
+
result=[]
|
|
603
622
|
for letter in letters:
|
|
604
623
|
if letter.isidentifier():
|
|
605
624
|
if letter not in namespace:
|
|
606
625
|
raise ValueError(f"variable {repr(letter)} not defined")
|
|
607
|
-
|
|
608
|
-
|
|
626
|
+
result.append(str(namespace[letter]))
|
|
627
|
+
else:
|
|
628
|
+
result.append(letter)
|
|
629
|
+
return cls("".join(result))
|
|
609
630
|
|
|
610
631
|
def __or__(self, other):
|
|
611
632
|
if isinstance(other, str):
|
|
@@ -746,7 +767,8 @@ class istr(str):
|
|
|
746
767
|
|
|
747
768
|
cls._int_format = int_format
|
|
748
769
|
|
|
749
|
-
def __enter__(self):
|
|
770
|
+
def __enter__(self):
|
|
771
|
+
...
|
|
750
772
|
|
|
751
773
|
def __exit__(self, exc_type, exc_value, exc_tb):
|
|
752
774
|
self.saved_cls._int_format = self.saved_int_format
|
|
@@ -767,7 +789,8 @@ class istr(str):
|
|
|
767
789
|
self.saved_cls = cls
|
|
768
790
|
cls._repr_mode = mode
|
|
769
791
|
|
|
770
|
-
def __enter__(self):
|
|
792
|
+
def __enter__(self):
|
|
793
|
+
...
|
|
771
794
|
|
|
772
795
|
def __exit__(self, exc_type, exc_value, exc_tb):
|
|
773
796
|
self.saved_cls._repr_mode = self.saved_repr_mode
|
|
@@ -786,7 +809,8 @@ class istr(str):
|
|
|
786
809
|
self.saved_cls = cls
|
|
787
810
|
cls._base = base
|
|
788
811
|
|
|
789
|
-
def __enter__(self):
|
|
812
|
+
def __enter__(self):
|
|
813
|
+
...
|
|
790
814
|
|
|
791
815
|
def __exit__(self, exc_type, exc_value, exc_tb):
|
|
792
816
|
self.saved_cls._base = self.saved_base
|
|
@@ -968,3 +992,4 @@ class istrModule(types.ModuleType):
|
|
|
968
992
|
|
|
969
993
|
if __name__ != "__main__":
|
|
970
994
|
sys.modules["istr"].__class__ = istrModule
|
|
995
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: istr-python
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.29
|
|
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
|
|
@@ -335,7 +335,7 @@ several other types:
|
|
|
335
335
|
```
|
|
336
336
|
istr([0, 1, 4]) ==> [istr('0'), istr('1'), istr('4')]
|
|
337
337
|
istr((0, 1, 4)) ==> (istr('0'), istr('1'), istr('4'))
|
|
338
|
-
istr({0, 1, 4}) ==>
|
|
338
|
+
istr({0, 1, 4}) ==> {istr('4'), istr('0'), istr('1')} # or similar
|
|
339
339
|
```
|
|
340
340
|
|
|
341
341
|
- if a range, an istr.range instance will be returned
|
|
@@ -395,6 +395,20 @@ istr.is_palindrome('no devil lived on') ==> True
|
|
|
395
395
|
istr.is_palindrome(min) ==> False
|
|
396
396
|
```
|
|
397
397
|
|
|
398
|
+
#### test for increasing, decreasing, non-decreasing and non-increasing
|
|
399
|
+
|
|
400
|
+
It is possible to test whether the characters of an istr are increasing, decreasing, non-decreasing or non-increasing, like
|
|
401
|
+
```
|
|
402
|
+
istr(1223).is_increasing() ==> False
|
|
403
|
+
istr(1223).is_non_decreasing() ==> True
|
|
404
|
+
istr(3221).is_decreasing() ==> False
|
|
405
|
+
istr(3221).is_non_increasing ==> True
|
|
406
|
+
```
|
|
407
|
+
It is also possible to test for 'increasingness' and friends for anything that can be converted to a str:
|
|
408
|
+
```
|
|
409
|
+
istr.is_increasing(123) ==> True
|
|
410
|
+
```
|
|
411
|
+
|
|
398
412
|
#### test for divisibility
|
|
399
413
|
|
|
400
414
|
It is possible to test whether an istr is divisible by a given value with the `is_divisible_by method,` e.g.
|
|
@@ -416,7 +430,7 @@ unless the *fallback* (last argument) is given, in which case *fallback* will be
|
|
|
416
430
|
istr(18).divided_by(3) ==> 6 (actually istr("6"))
|
|
417
431
|
istr(18).divided_by(istr(3)) ==> 6
|
|
418
432
|
istr(19).divided_by(3) ==> None
|
|
419
|
-
istr(19).divided_by(3, 0) ==>
|
|
433
|
+
istr(19).divided_by(3, 0) ==> 0
|
|
420
434
|
istr(19).divided_by(3) ==> None
|
|
421
435
|
istr(19).divided_by(istr(3)) ==> None
|
|
422
436
|
istr.divided_by(18, 3) ==> 6
|
|
@@ -447,7 +461,7 @@ istr(28).is_cube()) ==> False
|
|
|
447
461
|
It is also possible to test for cube of an ordinary int:
|
|
448
462
|
```
|
|
449
463
|
istr.is_cube(27) ==> True
|
|
450
|
-
istr.is_cube(28 ==> False
|
|
464
|
+
istr.is_cube(28) ==> False
|
|
451
465
|
```
|
|
452
466
|
|
|
453
467
|
#### test for power of
|
|
@@ -530,6 +544,7 @@ istr('0456')[::-1] ==> istr('6540')
|
|
|
530
544
|
> It is possible to reverse a negative istr, but the result can't be interpreted as an int anymore.
|
|
531
545
|
>
|
|
532
546
|
> ```
|
|
547
|
+
> istr(-456).reversed() ==> istr('654-')
|
|
533
548
|
> istr(-456).reversed() + 3 ==> TypeError
|
|
534
549
|
> ```
|
|
535
550
|
|
|
@@ -723,7 +738,7 @@ To decompose an istr into individual variables, it is arguably easier and safer
|
|
|
723
738
|
a, b, c = istr(485)
|
|
724
739
|
```
|
|
725
740
|
|
|
726
|
-
With `istr.compose()`, an istr can be constructed from individual (global) variables and
|
|
741
|
+
With `istr.compose()`, an istr can be constructed from individual (global) variables and letters that can't be identifiers.
|
|
727
742
|
E.g.
|
|
728
743
|
|
|
729
744
|
```
|
|
@@ -732,17 +747,19 @@ y = 9
|
|
|
732
747
|
z = 6
|
|
733
748
|
test1 = istr.compose("xyz")
|
|
734
749
|
test2 = istr.compose("xyz0")
|
|
750
|
+
test3 = istr.compose("(xyz)")
|
|
735
751
|
```
|
|
736
|
-
Now, `test1` will be `istr(396)` and `
|
|
752
|
+
Now, `test1` will be `istr(396)`, `test2` will be `istr(3960)` and `test3` will be `istr("(396)")`.
|
|
737
753
|
|
|
738
|
-
Composing can also be done by prefixing a string with
|
|
754
|
+
Composing can also be done by prefixing a string with `=`, like:
|
|
739
755
|
|
|
740
756
|
```
|
|
741
757
|
test1 = istr("=xyz")
|
|
742
758
|
test2 = istr("=xyz0")
|
|
743
|
-
|
|
744
|
-
Now, `test1` will be `istr(396)` and `test2` will be `istr(3960)`.
|
|
759
|
+
test3 = istr("=(xyz)")
|
|
745
760
|
```
|
|
761
|
+
Now, `test1` will be `istr(396)`, `test2` will be `istr(3960)` and `test3` will be `istr("(396)")`.
|
|
762
|
+
|
|
746
763
|
Note that `str(istr("="))` is "=".
|
|
747
764
|
|
|
748
765
|
Composing and assignment can be done by prefixing a string with ':=', like:
|
|
@@ -933,31 +950,32 @@ operator/function int str Example
|
|
|
933
950
|
+ x istr(20) + 3 ==> istr('23')
|
|
934
951
|
_ x istr(20) - 3 ==> istr('17')
|
|
935
952
|
* x istr(20) * 3 ==> istr('60')
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
953
|
+
/ x istr(20) / 3 ==> istr('6')
|
|
954
|
+
// x istr(20) // 3 ==> istr('6')
|
|
955
|
+
% x istr(20) % 3 ==> istr('2')
|
|
956
|
+
divmod x divmod(istr(20), 3) ==> (istr('6'), istr('2'))
|
|
957
|
+
** x istr(2) ** 3 ==> istr('8')
|
|
958
|
+
<=, <, >, >= x istr('100') > istr('2') ==> True
|
|
959
|
+
abs x abs(istr(-20)) ==> istr('20')
|
|
960
|
+
int x int(istr("20")) ==> 20
|
|
961
|
+
float x float(istr("20")) ==> 20.0
|
|
962
|
+
complex x complex(istr("20")) ==> (20+0j)
|
|
963
|
+
== x x istr(20) == 20 ==> True | istr(20) == '20' ==> True
|
|
964
|
+
bool x x *) bool(istr(' 0 ')) ==> False | bool(istr('')) ==> False
|
|
965
|
+
@ x istr(20) @ 3 ==> istr('202020')
|
|
966
|
+
| x istr(20) | '5' ==> istr('205')
|
|
967
|
+
slicing x istr(12345)[1:3] ==> istr('23')
|
|
968
|
+
iterate x [x for x in istr(20)] ==> [istr('2'), istr('0')]
|
|
969
|
+
len x len(istr(' 20 ')) ==> 4
|
|
970
|
+
count x istr(100).count(0) ==> 2
|
|
971
|
+
istr.count(100) ==> istr('100'), istr('101'). istr('102'), ...
|
|
972
|
+
index x istr(' 100 ').index('0') ==> 2
|
|
973
|
+
split x istr('1 2').split() ==> (istr('1'), istr('2'))
|
|
974
|
+
string format x f"|{istr(1234):6}|" ==> '|1234 |'
|
|
975
|
+
other string methods x istr('aAbBcC').lower() ==> istr('aabbcc')
|
|
976
|
+
istr('aAbBcC').islower() ==> False
|
|
977
|
+
istr(' abc ').strip() ==> istr('abc')
|
|
978
|
+
...
|
|
961
979
|
-----------------------------------------------------------------------------------------
|
|
962
980
|
*) str is applied if is_int() is False
|
|
963
981
|
```
|
|
@@ -256,24 +256,25 @@ def test_index():
|
|
|
256
256
|
|
|
257
257
|
def test_str_count():
|
|
258
258
|
assert istr("100").count("0") == 2
|
|
259
|
-
assert istr("100").count("0",0) ==2
|
|
260
|
-
assert istr("100").count("0",1)==2
|
|
261
|
-
assert istr("100").count("0",2)==1
|
|
262
|
-
assert istr("100").count("0",0,1)==0
|
|
263
|
-
assert istr("100").count(0)==2
|
|
264
|
-
assert istr("100").count(10)==1
|
|
265
|
-
assert istr("100").count(100)==1
|
|
266
|
-
assert istr("1000").count(100)==1
|
|
267
|
-
assert isinstance(istr("100").count(),map) # this is in fact the itertools version
|
|
259
|
+
assert istr("100").count("0", 0) == 2
|
|
260
|
+
assert istr("100").count("0", 1) == 2
|
|
261
|
+
assert istr("100").count("0", 2) == 1
|
|
262
|
+
assert istr("100").count("0", 0, 1) == 0
|
|
263
|
+
assert istr("100").count(0) == 2
|
|
264
|
+
assert istr("100").count(10) == 1
|
|
265
|
+
assert istr("100").count(100) == 1
|
|
266
|
+
assert istr("1000").count(100) == 1
|
|
267
|
+
assert isinstance(istr("100").count(), map) # this is in fact the itertools version
|
|
268
268
|
|
|
269
269
|
|
|
270
270
|
def test_itertools_count():
|
|
271
|
-
assert list(itertools.islice(istr.count(),3))==[istr(
|
|
272
|
-
assert list(istr.islice(istr.count(10),3)) ==[istr(
|
|
273
|
-
assert list(istr.islice(istr.count(istr(10)),3)) ==[istr(
|
|
274
|
-
assert list(istr.islice(istr.count(10,3),3))==[istr(
|
|
271
|
+
assert list(itertools.islice(istr.count(), 3)) == [istr("0"), istr("1"), istr("2")]
|
|
272
|
+
assert list(istr.islice(istr.count(10), 3)) == [istr("10"), istr("11"), istr("12")]
|
|
273
|
+
assert list(istr.islice(istr.count(istr(10)), 3)) == [istr("10"), istr("11"), istr("12")]
|
|
274
|
+
assert list(istr.islice(istr.count(10, 3), 3)) == [istr("10"), istr("13"), istr("16")]
|
|
275
|
+
|
|
276
|
+
assert istr.count(istr(10), 1) == 1 # this is in fact the istr version
|
|
275
277
|
|
|
276
|
-
assert istr.count(istr(10),1)==1 # this is in fact the istr version
|
|
277
278
|
|
|
278
279
|
def test_hash():
|
|
279
280
|
assert hash(istr.range(1, 13)) == hash(one_to_twelve)
|
|
@@ -347,13 +348,40 @@ def test_even_odd():
|
|
|
347
348
|
def test_is_palindrome():
|
|
348
349
|
assert istr(121).is_palindrome()
|
|
349
350
|
assert istr(1234321).is_palindrome()
|
|
350
|
-
assert not istr(123).is_palindrome()
|
|
351
|
-
assert istr(
|
|
352
|
-
assert not istr(
|
|
353
|
-
assert istr(
|
|
354
|
-
assert istr.is_palindrome(
|
|
355
|
-
assert istr.is_palindrome(121)
|
|
356
|
-
|
|
351
|
+
assert not istr(123).is_palindrome()
|
|
352
|
+
assert istr("aba").is_palindrome()
|
|
353
|
+
assert not istr("abc").is_palindrome()
|
|
354
|
+
assert istr("").is_palindrome()
|
|
355
|
+
assert istr.is_palindrome("121")
|
|
356
|
+
assert istr.is_palindrome(121)
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
def test_is_increasing_and_friends():
|
|
360
|
+
assert istr(123).is_increasing()
|
|
361
|
+
assert not istr(222).is_increasing()
|
|
362
|
+
assert not istr(321).is_increasing()
|
|
363
|
+
|
|
364
|
+
assert not istr(123).is_decreasing()
|
|
365
|
+
assert not istr(222).is_decreasing()
|
|
366
|
+
assert istr(321).is_decreasing()
|
|
367
|
+
|
|
368
|
+
assert istr(123).is_non_decreasing()
|
|
369
|
+
assert istr(222).is_non_decreasing()
|
|
370
|
+
assert not istr(321).is_non_decreasing()
|
|
371
|
+
|
|
372
|
+
assert not istr(123).is_non_increasing()
|
|
373
|
+
assert istr(222).is_non_increasing()
|
|
374
|
+
assert istr(321).is_non_increasing()
|
|
375
|
+
|
|
376
|
+
assert istr(1).is_increasing()
|
|
377
|
+
assert istr("").is_increasing()
|
|
378
|
+
|
|
379
|
+
assert not istr.is_increasing(222)
|
|
380
|
+
assert not istr.is_decreasing(222)
|
|
381
|
+
assert istr.is_non_decreasing(222)
|
|
382
|
+
assert istr.is_non_increasing(222)
|
|
383
|
+
|
|
384
|
+
|
|
357
385
|
def test_is_divisible_by():
|
|
358
386
|
assert istr(18).is_divisible_by(3)
|
|
359
387
|
assert istr(18).is_divisible_by(istr(3))
|
|
@@ -375,9 +403,9 @@ def test_divided_by():
|
|
|
375
403
|
assert istr.divided_by(18, 3).equals(istr(6))
|
|
376
404
|
assert istr.divided_by(19, 3) is None
|
|
377
405
|
assert istr.divided_by(18, 3, 0).equals(istr(6))
|
|
378
|
-
assert istr.divided_by(19, 3, 0)==0
|
|
379
|
-
assert istr.divided_by(4,0) is None
|
|
380
|
-
assert istr.divided_by(4,0,0) == 0
|
|
406
|
+
assert istr.divided_by(19, 3, 0) == 0
|
|
407
|
+
assert istr.divided_by(4, 0) is None
|
|
408
|
+
assert istr.divided_by(4, 0, 0) == 0
|
|
381
409
|
|
|
382
410
|
|
|
383
411
|
def test_is_square():
|
|
@@ -426,7 +454,7 @@ def test_is_power_of():
|
|
|
426
454
|
assert not istr(-1).is_power_of(4)
|
|
427
455
|
assert istr(-1).is_power_of(5)
|
|
428
456
|
assert istr(12345**3).is_power_of(3)
|
|
429
|
-
assert istr(-12345**3).is_power_of(3)
|
|
457
|
+
assert istr(-(12345**3)).is_power_of(3)
|
|
430
458
|
assert istr(0).is_power_of(3)
|
|
431
459
|
assert istr(1).is_power_of(3)
|
|
432
460
|
assert not istr(2).is_power_of(3)
|
|
@@ -491,10 +519,10 @@ def test_cubes():
|
|
|
491
519
|
def test_power_ofs():
|
|
492
520
|
assert istr.power_ofs(0, 1, 5) == [istr("1")]
|
|
493
521
|
assert istr.power_ofs(0, 1) == []
|
|
494
|
-
assert istr.power_ofs(1, -1, 5) == [istr("-1"),istr("0"), istr("1"), istr("2"), istr("3"), istr("4")]
|
|
522
|
+
assert istr.power_ofs(1, -1, 5) == [istr("-1"), istr("0"), istr("1"), istr("2"), istr("3"), istr("4")]
|
|
495
523
|
assert istr.power_ofs(2, -10, 10) == [istr("0"), istr("1"), istr("4"), istr("9")]
|
|
496
|
-
assert istr.power_ofs(3, -10, 10) == [istr("-8"), istr("-1"), istr("0"), istr("1"),istr("8")]
|
|
497
|
-
assert istr.power_ofs(3, -10, 9) == [istr("-8"), istr("-1"), istr("0"), istr("1"),istr("8")]
|
|
524
|
+
assert istr.power_ofs(3, -10, 10) == [istr("-8"), istr("-1"), istr("0"), istr("1"), istr("8")]
|
|
525
|
+
assert istr.power_ofs(3, -10, 9) == [istr("-8"), istr("-1"), istr("0"), istr("1"), istr("8")]
|
|
498
526
|
assert istr.power_ofs(3, -10, 8) == [istr("-8"), istr("-1"), istr("0"), istr("1")]
|
|
499
527
|
assert istr.power_ofs(4, -10, 10) == [istr("0"), istr("1")]
|
|
500
528
|
assert istr.power_ofs(2, 10, 0) == []
|
|
@@ -504,16 +532,18 @@ def test_power_ofs():
|
|
|
504
532
|
assert id(istr.power_ofs(3, 2000)) != id(istr.cubes(3, 2000)) # test caching
|
|
505
533
|
assert id(istr.power_ofs(3, 1000, cache=False)) != id(istr.cubes(3, 1000, cache=False)) # test caching
|
|
506
534
|
|
|
535
|
+
|
|
507
536
|
def test_in_range():
|
|
508
|
-
primes1000=istr.primes(1000)
|
|
509
|
-
n=len(primes1000)
|
|
510
|
-
assert len(primes1000)==n
|
|
511
|
-
assert istr.in_range(primes1000,0,5)==[istr(
|
|
512
|
-
assert istr.in_range(primes1000,0,6)==[istr(
|
|
513
|
-
assert istr.in_range(primes1000,3,6)==[istr(
|
|
514
|
-
assert len(istr.in_range(primes1000,0,998))==n
|
|
515
|
-
assert len(istr.in_range(primes1000,0,997))==n-1
|
|
516
|
-
assert len(istr.in_range(primes1000,3,997))==n-2
|
|
537
|
+
primes1000 = istr.primes(1000)
|
|
538
|
+
n = len(primes1000)
|
|
539
|
+
assert len(primes1000) == n
|
|
540
|
+
assert istr.in_range(primes1000, 0, 5) == [istr("2"), istr("3")]
|
|
541
|
+
assert istr.in_range(primes1000, 0, 6) == [istr("2"), istr("3"), istr("5")]
|
|
542
|
+
assert istr.in_range(primes1000, 3, 6) == [istr("3"), istr("5")]
|
|
543
|
+
assert len(istr.in_range(primes1000, 0, 998)) == n
|
|
544
|
+
assert len(istr.in_range(primes1000, 0, 997)) == n - 1
|
|
545
|
+
assert len(istr.in_range(primes1000, 3, 997)) == n - 2
|
|
546
|
+
|
|
517
547
|
|
|
518
548
|
def test_join():
|
|
519
549
|
s = "".join(istr(("4", "5", "6")))
|
|
@@ -683,12 +713,12 @@ def test_edge_cases():
|
|
|
683
713
|
istr()
|
|
684
714
|
rng = istr.range(5)
|
|
685
715
|
assert rng is istr(rng)
|
|
686
|
-
x = istr(5+6j)
|
|
687
|
-
assert x ==
|
|
716
|
+
x = istr(5 + 6j)
|
|
717
|
+
assert x == "(5+6j)"
|
|
688
718
|
assert not x.is_int()
|
|
689
719
|
x = istr(min)
|
|
690
|
-
assert x ==
|
|
691
|
-
assert not x.is_int()
|
|
720
|
+
assert x == "<built-in function min>"
|
|
721
|
+
assert not x.is_int()
|
|
692
722
|
|
|
693
723
|
|
|
694
724
|
def test_unpacking():
|
|
@@ -925,8 +955,7 @@ def test_sumprod():
|
|
|
925
955
|
|
|
926
956
|
|
|
927
957
|
def test_subclassing():
|
|
928
|
-
class jstr(istr.type):
|
|
929
|
-
...
|
|
958
|
+
class jstr(istr.type): ...
|
|
930
959
|
|
|
931
960
|
assert jstr(5).equals(jstr(5))
|
|
932
961
|
assert repr(jstr(*range(3))) == "(jstr('0'), jstr('1'), jstr('2'))"
|
|
@@ -960,11 +989,10 @@ def test_decompose():
|
|
|
960
989
|
|
|
961
990
|
|
|
962
991
|
def test_compose():
|
|
992
|
+
global x, y, z, _
|
|
963
993
|
x = 1
|
|
964
994
|
y = "2"
|
|
965
995
|
z = istr(3)
|
|
966
|
-
|
|
967
|
-
assert istr.compose("xyz").equals(istr(123))
|
|
968
996
|
with pytest.raises(ValueError):
|
|
969
997
|
istr.compose("wxyz") # w is not defined
|
|
970
998
|
assert istr.compose("xyz", namespace=dict(x=3, y=istr(4), z="5")).equals(istr(345))
|
|
@@ -972,10 +1000,10 @@ def test_compose():
|
|
|
972
1000
|
assert istr("=xyz").equals(istr(123))
|
|
973
1001
|
assert istr("=xyz", "=x") == (istr(123), istr(1))
|
|
974
1002
|
assert istr("=") == "="
|
|
975
|
-
|
|
976
|
-
assert istr(
|
|
977
|
-
assert istr(
|
|
978
|
-
|
|
1003
|
+
|
|
1004
|
+
assert istr("=09").equals(istr("09"))
|
|
1005
|
+
assert istr("=x09z").equals(istr("1093"))
|
|
1006
|
+
|
|
979
1007
|
assert istr(["=xyz", "=y"]) == [istr(123), istr(2)]
|
|
980
1008
|
|
|
981
1009
|
assert istr(dict(xyz="=xyz", y="=y")) == {"xyz": istr(123), "y": istr(2)}
|
|
@@ -986,17 +1014,19 @@ def test_compose():
|
|
|
986
1014
|
assert istr(":=xyz").equals(istr(123))
|
|
987
1015
|
assert xyz.equals(istr(123))
|
|
988
1016
|
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
1017
|
+
with pytest.raises(ValueError):
|
|
1018
|
+
istr("=123_000")
|
|
1019
|
+
_ = "_"
|
|
1020
|
+
xyz_000 = istr("=123_000")
|
|
1021
|
+
assert xyz_000.equals(istr("123_000"))
|
|
1022
|
+
assert xyz_000 == 123000
|
|
1023
|
+
|
|
993
1024
|
with pytest.raises(ValueError, match=re.escape(f"'0xyz' is not a valid identifier")):
|
|
994
|
-
istr(":=0xyz")
|
|
995
|
-
|
|
1025
|
+
istr(":=0xyz")
|
|
1026
|
+
|
|
996
1027
|
assert istr(":=") == ":="
|
|
997
1028
|
assert istr("=") == "="
|
|
998
1029
|
|
|
999
1030
|
|
|
1000
1031
|
if __name__ == "__main__":
|
|
1001
1032
|
pytest.main(["-vv", "-s", "-x", __file__])
|
|
1002
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|