istr-python 1.1.42__tar.gz → 1.1.44__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.42 → istr_python-1.1.44}/PKG-INFO +81 -22
- {istr_python-1.1.42 → istr_python-1.1.44}/README.md +80 -21
- {istr_python-1.1.42 → istr_python-1.1.44}/istr/istr.py +224 -103
- {istr_python-1.1.42 → istr_python-1.1.44}/istr_python.egg-info/PKG-INFO +81 -22
- {istr_python-1.1.42 → istr_python-1.1.44}/pyproject.toml +1 -1
- {istr_python-1.1.42 → istr_python-1.1.44}/tests/test_istr.py +18 -17
- {istr_python-1.1.42 → istr_python-1.1.44}/istr/LICENSE.txt +0 -0
- {istr_python-1.1.42 → istr_python-1.1.44}/istr/__init__.py +0 -0
- {istr_python-1.1.42 → istr_python-1.1.44}/istr_python.egg-info/SOURCES.txt +0 -0
- {istr_python-1.1.42 → istr_python-1.1.44}/istr_python.egg-info/dependency_links.txt +0 -0
- {istr_python-1.1.42 → istr_python-1.1.44}/istr_python.egg-info/top_level.txt +0 -0
- {istr_python-1.1.42 → istr_python-1.1.44}/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.44
|
|
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
|
|
@@ -852,16 +852,24 @@ istr.getitem('1234',5, None) ==> None
|
|
|
852
852
|
Note that this method has the advantage that it can accept an istr as index, in contrast to normal indexing.
|
|
853
853
|
|
|
854
854
|
#### long square root
|
|
855
|
-
The method `long_sqrt`
|
|
856
|
-
|
|
855
|
+
The method `long_sqrt` returns an instance of a class with attributes `lines`, `line_lengths` and `output`.
|
|
856
|
+
|
|
857
|
+
`lines` is list of the lines of a long square root. Both the result (root) and the original number, possibly with a trailing 0 are returned, along with the calculated values.
|
|
858
|
+
E.g. `istr.long_sqrt(123 ** 2).lines` results in
|
|
857
859
|
|
|
858
860
|
`[istr('123'), istr('15129'), istr('1'), istr('51'), istr('44'), istr('729'), istr('729'), istr('0')]`
|
|
859
861
|
|
|
860
862
|
Note the final `istr('0')` is included to support also long square roots that are not perfect.
|
|
861
863
|
|
|
862
|
-
|
|
864
|
+
`line_lengths` returns a list of the length of the lines (not istr-ed). E.g.:
|
|
865
|
+
|
|
866
|
+
E.g. `istr.long_sqrt(123 ** 2).line_lengths` results in
|
|
867
|
+
|
|
868
|
+
`[3, 5, 1, 2, 2, 3, 3, 1]`
|
|
863
869
|
|
|
864
|
-
|
|
870
|
+
`output` can be used to get a nice string representation of the long square root lines.
|
|
871
|
+
|
|
872
|
+
E.g. `print(istr.long_sqrt(123 ** 2).output)` will print
|
|
865
873
|
```
|
|
866
874
|
1 2 3
|
|
867
875
|
-----
|
|
@@ -879,18 +887,26 @@ E.g. `print(istr.long_sqrt(123 ** 2, as_str=True))` will print
|
|
|
879
887
|
|
|
880
888
|
#### long multiplication
|
|
881
889
|
|
|
882
|
-
The method `long_multiplication`
|
|
890
|
+
The method `long_multiplication` returns an instance of a class with attributes `lines`, `line_lengths` and `output`.
|
|
891
|
+
|
|
892
|
+
`lines` is list of the lines of a long multiplication.
|
|
893
|
+
|
|
894
|
+
E.g. `print(istr.long_multiplication(1234,567).lines` will print
|
|
883
895
|
|
|
884
|
-
E.g. `print(istr.long_multiplication(1234,567)` will print
|
|
885
|
-
|
|
886
896
|
`[istr('1234'), istr('567'), istr('8638'), istr('7404'), istr('6170'), istr('699678')]`
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
E.g. `print(istr.long_multiplication(1234,567
|
|
897
|
+
|
|
898
|
+
`line_lengths` returns a list of the length of the lines (not istr-ed). E.g.:
|
|
899
|
+
|
|
900
|
+
E. g. `print(istr.long_multiplication(1234,567).line_lengths` results in
|
|
901
|
+
|
|
902
|
+
`[4, 3, 4, 4, 4, 6]`
|
|
903
|
+
|
|
904
|
+
`output` can be used to get a nice string representation of the long multiplication lines.
|
|
905
|
+
|
|
906
|
+
E.g. `print(istr.long_multiplication(1234, 567).output)` will print
|
|
891
907
|
|
|
892
908
|
```
|
|
893
|
-
|
|
909
|
+
1234
|
|
894
910
|
567
|
|
895
911
|
------ x
|
|
896
912
|
8638
|
|
@@ -902,15 +918,23 @@ E.g. `print(istr.long_multiplication(1234,567, as_str=True)` will print
|
|
|
902
918
|
|
|
903
919
|
#### long division
|
|
904
920
|
|
|
905
|
-
The method `long_division`
|
|
921
|
+
The method `long_division` returns an instance of a class with attributes `lines`, `line_lengths` and `output`.
|
|
906
922
|
|
|
907
|
-
|
|
923
|
+
`lines` is a list of the lines of a long division.
|
|
908
924
|
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
925
|
+
E.g. `print(istr.long_division(1395, 45).lines` will print
|
|
926
|
+
|
|
927
|
+
`[istr('31'), istr('45'), istr('1395'), istr('135'), istr('45'), istr('45'), istr('0')]`
|
|
928
|
+
|
|
929
|
+
Note the final `istr('0')` is included to support also long divisions roots that are not perfect.
|
|
930
|
+
|
|
931
|
+
E.g. `print(istr.long_division(1395, 45).line_lengths` will print
|
|
932
|
+
|
|
933
|
+
`[2, 2, 4, 3, 2, 2, 1]`
|
|
934
|
+
|
|
935
|
+
`output` can be used to get a nice string representation of the long divsion lines.
|
|
936
|
+
|
|
937
|
+
E.g. `print(istr.long_division(1395, 45).output` will print
|
|
914
938
|
|
|
915
939
|
```
|
|
916
940
|
31
|
|
@@ -922,8 +946,8 @@ E.g. `print(istr.long_division(1395, 45, as_str=True)` will print
|
|
|
922
946
|
45
|
|
923
947
|
--
|
|
924
948
|
0
|
|
925
|
-
```
|
|
926
|
-
|
|
949
|
+
```
|
|
950
|
+
|
|
927
951
|
#### generate istr with digits
|
|
928
952
|
|
|
929
953
|
The class method `digits` can be used to return an istr of digits according to a given specification.
|
|
@@ -1017,6 +1041,41 @@ Note that `str(istr(":="))` is ":=" and does not assign any value.
|
|
|
1017
1041
|
|
|
1018
1042
|
Usually, composing and decomposing uses the globals namespace, but this can be overridden with the namespace parameter. See the test suite for details.
|
|
1019
1043
|
|
|
1044
|
+
#### Evaluating expressions with one letter variables
|
|
1045
|
+
The `istr.eval` method is essentially the same as `istr.compose`, but (safely) evaluates the result.
|
|
1046
|
+
E.g.
|
|
1047
|
+
|
|
1048
|
+
```
|
|
1049
|
+
a = 5
|
|
1050
|
+
b = 2
|
|
1051
|
+
print(istr.eval('aab + ba')
|
|
1052
|
+
```
|
|
1053
|
+
will print `577`
|
|
1054
|
+
|
|
1055
|
+
The operators +, -, * and / are supported.
|
|
1056
|
+
Comparisons (==, <=, <, >, >= are also supported. In that case, the result is also istr-ed, so istr('0') for False and istr('1') for True. E.g.
|
|
1057
|
+
|
|
1058
|
+
```
|
|
1059
|
+
a = 5
|
|
1060
|
+
b = 2
|
|
1061
|
+
print(istr.eval('a > b')
|
|
1062
|
+
```
|
|
1063
|
+
will print 1 (meaning True)
|
|
1064
|
+
|
|
1065
|
+
Note that leading zeroes are accepted. So, `istr.eval('03 + 7')` is `10`.
|
|
1066
|
+
Instead of ==, = can be used. So, `istr.eval('12 = 5 + 7')` is `1` (meaning True)
|
|
1067
|
+
|
|
1068
|
+
##### Alternative method
|
|
1069
|
+
|
|
1070
|
+
If istr is called with a string starting with a `?`, the string without the leading `?` will be evaluated using the new `istr.eval` method. So, the above examples read:
|
|
1071
|
+
```
|
|
1072
|
+
a = 5
|
|
1073
|
+
b = 2
|
|
1074
|
+
print(istr("?aab + ba':")
|
|
1075
|
+
print(istr("?a > b")
|
|
1076
|
+
```
|
|
1077
|
+
with output `577` and `1` (meaning True)
|
|
1078
|
+
|
|
1020
1079
|
#### Subclassing istr
|
|
1021
1080
|
|
|
1022
1081
|
When a class is derived from istr, all methods will return that newly derived class.
|
|
@@ -839,16 +839,24 @@ istr.getitem('1234',5, None) ==> None
|
|
|
839
839
|
Note that this method has the advantage that it can accept an istr as index, in contrast to normal indexing.
|
|
840
840
|
|
|
841
841
|
#### long square root
|
|
842
|
-
The method `long_sqrt`
|
|
843
|
-
|
|
842
|
+
The method `long_sqrt` returns an instance of a class with attributes `lines`, `line_lengths` and `output`.
|
|
843
|
+
|
|
844
|
+
`lines` is list of the lines of a long square root. Both the result (root) and the original number, possibly with a trailing 0 are returned, along with the calculated values.
|
|
845
|
+
E.g. `istr.long_sqrt(123 ** 2).lines` results in
|
|
844
846
|
|
|
845
847
|
`[istr('123'), istr('15129'), istr('1'), istr('51'), istr('44'), istr('729'), istr('729'), istr('0')]`
|
|
846
848
|
|
|
847
849
|
Note the final `istr('0')` is included to support also long square roots that are not perfect.
|
|
848
850
|
|
|
849
|
-
|
|
851
|
+
`line_lengths` returns a list of the length of the lines (not istr-ed). E.g.:
|
|
852
|
+
|
|
853
|
+
E.g. `istr.long_sqrt(123 ** 2).line_lengths` results in
|
|
854
|
+
|
|
855
|
+
`[3, 5, 1, 2, 2, 3, 3, 1]`
|
|
850
856
|
|
|
851
|
-
|
|
857
|
+
`output` can be used to get a nice string representation of the long square root lines.
|
|
858
|
+
|
|
859
|
+
E.g. `print(istr.long_sqrt(123 ** 2).output)` will print
|
|
852
860
|
```
|
|
853
861
|
1 2 3
|
|
854
862
|
-----
|
|
@@ -866,18 +874,26 @@ E.g. `print(istr.long_sqrt(123 ** 2, as_str=True))` will print
|
|
|
866
874
|
|
|
867
875
|
#### long multiplication
|
|
868
876
|
|
|
869
|
-
The method `long_multiplication`
|
|
877
|
+
The method `long_multiplication` returns an instance of a class with attributes `lines`, `line_lengths` and `output`.
|
|
878
|
+
|
|
879
|
+
`lines` is list of the lines of a long multiplication.
|
|
880
|
+
|
|
881
|
+
E.g. `print(istr.long_multiplication(1234,567).lines` will print
|
|
870
882
|
|
|
871
|
-
E.g. `print(istr.long_multiplication(1234,567)` will print
|
|
872
|
-
|
|
873
883
|
`[istr('1234'), istr('567'), istr('8638'), istr('7404'), istr('6170'), istr('699678')]`
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
E.g. `print(istr.long_multiplication(1234,567
|
|
884
|
+
|
|
885
|
+
`line_lengths` returns a list of the length of the lines (not istr-ed). E.g.:
|
|
886
|
+
|
|
887
|
+
E. g. `print(istr.long_multiplication(1234,567).line_lengths` results in
|
|
888
|
+
|
|
889
|
+
`[4, 3, 4, 4, 4, 6]`
|
|
890
|
+
|
|
891
|
+
`output` can be used to get a nice string representation of the long multiplication lines.
|
|
892
|
+
|
|
893
|
+
E.g. `print(istr.long_multiplication(1234, 567).output)` will print
|
|
878
894
|
|
|
879
895
|
```
|
|
880
|
-
|
|
896
|
+
1234
|
|
881
897
|
567
|
|
882
898
|
------ x
|
|
883
899
|
8638
|
|
@@ -889,15 +905,23 @@ E.g. `print(istr.long_multiplication(1234,567, as_str=True)` will print
|
|
|
889
905
|
|
|
890
906
|
#### long division
|
|
891
907
|
|
|
892
|
-
The method `long_division`
|
|
908
|
+
The method `long_division` returns an instance of a class with attributes `lines`, `line_lengths` and `output`.
|
|
893
909
|
|
|
894
|
-
|
|
910
|
+
`lines` is a list of the lines of a long division.
|
|
895
911
|
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
912
|
+
E.g. `print(istr.long_division(1395, 45).lines` will print
|
|
913
|
+
|
|
914
|
+
`[istr('31'), istr('45'), istr('1395'), istr('135'), istr('45'), istr('45'), istr('0')]`
|
|
915
|
+
|
|
916
|
+
Note the final `istr('0')` is included to support also long divisions roots that are not perfect.
|
|
917
|
+
|
|
918
|
+
E.g. `print(istr.long_division(1395, 45).line_lengths` will print
|
|
919
|
+
|
|
920
|
+
`[2, 2, 4, 3, 2, 2, 1]`
|
|
921
|
+
|
|
922
|
+
`output` can be used to get a nice string representation of the long divsion lines.
|
|
923
|
+
|
|
924
|
+
E.g. `print(istr.long_division(1395, 45).output` will print
|
|
901
925
|
|
|
902
926
|
```
|
|
903
927
|
31
|
|
@@ -909,8 +933,8 @@ E.g. `print(istr.long_division(1395, 45, as_str=True)` will print
|
|
|
909
933
|
45
|
|
910
934
|
--
|
|
911
935
|
0
|
|
912
|
-
```
|
|
913
|
-
|
|
936
|
+
```
|
|
937
|
+
|
|
914
938
|
#### generate istr with digits
|
|
915
939
|
|
|
916
940
|
The class method `digits` can be used to return an istr of digits according to a given specification.
|
|
@@ -1004,6 +1028,41 @@ Note that `str(istr(":="))` is ":=" and does not assign any value.
|
|
|
1004
1028
|
|
|
1005
1029
|
Usually, composing and decomposing uses the globals namespace, but this can be overridden with the namespace parameter. See the test suite for details.
|
|
1006
1030
|
|
|
1031
|
+
#### Evaluating expressions with one letter variables
|
|
1032
|
+
The `istr.eval` method is essentially the same as `istr.compose`, but (safely) evaluates the result.
|
|
1033
|
+
E.g.
|
|
1034
|
+
|
|
1035
|
+
```
|
|
1036
|
+
a = 5
|
|
1037
|
+
b = 2
|
|
1038
|
+
print(istr.eval('aab + ba')
|
|
1039
|
+
```
|
|
1040
|
+
will print `577`
|
|
1041
|
+
|
|
1042
|
+
The operators +, -, * and / are supported.
|
|
1043
|
+
Comparisons (==, <=, <, >, >= are also supported. In that case, the result is also istr-ed, so istr('0') for False and istr('1') for True. E.g.
|
|
1044
|
+
|
|
1045
|
+
```
|
|
1046
|
+
a = 5
|
|
1047
|
+
b = 2
|
|
1048
|
+
print(istr.eval('a > b')
|
|
1049
|
+
```
|
|
1050
|
+
will print 1 (meaning True)
|
|
1051
|
+
|
|
1052
|
+
Note that leading zeroes are accepted. So, `istr.eval('03 + 7')` is `10`.
|
|
1053
|
+
Instead of ==, = can be used. So, `istr.eval('12 = 5 + 7')` is `1` (meaning True)
|
|
1054
|
+
|
|
1055
|
+
##### Alternative method
|
|
1056
|
+
|
|
1057
|
+
If istr is called with a string starting with a `?`, the string without the leading `?` will be evaluated using the new `istr.eval` method. So, the above examples read:
|
|
1058
|
+
```
|
|
1059
|
+
a = 5
|
|
1060
|
+
b = 2
|
|
1061
|
+
print(istr("?aab + ba':")
|
|
1062
|
+
print(istr("?a > b")
|
|
1063
|
+
```
|
|
1064
|
+
with output `577` and `1` (meaning True)
|
|
1065
|
+
|
|
1007
1066
|
#### Subclassing istr
|
|
1008
1067
|
|
|
1009
1068
|
When a class is derived from istr, all methods will return that newly derived class.
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# |_||___/ \__||_|
|
|
6
6
|
# strings you can count on
|
|
7
7
|
|
|
8
|
-
__version__ = "1.1.
|
|
8
|
+
__version__ = "1.1.44"
|
|
9
9
|
import functools
|
|
10
10
|
import itertools
|
|
11
11
|
import types
|
|
@@ -17,6 +17,8 @@ import copy
|
|
|
17
17
|
import bisect
|
|
18
18
|
import collections
|
|
19
19
|
import numbers
|
|
20
|
+
import re
|
|
21
|
+
import ast
|
|
20
22
|
|
|
21
23
|
"""
|
|
22
24
|
Note: the changelog is in changelog.md
|
|
@@ -282,15 +284,18 @@ class istr(str):
|
|
|
282
284
|
return map(lambda v: cls(v, base=base, int_format=int_format, repr_mode=repr_mode, namespace=get_namespace(namespace)), value)
|
|
283
285
|
return type(value)(map(lambda v: cls(v, base=base, int_format=int_format, repr_mode=repr_mode, namespace=get_namespace(namespace)), value))
|
|
284
286
|
|
|
285
|
-
if isinstance(value, str) and (any(value.startswith(s) and value != s for s in ("=", ":="))):
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
287
|
+
if isinstance(value, str) and (any(value.startswith(s) and value != s for s in ("=", ":=",'?'))):
|
|
288
|
+
match value[0]:
|
|
289
|
+
case '?':
|
|
290
|
+
value = str(cls.eval(value[1:], namespace=get_namespace(namespace)))
|
|
291
|
+
case '=':
|
|
292
|
+
value = str(cls.compose(value[1:], namespace=get_namespace(namespace)))
|
|
293
|
+
case ':':
|
|
294
|
+
var_name = value[2:]
|
|
295
|
+
if not var_name.isidentifier():
|
|
296
|
+
raise ValueError(f"{var_name!r} is not a valid identifier")
|
|
297
|
+
value = str(cls.compose(var_name, namespace=get_namespace(namespace)))
|
|
298
|
+
get_namespace(namespace)[var_name] = cls(value)
|
|
294
299
|
as_int = cls._to_int(value, base)
|
|
295
300
|
if as_int is cls._nan or isinstance(value, str):
|
|
296
301
|
as_str = value
|
|
@@ -674,7 +679,20 @@ class istr(str):
|
|
|
674
679
|
result.append(str(namespace[letter]))
|
|
675
680
|
else:
|
|
676
681
|
result.append(letter)
|
|
677
|
-
|
|
682
|
+
|
|
683
|
+
result_str = "".join(result)
|
|
684
|
+
return cls(result_str)
|
|
685
|
+
|
|
686
|
+
@classmethod
|
|
687
|
+
def eval(cls, letters, namespace=None):
|
|
688
|
+
"""
|
|
689
|
+
evaluates an istr from individual letter variables
|
|
690
|
+
"""
|
|
691
|
+
expr = cls.compose(letters, namespace=namespace)
|
|
692
|
+
expr = re.sub(r"\b0+(\d+)\b", r"\1", expr) # delete leading zeroes
|
|
693
|
+
expr=re.sub(r'(?<![<>=!])=(?!=)', '==', expr) # support =
|
|
694
|
+
result = safe_eval(expr)
|
|
695
|
+
return cls(result)
|
|
678
696
|
|
|
679
697
|
def __or__(self, other):
|
|
680
698
|
if isinstance(other, str):
|
|
@@ -727,14 +745,14 @@ class istr(str):
|
|
|
727
745
|
return self[::-1]
|
|
728
746
|
|
|
729
747
|
def ceil(self, divisible_by=1):
|
|
730
|
-
if divisible_by != int(divisible_by) or divisible_by<1:
|
|
748
|
+
if divisible_by != int(divisible_by) or divisible_by < 1:
|
|
731
749
|
raise ValueError(f"divisible_by has to be an integer value >=1 , not {divisible_by}")
|
|
732
750
|
n = istr.interpret_as_float(self)
|
|
733
751
|
return istr((math.ceil(n / divisible_by)) * divisible_by)
|
|
734
752
|
|
|
735
753
|
def floor(self, divisible_by=1):
|
|
736
|
-
if divisible_by != int(divisible_by) or divisible_by<1:
|
|
737
|
-
raise ValueError(f"divisible_by has to be an integer value >=1 , not {divisible_by}")
|
|
754
|
+
if divisible_by != int(divisible_by) or divisible_by < 1:
|
|
755
|
+
raise ValueError(f"divisible_by has to be an integer value >=1 , not {divisible_by}")
|
|
738
756
|
n = istr.interpret_as_float(self)
|
|
739
757
|
return istr((math.floor(n / divisible_by)) * divisible_by)
|
|
740
758
|
|
|
@@ -764,13 +782,13 @@ class istr(str):
|
|
|
764
782
|
|
|
765
783
|
return str(self)
|
|
766
784
|
|
|
767
|
-
def interpret_as_istr(self):
|
|
785
|
+
def interpret_as_istr(self):
|
|
768
786
|
# ignore leading zeroes
|
|
769
787
|
if isinstance(self, collections.abc.Iterable) and not isinstance(self, str):
|
|
770
|
-
return istr.join(self)*1
|
|
788
|
+
return istr.join(self) * 1
|
|
789
|
+
|
|
790
|
+
return istr(self) * 1
|
|
771
791
|
|
|
772
|
-
return istr(self)*1
|
|
773
|
-
|
|
774
792
|
def _str_method(self, name, *args, **kwargs):
|
|
775
793
|
return self.__class__(getattr(super(), name)(*args, **kwargs))
|
|
776
794
|
|
|
@@ -860,22 +878,15 @@ class istr(str):
|
|
|
860
878
|
for i, value in enumerate(iterable, int(start)):
|
|
861
879
|
yield cls(i), value
|
|
862
880
|
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
(modified from a ChatGPT code suggestion)
|
|
867
|
-
returns root, number and the lines below the number, all istr-ed
|
|
868
|
-
if as_str is True, a formatted output will be returned
|
|
869
|
-
"""
|
|
870
|
-
|
|
871
|
-
number = istr.interpret_as_istr(self)
|
|
872
|
-
|
|
881
|
+
@staticmethod
|
|
882
|
+
@functools.lru_cache(maxsize=1)
|
|
883
|
+
def _long_sqrt(number):
|
|
873
884
|
lines = []
|
|
874
|
-
if len(number)%2==1:
|
|
875
|
-
pairs=istr.chain(number[0],istr.batched(number[1:],2,join=True))
|
|
876
|
-
else:
|
|
877
|
-
pairs=istr.batched(number,2,join=True)
|
|
878
|
-
|
|
885
|
+
if len(number) % 2 == 1:
|
|
886
|
+
pairs = istr.chain(number[0], istr.batched(number[1:], 2, join=True))
|
|
887
|
+
else:
|
|
888
|
+
pairs = istr.batched(number, 2, join=True)
|
|
889
|
+
|
|
879
890
|
root = istr(0)
|
|
880
891
|
remainder = 0
|
|
881
892
|
|
|
@@ -899,118 +910,180 @@ class istr(str):
|
|
|
899
910
|
|
|
900
911
|
lines.append(remainder)
|
|
901
912
|
lines = [root] + [number] + lines[1:]
|
|
902
|
-
|
|
903
|
-
result = []
|
|
904
|
-
extra = len(number)%2==0
|
|
905
|
-
result.append(f" {extra*' '}{' '.join(lines[0])}")
|
|
906
|
-
result.append(f" {len(lines[1])*'-'}")
|
|
907
|
-
result.append(f"\/{lines[1]}")
|
|
908
|
-
|
|
909
|
-
last_len=len(lines[2])
|
|
910
|
-
for i, line in enumerate(lines):
|
|
911
|
-
|
|
912
|
-
if i >= 2:
|
|
913
|
-
if i == len(lines) - 1:
|
|
914
|
-
n = i - 2 + extra
|
|
915
|
-
else:
|
|
916
|
-
n = i + extra
|
|
913
|
+
return lines
|
|
917
914
|
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
915
|
+
def long_sqrt(self):
|
|
916
|
+
"""
|
|
917
|
+
this function does long squre root and returns all the lines to be written.
|
|
918
|
+
(modified from a ChatGPT code suggestion)
|
|
919
|
+
returns root, number and the lines below the number, all istr-ed
|
|
920
|
+
if as_str is True, a formatted output will be returned
|
|
921
|
+
"""
|
|
922
|
+
|
|
923
|
+
class NumberHolder:
|
|
924
|
+
def __init__(self, number):
|
|
925
|
+
self.number = number
|
|
926
|
+
|
|
927
|
+
def __getattr__(self, attr):
|
|
928
|
+
match attr:
|
|
929
|
+
case "lines":
|
|
930
|
+
return istr._long_sqrt(self.number)
|
|
931
|
+
case "line_lengths":
|
|
932
|
+
return [*map(len, istr._long_sqrt(self.number))]
|
|
933
|
+
case "output":
|
|
934
|
+
lines = istr._long_sqrt(self.number)
|
|
935
|
+
result = []
|
|
936
|
+
extra = len(number) % 2 == 0
|
|
937
|
+
result.append(f" {extra*' '}{' '.join(lines[0])}")
|
|
938
|
+
result.append(f" {len(lines[1])*'-'}")
|
|
939
|
+
result.append(f"\/{lines[1]}")
|
|
940
|
+
|
|
941
|
+
last_len = len(lines[2])
|
|
942
|
+
for i, line in enumerate(lines):
|
|
943
|
+
if i >= 2:
|
|
944
|
+
if i == len(lines) - 1:
|
|
945
|
+
n = i - 2 + extra
|
|
946
|
+
else:
|
|
947
|
+
n = i + extra
|
|
948
|
+
|
|
949
|
+
if i % 2 == 0:
|
|
950
|
+
result.append(f" {line:>{n}}")
|
|
951
|
+
result.append(f" {last_len*'-':>{n}}")
|
|
952
|
+
else:
|
|
953
|
+
result.append(f" {line:>{n+1}}")
|
|
954
|
+
last_len = len(line)
|
|
955
|
+
return "\n".join(result)
|
|
956
|
+
case _:
|
|
957
|
+
raise AttributeError()
|
|
958
|
+
|
|
959
|
+
number = istr.interpret_as_istr(self)
|
|
960
|
+
|
|
961
|
+
return NumberHolder(number)
|
|
962
|
+
|
|
963
|
+
@staticmethod
|
|
964
|
+
@functools.lru_cache(maxsize=1)
|
|
965
|
+
def _long_multiplication(number0, number1):
|
|
966
|
+
lines = [number0, number1]
|
|
932
967
|
for i in number1.reversed():
|
|
933
|
-
lines.append(number0*i)
|
|
934
|
-
lines.append(number0*number1)
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
968
|
+
lines.append(number0 * i)
|
|
969
|
+
lines.append(number0 * number1)
|
|
970
|
+
|
|
971
|
+
return lines
|
|
972
|
+
|
|
973
|
+
def long_multiplication(self, number, as_str=False):
|
|
974
|
+
class NumbersHolder:
|
|
975
|
+
def __init__(self, number0, number1):
|
|
976
|
+
self.number0 = number0
|
|
977
|
+
self.number1 = number1
|
|
978
|
+
|
|
979
|
+
def __getattr__(self, attr):
|
|
980
|
+
match attr:
|
|
981
|
+
case "lines":
|
|
982
|
+
return istr._long_multiplication(self.number0, self.number1)
|
|
983
|
+
case "line_lengths":
|
|
984
|
+
return [*map(len, istr._long_multiplication(self.number0, self.number1))]
|
|
985
|
+
case "output":
|
|
986
|
+
lines = istr._long_multiplication(self.number0, self.number1)
|
|
987
|
+
result = []
|
|
988
|
+
|
|
989
|
+
n = len(lines[-1])
|
|
990
|
+
result.append(f"{lines[0]:>{n}}")
|
|
991
|
+
result.append(f"{lines[1]:>{n}}")
|
|
992
|
+
result.append(f"{n*'-'} x")
|
|
993
|
+
for i, line in enumerate(lines[2:-1]):
|
|
994
|
+
result.append(f"{line:>{n-i}}")
|
|
995
|
+
result.append(f"{n*'-'}")
|
|
996
|
+
result.append(lines[-1])
|
|
997
|
+
return "\n".join(result)
|
|
998
|
+
case _:
|
|
999
|
+
raise AttributeError()
|
|
1000
|
+
|
|
1001
|
+
number0 = istr.interpret_as_istr(self)
|
|
1002
|
+
number1 = istr.interpret_as_istr(number)
|
|
1003
|
+
return NumbersHolder(number0, number1)
|
|
1004
|
+
|
|
1005
|
+
@staticmethod
|
|
1006
|
+
@functools.lru_cache(maxsize=1)
|
|
1007
|
+
def _long_division(dividend, divisor, as_str=False):
|
|
953
1008
|
if dividend < 0:
|
|
954
1009
|
raise ValueError("dividend must be non-negative.")
|
|
955
|
-
|
|
1010
|
+
|
|
956
1011
|
if divisor <= 0:
|
|
957
1012
|
raise ValueError("divisor must be positive.")
|
|
958
|
-
|
|
1013
|
+
|
|
959
1014
|
dividend_start = len(divisor) + 3
|
|
960
1015
|
total_width = dividend_start + len(dividend)
|
|
961
|
-
|
|
1016
|
+
|
|
962
1017
|
quotient_characters = [" "] * len(dividend)
|
|
963
|
-
|
|
1018
|
+
|
|
964
1019
|
remainder = 0
|
|
965
1020
|
division_started = False
|
|
966
|
-
lines=[]
|
|
967
|
-
|
|
1021
|
+
lines = []
|
|
1022
|
+
|
|
968
1023
|
for digit_index, digit_character in enumerate(dividend):
|
|
969
1024
|
current = remainder * 10 + digit_character
|
|
970
1025
|
quotient_digit = current // divisor
|
|
971
|
-
|
|
1026
|
+
|
|
972
1027
|
if quotient_digit != 0 or division_started:
|
|
973
1028
|
division_started = True
|
|
974
|
-
|
|
1029
|
+
|
|
975
1030
|
if digit_index == len(dividend) - 1:
|
|
976
1031
|
division_started = True
|
|
977
|
-
|
|
1032
|
+
|
|
978
1033
|
if not division_started:
|
|
979
1034
|
remainder = current
|
|
980
1035
|
continue
|
|
981
|
-
|
|
1036
|
+
|
|
982
1037
|
quotient_characters[digit_index] = quotient_digit
|
|
983
|
-
|
|
1038
|
+
|
|
984
1039
|
product = quotient_digit * divisor
|
|
985
1040
|
remainder = current - product
|
|
986
|
-
|
|
1041
|
+
|
|
987
1042
|
if as_str:
|
|
988
1043
|
end_column = dividend_start + digit_index
|
|
989
1044
|
current_start = end_column - len(current) + 1
|
|
990
|
-
product_start = end_column - len(product) + 1
|
|
1045
|
+
product_start = end_column - len(product) + 1
|
|
991
1046
|
bar_start = min(current_start, product_start)
|
|
992
1047
|
bar_length = end_column - bar_start + 1
|
|
993
1048
|
lines.append(" " * current_start | current)
|
|
994
1049
|
lines.append(" " * product_start | product)
|
|
995
1050
|
lines.append(" " * bar_start + "-" * bar_length)
|
|
996
|
-
|
|
1051
|
+
|
|
997
1052
|
else:
|
|
998
1053
|
lines.append(current)
|
|
999
1054
|
lines.append(product)
|
|
1000
|
-
|
|
1055
|
+
|
|
1001
1056
|
quotient = istr.join(quotient_characters).rstrip()
|
|
1002
1057
|
if as_str:
|
|
1003
1058
|
remainder_start = total_width - len(remainder)
|
|
1004
1059
|
lines.append(" " * remainder_start | remainder)
|
|
1005
|
-
lines=[" " * dividend_start | quotient," " * dividend_start + "-" * len(dividend),f"{divisor} ) {dividend}"
|
|
1060
|
+
lines = [" " * dividend_start | quotient, " " * dividend_start + "-" * len(dividend), f"{divisor} ) {dividend}", *lines[1:]]
|
|
1006
1061
|
return "\n".join(lines)
|
|
1007
|
-
|
|
1062
|
+
|
|
1008
1063
|
else:
|
|
1009
1064
|
lines.append(remainder)
|
|
1010
|
-
lines=[istr(quotient),divisor,dividend
|
|
1011
|
-
return lines
|
|
1012
|
-
|
|
1013
|
-
|
|
1065
|
+
lines = [istr(quotient), divisor, dividend, *lines[1:]]
|
|
1066
|
+
return lines
|
|
1067
|
+
|
|
1068
|
+
def long_division(self, divisor):
|
|
1069
|
+
class NumbersHolder:
|
|
1070
|
+
def __init__(self, dividend, divisor):
|
|
1071
|
+
self.dividend = dividend
|
|
1072
|
+
self.divisor = divisor
|
|
1073
|
+
|
|
1074
|
+
def __getattr__(self, attr):
|
|
1075
|
+
match attr:
|
|
1076
|
+
case "lines":
|
|
1077
|
+
return istr._long_division(self.dividend, self.divisor)
|
|
1078
|
+
case "line_lengths":
|
|
1079
|
+
return [*map(len, istr._long_division(self.dividend, self.divisor))]
|
|
1080
|
+
case "output":
|
|
1081
|
+
return istr._long_division(self.dividend, self.divisor, as_str=True)
|
|
1082
|
+
|
|
1083
|
+
dividend = istr.interpret_as_istr(self)
|
|
1084
|
+
divisor = istr.interpret_as_istr(divisor)
|
|
1085
|
+
return NumbersHolder(dividend, divisor)
|
|
1086
|
+
|
|
1014
1087
|
def this_base(self):
|
|
1015
1088
|
return self._this_base
|
|
1016
1089
|
|
|
@@ -1275,6 +1348,54 @@ def real_caller_frame():
|
|
|
1275
1348
|
return frame
|
|
1276
1349
|
|
|
1277
1350
|
|
|
1351
|
+
OPS = {ast.Add: operator.add, ast.Sub: operator.sub, ast.Mult: operator.mul, ast.Div: operator.truediv, ast.Pow: operator.pow}
|
|
1352
|
+
|
|
1353
|
+
COMPARE_OPS = {
|
|
1354
|
+
ast.Eq: operator.eq, # ==
|
|
1355
|
+
ast.NotEq: operator.ne, # !=
|
|
1356
|
+
ast.Lt: operator.lt, # <
|
|
1357
|
+
ast.LtE: operator.le, # <=
|
|
1358
|
+
ast.Gt: operator.gt, # >
|
|
1359
|
+
ast.GtE: operator.ge, # >=
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
|
|
1363
|
+
def safe_eval(expr):
|
|
1364
|
+
def evaluate(node):
|
|
1365
|
+
if isinstance(node, ast.Constant) and isinstance(node.value, (int, float, str, bool)):
|
|
1366
|
+
return node.value
|
|
1367
|
+
|
|
1368
|
+
if isinstance(node, ast.BinOp) and type(node.op) in OPS:
|
|
1369
|
+
return OPS[type(node.op)](evaluate(node.left), evaluate(node.right))
|
|
1370
|
+
|
|
1371
|
+
if isinstance(node, ast.UnaryOp) and isinstance(node.op, (ast.UAdd, ast.USub)):
|
|
1372
|
+
value = evaluate(node.operand)
|
|
1373
|
+
return value if isinstance(node.op, ast.UAdd) else -value
|
|
1374
|
+
|
|
1375
|
+
if isinstance(node, ast.Compare):
|
|
1376
|
+
left = evaluate(node.left)
|
|
1377
|
+
|
|
1378
|
+
# Supports chained comparisons, e.g. 1 < 2 < 3
|
|
1379
|
+
for op, comparator in zip(node.ops, node.comparators):
|
|
1380
|
+
op_func = COMPARE_OPS.get(type(op))
|
|
1381
|
+
if op_func is None:
|
|
1382
|
+
raise ValueError("Unsupported comparison")
|
|
1383
|
+
|
|
1384
|
+
right = evaluate(comparator)
|
|
1385
|
+
|
|
1386
|
+
if not op_func(left, right):
|
|
1387
|
+
return False
|
|
1388
|
+
|
|
1389
|
+
left = right
|
|
1390
|
+
|
|
1391
|
+
return True
|
|
1392
|
+
|
|
1393
|
+
raise ValueError("Unsupported expression")
|
|
1394
|
+
|
|
1395
|
+
tree = ast.parse(expr, mode="eval")
|
|
1396
|
+
return evaluate(tree.body)
|
|
1397
|
+
|
|
1398
|
+
|
|
1278
1399
|
istr.type = type(istr(0))
|
|
1279
1400
|
|
|
1280
1401
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: istr-python
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.44
|
|
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
|
|
@@ -852,16 +852,24 @@ istr.getitem('1234',5, None) ==> None
|
|
|
852
852
|
Note that this method has the advantage that it can accept an istr as index, in contrast to normal indexing.
|
|
853
853
|
|
|
854
854
|
#### long square root
|
|
855
|
-
The method `long_sqrt`
|
|
856
|
-
|
|
855
|
+
The method `long_sqrt` returns an instance of a class with attributes `lines`, `line_lengths` and `output`.
|
|
856
|
+
|
|
857
|
+
`lines` is list of the lines of a long square root. Both the result (root) and the original number, possibly with a trailing 0 are returned, along with the calculated values.
|
|
858
|
+
E.g. `istr.long_sqrt(123 ** 2).lines` results in
|
|
857
859
|
|
|
858
860
|
`[istr('123'), istr('15129'), istr('1'), istr('51'), istr('44'), istr('729'), istr('729'), istr('0')]`
|
|
859
861
|
|
|
860
862
|
Note the final `istr('0')` is included to support also long square roots that are not perfect.
|
|
861
863
|
|
|
862
|
-
|
|
864
|
+
`line_lengths` returns a list of the length of the lines (not istr-ed). E.g.:
|
|
865
|
+
|
|
866
|
+
E.g. `istr.long_sqrt(123 ** 2).line_lengths` results in
|
|
867
|
+
|
|
868
|
+
`[3, 5, 1, 2, 2, 3, 3, 1]`
|
|
863
869
|
|
|
864
|
-
|
|
870
|
+
`output` can be used to get a nice string representation of the long square root lines.
|
|
871
|
+
|
|
872
|
+
E.g. `print(istr.long_sqrt(123 ** 2).output)` will print
|
|
865
873
|
```
|
|
866
874
|
1 2 3
|
|
867
875
|
-----
|
|
@@ -879,18 +887,26 @@ E.g. `print(istr.long_sqrt(123 ** 2, as_str=True))` will print
|
|
|
879
887
|
|
|
880
888
|
#### long multiplication
|
|
881
889
|
|
|
882
|
-
The method `long_multiplication`
|
|
890
|
+
The method `long_multiplication` returns an instance of a class with attributes `lines`, `line_lengths` and `output`.
|
|
891
|
+
|
|
892
|
+
`lines` is list of the lines of a long multiplication.
|
|
893
|
+
|
|
894
|
+
E.g. `print(istr.long_multiplication(1234,567).lines` will print
|
|
883
895
|
|
|
884
|
-
E.g. `print(istr.long_multiplication(1234,567)` will print
|
|
885
|
-
|
|
886
896
|
`[istr('1234'), istr('567'), istr('8638'), istr('7404'), istr('6170'), istr('699678')]`
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
E.g. `print(istr.long_multiplication(1234,567
|
|
897
|
+
|
|
898
|
+
`line_lengths` returns a list of the length of the lines (not istr-ed). E.g.:
|
|
899
|
+
|
|
900
|
+
E. g. `print(istr.long_multiplication(1234,567).line_lengths` results in
|
|
901
|
+
|
|
902
|
+
`[4, 3, 4, 4, 4, 6]`
|
|
903
|
+
|
|
904
|
+
`output` can be used to get a nice string representation of the long multiplication lines.
|
|
905
|
+
|
|
906
|
+
E.g. `print(istr.long_multiplication(1234, 567).output)` will print
|
|
891
907
|
|
|
892
908
|
```
|
|
893
|
-
|
|
909
|
+
1234
|
|
894
910
|
567
|
|
895
911
|
------ x
|
|
896
912
|
8638
|
|
@@ -902,15 +918,23 @@ E.g. `print(istr.long_multiplication(1234,567, as_str=True)` will print
|
|
|
902
918
|
|
|
903
919
|
#### long division
|
|
904
920
|
|
|
905
|
-
The method `long_division`
|
|
921
|
+
The method `long_division` returns an instance of a class with attributes `lines`, `line_lengths` and `output`.
|
|
906
922
|
|
|
907
|
-
|
|
923
|
+
`lines` is a list of the lines of a long division.
|
|
908
924
|
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
925
|
+
E.g. `print(istr.long_division(1395, 45).lines` will print
|
|
926
|
+
|
|
927
|
+
`[istr('31'), istr('45'), istr('1395'), istr('135'), istr('45'), istr('45'), istr('0')]`
|
|
928
|
+
|
|
929
|
+
Note the final `istr('0')` is included to support also long divisions roots that are not perfect.
|
|
930
|
+
|
|
931
|
+
E.g. `print(istr.long_division(1395, 45).line_lengths` will print
|
|
932
|
+
|
|
933
|
+
`[2, 2, 4, 3, 2, 2, 1]`
|
|
934
|
+
|
|
935
|
+
`output` can be used to get a nice string representation of the long divsion lines.
|
|
936
|
+
|
|
937
|
+
E.g. `print(istr.long_division(1395, 45).output` will print
|
|
914
938
|
|
|
915
939
|
```
|
|
916
940
|
31
|
|
@@ -922,8 +946,8 @@ E.g. `print(istr.long_division(1395, 45, as_str=True)` will print
|
|
|
922
946
|
45
|
|
923
947
|
--
|
|
924
948
|
0
|
|
925
|
-
```
|
|
926
|
-
|
|
949
|
+
```
|
|
950
|
+
|
|
927
951
|
#### generate istr with digits
|
|
928
952
|
|
|
929
953
|
The class method `digits` can be used to return an istr of digits according to a given specification.
|
|
@@ -1017,6 +1041,41 @@ Note that `str(istr(":="))` is ":=" and does not assign any value.
|
|
|
1017
1041
|
|
|
1018
1042
|
Usually, composing and decomposing uses the globals namespace, but this can be overridden with the namespace parameter. See the test suite for details.
|
|
1019
1043
|
|
|
1044
|
+
#### Evaluating expressions with one letter variables
|
|
1045
|
+
The `istr.eval` method is essentially the same as `istr.compose`, but (safely) evaluates the result.
|
|
1046
|
+
E.g.
|
|
1047
|
+
|
|
1048
|
+
```
|
|
1049
|
+
a = 5
|
|
1050
|
+
b = 2
|
|
1051
|
+
print(istr.eval('aab + ba')
|
|
1052
|
+
```
|
|
1053
|
+
will print `577`
|
|
1054
|
+
|
|
1055
|
+
The operators +, -, * and / are supported.
|
|
1056
|
+
Comparisons (==, <=, <, >, >= are also supported. In that case, the result is also istr-ed, so istr('0') for False and istr('1') for True. E.g.
|
|
1057
|
+
|
|
1058
|
+
```
|
|
1059
|
+
a = 5
|
|
1060
|
+
b = 2
|
|
1061
|
+
print(istr.eval('a > b')
|
|
1062
|
+
```
|
|
1063
|
+
will print 1 (meaning True)
|
|
1064
|
+
|
|
1065
|
+
Note that leading zeroes are accepted. So, `istr.eval('03 + 7')` is `10`.
|
|
1066
|
+
Instead of ==, = can be used. So, `istr.eval('12 = 5 + 7')` is `1` (meaning True)
|
|
1067
|
+
|
|
1068
|
+
##### Alternative method
|
|
1069
|
+
|
|
1070
|
+
If istr is called with a string starting with a `?`, the string without the leading `?` will be evaluated using the new `istr.eval` method. So, the above examples read:
|
|
1071
|
+
```
|
|
1072
|
+
a = 5
|
|
1073
|
+
b = 2
|
|
1074
|
+
print(istr("?aab + ba':")
|
|
1075
|
+
print(istr("?a > b")
|
|
1076
|
+
```
|
|
1077
|
+
with output `577` and `1` (meaning True)
|
|
1078
|
+
|
|
1020
1079
|
#### Subclassing istr
|
|
1021
1080
|
|
|
1022
1081
|
When a class is derived from istr, all methods will return that newly derived class.
|
|
@@ -1227,7 +1227,7 @@ def test_compose():
|
|
|
1227
1227
|
|
|
1228
1228
|
|
|
1229
1229
|
def test_long_sqrt():
|
|
1230
|
-
assert istr.long_sqrt(1234**2) == [
|
|
1230
|
+
assert istr.long_sqrt(1234**2).lines == [
|
|
1231
1231
|
istr("1234"),
|
|
1232
1232
|
istr("1522756"),
|
|
1233
1233
|
istr("1"),
|
|
@@ -1239,7 +1239,7 @@ def test_long_sqrt():
|
|
|
1239
1239
|
istr("9856"),
|
|
1240
1240
|
istr("0"),
|
|
1241
1241
|
]
|
|
1242
|
-
assert istr.long_sqrt(1234**2 + 1) == [
|
|
1242
|
+
assert istr.long_sqrt(1234**2 + 1).lines == [
|
|
1243
1243
|
istr("1234"),
|
|
1244
1244
|
istr("1522757"),
|
|
1245
1245
|
istr("1"),
|
|
@@ -1251,8 +1251,8 @@ def test_long_sqrt():
|
|
|
1251
1251
|
istr("9856"),
|
|
1252
1252
|
istr("1"),
|
|
1253
1253
|
]
|
|
1254
|
-
|
|
1255
|
-
assert istr(1234**2).long_sqrt() == [
|
|
1254
|
+
|
|
1255
|
+
assert istr(1234**2).long_sqrt().lines == [
|
|
1256
1256
|
istr("1234"),
|
|
1257
1257
|
istr("1522756"),
|
|
1258
1258
|
istr("1"),
|
|
@@ -1264,11 +1264,12 @@ def test_long_sqrt():
|
|
|
1264
1264
|
istr("9856"),
|
|
1265
1265
|
istr("0"),
|
|
1266
1266
|
]
|
|
1267
|
-
assert istr.long_sqrt(34**2) == [istr("34"), istr("1156"), istr("9"), istr("256"), istr("256"), istr("0")]
|
|
1268
|
-
assert istr.long_sqrt("001156") == [istr("34"), istr("1156"), istr("9"), istr("256"), istr("256"), istr("0")]
|
|
1269
|
-
|
|
1267
|
+
assert istr.long_sqrt(34**2).lines == [istr("34"), istr("1156"), istr("9"), istr("256"), istr("256"), istr("0")]
|
|
1268
|
+
assert istr.long_sqrt("001156").lines == [istr("34"), istr("1156"), istr("9"), istr("256"), istr("256"), istr("0")]
|
|
1269
|
+
assert istr.long_sqrt(34**2).line_lengths == [2, 4, 1, 3, 3, 1]
|
|
1270
|
+
assert istr.long_sqrt("001156").line_lengths == [2, 4, 1, 3, 3, 1]
|
|
1270
1271
|
assert (
|
|
1271
|
-
istr.long_sqrt(34**2
|
|
1272
|
+
istr.long_sqrt(34**2).output
|
|
1272
1273
|
== """\
|
|
1273
1274
|
3 4
|
|
1274
1275
|
----
|
|
@@ -1283,12 +1284,12 @@ def test_long_sqrt():
|
|
|
1283
1284
|
|
|
1284
1285
|
|
|
1285
1286
|
def test_long_multiplication():
|
|
1286
|
-
assert istr.long_multiplication(1234, 567) == [istr("1234"), istr("567"), istr("8638"), istr("7404"), istr("6170"), istr("699678")]
|
|
1287
|
-
assert istr(1234).long_multiplication(567) == [istr("1234"), istr("567"), istr("8638"), istr("7404"), istr("6170"), istr("699678")]
|
|
1288
|
-
assert istr("01234").long_multiplication("0567") == [istr("1234"), istr("567"), istr("8638"), istr("7404"), istr("6170"), istr("699678")]
|
|
1287
|
+
assert istr.long_multiplication(1234, 567).lines == [istr("1234"), istr("567"), istr("8638"), istr("7404"), istr("6170"), istr("699678")]
|
|
1288
|
+
assert istr(1234).long_multiplication(567).lines == [istr("1234"), istr("567"), istr("8638"), istr("7404"), istr("6170"), istr("699678")]
|
|
1289
|
+
assert istr("01234").long_multiplication("0567").lines == [istr("1234"), istr("567"), istr("8638"), istr("7404"), istr("6170"), istr("699678")]
|
|
1289
1290
|
|
|
1290
1291
|
assert (
|
|
1291
|
-
istr.long_multiplication(1234, 567
|
|
1292
|
+
istr.long_multiplication(1234, 567).output
|
|
1292
1293
|
== """\
|
|
1293
1294
|
1234
|
|
1294
1295
|
567
|
|
@@ -1302,12 +1303,12 @@ def test_long_multiplication():
|
|
|
1302
1303
|
|
|
1303
1304
|
|
|
1304
1305
|
def test_long_division():
|
|
1305
|
-
assert istr.long_division(1395, 45) == [istr("31"), istr("45"), istr("1395"), istr("135"), istr("45"), istr("45"), istr("0")]
|
|
1306
|
-
assert istr(1395).long_division(45) == [istr("31"), istr("45"), istr("1395"), istr("135"), istr("45"), istr("45"), istr("0")]
|
|
1307
|
-
assert istr.long_division(istr("01395"), istr("045")) == [istr("31"), istr("45"), istr("1395"), istr("135"), istr("45"), istr("45"), istr("0")]
|
|
1308
|
-
|
|
1306
|
+
assert istr.long_division(1395, 45).lines == [istr("31"), istr("45"), istr("1395"), istr("135"), istr("45"), istr("45"), istr("0")]
|
|
1307
|
+
assert istr(1395).long_division(45).lines == [istr("31"), istr("45"), istr("1395"), istr("135"), istr("45"), istr("45"), istr("0")]
|
|
1308
|
+
assert istr.long_division(istr("01395"), istr("045")).lines == [istr("31"), istr("45"), istr("1395"), istr("135"), istr("45"), istr("45"), istr("0")]
|
|
1309
|
+
assert istr.long_division(1395, 45).line_lengths == [2, 2, 4, 3, 2, 2, 1]
|
|
1309
1310
|
assert (
|
|
1310
|
-
istr.long_division(1395, 45
|
|
1311
|
+
istr.long_division(1395, 45).output
|
|
1311
1312
|
== """\
|
|
1312
1313
|
31
|
|
1313
1314
|
----
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|