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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: istr-python
3
- Version: 1.1.27
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}) ==> `{istr('4'), istr('0'), istr('1')} # or similar
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 digits.
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 `test2` will be `istr(3960)`.
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 '=', like:
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
- / x istr(20) / 3 ==> istr('6')
937
- // x istr(20) // 3 ==> istr('6')
938
- % x istr(20) % 3 ==> istr('2')
939
- divmod x divmod(istr(20), 3) ==> (istr('6'), istr('2'))
940
- ** x istr(2) ** 3 ==> istr('8')
941
- <=, <, >, >= x istr('100') > istr('2') ==> True
942
- abs x abs(istr(-20)) ==> istr('20')
943
- int x int(istr("20")) ==> 20
944
- float x float(istr("20")) ==> 20.0
945
- complex x complex(istr("20")) ==> (20+0j)
946
- == x x istr(20) == 20 ==> True | istr(20) == '20' ==> True
947
- bool x x *) bool(istr(' 0 ')) ==> False | bool(istr('')) ==> False
948
- @ x istr(20) @ 3 ==> istr('202020')
949
- | x istr(20) | '5' ==> istr('205')
950
- slicing x istr(12345)[1:3] ==> istr('23')
951
- iterate x [x for x in istr(20)] ==> [istr('2'), istr('0')]
952
- len x len(istr(' 20 ')) ==> 4
953
- count x istr(100).count(0) ==> 2
954
- index x istr(' 100 ').index('0') ==> 2
955
- split x istr('1 2').split() ==> (istr('1'), istr('2'))
956
- string format x f"|{istr(1234):6}|" ==> '|1234 |'
957
- other string methods x istr('aAbBcC').lower() ==> istr('aabbcc')
958
- istr('aAbBcC').islower() ==> False
959
- istr(' abc ').strip() ==> istr('abc')
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}) ==> `{istr('4'), istr('0'), istr('1')} # or similar
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 digits.
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 `test2` will be `istr(3960)`.
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 '=', like:
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
- / x istr(20) / 3 ==> istr('6')
924
- // x istr(20) // 3 ==> istr('6')
925
- % x istr(20) % 3 ==> istr('2')
926
- divmod x divmod(istr(20), 3) ==> (istr('6'), istr('2'))
927
- ** x istr(2) ** 3 ==> istr('8')
928
- <=, <, >, >= x istr('100') > istr('2') ==> True
929
- abs x abs(istr(-20)) ==> istr('20')
930
- int x int(istr("20")) ==> 20
931
- float x float(istr("20")) ==> 20.0
932
- complex x complex(istr("20")) ==> (20+0j)
933
- == x x istr(20) == 20 ==> True | istr(20) == '20' ==> True
934
- bool x x *) bool(istr(' 0 ')) ==> False | bool(istr('')) ==> False
935
- @ x istr(20) @ 3 ==> istr('202020')
936
- | x istr(20) | '5' ==> istr('205')
937
- slicing x istr(12345)[1:3] ==> istr('23')
938
- iterate x [x for x in istr(20)] ==> [istr('2'), istr('0')]
939
- len x len(istr(' 20 ')) ==> 4
940
- count x istr(100).count(0) ==> 2
941
- index x istr(' 100 ').index('0') ==> 2
942
- split x istr('1 2').split() ==> (istr('1'), istr('2'))
943
- string format x f"|{istr(1234):6}|" ==> '|1234 |'
944
- other string methods x istr('aAbBcC').lower() ==> istr('aabbcc')
945
- istr('aAbBcC').islower() ==> False
946
- istr(' abc ').strip() ==> istr('abc')
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.27"
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) | {ch: ch for ch in "0123456789_"}
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
- s = "".join(str(namespace[letter]) for letter in letters)
608
- return cls(s)
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.27
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}) ==> `{istr('4'), istr('0'), istr('1')} # or similar
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 digits.
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 `test2` will be `istr(3960)`.
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 '=', like:
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
- / x istr(20) / 3 ==> istr('6')
937
- // x istr(20) // 3 ==> istr('6')
938
- % x istr(20) % 3 ==> istr('2')
939
- divmod x divmod(istr(20), 3) ==> (istr('6'), istr('2'))
940
- ** x istr(2) ** 3 ==> istr('8')
941
- <=, <, >, >= x istr('100') > istr('2') ==> True
942
- abs x abs(istr(-20)) ==> istr('20')
943
- int x int(istr("20")) ==> 20
944
- float x float(istr("20")) ==> 20.0
945
- complex x complex(istr("20")) ==> (20+0j)
946
- == x x istr(20) == 20 ==> True | istr(20) == '20' ==> True
947
- bool x x *) bool(istr(' 0 ')) ==> False | bool(istr('')) ==> False
948
- @ x istr(20) @ 3 ==> istr('202020')
949
- | x istr(20) | '5' ==> istr('205')
950
- slicing x istr(12345)[1:3] ==> istr('23')
951
- iterate x [x for x in istr(20)] ==> [istr('2'), istr('0')]
952
- len x len(istr(' 20 ')) ==> 4
953
- count x istr(100).count(0) ==> 2
954
- index x istr(' 100 ').index('0') ==> 2
955
- split x istr('1 2').split() ==> (istr('1'), istr('2'))
956
- string format x f"|{istr(1234):6}|" ==> '|1234 |'
957
- other string methods x istr('aAbBcC').lower() ==> istr('aabbcc')
958
- istr('aAbBcC').islower() ==> False
959
- istr(' abc ').strip() ==> istr('abc')
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
  ```
@@ -10,7 +10,7 @@ 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.27"
13
+ version = "1.1.29"
14
14
  readme = "README.md"
15
15
  requires-python = ">=3.10"
16
16
  dependencies = []
@@ -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('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')]
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('aba').is_palindrome()
352
- assert not istr('abc').is_palindrome()
353
- assert istr('').is_palindrome()
354
- assert istr.is_palindrome('121')
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('2'), istr('3')]
512
- assert istr.in_range(primes1000,0,6)==[istr('2'), istr('3'),istr('5')]
513
- assert istr.in_range(primes1000,3,6)==[istr('3'),istr('5')]
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 == '(5+6j)'
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 == '<built-in function min>'
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('=09').equals(istr('09'))
977
- assert istr('=x09z').equals(istr('1093'))
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
- assert istr(":=xyz_000").equals(istr('123_000'))
990
- assert xyz_000.equals(istr('123_000'))
991
- assert xyz_000==123000
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