istr-python 1.1.41__tar.gz → 1.1.43__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.41 → istr_python-1.1.43}/PKG-INFO +46 -25
- {istr_python-1.1.41 → istr_python-1.1.43}/README.md +45 -24
- {istr_python-1.1.41 → istr_python-1.1.43}/istr/istr.py +154 -101
- {istr_python-1.1.41 → istr_python-1.1.43}/istr_python.egg-info/PKG-INFO +46 -25
- {istr_python-1.1.41 → istr_python-1.1.43}/istr_python.egg-info/SOURCES.txt +0 -1
- {istr_python-1.1.41 → istr_python-1.1.43}/pyproject.toml +1 -1
- {istr_python-1.1.41 → istr_python-1.1.43}/tests/test_istr.py +27 -14
- istr_python-1.1.41/istr/istr - Copy.py +0 -1084
- {istr_python-1.1.41 → istr_python-1.1.43}/istr/LICENSE.txt +0 -0
- {istr_python-1.1.41 → istr_python-1.1.43}/istr/__init__.py +0 -0
- {istr_python-1.1.41 → istr_python-1.1.43}/istr_python.egg-info/dependency_links.txt +0 -0
- {istr_python-1.1.41 → istr_python-1.1.43}/istr_python.egg-info/top_level.txt +0 -0
- {istr_python-1.1.41 → istr_python-1.1.43}/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.43
|
|
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
|
|
@@ -589,9 +589,6 @@ map(istr.join,filter(istr.prime, istr.combinations(range(10),2)))
|
|
|
589
589
|
==> istr('02'), istr('03'), ... istr('89')
|
|
590
590
|
```
|
|
591
591
|
|
|
592
|
-
#### version 1.1.30 2026-05-19
|
|
593
|
-
|
|
594
|
-
|
|
595
592
|
#### reverse an istr
|
|
596
593
|
|
|
597
594
|
The method `reversed()` will return an istr with the reversed content:
|
|
@@ -855,16 +852,24 @@ istr.getitem('1234',5, None) ==> None
|
|
|
855
852
|
Note that this method has the advantage that it can accept an istr as index, in contrast to normal indexing.
|
|
856
853
|
|
|
857
854
|
#### long square root
|
|
858
|
-
The method `long_sqrt`
|
|
859
|
-
|
|
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
|
|
860
859
|
|
|
861
860
|
`[istr('123'), istr('15129'), istr('1'), istr('51'), istr('44'), istr('729'), istr('729'), istr('0')]`
|
|
862
861
|
|
|
863
862
|
Note the final `istr('0')` is included to support also long square roots that are not perfect.
|
|
864
863
|
|
|
865
|
-
|
|
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
|
|
866
867
|
|
|
867
|
-
|
|
868
|
+
`[3, 5, 1, 2, 2, 3, 3, 1]`
|
|
869
|
+
|
|
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
|
|
868
873
|
```
|
|
869
874
|
1 2 3
|
|
870
875
|
-----
|
|
@@ -882,18 +887,26 @@ E.g. `print(istr.long_sqrt(123 ** 2, as_str=True))` will print
|
|
|
882
887
|
|
|
883
888
|
#### long multiplication
|
|
884
889
|
|
|
885
|
-
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
|
|
886
895
|
|
|
887
|
-
E.g. `print(istr.long_multiplication(1234,567)` will print
|
|
888
|
-
|
|
889
896
|
`[istr('1234'), istr('567'), istr('8638'), istr('7404'), istr('6170'), istr('699678')]`
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
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
|
|
894
907
|
|
|
895
908
|
```
|
|
896
|
-
|
|
909
|
+
1234
|
|
897
910
|
567
|
|
898
911
|
------ x
|
|
899
912
|
8638
|
|
@@ -905,15 +918,23 @@ E.g. `print(istr.long_multiplication(1234,567, as_str=True)` will print
|
|
|
905
918
|
|
|
906
919
|
#### long division
|
|
907
920
|
|
|
908
|
-
The method `long_division`
|
|
921
|
+
The method `long_division` returns an instance of a class with attributes `lines`, `line_lengths` and `output`.
|
|
909
922
|
|
|
910
|
-
|
|
923
|
+
`lines` is a list of the lines of a long division.
|
|
911
924
|
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
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
|
|
917
938
|
|
|
918
939
|
```
|
|
919
940
|
31
|
|
@@ -925,8 +946,8 @@ E.g. `print(istr.long_division(1395, 45, as_str=True)` will print
|
|
|
925
946
|
45
|
|
926
947
|
--
|
|
927
948
|
0
|
|
928
|
-
```
|
|
929
|
-
|
|
949
|
+
```
|
|
950
|
+
|
|
930
951
|
#### generate istr with digits
|
|
931
952
|
|
|
932
953
|
The class method `digits` can be used to return an istr of digits according to a given specification.
|
|
@@ -576,9 +576,6 @@ map(istr.join,filter(istr.prime, istr.combinations(range(10),2)))
|
|
|
576
576
|
==> istr('02'), istr('03'), ... istr('89')
|
|
577
577
|
```
|
|
578
578
|
|
|
579
|
-
#### version 1.1.30 2026-05-19
|
|
580
|
-
|
|
581
|
-
|
|
582
579
|
#### reverse an istr
|
|
583
580
|
|
|
584
581
|
The method `reversed()` will return an istr with the reversed content:
|
|
@@ -842,16 +839,24 @@ istr.getitem('1234',5, None) ==> None
|
|
|
842
839
|
Note that this method has the advantage that it can accept an istr as index, in contrast to normal indexing.
|
|
843
840
|
|
|
844
841
|
#### long square root
|
|
845
|
-
The method `long_sqrt`
|
|
846
|
-
|
|
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
|
|
847
846
|
|
|
848
847
|
`[istr('123'), istr('15129'), istr('1'), istr('51'), istr('44'), istr('729'), istr('729'), istr('0')]`
|
|
849
848
|
|
|
850
849
|
Note the final `istr('0')` is included to support also long square roots that are not perfect.
|
|
851
850
|
|
|
852
|
-
|
|
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
|
|
853
854
|
|
|
854
|
-
|
|
855
|
+
`[3, 5, 1, 2, 2, 3, 3, 1]`
|
|
856
|
+
|
|
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
|
|
855
860
|
```
|
|
856
861
|
1 2 3
|
|
857
862
|
-----
|
|
@@ -869,18 +874,26 @@ E.g. `print(istr.long_sqrt(123 ** 2, as_str=True))` will print
|
|
|
869
874
|
|
|
870
875
|
#### long multiplication
|
|
871
876
|
|
|
872
|
-
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
|
|
873
882
|
|
|
874
|
-
E.g. `print(istr.long_multiplication(1234,567)` will print
|
|
875
|
-
|
|
876
883
|
`[istr('1234'), istr('567'), istr('8638'), istr('7404'), istr('6170'), istr('699678')]`
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
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
|
|
881
894
|
|
|
882
895
|
```
|
|
883
|
-
|
|
896
|
+
1234
|
|
884
897
|
567
|
|
885
898
|
------ x
|
|
886
899
|
8638
|
|
@@ -892,15 +905,23 @@ E.g. `print(istr.long_multiplication(1234,567, as_str=True)` will print
|
|
|
892
905
|
|
|
893
906
|
#### long division
|
|
894
907
|
|
|
895
|
-
The method `long_division`
|
|
908
|
+
The method `long_division` returns an instance of a class with attributes `lines`, `line_lengths` and `output`.
|
|
896
909
|
|
|
897
|
-
|
|
910
|
+
`lines` is a list of the lines of a long division.
|
|
898
911
|
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
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
|
|
904
925
|
|
|
905
926
|
```
|
|
906
927
|
31
|
|
@@ -912,8 +933,8 @@ E.g. `print(istr.long_division(1395, 45, as_str=True)` will print
|
|
|
912
933
|
45
|
|
913
934
|
--
|
|
914
935
|
0
|
|
915
|
-
```
|
|
916
|
-
|
|
936
|
+
```
|
|
937
|
+
|
|
917
938
|
#### generate istr with digits
|
|
918
939
|
|
|
919
940
|
The class method `digits` can be used to return an istr of digits according to a given specification.
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# |_||___/ \__||_|
|
|
6
6
|
# strings you can count on
|
|
7
7
|
|
|
8
|
-
__version__ = "1.1.
|
|
8
|
+
__version__ = "1.1.43"
|
|
9
9
|
import functools
|
|
10
10
|
import itertools
|
|
11
11
|
import types
|
|
@@ -727,19 +727,16 @@ class istr(str):
|
|
|
727
727
|
return self[::-1]
|
|
728
728
|
|
|
729
729
|
def ceil(self, divisible_by=1):
|
|
730
|
-
if divisible_by
|
|
731
|
-
raise ValueError(f"
|
|
732
|
-
if divisible_by != int(divisible_by):
|
|
733
|
-
raise ValueError(f"step has to be an integer value, not {divisible_by}")
|
|
730
|
+
if divisible_by != int(divisible_by) or divisible_by < 1:
|
|
731
|
+
raise ValueError(f"divisible_by has to be an integer value >=1 , not {divisible_by}")
|
|
734
732
|
n = istr.interpret_as_float(self)
|
|
735
733
|
return istr((math.ceil(n / divisible_by)) * divisible_by)
|
|
736
734
|
|
|
737
735
|
def floor(self, divisible_by=1):
|
|
738
|
-
if divisible_by
|
|
739
|
-
raise ValueError(f"
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
return istr((math.floor(self / divisible_by)) * divisible_by)
|
|
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}")
|
|
738
|
+
n = istr.interpret_as_float(self)
|
|
739
|
+
return istr((math.floor(n / divisible_by)) * divisible_by)
|
|
743
740
|
|
|
744
741
|
def interpret_as_int(self):
|
|
745
742
|
if isinstance(self, istr):
|
|
@@ -767,13 +764,13 @@ class istr(str):
|
|
|
767
764
|
|
|
768
765
|
return str(self)
|
|
769
766
|
|
|
770
|
-
def interpret_as_istr(self):
|
|
767
|
+
def interpret_as_istr(self):
|
|
771
768
|
# ignore leading zeroes
|
|
772
769
|
if isinstance(self, collections.abc.Iterable) and not isinstance(self, str):
|
|
773
|
-
return istr.join(self)*1
|
|
770
|
+
return istr.join(self) * 1
|
|
771
|
+
|
|
772
|
+
return istr(self) * 1
|
|
774
773
|
|
|
775
|
-
return istr(self)*1
|
|
776
|
-
|
|
777
774
|
def _str_method(self, name, *args, **kwargs):
|
|
778
775
|
return self.__class__(getattr(super(), name)(*args, **kwargs))
|
|
779
776
|
|
|
@@ -863,22 +860,15 @@ class istr(str):
|
|
|
863
860
|
for i, value in enumerate(iterable, int(start)):
|
|
864
861
|
yield cls(i), value
|
|
865
862
|
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
(modified from a ChatGPT code suggestion)
|
|
870
|
-
returns root, number and the lines below the number, all istr-ed
|
|
871
|
-
if as_str is True, a formatted output will be returned
|
|
872
|
-
"""
|
|
873
|
-
|
|
874
|
-
number = istr.interpret_as_istr(self)
|
|
875
|
-
|
|
863
|
+
@staticmethod
|
|
864
|
+
@functools.lru_cache(maxsize=1)
|
|
865
|
+
def _long_sqrt(number):
|
|
876
866
|
lines = []
|
|
877
|
-
if len(number)%2==1:
|
|
878
|
-
pairs=istr.chain(number[0],istr.batched(number[1:],2,join=True))
|
|
879
|
-
else:
|
|
880
|
-
pairs=istr.batched(number,2,join=True)
|
|
881
|
-
|
|
867
|
+
if len(number) % 2 == 1:
|
|
868
|
+
pairs = istr.chain(number[0], istr.batched(number[1:], 2, join=True))
|
|
869
|
+
else:
|
|
870
|
+
pairs = istr.batched(number, 2, join=True)
|
|
871
|
+
|
|
882
872
|
root = istr(0)
|
|
883
873
|
remainder = 0
|
|
884
874
|
|
|
@@ -896,123 +886,186 @@ class istr(str):
|
|
|
896
886
|
remainder = dividend - trial
|
|
897
887
|
|
|
898
888
|
root = root * 10 + x
|
|
899
|
-
|
|
900
|
-
|
|
889
|
+
if trial:
|
|
890
|
+
lines.append(dividend)
|
|
891
|
+
lines.append(trial)
|
|
901
892
|
|
|
902
893
|
lines.append(remainder)
|
|
903
894
|
lines = [root] + [number] + lines[1:]
|
|
904
|
-
|
|
905
|
-
result = []
|
|
906
|
-
extra = len(number)%2==0
|
|
907
|
-
result.append(f" {extra*' '}{' '.join(lines[0])}")
|
|
908
|
-
result.append(f" {len(lines[1])*'-'}")
|
|
909
|
-
result.append(f"\/{lines[1]}")
|
|
910
|
-
|
|
911
|
-
last_len=len(lines[2])
|
|
912
|
-
for i, line in enumerate(lines):
|
|
913
|
-
|
|
914
|
-
if i >= 2:
|
|
915
|
-
if i == len(lines) - 1:
|
|
916
|
-
n = i - 2 + extra
|
|
917
|
-
else:
|
|
918
|
-
n = i + extra
|
|
895
|
+
return lines
|
|
919
896
|
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
897
|
+
def long_sqrt(self):
|
|
898
|
+
"""
|
|
899
|
+
this function does long squre root and returns all the lines to be written.
|
|
900
|
+
(modified from a ChatGPT code suggestion)
|
|
901
|
+
returns root, number and the lines below the number, all istr-ed
|
|
902
|
+
if as_str is True, a formatted output will be returned
|
|
903
|
+
"""
|
|
904
|
+
|
|
905
|
+
class NumberHolder:
|
|
906
|
+
def __init__(self, number):
|
|
907
|
+
self.number = number
|
|
908
|
+
|
|
909
|
+
def __getattr__(self, attr):
|
|
910
|
+
match attr:
|
|
911
|
+
case "lines":
|
|
912
|
+
return istr._long_sqrt(self.number)
|
|
913
|
+
case "line_lengths":
|
|
914
|
+
return [*map(len, istr._long_sqrt(self.number))]
|
|
915
|
+
case "output":
|
|
916
|
+
lines = istr._long_sqrt(self.number)
|
|
917
|
+
result = []
|
|
918
|
+
extra = len(number) % 2 == 0
|
|
919
|
+
result.append(f" {extra*' '}{' '.join(lines[0])}")
|
|
920
|
+
result.append(f" {len(lines[1])*'-'}")
|
|
921
|
+
result.append(f"\/{lines[1]}")
|
|
922
|
+
|
|
923
|
+
last_len = len(lines[2])
|
|
924
|
+
for i, line in enumerate(lines):
|
|
925
|
+
if i >= 2:
|
|
926
|
+
if i == len(lines) - 1:
|
|
927
|
+
n = i - 2 + extra
|
|
928
|
+
else:
|
|
929
|
+
n = i + extra
|
|
930
|
+
|
|
931
|
+
if i % 2 == 0:
|
|
932
|
+
result.append(f" {line:>{n}}")
|
|
933
|
+
result.append(f" {last_len*'-':>{n}}")
|
|
934
|
+
else:
|
|
935
|
+
result.append(f" {line:>{n+1}}")
|
|
936
|
+
last_len = len(line)
|
|
937
|
+
return "\n".join(result)
|
|
938
|
+
case _:
|
|
939
|
+
raise AttributeError()
|
|
940
|
+
|
|
941
|
+
number = istr.interpret_as_istr(self)
|
|
942
|
+
|
|
943
|
+
return NumberHolder(number)
|
|
944
|
+
|
|
945
|
+
@staticmethod
|
|
946
|
+
@functools.lru_cache(maxsize=1)
|
|
947
|
+
def _long_multiplication(number0, number1):
|
|
948
|
+
lines = [number0, number1]
|
|
934
949
|
for i in number1.reversed():
|
|
935
|
-
lines.append(number0*i)
|
|
936
|
-
lines.append(number0*number1)
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
950
|
+
lines.append(number0 * i)
|
|
951
|
+
lines.append(number0 * number1)
|
|
952
|
+
|
|
953
|
+
return lines
|
|
954
|
+
|
|
955
|
+
def long_multiplication(self, number, as_str=False):
|
|
956
|
+
class NumbersHolder:
|
|
957
|
+
def __init__(self, number0, number1):
|
|
958
|
+
self.number0 = number0
|
|
959
|
+
self.number1 = number1
|
|
960
|
+
|
|
961
|
+
def __getattr__(self, attr):
|
|
962
|
+
match attr:
|
|
963
|
+
case "lines":
|
|
964
|
+
return istr._long_multiplication(self.number0, self.number1)
|
|
965
|
+
case "line_lengths":
|
|
966
|
+
return [*map(len, istr._long_multiplication(self.number0, self.number1))]
|
|
967
|
+
case "output":
|
|
968
|
+
lines = istr._long_multiplication(self.number0, self.number1)
|
|
969
|
+
result = []
|
|
970
|
+
|
|
971
|
+
n = len(lines[-1])
|
|
972
|
+
result.append(f"{lines[0]:>{n}}")
|
|
973
|
+
result.append(f"{lines[1]:>{n}}")
|
|
974
|
+
result.append(f"{n*'-'} x")
|
|
975
|
+
for i, line in enumerate(lines[2:-1]):
|
|
976
|
+
result.append(f"{line:>{n-i}}")
|
|
977
|
+
result.append(f"{n*'-'}")
|
|
978
|
+
result.append(lines[-1])
|
|
979
|
+
return "\n".join(result)
|
|
980
|
+
case _:
|
|
981
|
+
raise AttributeError()
|
|
982
|
+
|
|
983
|
+
number0 = istr.interpret_as_istr(self)
|
|
984
|
+
number1 = istr.interpret_as_istr(number)
|
|
985
|
+
return NumbersHolder(number0, number1)
|
|
986
|
+
|
|
987
|
+
@staticmethod
|
|
988
|
+
@functools.lru_cache(maxsize=1)
|
|
989
|
+
def _long_division(dividend, divisor, as_str=False):
|
|
955
990
|
if dividend < 0:
|
|
956
991
|
raise ValueError("dividend must be non-negative.")
|
|
957
|
-
|
|
992
|
+
|
|
958
993
|
if divisor <= 0:
|
|
959
994
|
raise ValueError("divisor must be positive.")
|
|
960
|
-
|
|
995
|
+
|
|
961
996
|
dividend_start = len(divisor) + 3
|
|
962
997
|
total_width = dividend_start + len(dividend)
|
|
963
|
-
|
|
998
|
+
|
|
964
999
|
quotient_characters = [" "] * len(dividend)
|
|
965
|
-
|
|
1000
|
+
|
|
966
1001
|
remainder = 0
|
|
967
1002
|
division_started = False
|
|
968
|
-
lines=[]
|
|
969
|
-
|
|
1003
|
+
lines = []
|
|
1004
|
+
|
|
970
1005
|
for digit_index, digit_character in enumerate(dividend):
|
|
971
1006
|
current = remainder * 10 + digit_character
|
|
972
1007
|
quotient_digit = current // divisor
|
|
973
|
-
|
|
1008
|
+
|
|
974
1009
|
if quotient_digit != 0 or division_started:
|
|
975
1010
|
division_started = True
|
|
976
|
-
|
|
1011
|
+
|
|
977
1012
|
if digit_index == len(dividend) - 1:
|
|
978
1013
|
division_started = True
|
|
979
|
-
|
|
1014
|
+
|
|
980
1015
|
if not division_started:
|
|
981
1016
|
remainder = current
|
|
982
1017
|
continue
|
|
983
|
-
|
|
1018
|
+
|
|
984
1019
|
quotient_characters[digit_index] = quotient_digit
|
|
985
|
-
|
|
1020
|
+
|
|
986
1021
|
product = quotient_digit * divisor
|
|
987
1022
|
remainder = current - product
|
|
988
|
-
|
|
1023
|
+
|
|
989
1024
|
if as_str:
|
|
990
1025
|
end_column = dividend_start + digit_index
|
|
991
1026
|
current_start = end_column - len(current) + 1
|
|
992
|
-
product_start = end_column - len(product) + 1
|
|
1027
|
+
product_start = end_column - len(product) + 1
|
|
993
1028
|
bar_start = min(current_start, product_start)
|
|
994
1029
|
bar_length = end_column - bar_start + 1
|
|
995
1030
|
lines.append(" " * current_start | current)
|
|
996
1031
|
lines.append(" " * product_start | product)
|
|
997
1032
|
lines.append(" " * bar_start + "-" * bar_length)
|
|
998
|
-
|
|
1033
|
+
|
|
999
1034
|
else:
|
|
1000
1035
|
lines.append(current)
|
|
1001
1036
|
lines.append(product)
|
|
1002
|
-
|
|
1037
|
+
|
|
1003
1038
|
quotient = istr.join(quotient_characters).rstrip()
|
|
1004
1039
|
if as_str:
|
|
1005
1040
|
remainder_start = total_width - len(remainder)
|
|
1006
1041
|
lines.append(" " * remainder_start | remainder)
|
|
1007
|
-
lines=[" " * dividend_start | quotient," " * dividend_start + "-" * len(dividend),f"{divisor} ) {dividend}"
|
|
1042
|
+
lines = [" " * dividend_start | quotient, " " * dividend_start + "-" * len(dividend), f"{divisor} ) {dividend}", *lines[1:]]
|
|
1008
1043
|
return "\n".join(lines)
|
|
1009
|
-
|
|
1044
|
+
|
|
1010
1045
|
else:
|
|
1011
1046
|
lines.append(remainder)
|
|
1012
|
-
lines=[istr(quotient),divisor,dividend
|
|
1013
|
-
return lines
|
|
1014
|
-
|
|
1015
|
-
|
|
1047
|
+
lines = [istr(quotient), divisor, dividend, *lines[1:]]
|
|
1048
|
+
return lines
|
|
1049
|
+
|
|
1050
|
+
def long_division(self, divisor):
|
|
1051
|
+
class NumbersHolder:
|
|
1052
|
+
def __init__(self, dividend, divisor):
|
|
1053
|
+
self.dividend = dividend
|
|
1054
|
+
self.divisor = divisor
|
|
1055
|
+
|
|
1056
|
+
def __getattr__(self, attr):
|
|
1057
|
+
match attr:
|
|
1058
|
+
case "lines":
|
|
1059
|
+
return istr._long_division(self.dividend, self.divisor)
|
|
1060
|
+
case "line_lengths":
|
|
1061
|
+
return [*map(len, istr._long_division(self.dividend, self.divisor))]
|
|
1062
|
+
case "output":
|
|
1063
|
+
return istr._long_division(self.dividend, self.divisor, as_str=True)
|
|
1064
|
+
|
|
1065
|
+
dividend = istr.interpret_as_istr(self)
|
|
1066
|
+
divisor = istr.interpret_as_istr(divisor)
|
|
1067
|
+
return NumbersHolder(dividend, divisor)
|
|
1068
|
+
|
|
1016
1069
|
def this_base(self):
|
|
1017
1070
|
return self._this_base
|
|
1018
1071
|
|