istr-python 1.1.6__tar.gz → 1.1.8__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.6 → istr_python-1.1.8}/PKG-INFO +79 -62
- {istr_python-1.1.6 → istr_python-1.1.8}/README.md +77 -60
- {istr_python-1.1.6 → istr_python-1.1.8}/istr/istr.py +59 -8
- {istr_python-1.1.6 → istr_python-1.1.8}/istr_python.egg-info/PKG-INFO +79 -62
- {istr_python-1.1.6 → istr_python-1.1.8}/pyproject.toml +2 -2
- {istr_python-1.1.6 → istr_python-1.1.8}/tests/test_istr.py +46 -18
- {istr_python-1.1.6 → istr_python-1.1.8}/istr/LICENSE.txt +0 -0
- {istr_python-1.1.6 → istr_python-1.1.8}/istr/__init__.py +0 -0
- {istr_python-1.1.6 → istr_python-1.1.8}/istr_python.egg-info/SOURCES.txt +0 -0
- {istr_python-1.1.6 → istr_python-1.1.8}/istr_python.egg-info/dependency_links.txt +0 -0
- {istr_python-1.1.6 → istr_python-1.1.8}/istr_python.egg-info/top_level.txt +0 -0
- {istr_python-1.1.6 → istr_python-1.1.8}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: istr-python
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.8
|
|
4
4
|
Summary: istr - strings you can count on
|
|
5
5
|
Author-email: Ruud van der Ham <rt.van.der.ham@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/salabim/istr
|
|
@@ -8,7 +8,7 @@ Project-URL: Repository, https://github.com/salabim/istr
|
|
|
8
8
|
Classifier: Development Status :: 5 - Production/Stable
|
|
9
9
|
Classifier: License :: OSI Approved :: MIT License
|
|
10
10
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
11
|
-
Requires-Python: >=3.
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
|
|
14
14
|
<img src="https://www.salabim.org/istr/istr_logo.png" width=500>
|
|
@@ -31,20 +31,33 @@ can be nicely, albeit not very efficient, coded as:
|
|
|
31
31
|
import istr
|
|
32
32
|
|
|
33
33
|
for s, e, n, d, m, o, r, y in istr.permutations(range(10), 8):
|
|
34
|
-
if m and ((s|e|n|d) + (m|o|r|e) == (m|o|n|e|y)
|
|
34
|
+
if m and ((s|e|n|d) + (m|o|r|e) == (m|o|n|e|y):
|
|
35
35
|
print(f' {s|e|n|d}')
|
|
36
36
|
print(f' {m|o|r|e}')
|
|
37
37
|
print('-----')
|
|
38
38
|
print(f'{m|o|n|e|y}')
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
+
or even
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
import istr
|
|
45
|
+
|
|
46
|
+
for S, E, N, D, M, O, R, Y in istr.permutations(range(10), 8):
|
|
47
|
+
if m and (istr.compose("SEND") + ist.compose("MORE") == istr.compose("MONEY"):
|
|
48
|
+
print(" ",istr.compose("SEND"))
|
|
49
|
+
print(" ",istr.compose("MORE"))
|
|
50
|
+
print('-----')
|
|
51
|
+
print(istr.compose("MONEY"))
|
|
52
|
+
```
|
|
53
|
+
|
|
41
54
|
Of, if we want to add all the digits in a string:
|
|
42
55
|
|
|
43
56
|
```
|
|
44
57
|
sum_digits = sum(istr('9282334')) # answer 31
|
|
45
58
|
```
|
|
46
59
|
|
|
47
|
-
|
|
60
|
+
The module is a demonstration of extending a class (str) with additional and modified functionality.
|
|
48
61
|
|
|
49
62
|
### Installation
|
|
50
63
|
Installing istr with pip is easy.
|
|
@@ -55,7 +68,7 @@ or when you want to upgrade,
|
|
|
55
68
|
```
|
|
56
69
|
pip install istr-python --upgrade
|
|
57
70
|
```
|
|
58
|
-
Alternatively, istr.py can be just copied into
|
|
71
|
+
Alternatively, istr.py can be just copied into your current work directory from GitHub (https://github.com/salabim/istr).
|
|
59
72
|
|
|
60
73
|
No dependencies!
|
|
61
74
|
|
|
@@ -156,16 +169,16 @@ four, five = istr(4, 5)
|
|
|
156
169
|
```
|
|
157
170
|
|
|
158
171
|
##### Important
|
|
159
|
-
>All calculations are strictly integer calculations. That means that if a float or decimal variable is ever produced it will be converted to an int.
|
|
160
|
-
> Also divisions are always floor divisions!
|
|
172
|
+
>All calculations are strictly integer calculations. That means that if a float or decimal variable is ever produced, it will be converted to an int.
|
|
173
|
+
> Also, divisions are always floor divisions!
|
|
161
174
|
|
|
162
175
|
#### Use istr as a string
|
|
163
176
|
|
|
164
177
|
We should realize that istrs are in fact strings.
|
|
165
178
|
|
|
166
|
-
|
|
179
|
+
To concatenate two istrs (or an istr and a str), we cannot use the `+` operator (remember `four + five` is `istr('9')`).
|
|
167
180
|
|
|
168
|
-
|
|
181
|
+
To concatenate strings, we use the or operator (`|`). So
|
|
169
182
|
|
|
170
183
|
```
|
|
171
184
|
four | five
|
|
@@ -178,9 +191,9 @@ And
|
|
|
178
191
|
```
|
|
179
192
|
is `istr('9')`.
|
|
180
193
|
|
|
181
|
-
|
|
194
|
+
To repeat a string in the usual sense, you cannot use the `*` operator (remember `3 * four` is `istr('12')`.
|
|
182
195
|
|
|
183
|
-
|
|
196
|
+
To repeat, we use the matrix multiplication operator (`@`). So
|
|
184
197
|
|
|
185
198
|
`3 @ four`
|
|
186
199
|
|
|
@@ -199,7 +212,7 @@ is also `istr('444')`
|
|
|
199
212
|
#### istr that can't be interpreted as an int
|
|
200
213
|
|
|
201
214
|
|
|
202
|
-
Although
|
|
215
|
+
Although usually istrs are to be interpreted as an int, that's not a requirement.
|
|
203
216
|
|
|
204
217
|
So
|
|
205
218
|
|
|
@@ -215,7 +228,7 @@ istr('1,2,3')
|
|
|
215
228
|
|
|
216
229
|
are perfectly acceptable.
|
|
217
230
|
|
|
218
|
-
|
|
231
|
+
However, we cannot perform any arithmetic or comparison operations with them.
|
|
219
232
|
|
|
220
233
|
If we try
|
|
221
234
|
|
|
@@ -295,9 +308,9 @@ several other types:
|
|
|
295
308
|
|
|
296
309
|
|
|
297
310
|
- if a dict (or subtype of dict), the same type dict will be returned with all *values* istr'ed
|
|
298
|
-
|
|
311
|
+
```
|
|
299
312
|
istr({'one': 1, 'two':2}) ==> {'one': istr('1'), 'two': istr('2')}
|
|
300
|
-
|
|
313
|
+
```
|
|
301
314
|
|
|
302
315
|
- if an iterator, the iterator will be mapped with istr
|
|
303
316
|
```
|
|
@@ -313,11 +326,11 @@ several other types:
|
|
|
313
326
|
|
|
314
327
|
- if an iterable, the same type will be returned with all elements istr'ed
|
|
315
328
|
|
|
316
|
-
```
|
|
329
|
+
```
|
|
317
330
|
istr([0, 1, 4]) ==> [istr('0'), istr('1'), istr('4')]
|
|
318
331
|
istr((0, 1, 4)) ==> (istr('0'), istr('1'), istr('4'))
|
|
319
332
|
istr({0, 1, 4}) ==> `{istr('4'), istr('0'), istr('1')} # or similar
|
|
320
|
-
```
|
|
333
|
+
```
|
|
321
334
|
|
|
322
335
|
- if a range, an istr.range instance will be returned
|
|
323
336
|
|
|
@@ -328,26 +341,25 @@ several other types:
|
|
|
328
341
|
```
|
|
329
342
|
|
|
330
343
|
- if an istr.range instance, the same istr.range will be returned
|
|
331
|
-
|
|
344
|
+
```
|
|
332
345
|
istr(istr.range(5)) ==> istr.range(5)
|
|
333
|
-
|
|
346
|
+
```
|
|
334
347
|
|
|
335
348
|
|
|
336
349
|
- if an istr, the same istr will be returned
|
|
337
350
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
351
|
+
```
|
|
352
|
+
istr(istr('4')) ==> istr ('4')
|
|
353
|
+
```
|
|
341
354
|
|
|
342
355
|
#### More than one parameter for istr
|
|
343
356
|
It is possible to give more than one parameter, in which case a tuple
|
|
344
357
|
of the istrs of the parameters will be returned, which can be handy
|
|
345
358
|
to unpack multiple values, e.g.
|
|
346
359
|
|
|
347
|
-
```
|
|
360
|
+
```
|
|
348
361
|
a, b, c = istr(5, 6, 7) ==> a=istr('5') , b=istr('6'), c=istr('7')
|
|
349
|
-
```
|
|
350
|
-
|
|
362
|
+
```
|
|
351
363
|
#### test for even/odd
|
|
352
364
|
It is possible to test for even/odd (provided the istr can be interpreted as an int) with the `is_even` and `is_odd` method, e.g.
|
|
353
365
|
|
|
@@ -360,6 +372,21 @@ It is also possible to test for even/odd of an ordinary int:
|
|
|
360
372
|
istr.is_even(4) ==> True
|
|
361
373
|
istr.is_odd(5) ==> True
|
|
362
374
|
```
|
|
375
|
+
#### test for divisibility
|
|
376
|
+
|
|
377
|
+
It is possible to test whether an istr is divisible by a given value with the `is_divisible_by method,` e.g.
|
|
378
|
+
|
|
379
|
+
```
|
|
380
|
+
istr(18).is_divisible_by(3) ==> True
|
|
381
|
+
istr(18).is_divisible_by(istr(3)) ==> True
|
|
382
|
+
istr(19).is_divisible_by(3) ==> False
|
|
383
|
+
istr(19).is_divisible_by(istr(3)) == False
|
|
384
|
+
```
|
|
385
|
+
It is also possible to test for divisibility of an ordinary int:
|
|
386
|
+
```
|
|
387
|
+
istr.is_divisible(18, 3) ==> True
|
|
388
|
+
istr.is_divisible(19, 3) ==> False
|
|
389
|
+
```
|
|
363
390
|
#### test for square
|
|
364
391
|
|
|
365
392
|
It is possible to test whether the value is a perfect square (provided the istr can be interpreted as an int) with the `is_square` method, e.g.
|
|
@@ -415,21 +442,6 @@ It is also possible to test for prime of an ordinary int:
|
|
|
415
442
|
istr.is_prime(4) ==> False
|
|
416
443
|
istr.is_prime(5) ==> True
|
|
417
444
|
```
|
|
418
|
-
#### test for divisibility
|
|
419
|
-
|
|
420
|
-
It is possible to test whether an istr is divisible by a given value with the `is_divisible_by method,` e.g.
|
|
421
|
-
|
|
422
|
-
```
|
|
423
|
-
istr(18).is_divisible_by(3) ==> True
|
|
424
|
-
istr(18).is_divisible_by(istr(3)) ==> True
|
|
425
|
-
istr(19).is_divisible_by(3) ==> False
|
|
426
|
-
istr(19).is_divisible_by(istr(3)) == False
|
|
427
|
-
```
|
|
428
|
-
It is also possible to test for divisibility of an ordinary int:
|
|
429
|
-
```
|
|
430
|
-
istr.is_divisible(18, 3) ==> True
|
|
431
|
-
istr.is_divisible(19, 3) ==> False
|
|
432
|
-
```
|
|
433
445
|
#### test whether all characters are distinct
|
|
434
446
|
|
|
435
447
|
With the `all_distinct` method, it is possible to test whether all characters are distinct (i.e. no character appears more than once).
|
|
@@ -450,7 +462,7 @@ The method `reversed()` will return an istr with the reversed content:
|
|
|
450
462
|
istr(456).reversed() ==> istr('654')
|
|
451
463
|
istr('0456').reversed() ==> istr('6540')
|
|
452
464
|
```
|
|
453
|
-
The same can
|
|
465
|
+
The same can, of course, be achieved with
|
|
454
466
|
```
|
|
455
467
|
istr(456)[::-1] ==> istr('654')
|
|
456
468
|
istr('0456')[::-1] ==> istr('6540')
|
|
@@ -597,6 +609,12 @@ istr(485).decompose("abc")
|
|
|
597
609
|
will set the global variables `a`, `b` and `c` to be set to `istr(4)`. `istr(8)` and` istr(5)`.
|
|
598
610
|
Note that the length of the letters specifier must be the same as the length of the istr. Furthermore, multiple values for the same variables result in a ValueError.
|
|
599
611
|
|
|
612
|
+
To decompose an istr into individual variables, it is arguably easier and safer to unpack the istr, like
|
|
613
|
+
|
|
614
|
+
```
|
|
615
|
+
a, b, c = istr(485)
|
|
616
|
+
```
|
|
617
|
+
|
|
600
618
|
With `istr.compose()`, an istr can be constructed from individual (global) variables.
|
|
601
619
|
E.g.
|
|
602
620
|
|
|
@@ -778,7 +796,7 @@ istr('1234')
|
|
|
778
796
|
|
|
779
797
|
### Overview of operations
|
|
780
798
|
|
|
781
|
-
The table below
|
|
799
|
+
The table below indicates whether the string or integer version of istr is applied.
|
|
782
800
|
|
|
783
801
|
```
|
|
784
802
|
operator/function int str Example
|
|
@@ -786,31 +804,30 @@ operator/function int str Example
|
|
|
786
804
|
+ x istr(20) + 3 ==> istr('23')
|
|
787
805
|
_ x istr(20) - 3 ==> istr('17')
|
|
788
806
|
* x istr(20) * 3 ==> istr('60')
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
807
|
+
/ x istr(20) / 3 ==> istr('6')
|
|
808
|
+
// x istr(20) // 3 ==> istr('6')
|
|
809
|
+
% x istr(20) % 3 ==> istr('2')
|
|
810
|
+
divmod x divmod(istr(20), 3) ==> (istr('6'), istr('2'))
|
|
811
|
+
** x istr(2) ** 3 ==> istr('8')
|
|
812
|
+
<=, <, >, >= x istr('100') > istr('2') ==> True
|
|
813
|
+
abs x abs(istr(-20)) ==> istr('20')
|
|
814
|
+
== x x istr(20) == 20 ==> True | istr(20) == '20' ==> True
|
|
815
|
+
bool x x *) bool(istr(' 0 ')) ==> False | bool(istr('')) ==> False
|
|
816
|
+
@ x istr(20) @ 3 ==> istr('202020')
|
|
817
|
+
| x istr(20) | '5' ==> istr('205')
|
|
818
|
+
slicing x istr(12345)[1:3] ==> istr('23')
|
|
819
|
+
iterate x [x for x in istr(20)] ==> [istr('2'), istr('0')]
|
|
820
|
+
len x len(istr(' 20 ')) ==> 4
|
|
821
|
+
count x istr(100).count('0') ==> 2
|
|
822
|
+
index x istr(' 100 ').index('0') ==> 2
|
|
823
|
+
split x istr('1 2').split() ==> (istr('1'), istr('2'))
|
|
824
|
+
string format x f"|{istr(1234):6}|" ==> '|1234 |'
|
|
825
|
+
other string methods x istr('aAbBcC').lower() ==> istr('aabbcc')
|
|
808
826
|
istr('aAbBcC').islower() ==> False
|
|
809
827
|
istr(' abc ').strip() ==> istr('abc')
|
|
810
828
|
...
|
|
811
829
|
-----------------------------------------------------------------------------------------
|
|
812
830
|
*) str is applied if is_int() is False
|
|
813
|
-
|
|
814
831
|
```
|
|
815
832
|
### Test script
|
|
816
833
|
There's an extensive pytest script in the `\tests` directory.
|
|
@@ -18,20 +18,33 @@ can be nicely, albeit not very efficient, coded as:
|
|
|
18
18
|
import istr
|
|
19
19
|
|
|
20
20
|
for s, e, n, d, m, o, r, y in istr.permutations(range(10), 8):
|
|
21
|
-
if m and ((s|e|n|d) + (m|o|r|e) == (m|o|n|e|y)
|
|
21
|
+
if m and ((s|e|n|d) + (m|o|r|e) == (m|o|n|e|y):
|
|
22
22
|
print(f' {s|e|n|d}')
|
|
23
23
|
print(f' {m|o|r|e}')
|
|
24
24
|
print('-----')
|
|
25
25
|
print(f'{m|o|n|e|y}')
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
+
or even
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
import istr
|
|
32
|
+
|
|
33
|
+
for S, E, N, D, M, O, R, Y in istr.permutations(range(10), 8):
|
|
34
|
+
if m and (istr.compose("SEND") + ist.compose("MORE") == istr.compose("MONEY"):
|
|
35
|
+
print(" ",istr.compose("SEND"))
|
|
36
|
+
print(" ",istr.compose("MORE"))
|
|
37
|
+
print('-----')
|
|
38
|
+
print(istr.compose("MONEY"))
|
|
39
|
+
```
|
|
40
|
+
|
|
28
41
|
Of, if we want to add all the digits in a string:
|
|
29
42
|
|
|
30
43
|
```
|
|
31
44
|
sum_digits = sum(istr('9282334')) # answer 31
|
|
32
45
|
```
|
|
33
46
|
|
|
34
|
-
|
|
47
|
+
The module is a demonstration of extending a class (str) with additional and modified functionality.
|
|
35
48
|
|
|
36
49
|
### Installation
|
|
37
50
|
Installing istr with pip is easy.
|
|
@@ -42,7 +55,7 @@ or when you want to upgrade,
|
|
|
42
55
|
```
|
|
43
56
|
pip install istr-python --upgrade
|
|
44
57
|
```
|
|
45
|
-
Alternatively, istr.py can be just copied into
|
|
58
|
+
Alternatively, istr.py can be just copied into your current work directory from GitHub (https://github.com/salabim/istr).
|
|
46
59
|
|
|
47
60
|
No dependencies!
|
|
48
61
|
|
|
@@ -143,16 +156,16 @@ four, five = istr(4, 5)
|
|
|
143
156
|
```
|
|
144
157
|
|
|
145
158
|
##### Important
|
|
146
|
-
>All calculations are strictly integer calculations. That means that if a float or decimal variable is ever produced it will be converted to an int.
|
|
147
|
-
> Also divisions are always floor divisions!
|
|
159
|
+
>All calculations are strictly integer calculations. That means that if a float or decimal variable is ever produced, it will be converted to an int.
|
|
160
|
+
> Also, divisions are always floor divisions!
|
|
148
161
|
|
|
149
162
|
#### Use istr as a string
|
|
150
163
|
|
|
151
164
|
We should realize that istrs are in fact strings.
|
|
152
165
|
|
|
153
|
-
|
|
166
|
+
To concatenate two istrs (or an istr and a str), we cannot use the `+` operator (remember `four + five` is `istr('9')`).
|
|
154
167
|
|
|
155
|
-
|
|
168
|
+
To concatenate strings, we use the or operator (`|`). So
|
|
156
169
|
|
|
157
170
|
```
|
|
158
171
|
four | five
|
|
@@ -165,9 +178,9 @@ And
|
|
|
165
178
|
```
|
|
166
179
|
is `istr('9')`.
|
|
167
180
|
|
|
168
|
-
|
|
181
|
+
To repeat a string in the usual sense, you cannot use the `*` operator (remember `3 * four` is `istr('12')`.
|
|
169
182
|
|
|
170
|
-
|
|
183
|
+
To repeat, we use the matrix multiplication operator (`@`). So
|
|
171
184
|
|
|
172
185
|
`3 @ four`
|
|
173
186
|
|
|
@@ -186,7 +199,7 @@ is also `istr('444')`
|
|
|
186
199
|
#### istr that can't be interpreted as an int
|
|
187
200
|
|
|
188
201
|
|
|
189
|
-
Although
|
|
202
|
+
Although usually istrs are to be interpreted as an int, that's not a requirement.
|
|
190
203
|
|
|
191
204
|
So
|
|
192
205
|
|
|
@@ -202,7 +215,7 @@ istr('1,2,3')
|
|
|
202
215
|
|
|
203
216
|
are perfectly acceptable.
|
|
204
217
|
|
|
205
|
-
|
|
218
|
+
However, we cannot perform any arithmetic or comparison operations with them.
|
|
206
219
|
|
|
207
220
|
If we try
|
|
208
221
|
|
|
@@ -282,9 +295,9 @@ several other types:
|
|
|
282
295
|
|
|
283
296
|
|
|
284
297
|
- if a dict (or subtype of dict), the same type dict will be returned with all *values* istr'ed
|
|
285
|
-
|
|
298
|
+
```
|
|
286
299
|
istr({'one': 1, 'two':2}) ==> {'one': istr('1'), 'two': istr('2')}
|
|
287
|
-
|
|
300
|
+
```
|
|
288
301
|
|
|
289
302
|
- if an iterator, the iterator will be mapped with istr
|
|
290
303
|
```
|
|
@@ -300,11 +313,11 @@ several other types:
|
|
|
300
313
|
|
|
301
314
|
- if an iterable, the same type will be returned with all elements istr'ed
|
|
302
315
|
|
|
303
|
-
```
|
|
316
|
+
```
|
|
304
317
|
istr([0, 1, 4]) ==> [istr('0'), istr('1'), istr('4')]
|
|
305
318
|
istr((0, 1, 4)) ==> (istr('0'), istr('1'), istr('4'))
|
|
306
319
|
istr({0, 1, 4}) ==> `{istr('4'), istr('0'), istr('1')} # or similar
|
|
307
|
-
```
|
|
320
|
+
```
|
|
308
321
|
|
|
309
322
|
- if a range, an istr.range instance will be returned
|
|
310
323
|
|
|
@@ -315,26 +328,25 @@ several other types:
|
|
|
315
328
|
```
|
|
316
329
|
|
|
317
330
|
- if an istr.range instance, the same istr.range will be returned
|
|
318
|
-
|
|
331
|
+
```
|
|
319
332
|
istr(istr.range(5)) ==> istr.range(5)
|
|
320
|
-
|
|
333
|
+
```
|
|
321
334
|
|
|
322
335
|
|
|
323
336
|
- if an istr, the same istr will be returned
|
|
324
337
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
338
|
+
```
|
|
339
|
+
istr(istr('4')) ==> istr ('4')
|
|
340
|
+
```
|
|
328
341
|
|
|
329
342
|
#### More than one parameter for istr
|
|
330
343
|
It is possible to give more than one parameter, in which case a tuple
|
|
331
344
|
of the istrs of the parameters will be returned, which can be handy
|
|
332
345
|
to unpack multiple values, e.g.
|
|
333
346
|
|
|
334
|
-
```
|
|
347
|
+
```
|
|
335
348
|
a, b, c = istr(5, 6, 7) ==> a=istr('5') , b=istr('6'), c=istr('7')
|
|
336
|
-
```
|
|
337
|
-
|
|
349
|
+
```
|
|
338
350
|
#### test for even/odd
|
|
339
351
|
It is possible to test for even/odd (provided the istr can be interpreted as an int) with the `is_even` and `is_odd` method, e.g.
|
|
340
352
|
|
|
@@ -347,6 +359,21 @@ It is also possible to test for even/odd of an ordinary int:
|
|
|
347
359
|
istr.is_even(4) ==> True
|
|
348
360
|
istr.is_odd(5) ==> True
|
|
349
361
|
```
|
|
362
|
+
#### test for divisibility
|
|
363
|
+
|
|
364
|
+
It is possible to test whether an istr is divisible by a given value with the `is_divisible_by method,` e.g.
|
|
365
|
+
|
|
366
|
+
```
|
|
367
|
+
istr(18).is_divisible_by(3) ==> True
|
|
368
|
+
istr(18).is_divisible_by(istr(3)) ==> True
|
|
369
|
+
istr(19).is_divisible_by(3) ==> False
|
|
370
|
+
istr(19).is_divisible_by(istr(3)) == False
|
|
371
|
+
```
|
|
372
|
+
It is also possible to test for divisibility of an ordinary int:
|
|
373
|
+
```
|
|
374
|
+
istr.is_divisible(18, 3) ==> True
|
|
375
|
+
istr.is_divisible(19, 3) ==> False
|
|
376
|
+
```
|
|
350
377
|
#### test for square
|
|
351
378
|
|
|
352
379
|
It is possible to test whether the value is a perfect square (provided the istr can be interpreted as an int) with the `is_square` method, e.g.
|
|
@@ -402,21 +429,6 @@ It is also possible to test for prime of an ordinary int:
|
|
|
402
429
|
istr.is_prime(4) ==> False
|
|
403
430
|
istr.is_prime(5) ==> True
|
|
404
431
|
```
|
|
405
|
-
#### test for divisibility
|
|
406
|
-
|
|
407
|
-
It is possible to test whether an istr is divisible by a given value with the `is_divisible_by method,` e.g.
|
|
408
|
-
|
|
409
|
-
```
|
|
410
|
-
istr(18).is_divisible_by(3) ==> True
|
|
411
|
-
istr(18).is_divisible_by(istr(3)) ==> True
|
|
412
|
-
istr(19).is_divisible_by(3) ==> False
|
|
413
|
-
istr(19).is_divisible_by(istr(3)) == False
|
|
414
|
-
```
|
|
415
|
-
It is also possible to test for divisibility of an ordinary int:
|
|
416
|
-
```
|
|
417
|
-
istr.is_divisible(18, 3) ==> True
|
|
418
|
-
istr.is_divisible(19, 3) ==> False
|
|
419
|
-
```
|
|
420
432
|
#### test whether all characters are distinct
|
|
421
433
|
|
|
422
434
|
With the `all_distinct` method, it is possible to test whether all characters are distinct (i.e. no character appears more than once).
|
|
@@ -437,7 +449,7 @@ The method `reversed()` will return an istr with the reversed content:
|
|
|
437
449
|
istr(456).reversed() ==> istr('654')
|
|
438
450
|
istr('0456').reversed() ==> istr('6540')
|
|
439
451
|
```
|
|
440
|
-
The same can
|
|
452
|
+
The same can, of course, be achieved with
|
|
441
453
|
```
|
|
442
454
|
istr(456)[::-1] ==> istr('654')
|
|
443
455
|
istr('0456')[::-1] ==> istr('6540')
|
|
@@ -584,6 +596,12 @@ istr(485).decompose("abc")
|
|
|
584
596
|
will set the global variables `a`, `b` and `c` to be set to `istr(4)`. `istr(8)` and` istr(5)`.
|
|
585
597
|
Note that the length of the letters specifier must be the same as the length of the istr. Furthermore, multiple values for the same variables result in a ValueError.
|
|
586
598
|
|
|
599
|
+
To decompose an istr into individual variables, it is arguably easier and safer to unpack the istr, like
|
|
600
|
+
|
|
601
|
+
```
|
|
602
|
+
a, b, c = istr(485)
|
|
603
|
+
```
|
|
604
|
+
|
|
587
605
|
With `istr.compose()`, an istr can be constructed from individual (global) variables.
|
|
588
606
|
E.g.
|
|
589
607
|
|
|
@@ -765,7 +783,7 @@ istr('1234')
|
|
|
765
783
|
|
|
766
784
|
### Overview of operations
|
|
767
785
|
|
|
768
|
-
The table below
|
|
786
|
+
The table below indicates whether the string or integer version of istr is applied.
|
|
769
787
|
|
|
770
788
|
```
|
|
771
789
|
operator/function int str Example
|
|
@@ -773,31 +791,30 @@ operator/function int str Example
|
|
|
773
791
|
+ x istr(20) + 3 ==> istr('23')
|
|
774
792
|
_ x istr(20) - 3 ==> istr('17')
|
|
775
793
|
* x istr(20) * 3 ==> istr('60')
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
794
|
+
/ x istr(20) / 3 ==> istr('6')
|
|
795
|
+
// x istr(20) // 3 ==> istr('6')
|
|
796
|
+
% x istr(20) % 3 ==> istr('2')
|
|
797
|
+
divmod x divmod(istr(20), 3) ==> (istr('6'), istr('2'))
|
|
798
|
+
** x istr(2) ** 3 ==> istr('8')
|
|
799
|
+
<=, <, >, >= x istr('100') > istr('2') ==> True
|
|
800
|
+
abs x abs(istr(-20)) ==> istr('20')
|
|
801
|
+
== x x istr(20) == 20 ==> True | istr(20) == '20' ==> True
|
|
802
|
+
bool x x *) bool(istr(' 0 ')) ==> False | bool(istr('')) ==> False
|
|
803
|
+
@ x istr(20) @ 3 ==> istr('202020')
|
|
804
|
+
| x istr(20) | '5' ==> istr('205')
|
|
805
|
+
slicing x istr(12345)[1:3] ==> istr('23')
|
|
806
|
+
iterate x [x for x in istr(20)] ==> [istr('2'), istr('0')]
|
|
807
|
+
len x len(istr(' 20 ')) ==> 4
|
|
808
|
+
count x istr(100).count('0') ==> 2
|
|
809
|
+
index x istr(' 100 ').index('0') ==> 2
|
|
810
|
+
split x istr('1 2').split() ==> (istr('1'), istr('2'))
|
|
811
|
+
string format x f"|{istr(1234):6}|" ==> '|1234 |'
|
|
812
|
+
other string methods x istr('aAbBcC').lower() ==> istr('aabbcc')
|
|
795
813
|
istr('aAbBcC').islower() ==> False
|
|
796
814
|
istr(' abc ').strip() ==> istr('abc')
|
|
797
815
|
...
|
|
798
816
|
-----------------------------------------------------------------------------------------
|
|
799
817
|
*) str is applied if is_int() is False
|
|
800
|
-
|
|
801
818
|
```
|
|
802
819
|
### Test script
|
|
803
820
|
There's an extensive pytest script in the `\tests` directory.
|
|
@@ -5,12 +5,14 @@
|
|
|
5
5
|
# |_||___/ \__||_|
|
|
6
6
|
# strings you can count on
|
|
7
7
|
|
|
8
|
-
__version__ = "1.1.
|
|
8
|
+
__version__ = "1.1.8"
|
|
9
9
|
import functools
|
|
10
10
|
import itertools
|
|
11
11
|
import types
|
|
12
12
|
import sys
|
|
13
13
|
import inspect
|
|
14
|
+
import math
|
|
15
|
+
import operator
|
|
14
16
|
|
|
15
17
|
"""
|
|
16
18
|
Note: the changelog is now in changelog.md
|
|
@@ -230,7 +232,7 @@ class istr(str):
|
|
|
230
232
|
return int(value, cls._base)
|
|
231
233
|
else:
|
|
232
234
|
return int(value)
|
|
233
|
-
except:
|
|
235
|
+
except Exception:
|
|
234
236
|
return cls._nan
|
|
235
237
|
|
|
236
238
|
def __new__(cls, *value):
|
|
@@ -250,6 +252,9 @@ class istr(str):
|
|
|
250
252
|
if hasattr(value, "__next__"):
|
|
251
253
|
return map(functools.partial(cls), value)
|
|
252
254
|
return type(value)(map(functools.partial(cls), value))
|
|
255
|
+
|
|
256
|
+
if isinstance(value, str) and value.startswith("="):
|
|
257
|
+
value = str(cls.compose(value[1:], inspect.currentframe().f_back.f_back.f_globals))
|
|
253
258
|
as_int = cls._to_int(value)
|
|
254
259
|
if isinstance(value, str):
|
|
255
260
|
as_str = value
|
|
@@ -346,10 +351,10 @@ class istr(str):
|
|
|
346
351
|
return int(self._as_int)
|
|
347
352
|
|
|
348
353
|
def is_even(self):
|
|
349
|
-
return istr.is_divisible_by(self,2)
|
|
354
|
+
return istr.is_divisible_by(self, 2)
|
|
350
355
|
|
|
351
356
|
def is_odd(self):
|
|
352
|
-
return not istr.is_divisible_by(self,2)
|
|
357
|
+
return not istr.is_divisible_by(self, 2)
|
|
353
358
|
|
|
354
359
|
def is_divisible_by(self, divisor):
|
|
355
360
|
return istr.interpret_as_int(self) % int(divisor) == 0
|
|
@@ -384,13 +389,14 @@ class istr(str):
|
|
|
384
389
|
|
|
385
390
|
def decompose(self, letters, namespace=None):
|
|
386
391
|
"""
|
|
387
|
-
decompose letter variables into
|
|
388
|
-
each letter variable must represent just one character
|
|
389
|
-
same letter variables represent the the same character
|
|
392
|
+
decompose one-letter variables into global variables
|
|
393
|
+
each one-letter variable must represent just one character
|
|
394
|
+
same one-letter variables represent the the same character
|
|
390
395
|
the istr must have the same length as the letters
|
|
391
396
|
"""
|
|
392
397
|
if namespace is None:
|
|
393
398
|
namespace = inspect.currentframe().f_back.f_globals
|
|
399
|
+
|
|
394
400
|
lookup = {}
|
|
395
401
|
|
|
396
402
|
for letter, ch in zip(letters, self):
|
|
@@ -485,6 +491,16 @@ class istr(str):
|
|
|
485
491
|
def concat(cls, iterable):
|
|
486
492
|
return map(lambda x: istr("").join(x), istr(iterable))
|
|
487
493
|
|
|
494
|
+
@classmethod
|
|
495
|
+
def prod(cls, iterable, *, start=1):
|
|
496
|
+
return math.prod(iterable, start=cls(start))
|
|
497
|
+
|
|
498
|
+
@classmethod
|
|
499
|
+
def sumprod(cls, p, q, /, strict=True):
|
|
500
|
+
if "sumprod" in math.__dict__ and strict:
|
|
501
|
+
return istr(math.sumprod(p, q))
|
|
502
|
+
return sum(_map(operator.__mul__, cls(p), cls(q), strict=strict))
|
|
503
|
+
|
|
488
504
|
@classmethod
|
|
489
505
|
def enumerate(cls, iterable, start=0):
|
|
490
506
|
for i, value in enumerate(iterable, start):
|
|
@@ -515,7 +531,7 @@ class istr(str):
|
|
|
515
531
|
def __new__(cls, cls_repr_mode, mode=None):
|
|
516
532
|
if mode is None:
|
|
517
533
|
return cls_repr_mode._repr_mode
|
|
518
|
-
if mode
|
|
534
|
+
if mode is int:
|
|
519
535
|
mode = "int"
|
|
520
536
|
if mode in ("istr", "str", "int"): # _istr is used only for TypeErrors
|
|
521
537
|
return super().__new__(cls)
|
|
@@ -624,6 +640,41 @@ class istr(str):
|
|
|
624
640
|
return result
|
|
625
641
|
|
|
626
642
|
|
|
643
|
+
def _map(func, *iterables, strict=False):
|
|
644
|
+
"""
|
|
645
|
+
like map, but with a strict parameter (also for Python < 3.14)
|
|
646
|
+
"""
|
|
647
|
+
if sys.version_info >= (3, 14):
|
|
648
|
+
yield from map(func, *iterables, strict=strict)
|
|
649
|
+
return
|
|
650
|
+
|
|
651
|
+
if not strict:
|
|
652
|
+
yield from map(func, *iterables)
|
|
653
|
+
return
|
|
654
|
+
|
|
655
|
+
iterators = [iter(it) for it in iterables]
|
|
656
|
+
|
|
657
|
+
while True:
|
|
658
|
+
values = []
|
|
659
|
+
exhausted = []
|
|
660
|
+
for it in iterators:
|
|
661
|
+
try:
|
|
662
|
+
v = next(it)
|
|
663
|
+
values.append(v)
|
|
664
|
+
exhausted.append(False)
|
|
665
|
+
except StopIteration:
|
|
666
|
+
values.append(None)
|
|
667
|
+
exhausted.append(True)
|
|
668
|
+
|
|
669
|
+
if all(exhausted):
|
|
670
|
+
return
|
|
671
|
+
|
|
672
|
+
if any(exhausted) and not all(exhausted):
|
|
673
|
+
raise ValueError("map_strict: iterables have different lengths")
|
|
674
|
+
|
|
675
|
+
yield func(*values)
|
|
676
|
+
|
|
677
|
+
|
|
627
678
|
istr.type = type(istr(0))
|
|
628
679
|
|
|
629
680
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: istr-python
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.8
|
|
4
4
|
Summary: istr - strings you can count on
|
|
5
5
|
Author-email: Ruud van der Ham <rt.van.der.ham@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/salabim/istr
|
|
@@ -8,7 +8,7 @@ Project-URL: Repository, https://github.com/salabim/istr
|
|
|
8
8
|
Classifier: Development Status :: 5 - Production/Stable
|
|
9
9
|
Classifier: License :: OSI Approved :: MIT License
|
|
10
10
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
11
|
-
Requires-Python: >=3.
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
|
|
14
14
|
<img src="https://www.salabim.org/istr/istr_logo.png" width=500>
|
|
@@ -31,20 +31,33 @@ can be nicely, albeit not very efficient, coded as:
|
|
|
31
31
|
import istr
|
|
32
32
|
|
|
33
33
|
for s, e, n, d, m, o, r, y in istr.permutations(range(10), 8):
|
|
34
|
-
if m and ((s|e|n|d) + (m|o|r|e) == (m|o|n|e|y)
|
|
34
|
+
if m and ((s|e|n|d) + (m|o|r|e) == (m|o|n|e|y):
|
|
35
35
|
print(f' {s|e|n|d}')
|
|
36
36
|
print(f' {m|o|r|e}')
|
|
37
37
|
print('-----')
|
|
38
38
|
print(f'{m|o|n|e|y}')
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
+
or even
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
import istr
|
|
45
|
+
|
|
46
|
+
for S, E, N, D, M, O, R, Y in istr.permutations(range(10), 8):
|
|
47
|
+
if m and (istr.compose("SEND") + ist.compose("MORE") == istr.compose("MONEY"):
|
|
48
|
+
print(" ",istr.compose("SEND"))
|
|
49
|
+
print(" ",istr.compose("MORE"))
|
|
50
|
+
print('-----')
|
|
51
|
+
print(istr.compose("MONEY"))
|
|
52
|
+
```
|
|
53
|
+
|
|
41
54
|
Of, if we want to add all the digits in a string:
|
|
42
55
|
|
|
43
56
|
```
|
|
44
57
|
sum_digits = sum(istr('9282334')) # answer 31
|
|
45
58
|
```
|
|
46
59
|
|
|
47
|
-
|
|
60
|
+
The module is a demonstration of extending a class (str) with additional and modified functionality.
|
|
48
61
|
|
|
49
62
|
### Installation
|
|
50
63
|
Installing istr with pip is easy.
|
|
@@ -55,7 +68,7 @@ or when you want to upgrade,
|
|
|
55
68
|
```
|
|
56
69
|
pip install istr-python --upgrade
|
|
57
70
|
```
|
|
58
|
-
Alternatively, istr.py can be just copied into
|
|
71
|
+
Alternatively, istr.py can be just copied into your current work directory from GitHub (https://github.com/salabim/istr).
|
|
59
72
|
|
|
60
73
|
No dependencies!
|
|
61
74
|
|
|
@@ -156,16 +169,16 @@ four, five = istr(4, 5)
|
|
|
156
169
|
```
|
|
157
170
|
|
|
158
171
|
##### Important
|
|
159
|
-
>All calculations are strictly integer calculations. That means that if a float or decimal variable is ever produced it will be converted to an int.
|
|
160
|
-
> Also divisions are always floor divisions!
|
|
172
|
+
>All calculations are strictly integer calculations. That means that if a float or decimal variable is ever produced, it will be converted to an int.
|
|
173
|
+
> Also, divisions are always floor divisions!
|
|
161
174
|
|
|
162
175
|
#### Use istr as a string
|
|
163
176
|
|
|
164
177
|
We should realize that istrs are in fact strings.
|
|
165
178
|
|
|
166
|
-
|
|
179
|
+
To concatenate two istrs (or an istr and a str), we cannot use the `+` operator (remember `four + five` is `istr('9')`).
|
|
167
180
|
|
|
168
|
-
|
|
181
|
+
To concatenate strings, we use the or operator (`|`). So
|
|
169
182
|
|
|
170
183
|
```
|
|
171
184
|
four | five
|
|
@@ -178,9 +191,9 @@ And
|
|
|
178
191
|
```
|
|
179
192
|
is `istr('9')`.
|
|
180
193
|
|
|
181
|
-
|
|
194
|
+
To repeat a string in the usual sense, you cannot use the `*` operator (remember `3 * four` is `istr('12')`.
|
|
182
195
|
|
|
183
|
-
|
|
196
|
+
To repeat, we use the matrix multiplication operator (`@`). So
|
|
184
197
|
|
|
185
198
|
`3 @ four`
|
|
186
199
|
|
|
@@ -199,7 +212,7 @@ is also `istr('444')`
|
|
|
199
212
|
#### istr that can't be interpreted as an int
|
|
200
213
|
|
|
201
214
|
|
|
202
|
-
Although
|
|
215
|
+
Although usually istrs are to be interpreted as an int, that's not a requirement.
|
|
203
216
|
|
|
204
217
|
So
|
|
205
218
|
|
|
@@ -215,7 +228,7 @@ istr('1,2,3')
|
|
|
215
228
|
|
|
216
229
|
are perfectly acceptable.
|
|
217
230
|
|
|
218
|
-
|
|
231
|
+
However, we cannot perform any arithmetic or comparison operations with them.
|
|
219
232
|
|
|
220
233
|
If we try
|
|
221
234
|
|
|
@@ -295,9 +308,9 @@ several other types:
|
|
|
295
308
|
|
|
296
309
|
|
|
297
310
|
- if a dict (or subtype of dict), the same type dict will be returned with all *values* istr'ed
|
|
298
|
-
|
|
311
|
+
```
|
|
299
312
|
istr({'one': 1, 'two':2}) ==> {'one': istr('1'), 'two': istr('2')}
|
|
300
|
-
|
|
313
|
+
```
|
|
301
314
|
|
|
302
315
|
- if an iterator, the iterator will be mapped with istr
|
|
303
316
|
```
|
|
@@ -313,11 +326,11 @@ several other types:
|
|
|
313
326
|
|
|
314
327
|
- if an iterable, the same type will be returned with all elements istr'ed
|
|
315
328
|
|
|
316
|
-
```
|
|
329
|
+
```
|
|
317
330
|
istr([0, 1, 4]) ==> [istr('0'), istr('1'), istr('4')]
|
|
318
331
|
istr((0, 1, 4)) ==> (istr('0'), istr('1'), istr('4'))
|
|
319
332
|
istr({0, 1, 4}) ==> `{istr('4'), istr('0'), istr('1')} # or similar
|
|
320
|
-
```
|
|
333
|
+
```
|
|
321
334
|
|
|
322
335
|
- if a range, an istr.range instance will be returned
|
|
323
336
|
|
|
@@ -328,26 +341,25 @@ several other types:
|
|
|
328
341
|
```
|
|
329
342
|
|
|
330
343
|
- if an istr.range instance, the same istr.range will be returned
|
|
331
|
-
|
|
344
|
+
```
|
|
332
345
|
istr(istr.range(5)) ==> istr.range(5)
|
|
333
|
-
|
|
346
|
+
```
|
|
334
347
|
|
|
335
348
|
|
|
336
349
|
- if an istr, the same istr will be returned
|
|
337
350
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
351
|
+
```
|
|
352
|
+
istr(istr('4')) ==> istr ('4')
|
|
353
|
+
```
|
|
341
354
|
|
|
342
355
|
#### More than one parameter for istr
|
|
343
356
|
It is possible to give more than one parameter, in which case a tuple
|
|
344
357
|
of the istrs of the parameters will be returned, which can be handy
|
|
345
358
|
to unpack multiple values, e.g.
|
|
346
359
|
|
|
347
|
-
```
|
|
360
|
+
```
|
|
348
361
|
a, b, c = istr(5, 6, 7) ==> a=istr('5') , b=istr('6'), c=istr('7')
|
|
349
|
-
```
|
|
350
|
-
|
|
362
|
+
```
|
|
351
363
|
#### test for even/odd
|
|
352
364
|
It is possible to test for even/odd (provided the istr can be interpreted as an int) with the `is_even` and `is_odd` method, e.g.
|
|
353
365
|
|
|
@@ -360,6 +372,21 @@ It is also possible to test for even/odd of an ordinary int:
|
|
|
360
372
|
istr.is_even(4) ==> True
|
|
361
373
|
istr.is_odd(5) ==> True
|
|
362
374
|
```
|
|
375
|
+
#### test for divisibility
|
|
376
|
+
|
|
377
|
+
It is possible to test whether an istr is divisible by a given value with the `is_divisible_by method,` e.g.
|
|
378
|
+
|
|
379
|
+
```
|
|
380
|
+
istr(18).is_divisible_by(3) ==> True
|
|
381
|
+
istr(18).is_divisible_by(istr(3)) ==> True
|
|
382
|
+
istr(19).is_divisible_by(3) ==> False
|
|
383
|
+
istr(19).is_divisible_by(istr(3)) == False
|
|
384
|
+
```
|
|
385
|
+
It is also possible to test for divisibility of an ordinary int:
|
|
386
|
+
```
|
|
387
|
+
istr.is_divisible(18, 3) ==> True
|
|
388
|
+
istr.is_divisible(19, 3) ==> False
|
|
389
|
+
```
|
|
363
390
|
#### test for square
|
|
364
391
|
|
|
365
392
|
It is possible to test whether the value is a perfect square (provided the istr can be interpreted as an int) with the `is_square` method, e.g.
|
|
@@ -415,21 +442,6 @@ It is also possible to test for prime of an ordinary int:
|
|
|
415
442
|
istr.is_prime(4) ==> False
|
|
416
443
|
istr.is_prime(5) ==> True
|
|
417
444
|
```
|
|
418
|
-
#### test for divisibility
|
|
419
|
-
|
|
420
|
-
It is possible to test whether an istr is divisible by a given value with the `is_divisible_by method,` e.g.
|
|
421
|
-
|
|
422
|
-
```
|
|
423
|
-
istr(18).is_divisible_by(3) ==> True
|
|
424
|
-
istr(18).is_divisible_by(istr(3)) ==> True
|
|
425
|
-
istr(19).is_divisible_by(3) ==> False
|
|
426
|
-
istr(19).is_divisible_by(istr(3)) == False
|
|
427
|
-
```
|
|
428
|
-
It is also possible to test for divisibility of an ordinary int:
|
|
429
|
-
```
|
|
430
|
-
istr.is_divisible(18, 3) ==> True
|
|
431
|
-
istr.is_divisible(19, 3) ==> False
|
|
432
|
-
```
|
|
433
445
|
#### test whether all characters are distinct
|
|
434
446
|
|
|
435
447
|
With the `all_distinct` method, it is possible to test whether all characters are distinct (i.e. no character appears more than once).
|
|
@@ -450,7 +462,7 @@ The method `reversed()` will return an istr with the reversed content:
|
|
|
450
462
|
istr(456).reversed() ==> istr('654')
|
|
451
463
|
istr('0456').reversed() ==> istr('6540')
|
|
452
464
|
```
|
|
453
|
-
The same can
|
|
465
|
+
The same can, of course, be achieved with
|
|
454
466
|
```
|
|
455
467
|
istr(456)[::-1] ==> istr('654')
|
|
456
468
|
istr('0456')[::-1] ==> istr('6540')
|
|
@@ -597,6 +609,12 @@ istr(485).decompose("abc")
|
|
|
597
609
|
will set the global variables `a`, `b` and `c` to be set to `istr(4)`. `istr(8)` and` istr(5)`.
|
|
598
610
|
Note that the length of the letters specifier must be the same as the length of the istr. Furthermore, multiple values for the same variables result in a ValueError.
|
|
599
611
|
|
|
612
|
+
To decompose an istr into individual variables, it is arguably easier and safer to unpack the istr, like
|
|
613
|
+
|
|
614
|
+
```
|
|
615
|
+
a, b, c = istr(485)
|
|
616
|
+
```
|
|
617
|
+
|
|
600
618
|
With `istr.compose()`, an istr can be constructed from individual (global) variables.
|
|
601
619
|
E.g.
|
|
602
620
|
|
|
@@ -778,7 +796,7 @@ istr('1234')
|
|
|
778
796
|
|
|
779
797
|
### Overview of operations
|
|
780
798
|
|
|
781
|
-
The table below
|
|
799
|
+
The table below indicates whether the string or integer version of istr is applied.
|
|
782
800
|
|
|
783
801
|
```
|
|
784
802
|
operator/function int str Example
|
|
@@ -786,31 +804,30 @@ operator/function int str Example
|
|
|
786
804
|
+ x istr(20) + 3 ==> istr('23')
|
|
787
805
|
_ x istr(20) - 3 ==> istr('17')
|
|
788
806
|
* x istr(20) * 3 ==> istr('60')
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
807
|
+
/ x istr(20) / 3 ==> istr('6')
|
|
808
|
+
// x istr(20) // 3 ==> istr('6')
|
|
809
|
+
% x istr(20) % 3 ==> istr('2')
|
|
810
|
+
divmod x divmod(istr(20), 3) ==> (istr('6'), istr('2'))
|
|
811
|
+
** x istr(2) ** 3 ==> istr('8')
|
|
812
|
+
<=, <, >, >= x istr('100') > istr('2') ==> True
|
|
813
|
+
abs x abs(istr(-20)) ==> istr('20')
|
|
814
|
+
== x x istr(20) == 20 ==> True | istr(20) == '20' ==> True
|
|
815
|
+
bool x x *) bool(istr(' 0 ')) ==> False | bool(istr('')) ==> False
|
|
816
|
+
@ x istr(20) @ 3 ==> istr('202020')
|
|
817
|
+
| x istr(20) | '5' ==> istr('205')
|
|
818
|
+
slicing x istr(12345)[1:3] ==> istr('23')
|
|
819
|
+
iterate x [x for x in istr(20)] ==> [istr('2'), istr('0')]
|
|
820
|
+
len x len(istr(' 20 ')) ==> 4
|
|
821
|
+
count x istr(100).count('0') ==> 2
|
|
822
|
+
index x istr(' 100 ').index('0') ==> 2
|
|
823
|
+
split x istr('1 2').split() ==> (istr('1'), istr('2'))
|
|
824
|
+
string format x f"|{istr(1234):6}|" ==> '|1234 |'
|
|
825
|
+
other string methods x istr('aAbBcC').lower() ==> istr('aabbcc')
|
|
808
826
|
istr('aAbBcC').islower() ==> False
|
|
809
827
|
istr(' abc ').strip() ==> istr('abc')
|
|
810
828
|
...
|
|
811
829
|
-----------------------------------------------------------------------------------------
|
|
812
830
|
*) str is applied if is_int() is False
|
|
813
|
-
|
|
814
831
|
```
|
|
815
832
|
### Test script
|
|
816
833
|
There's an extensive pytest script in the `\tests` directory.
|
|
@@ -10,9 +10,9 @@ authors = [
|
|
|
10
10
|
{ name = "Ruud van der Ham", email = "rt.van.der.ham@gmail.com" },
|
|
11
11
|
]
|
|
12
12
|
description = "istr - strings you can count on"
|
|
13
|
-
version = "1.1.
|
|
13
|
+
version = "1.1.8"
|
|
14
14
|
readme = "README.md"
|
|
15
|
-
requires-python = ">=3.
|
|
15
|
+
requires-python = ">=3.8"
|
|
16
16
|
dependencies = []
|
|
17
17
|
classifiers = [
|
|
18
18
|
"Development Status :: 5 - Production/Stable",
|
|
@@ -314,6 +314,17 @@ def test_even_odd():
|
|
|
314
314
|
assert istr.is_odd(11111111)
|
|
315
315
|
|
|
316
316
|
|
|
317
|
+
def test_is_divisible_by():
|
|
318
|
+
assert istr(18).is_divisible_by(3)
|
|
319
|
+
assert istr(18).is_divisible_by(istr(3))
|
|
320
|
+
assert not istr(19).is_divisible_by(3)
|
|
321
|
+
assert not istr(19).is_divisible_by(istr(3))
|
|
322
|
+
with pytest.raises(TypeError, match=re.escape(f"not interpretable as int")):
|
|
323
|
+
istr("a").is_divisible_by(3)
|
|
324
|
+
assert istr.is_divisible_by(18, 3)
|
|
325
|
+
assert not istr.is_divisible_by(19, 3)
|
|
326
|
+
|
|
327
|
+
|
|
317
328
|
def test_is_square():
|
|
318
329
|
assert not istr(-1).is_square()
|
|
319
330
|
assert istr(0).is_square()
|
|
@@ -330,6 +341,7 @@ def test_is_square():
|
|
|
330
341
|
assert istr.is_square(4)
|
|
331
342
|
assert istr.is_square(16)
|
|
332
343
|
|
|
344
|
+
|
|
333
345
|
def test_is_cube():
|
|
334
346
|
assert not istr(-1).is_cube()
|
|
335
347
|
assert istr(0).is_cube()
|
|
@@ -357,16 +369,17 @@ def test_is_power_of():
|
|
|
357
369
|
assert not istr(99).is_power_of(3)
|
|
358
370
|
with pytest.raises(TypeError, match=re.escape(f"not interpretable as int")):
|
|
359
371
|
istr("a").is_power_of(3)
|
|
360
|
-
assert istr.is_power_of(0,3)
|
|
361
|
-
assert istr.is_power_of(1,3)
|
|
362
|
-
assert not istr.is_power_of(2,3)
|
|
363
|
-
assert istr.is_power_of(8,3)
|
|
364
|
-
assert istr.is_power_of(27,3)
|
|
372
|
+
assert istr.is_power_of(0, 3)
|
|
373
|
+
assert istr.is_power_of(1, 3)
|
|
374
|
+
assert not istr.is_power_of(2, 3)
|
|
375
|
+
assert istr.is_power_of(8, 3)
|
|
376
|
+
assert istr.is_power_of(27, 3)
|
|
365
377
|
with pytest.raises(TypeError):
|
|
366
378
|
istr(1).is_power_of(3.1)
|
|
367
379
|
with pytest.raises(ValueError):
|
|
368
380
|
istr(1).is_power_of(-1)
|
|
369
|
-
|
|
381
|
+
|
|
382
|
+
|
|
370
383
|
def test_is_prime():
|
|
371
384
|
assert not istr(0).is_prime()
|
|
372
385
|
assert not istr(1).is_prime()
|
|
@@ -544,6 +557,12 @@ def test_unpacking():
|
|
|
544
557
|
assert x.equals(istr(1))
|
|
545
558
|
assert y.equals(istr(2))
|
|
546
559
|
assert z.equals(istr(3))
|
|
560
|
+
del x, y, z
|
|
561
|
+
|
|
562
|
+
x, y, z = a
|
|
563
|
+
assert x.equals(istr(1))
|
|
564
|
+
assert y.equals(istr(2))
|
|
565
|
+
assert z == "3"
|
|
547
566
|
|
|
548
567
|
|
|
549
568
|
def test_repr_mode():
|
|
@@ -635,17 +654,6 @@ def test_base():
|
|
|
635
654
|
assert a * a == 225
|
|
636
655
|
|
|
637
656
|
|
|
638
|
-
def test_is_divisible():
|
|
639
|
-
assert istr(18).is_divisible_by(3)
|
|
640
|
-
assert istr(18).is_divisible_by(istr(3))
|
|
641
|
-
assert not istr(19).is_divisible_by(3)
|
|
642
|
-
assert not istr(19).is_divisible_by(istr(3))
|
|
643
|
-
with pytest.raises(TypeError, match=re.escape(f"not interpretable as int")):
|
|
644
|
-
istr("a").is_divisible_by(3)
|
|
645
|
-
assert istr.is_divisible_by(18, 3)
|
|
646
|
-
assert not istr.is_divisible_by(19, 3)
|
|
647
|
-
|
|
648
|
-
|
|
649
657
|
def test_digits():
|
|
650
658
|
assert istr.digits().equals(istr("0123456789"))
|
|
651
659
|
assert istr.digits("").equals(istr("0123456789"))
|
|
@@ -697,13 +705,16 @@ def test_itertools():
|
|
|
697
705
|
assert list(istr.dropwhile(lambda x: x < 5, [1, 4, 6, 4, 1])) == [istr("6"), istr("4"), istr("1")]
|
|
698
706
|
assert list(istr.filterfalse(lambda x: x % 2, range(10))) == [istr("0"), istr("2"), istr("4"), istr("6"), istr("8")]
|
|
699
707
|
assert list(istr.islice("123456", 2)) == [istr("1"), istr("2")]
|
|
700
|
-
assert list(istr.pairwise("1234")) == [(istr("1"), istr("2")), (istr("2"), istr("3")), (istr("3"), istr("4"))]
|
|
701
708
|
assert list(istr.permutations(range(5), 3)) == list(istr(itertools.permutations(range(5), 3)))
|
|
702
709
|
assert list(istr.product(range(5), range(4))) == list(istr(itertools.product(range(5), range(4))))
|
|
703
710
|
assert list100(istr.repeat(10)) == list100(istr(itertools.repeat(10)))
|
|
704
711
|
assert list(istr.starmap(pow, [(2, 5), (3, 2), (10, 3)])) == [istr("32"), istr("9"), istr("1000")]
|
|
705
712
|
assert list(istr.takewhile(lambda x: x < 5, [1, 4, 6, 3, 8])) == [istr("1"), istr("4")]
|
|
706
713
|
assert list(istr.zip_longest("123", "56", fillvalue="0")) == [(istr("1"), istr("5")), (istr("2"), istr("6")), (istr("3"), istr("0"))]
|
|
714
|
+
if sys.version_info >= (3, 10):
|
|
715
|
+
assert list(istr.pairwise("1234")) == [(istr("1"), istr("2")), (istr("2"), istr("3")), (istr("3"), istr("4"))]
|
|
716
|
+
if sys.version_info >= (3, 12):
|
|
717
|
+
assert list(istr.batched("12345", n=2)) == [(istr("1"), istr("2")), (istr("3"), istr("4")), (istr("5"),)]
|
|
707
718
|
|
|
708
719
|
|
|
709
720
|
def test_all_distinct():
|
|
@@ -712,6 +723,23 @@ def test_all_distinct():
|
|
|
712
723
|
assert istr("").all_distinct()
|
|
713
724
|
|
|
714
725
|
|
|
726
|
+
def test_prod():
|
|
727
|
+
assert istr.prod(range(1, 5)).equals(istr(24))
|
|
728
|
+
assert istr.prod((1, 2, 3), start=4).equals(istr(24))
|
|
729
|
+
|
|
730
|
+
|
|
731
|
+
def test_sumprod():
|
|
732
|
+
assert istr.sumprod((1, 2), (3, 4)).equals(istr(11))
|
|
733
|
+
assert istr.sumprod(istr("12"), (3, 4)).equals(istr(11))
|
|
734
|
+
assert istr.sumprod(istr("12"), "34").equals(istr(11))
|
|
735
|
+
assert istr.sumprod(istr("12"), "34", strict=False).equals(istr(11))
|
|
736
|
+
assert istr.sumprod(istr("12"), "345", strict=False).equals(istr(11))
|
|
737
|
+
with pytest.raises(ValueError):
|
|
738
|
+
istr.sumprod((1, 2), (3, 4, 5))
|
|
739
|
+
with pytest.raises(ValueError):
|
|
740
|
+
istr.sumprod((1, 2), (3, 4, 5), strict=True)
|
|
741
|
+
|
|
742
|
+
|
|
715
743
|
def test_subclassing():
|
|
716
744
|
class jstr(istr.type): ...
|
|
717
745
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|