pythonic-fp-circulararray 5.3.0__py3-none-any.whl → 5.3.2__py3-none-any.whl
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.
- pythonic_fp/circulararray/__init__.py +5 -1
- pythonic_fp/circulararray/auto.py +55 -39
- pythonic_fp/circulararray/auto.pyi +7 -67
- pythonic_fp/circulararray/fixed.py +57 -46
- pythonic_fp/circulararray/fixed.pyi +6 -63
- {pythonic_fp_circulararray-5.3.0.dist-info → pythonic_fp_circulararray-5.3.2.dist-info}/METADATA +9 -9
- pythonic_fp_circulararray-5.3.2.dist-info/RECORD +10 -0
- pythonic_fp_circulararray-5.3.0.dist-info/RECORD +0 -10
- {pythonic_fp_circulararray-5.3.0.dist-info → pythonic_fp_circulararray-5.3.2.dist-info}/WHEEL +0 -0
- {pythonic_fp_circulararray-5.3.0.dist-info → pythonic_fp_circulararray-5.3.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -12,7 +12,11 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
-
"""
|
|
15
|
+
"""
|
|
16
|
+
Circular Array
|
|
17
|
+
==============
|
|
18
|
+
|
|
19
|
+
Package implementing stateful circular array data structures.
|
|
16
20
|
|
|
17
21
|
- O(1) pops and pushes either end
|
|
18
22
|
- O(1) indexing and size determination
|
|
@@ -12,7 +12,11 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
-
"""
|
|
15
|
+
"""
|
|
16
|
+
Variable Storage Capacity
|
|
17
|
+
=========================
|
|
18
|
+
|
|
19
|
+
Circular array with variable storage capacity.
|
|
16
20
|
|
|
17
21
|
- O(1) pops either end
|
|
18
22
|
- O(1) amortized pushes either end
|
|
@@ -25,27 +29,21 @@
|
|
|
25
29
|
|
|
26
30
|
"""
|
|
27
31
|
from collections.abc import Callable, Iterable, Iterator
|
|
28
|
-
from typing import cast,
|
|
32
|
+
from typing import cast, overload
|
|
29
33
|
|
|
30
34
|
__all__ = ['CA', 'ca']
|
|
31
35
|
|
|
32
|
-
I = TypeVar('I')
|
|
33
|
-
T = TypeVar('T')
|
|
34
|
-
|
|
35
36
|
|
|
36
37
|
class CA[I]():
|
|
37
38
|
|
|
38
|
-
L = TypeVar('L')
|
|
39
|
-
R = TypeVar('R')
|
|
40
|
-
U = TypeVar('U')
|
|
41
|
-
|
|
42
39
|
__slots__ = '_items', '_cnt', '_cap', '_front', '_rear'
|
|
43
40
|
|
|
44
41
|
def __init__(
|
|
45
42
|
self,
|
|
46
43
|
items: Iterable[I] | None = None
|
|
47
44
|
) -> None:
|
|
48
|
-
"""
|
|
45
|
+
"""
|
|
46
|
+
Basically a list that can be grown from both ends
|
|
49
47
|
in O(1) time and space complexity.
|
|
50
48
|
|
|
51
49
|
:param items: optional iterable to initial populate circular array
|
|
@@ -312,7 +310,8 @@ class CA[I]():
|
|
|
312
310
|
return True
|
|
313
311
|
|
|
314
312
|
def pushl(self, *items: I) -> None:
|
|
315
|
-
"""
|
|
313
|
+
"""
|
|
314
|
+
Push items onto left side (front) of circular array.
|
|
316
315
|
|
|
317
316
|
:param items: items pushed onto circular array from left
|
|
318
317
|
|
|
@@ -331,7 +330,8 @@ class CA[I]():
|
|
|
331
330
|
)
|
|
332
331
|
|
|
333
332
|
def pushr(self, *items: I) -> None:
|
|
334
|
-
"""
|
|
333
|
+
"""
|
|
334
|
+
Push items onto right side (rear) of circular array.
|
|
335
335
|
|
|
336
336
|
:param items: items pushed onto circular array from right
|
|
337
337
|
|
|
@@ -349,10 +349,11 @@ class CA[I]():
|
|
|
349
349
|
self._cnt + 1,
|
|
350
350
|
)
|
|
351
351
|
|
|
352
|
-
def popl(self) -> I
|
|
353
|
-
"""
|
|
352
|
+
def popl(self) -> I:
|
|
353
|
+
"""
|
|
354
|
+
Pop item off left side (front) of circular array.
|
|
354
355
|
|
|
355
|
-
:
|
|
356
|
+
:returns: item popped from left side of circular array
|
|
356
357
|
:raises ValueError: when called on an empty circular array
|
|
357
358
|
|
|
358
359
|
"""
|
|
@@ -387,8 +388,9 @@ class CA[I]():
|
|
|
387
388
|
raise ValueError(msg)
|
|
388
389
|
return cast(I, d)
|
|
389
390
|
|
|
390
|
-
def popr(self) -> I
|
|
391
|
-
"""
|
|
391
|
+
def popr(self) -> I:
|
|
392
|
+
"""
|
|
393
|
+
Pop item off right side (rear) of circular array.
|
|
392
394
|
|
|
393
395
|
:return: item popped from right side of circular array
|
|
394
396
|
:raises ValueError: when called on an empty circular array
|
|
@@ -426,7 +428,8 @@ class CA[I]():
|
|
|
426
428
|
return cast(I, d)
|
|
427
429
|
|
|
428
430
|
def popld(self, default: I) -> I:
|
|
429
|
-
"""
|
|
431
|
+
"""
|
|
432
|
+
Pop one item from left side of the circular array, provide
|
|
430
433
|
a mandatory default value. "Safe" version of popl.
|
|
431
434
|
|
|
432
435
|
:param default: item returned if circular array is empty
|
|
@@ -439,7 +442,8 @@ class CA[I]():
|
|
|
439
442
|
return default
|
|
440
443
|
|
|
441
444
|
def poprd(self, default: I) -> I:
|
|
442
|
-
"""
|
|
445
|
+
"""
|
|
446
|
+
Pop one item from right side of the circular array, provide
|
|
443
447
|
a mandatory default value. "Safe" version of popr.
|
|
444
448
|
|
|
445
449
|
:param default: item returned if circular array is empty
|
|
@@ -452,7 +456,8 @@ class CA[I]():
|
|
|
452
456
|
return default
|
|
453
457
|
|
|
454
458
|
def poplt(self, maximum: int) -> tuple[I, ...]:
|
|
455
|
-
"""
|
|
459
|
+
"""
|
|
460
|
+
Pop multiple items from left side of circular array.
|
|
456
461
|
|
|
457
462
|
:param maximum: maximum number of items to pop, may pop less if not enough items
|
|
458
463
|
:return: items in the order popped, left to right
|
|
@@ -471,7 +476,8 @@ class CA[I]():
|
|
|
471
476
|
return tuple(item_list)
|
|
472
477
|
|
|
473
478
|
def poprt(self, maximum: int) -> tuple[I, ...]:
|
|
474
|
-
"""
|
|
479
|
+
"""
|
|
480
|
+
Pop multiple items from right side of circular array.
|
|
475
481
|
|
|
476
482
|
:param maximum: maximum number of items to pop, may pop less if not enough items
|
|
477
483
|
:return: items in the order popped, right to left
|
|
@@ -488,7 +494,8 @@ class CA[I]():
|
|
|
488
494
|
return tuple(item_list)
|
|
489
495
|
|
|
490
496
|
def rotl(self, n: int = 1) -> None:
|
|
491
|
-
"""
|
|
497
|
+
"""
|
|
498
|
+
Rotate items to the left.
|
|
492
499
|
|
|
493
500
|
:param n: number of times to shift elements to the left
|
|
494
501
|
|
|
@@ -499,7 +506,8 @@ class CA[I]():
|
|
|
499
506
|
self.pushr(self.popl())
|
|
500
507
|
|
|
501
508
|
def rotr(self, n: int = 1) -> None:
|
|
502
|
-
"""
|
|
509
|
+
"""
|
|
510
|
+
Rotate items to the right.
|
|
503
511
|
|
|
504
512
|
:param n: number of times to shift elements to the right
|
|
505
513
|
|
|
@@ -510,20 +518,22 @@ class CA[I]():
|
|
|
510
518
|
self.pushl(self.popr())
|
|
511
519
|
|
|
512
520
|
def map[U](self, f: Callable[[I], U]) -> "CA[U]":
|
|
513
|
-
"""
|
|
521
|
+
"""
|
|
522
|
+
Apply function f over the circular array's contents,
|
|
514
523
|
|
|
515
524
|
:param f: callable from type I to type U
|
|
516
|
-
:
|
|
525
|
+
:returns: new circular array instance
|
|
517
526
|
|
|
518
527
|
"""
|
|
519
528
|
return CA(map(f, self))
|
|
520
529
|
|
|
521
|
-
def foldl[L](self, f: Callable[[L, I], L], start: L | None = None) -> L
|
|
522
|
-
"""
|
|
530
|
+
def foldl[L](self, f: Callable[[L, I], L], start: L | None = None) -> L:
|
|
531
|
+
"""
|
|
532
|
+
Fold left with a function and optional starting item.
|
|
523
533
|
|
|
524
534
|
:param f: first argument to f is for the accumulator
|
|
525
535
|
:param start: optional starting item
|
|
526
|
-
:
|
|
536
|
+
:returns: reduced value produced by the left fold
|
|
527
537
|
:raises ValueError: when circular array empty and no starting item given
|
|
528
538
|
|
|
529
539
|
"""
|
|
@@ -544,12 +554,13 @@ class CA[I]():
|
|
|
544
554
|
acc = f(acc, d)
|
|
545
555
|
return acc
|
|
546
556
|
|
|
547
|
-
def foldr[R](self, f: Callable[[I, R], R], start: R | None = None) -> R
|
|
548
|
-
"""
|
|
557
|
+
def foldr[R](self, f: Callable[[I, R], R], start: R | None = None) -> R:
|
|
558
|
+
"""
|
|
559
|
+
Fold right with a function and an optional starting item.
|
|
549
560
|
|
|
550
561
|
:param f: second argument to f is for the accumulator
|
|
551
562
|
:param start: optional starting item
|
|
552
|
-
:
|
|
563
|
+
:returns: reduced value produced by the right fold
|
|
553
564
|
:raises ValueError: when circular array empty and no starting item given
|
|
554
565
|
|
|
555
566
|
"""
|
|
@@ -571,15 +582,17 @@ class CA[I]():
|
|
|
571
582
|
return acc
|
|
572
583
|
|
|
573
584
|
def capacity(self) -> int:
|
|
574
|
-
"""
|
|
585
|
+
"""
|
|
586
|
+
Return current storage capacity of the circular array.
|
|
575
587
|
|
|
576
|
-
:
|
|
588
|
+
:returns: current storage capacity
|
|
577
589
|
|
|
578
590
|
"""
|
|
579
591
|
return self._cap
|
|
580
592
|
|
|
581
593
|
def empty(self) -> None:
|
|
582
|
-
"""
|
|
594
|
+
"""
|
|
595
|
+
Empty the circular array, keep current storage capacity."""
|
|
583
596
|
(
|
|
584
597
|
self._items,
|
|
585
598
|
self._front,
|
|
@@ -593,15 +606,17 @@ class CA[I]():
|
|
|
593
606
|
)
|
|
594
607
|
|
|
595
608
|
def fraction_filled(self) -> float:
|
|
596
|
-
"""
|
|
609
|
+
"""
|
|
610
|
+
Find fraction of the storage capacity which is filled.
|
|
597
611
|
|
|
598
|
-
:
|
|
612
|
+
:returns: the ratio count/capacity
|
|
599
613
|
|
|
600
614
|
"""
|
|
601
615
|
return self._cnt / self._cap
|
|
602
616
|
|
|
603
617
|
def resize(self, minimum_capacity: int = 2) -> None:
|
|
604
|
-
"""
|
|
618
|
+
"""
|
|
619
|
+
Compact circular array and, if necessary, resize to a minimum
|
|
605
620
|
storage capacity. To just compact the circular array, do not
|
|
606
621
|
provide ``minimum_capacity``.
|
|
607
622
|
|
|
@@ -622,10 +637,11 @@ class CA[I]():
|
|
|
622
637
|
|
|
623
638
|
|
|
624
639
|
def ca[T](*items: T) -> CA[T]:
|
|
625
|
-
"""
|
|
640
|
+
"""
|
|
641
|
+
Produce circular array from a variable number of arguments.
|
|
626
642
|
|
|
627
643
|
:param items: initial items for a new circular array
|
|
628
|
-
:
|
|
644
|
+
:returns: new variable storage capacity circular array
|
|
629
645
|
|
|
630
646
|
"""
|
|
631
647
|
return CA(items)
|
|
@@ -1,103 +1,43 @@
|
|
|
1
|
-
# Copyright 2023-202 Geoffrey R. Scheller
|
|
2
|
-
#
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
# you may not use this file except in compliance with the License.
|
|
5
|
-
# You may obtain a copy of the License at
|
|
6
|
-
#
|
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
#
|
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
# See the License for the specific language governing permissions and
|
|
13
|
-
# limitations under the License.
|
|
14
|
-
|
|
15
1
|
from collections.abc import Callable, Iterable, Iterator
|
|
16
|
-
from typing import
|
|
2
|
+
from typing import overload
|
|
17
3
|
|
|
18
4
|
__all__ = ['CA', 'ca']
|
|
19
5
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class CA[I]():
|
|
25
|
-
|
|
26
|
-
L = TypeVar('L')
|
|
27
|
-
R = TypeVar('R')
|
|
28
|
-
U = TypeVar('U')
|
|
29
|
-
|
|
30
|
-
def __init__(
|
|
31
|
-
self,
|
|
32
|
-
items: Iterable[I] | None = None
|
|
33
|
-
) -> None: ...
|
|
34
|
-
|
|
35
|
-
def _double_storage_capacity(self) -> None: ...
|
|
36
|
-
|
|
37
|
-
def _compact_storage_capacity(self) -> None: ...
|
|
38
|
-
|
|
6
|
+
class CA[I]:
|
|
7
|
+
def __init__(self, items: Iterable[I] | None = None) -> None: ...
|
|
39
8
|
def __iter__(self) -> Iterator[I]: ...
|
|
40
|
-
|
|
41
9
|
def __reversed__(self) -> Iterator[I]: ...
|
|
42
|
-
|
|
43
|
-
def __repr__(self) -> str: ...
|
|
44
|
-
|
|
45
|
-
def __str__(self) -> str: ...
|
|
46
|
-
|
|
47
10
|
def __bool__(self) -> bool: ...
|
|
48
|
-
|
|
49
11
|
def __len__(self) -> int: ...
|
|
50
|
-
|
|
51
12
|
@overload
|
|
52
13
|
def __getitem__(self, idx: int) -> I: ...
|
|
53
14
|
@overload
|
|
54
15
|
def __getitem__(self, idx: slice) -> CA[I]: ...
|
|
55
|
-
|
|
56
16
|
@overload
|
|
57
17
|
def __setitem__(self, idx: int, vals: I) -> None: ...
|
|
58
18
|
@overload
|
|
59
19
|
def __setitem__(self, idx: slice, vals: Iterable[I]) -> None: ...
|
|
60
|
-
|
|
61
20
|
@overload
|
|
62
21
|
def __delitem__(self, idx: int) -> None: ...
|
|
63
22
|
@overload
|
|
64
23
|
def __delitem__(self, idx: slice) -> None: ...
|
|
65
|
-
|
|
66
24
|
def __eq__(self, other: object) -> bool: ...
|
|
67
|
-
|
|
68
25
|
def pushl(self, *items: I) -> None: ...
|
|
69
|
-
|
|
70
26
|
def pushr(self, *items: I) -> None: ...
|
|
71
|
-
|
|
72
|
-
def
|
|
73
|
-
|
|
74
|
-
def popr(self) -> I | Never: ...
|
|
75
|
-
|
|
27
|
+
def popl(self) -> I: ...
|
|
28
|
+
def popr(self) -> I: ...
|
|
76
29
|
def popld(self, default: I) -> I: ...
|
|
77
|
-
|
|
78
30
|
def poprd(self, default: I) -> I: ...
|
|
79
|
-
|
|
80
31
|
def poplt(self, maximum: int) -> tuple[I, ...]: ...
|
|
81
|
-
|
|
82
32
|
def poprt(self, maximum: int) -> tuple[I, ...]: ...
|
|
83
|
-
|
|
84
33
|
def rotl(self, n: int = 1) -> None: ...
|
|
85
|
-
|
|
86
34
|
def rotr(self, n: int = 1) -> None: ...
|
|
87
|
-
|
|
88
35
|
def map[U](self, f: Callable[[I], U]) -> CA[U]: ...
|
|
89
|
-
|
|
90
|
-
def
|
|
91
|
-
|
|
92
|
-
def foldr[R](self, f: Callable[[I, R], R], start: R | None = None) -> R | Never: ...
|
|
93
|
-
|
|
36
|
+
def foldl[L](self, f: Callable[[L, I], L], start: L | None = None) -> L: ...
|
|
37
|
+
def foldr[R](self, f: Callable[[I, R], R], start: R | None = None) -> R: ...
|
|
94
38
|
def capacity(self) -> int: ...
|
|
95
|
-
|
|
96
39
|
def empty(self) -> None: ...
|
|
97
|
-
|
|
98
40
|
def fraction_filled(self) -> float: ...
|
|
99
|
-
|
|
100
41
|
def resize(self, minimum_capacity: int = 2) -> None: ...
|
|
101
42
|
|
|
102
|
-
|
|
103
43
|
def ca[T](*items: T) -> CA[T]: ...
|
|
@@ -12,7 +12,11 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
-
"""
|
|
15
|
+
"""
|
|
16
|
+
Fixed Storage Capacity
|
|
17
|
+
======================
|
|
18
|
+
|
|
19
|
+
Circular array with fixed storage capacity.
|
|
16
20
|
|
|
17
21
|
- O(1) pops and pushes either end
|
|
18
22
|
- O(1) indexing, does not support slicing
|
|
@@ -24,20 +28,13 @@
|
|
|
24
28
|
|
|
25
29
|
"""
|
|
26
30
|
from collections.abc import Callable, Iterable, Iterator
|
|
27
|
-
from typing import cast, Final
|
|
31
|
+
from typing import cast, Final
|
|
28
32
|
|
|
29
33
|
__all__ = ['CAF', 'caf']
|
|
30
34
|
|
|
31
|
-
I = TypeVar('I')
|
|
32
|
-
T = TypeVar('T')
|
|
33
|
-
|
|
34
35
|
|
|
35
36
|
class CAF[I]():
|
|
36
37
|
|
|
37
|
-
L = TypeVar('L')
|
|
38
|
-
R = TypeVar('R')
|
|
39
|
-
U = TypeVar('U')
|
|
40
|
-
|
|
41
38
|
__slots__ = '_items', '_cnt', '_cap', '_front', '_rear'
|
|
42
39
|
|
|
43
40
|
def __init__(
|
|
@@ -45,7 +42,8 @@ class CAF[I]():
|
|
|
45
42
|
items: Iterable[I] | None = None,
|
|
46
43
|
capacity: int = 2
|
|
47
44
|
) -> None:
|
|
48
|
-
"""
|
|
45
|
+
"""
|
|
46
|
+
Basically a list that can be grown from both ends
|
|
49
47
|
in O(1) time and space complexity.
|
|
50
48
|
|
|
51
49
|
:param items: optional iterable to initial populate circular array
|
|
@@ -203,7 +201,8 @@ class CAF[I]():
|
|
|
203
201
|
return True
|
|
204
202
|
|
|
205
203
|
def pushl(self, item: I) -> None:
|
|
206
|
-
"""
|
|
204
|
+
"""
|
|
205
|
+
Push single item onto left side (front) of circular array.
|
|
207
206
|
|
|
208
207
|
:param item: single item pushed onto circular array from left
|
|
209
208
|
:raises ValueError: when called on a full CAF
|
|
@@ -224,7 +223,8 @@ class CAF[I]():
|
|
|
224
223
|
)
|
|
225
224
|
|
|
226
225
|
def pushr(self, item: I) -> None:
|
|
227
|
-
"""
|
|
226
|
+
"""
|
|
227
|
+
Push a single item onto right side (rear) of circular array.
|
|
228
228
|
|
|
229
229
|
:param item: single item pushed onto circular array from right
|
|
230
230
|
:raises ValueError: when called on a full fixed storage capacity circular array
|
|
@@ -244,10 +244,11 @@ class CAF[I]():
|
|
|
244
244
|
self._cnt + 1,
|
|
245
245
|
)
|
|
246
246
|
|
|
247
|
-
def popl(self) -> I
|
|
248
|
-
"""
|
|
247
|
+
def popl(self) -> I:
|
|
248
|
+
"""
|
|
249
|
+
Pop item off left side (front) of circular array.
|
|
249
250
|
|
|
250
|
-
:
|
|
251
|
+
:returns: item popped from left side of circular array
|
|
251
252
|
:raises ValueError: when called on an empty circular array
|
|
252
253
|
|
|
253
254
|
"""
|
|
@@ -282,10 +283,11 @@ class CAF[I]():
|
|
|
282
283
|
raise ValueError(msg)
|
|
283
284
|
return cast(I, d)
|
|
284
285
|
|
|
285
|
-
def popr(self) -> I
|
|
286
|
-
"""
|
|
286
|
+
def popr(self) -> I:
|
|
287
|
+
"""
|
|
288
|
+
Pop item off right side (rear) of circular array.
|
|
287
289
|
|
|
288
|
-
:
|
|
290
|
+
:returns: item popped from right side of circular array
|
|
289
291
|
:raises ValueError: when called on an empty circular array
|
|
290
292
|
|
|
291
293
|
"""
|
|
@@ -321,15 +323,12 @@ class CAF[I]():
|
|
|
321
323
|
return cast(I, d)
|
|
322
324
|
|
|
323
325
|
def popld(self, default: I) -> I:
|
|
324
|
-
"""
|
|
325
|
-
a mandatory default value. "Safe" version of popl.
|
|
326
|
-
|
|
327
|
-
|
|
326
|
+
"""
|
|
328
327
|
Pop one item from left side of the circular array, provide
|
|
329
328
|
a mandatory default value. "Safe" version of popl.
|
|
330
329
|
|
|
331
330
|
:param default: item returned if circular array is empty
|
|
332
|
-
:
|
|
331
|
+
:returns: item popped from left side or default item if empty
|
|
333
332
|
|
|
334
333
|
"""
|
|
335
334
|
try:
|
|
@@ -338,11 +337,12 @@ class CAF[I]():
|
|
|
338
337
|
return default
|
|
339
338
|
|
|
340
339
|
def poprd(self, default: I) -> I:
|
|
341
|
-
"""
|
|
340
|
+
"""
|
|
341
|
+
Pop one item from right side of the circular array, provide
|
|
342
342
|
a mandatory default value. "Safe" version of popr.
|
|
343
343
|
|
|
344
344
|
:param default: item returned if circular array is empty
|
|
345
|
-
:
|
|
345
|
+
:returns: item popped from right side or default item if empty
|
|
346
346
|
|
|
347
347
|
"""
|
|
348
348
|
try:
|
|
@@ -351,10 +351,11 @@ class CAF[I]():
|
|
|
351
351
|
return default
|
|
352
352
|
|
|
353
353
|
def poplt(self, maximum: int) -> tuple[I, ...]:
|
|
354
|
-
"""
|
|
354
|
+
"""
|
|
355
|
+
Pop multiple items from left side of circular array.
|
|
355
356
|
|
|
356
357
|
:param maximum: maximum number of items to pop, may pop less if not enough items
|
|
357
|
-
:
|
|
358
|
+
:returns: items in the order popped, left to right
|
|
358
359
|
|
|
359
360
|
"""
|
|
360
361
|
item_list: list[I] = []
|
|
@@ -370,10 +371,11 @@ class CAF[I]():
|
|
|
370
371
|
return tuple(item_list)
|
|
371
372
|
|
|
372
373
|
def poprt(self, maximum: int) -> tuple[I, ...]:
|
|
373
|
-
"""
|
|
374
|
+
"""
|
|
375
|
+
Pop multiple items from right side of circular array.
|
|
374
376
|
|
|
375
377
|
:param maximum: maximum number of items to pop, may pop less if not enough items
|
|
376
|
-
:
|
|
378
|
+
:returns: items in the order popped, right to left
|
|
377
379
|
|
|
378
380
|
"""
|
|
379
381
|
item_list: list[I] = []
|
|
@@ -387,7 +389,8 @@ class CAF[I]():
|
|
|
387
389
|
return tuple(item_list)
|
|
388
390
|
|
|
389
391
|
def rotl(self, n: int = 1) -> None:
|
|
390
|
-
"""
|
|
392
|
+
"""
|
|
393
|
+
Rotate items to the left.
|
|
391
394
|
|
|
392
395
|
:param n: number of times to shift elements to the left
|
|
393
396
|
|
|
@@ -398,7 +401,8 @@ class CAF[I]():
|
|
|
398
401
|
self.pushr(self.popl())
|
|
399
402
|
|
|
400
403
|
def rotr(self, n: int = 1) -> None:
|
|
401
|
-
"""
|
|
404
|
+
"""
|
|
405
|
+
Rotate items to the right.
|
|
402
406
|
|
|
403
407
|
:param n: number of times to shift elements to the right
|
|
404
408
|
|
|
@@ -409,20 +413,22 @@ class CAF[I]():
|
|
|
409
413
|
self.pushl(self.popr())
|
|
410
414
|
|
|
411
415
|
def map[U](self, f: Callable[[I], U]) -> "CAF[U]":
|
|
412
|
-
"""
|
|
416
|
+
"""
|
|
417
|
+
Apply function ``f`` over the circular array's contents,
|
|
413
418
|
|
|
414
419
|
:param f: callable from type I to type U
|
|
415
|
-
:
|
|
420
|
+
:returns: new fixed circular array instance
|
|
416
421
|
|
|
417
422
|
"""
|
|
418
423
|
return CAF(map(f, self), self._cap)
|
|
419
424
|
|
|
420
|
-
def foldl[L](self, f: Callable[[L, I], L], start: L | None = None) -> L
|
|
421
|
-
"""
|
|
425
|
+
def foldl[L](self, f: Callable[[L, I], L], start: L | None = None) -> L:
|
|
426
|
+
"""
|
|
427
|
+
Fold left with a function and optional stating item.
|
|
422
428
|
|
|
423
429
|
:param f: first argument to f is for the accumulator
|
|
424
430
|
:param start: optional starting item
|
|
425
|
-
:
|
|
431
|
+
:returns: reduced value produced by the left fold
|
|
426
432
|
:raises ValueError: when circular array empty and no starting item given
|
|
427
433
|
|
|
428
434
|
"""
|
|
@@ -443,12 +449,13 @@ class CAF[I]():
|
|
|
443
449
|
acc = f(acc, d)
|
|
444
450
|
return acc
|
|
445
451
|
|
|
446
|
-
def foldr[R](self, f: Callable[[I, R], R], start: R | None = None) -> R
|
|
447
|
-
"""
|
|
452
|
+
def foldr[R](self, f: Callable[[I, R], R], start: R | None = None) -> R:
|
|
453
|
+
"""
|
|
454
|
+
Fold right with a function and an optional starting item.
|
|
448
455
|
|
|
449
456
|
:param f: second argument to f is for the accumulator
|
|
450
457
|
:param start: optional starting item
|
|
451
|
-
:
|
|
458
|
+
:returns: reduced value produced by the right fold
|
|
452
459
|
:raises ValueError: when circular array empty and no starting item given
|
|
453
460
|
|
|
454
461
|
"""
|
|
@@ -470,15 +477,17 @@ class CAF[I]():
|
|
|
470
477
|
return acc
|
|
471
478
|
|
|
472
479
|
def capacity(self) -> int:
|
|
473
|
-
"""
|
|
480
|
+
"""
|
|
481
|
+
Return fixed storage capacity of the circular array.
|
|
474
482
|
|
|
475
|
-
:
|
|
483
|
+
:returns: fixed storage capacity
|
|
476
484
|
|
|
477
485
|
"""
|
|
478
486
|
return self._cap
|
|
479
487
|
|
|
480
488
|
def empty(self) -> None:
|
|
481
|
-
"""
|
|
489
|
+
"""
|
|
490
|
+
Empty the circular array."""
|
|
482
491
|
(
|
|
483
492
|
self._items,
|
|
484
493
|
self._front,
|
|
@@ -492,20 +501,22 @@ class CAF[I]():
|
|
|
492
501
|
)
|
|
493
502
|
|
|
494
503
|
def fraction_filled(self) -> float:
|
|
495
|
-
"""
|
|
504
|
+
"""
|
|
505
|
+
Find fraction of the storage capacity which is filled.
|
|
496
506
|
|
|
497
|
-
:
|
|
507
|
+
:returns: the ratio count/capacity
|
|
498
508
|
|
|
499
509
|
"""
|
|
500
510
|
return self._cnt / self._cap
|
|
501
511
|
|
|
502
512
|
|
|
503
513
|
def caf[T](*items: T, capacity: int = 2) -> CAF[T]:
|
|
504
|
-
"""
|
|
514
|
+
"""
|
|
515
|
+
Produce a circular array from a variable number of arguments.
|
|
505
516
|
|
|
506
517
|
:param items: initial items for a new circular array
|
|
507
518
|
:param capacity: the minimum storage capacity to set
|
|
508
|
-
:
|
|
519
|
+
:returns: new fixed storage capacity circular array
|
|
509
520
|
|
|
510
521
|
"""
|
|
511
522
|
return CAF(items, capacity = capacity)
|
|
@@ -1,89 +1,32 @@
|
|
|
1
|
-
# Copyright 2023-2025 Geoffrey R. Scheller
|
|
2
|
-
#
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
# you may not use this file except in compliance with the License.
|
|
5
|
-
# You may obtain a copy of the License at
|
|
6
|
-
#
|
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
#
|
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
# See the License for the specific language governing permissions and
|
|
13
|
-
# limitations under the License.
|
|
14
|
-
|
|
15
1
|
from collections.abc import Callable, Iterable, Iterator
|
|
16
|
-
from typing import Never, TypeVar
|
|
17
2
|
|
|
18
3
|
__all__ = ['CAF', 'caf']
|
|
19
4
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class CAF[I]():
|
|
25
|
-
|
|
26
|
-
L = TypeVar('L')
|
|
27
|
-
R = TypeVar('R')
|
|
28
|
-
U = TypeVar('U')
|
|
29
|
-
|
|
30
|
-
def __init__(
|
|
31
|
-
self,
|
|
32
|
-
items: Iterable[I] | None = None,
|
|
33
|
-
capacity: int = 2
|
|
34
|
-
) -> None: ...
|
|
35
|
-
|
|
5
|
+
class CAF[I]:
|
|
6
|
+
def __init__(self, items: Iterable[I] | None = None, capacity: int = 2) -> None: ...
|
|
36
7
|
def __iter__(self) -> Iterator[I]: ...
|
|
37
|
-
|
|
38
8
|
def __reversed__(self) -> Iterator[I]: ...
|
|
39
|
-
|
|
40
|
-
def __repr__(self) -> str: ...
|
|
41
|
-
|
|
42
|
-
def __str__(self) -> str: ...
|
|
43
|
-
|
|
44
9
|
def __bool__(self) -> bool: ...
|
|
45
|
-
|
|
46
10
|
def __len__(self) -> int: ...
|
|
47
|
-
|
|
48
11
|
def __getitem__(self, idx: int) -> I: ...
|
|
49
|
-
|
|
50
12
|
def __setitem__(self, idx: int, val: I) -> None: ...
|
|
51
|
-
|
|
52
13
|
def __delitem__(self, idx: int) -> None: ...
|
|
53
|
-
|
|
54
14
|
def __eq__(self, other: object) -> bool: ...
|
|
55
|
-
|
|
56
15
|
def pushl(self, item: I) -> None: ...
|
|
57
|
-
|
|
58
16
|
def pushr(self, item: I) -> None: ...
|
|
59
|
-
|
|
60
|
-
def
|
|
61
|
-
|
|
62
|
-
def popr(self) -> I | Never: ...
|
|
63
|
-
|
|
17
|
+
def popl(self) -> I: ...
|
|
18
|
+
def popr(self) -> I: ...
|
|
64
19
|
def popld(self, default: I) -> I: ...
|
|
65
|
-
|
|
66
20
|
def poprd(self, default: I) -> I: ...
|
|
67
|
-
|
|
68
21
|
def poplt(self, maximum: int) -> tuple[I, ...]: ...
|
|
69
|
-
|
|
70
22
|
def poprt(self, maximum: int) -> tuple[I, ...]: ...
|
|
71
|
-
|
|
72
23
|
def rotl(self, n: int = 1) -> None: ...
|
|
73
|
-
|
|
74
24
|
def rotr(self, n: int = 1) -> None: ...
|
|
75
|
-
|
|
76
25
|
def map[U](self, f: Callable[[I], U]) -> CAF[U]: ...
|
|
77
|
-
|
|
78
|
-
def
|
|
79
|
-
|
|
80
|
-
def foldr[R](self, f: Callable[[I, R], R], start: R | None = None) -> R | Never: ...
|
|
81
|
-
|
|
26
|
+
def foldl[L](self, f: Callable[[L, I], L], start: L | None = None) -> L: ...
|
|
27
|
+
def foldr[R](self, f: Callable[[I, R], R], start: R | None = None) -> R: ...
|
|
82
28
|
def capacity(self) -> int: ...
|
|
83
|
-
|
|
84
29
|
def empty(self) -> None: ...
|
|
85
|
-
|
|
86
30
|
def fraction_filled(self) -> float: ...
|
|
87
31
|
|
|
88
|
-
|
|
89
32
|
def caf[T](*items: T, capacity: int = 2) -> CAF[T]: ...
|
{pythonic_fp_circulararray-5.3.0.dist-info → pythonic_fp_circulararray-5.3.2.dist-info}/METADATA
RENAMED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pythonic-fp-circulararray
|
|
3
|
-
Version: 5.3.
|
|
4
|
-
Summary:
|
|
5
|
-
Keywords: auto resizing,circular array,dequeue,indexable,pop,push
|
|
3
|
+
Version: 5.3.2
|
|
4
|
+
Summary: Circular Array
|
|
5
|
+
Keywords: auto resizing,circular array,circulararray,dequeue,indexable,pop,push
|
|
6
6
|
Author-email: "Geoffrey R. Scheller" <geoffrey@scheller.com>
|
|
7
|
-
Requires-Python: >=3.
|
|
7
|
+
Requires-Python: >=3.13
|
|
8
8
|
Description-Content-Type: text/x-rst
|
|
9
9
|
Classifier: Development Status :: 5 - Production/Stable
|
|
10
10
|
Classifier: Framework :: Pytest
|
|
@@ -17,16 +17,16 @@ License-File: LICENSE
|
|
|
17
17
|
Requires-Dist: pytest>=8.4.1 ; extra == "test"
|
|
18
18
|
Project-URL: Changelog, https://github.com/grscheller/pythonic-fp-circulararray/blob/main/CHANGELOG.rst
|
|
19
19
|
Project-URL: Documentation, https://grscheller.github.io/pythonic-fp/circulararray/development/build/html/releases.html
|
|
20
|
-
Project-URL: Homepage, https://github.com/grscheller/pythonic-fp/blob/main/README.
|
|
20
|
+
Project-URL: Homepage, https://github.com/grscheller/pythonic-fp/blob/main/README.md
|
|
21
21
|
Project-URL: Source, https://github.com/grscheller/pythonic-fp-circulararray
|
|
22
22
|
Provides-Extra: test
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
Pythonic FP - Circular Array
|
|
25
|
+
============================
|
|
26
26
|
|
|
27
27
|
PyPI project
|
|
28
|
-
`pythonic-fp
|
|
29
|
-
<https://pypi.org/project/pythonic-fp
|
|
28
|
+
`pythonic-fp-circulararray
|
|
29
|
+
<https://pypi.org/project/pythonic-fp-circulararray>`_.
|
|
30
30
|
|
|
31
31
|
Python module implementing stateful circular array data structures.
|
|
32
32
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
pythonic_fp/circulararray/__init__.py,sha256=4RaMexsQxHwp80j3Z75_td8PGRqLoz1yMvK_ZZ07vi8,1516
|
|
2
|
+
pythonic_fp/circulararray/auto.py,sha256=YIBKvnjerpCg8hmcAS-HSSjGRZSD4C7S_RyCNH4FwoE,19502
|
|
3
|
+
pythonic_fp/circulararray/auto.pyi,sha256=yfQ2kzIiXFb2Bpg3cMwHwv2oSlyOUMTgmdPZM_-oU_8,1669
|
|
4
|
+
pythonic_fp/circulararray/fixed.py,sha256=G58qee_2Rl9e-4hG3vZrQIJTDbpqoECpT-d2M98BcgY,15494
|
|
5
|
+
pythonic_fp/circulararray/fixed.pyi,sha256=y_7eMvH18B1lpLPp2P-VkN-xcQVKJn6cOisp9LSBBRk,1362
|
|
6
|
+
pythonic_fp/circulararray/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
+
pythonic_fp_circulararray-5.3.2.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
|
|
8
|
+
pythonic_fp_circulararray-5.3.2.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
9
|
+
pythonic_fp_circulararray-5.3.2.dist-info/METADATA,sha256=DJnFE-yTJU7yhdQNjXA4lTc4tsWWp1zULxsBlN5e46w,2183
|
|
10
|
+
pythonic_fp_circulararray-5.3.2.dist-info/RECORD,,
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
pythonic_fp/circulararray/__init__.py,sha256=YjAKcjcSpEYW5mhTiGwtnx9xhCdK68CrAiYAhlqSkCY,1484
|
|
2
|
-
pythonic_fp/circulararray/auto.py,sha256=DzQJl6-Yuns3pgYe7a_pgKxEPY5RBx8gHD4rUIvhHcc,19407
|
|
3
|
-
pythonic_fp/circulararray/auto.pyi,sha256=xK10nhGdyHcBSEsaWfZA83y3fZc89FP2_YsFAO7Iyzc,2647
|
|
4
|
-
pythonic_fp/circulararray/fixed.py,sha256=-FhBFwxnSgeqJhNLSARM_jhUIr0nPmFiMmGXMWotmMc,15533
|
|
5
|
-
pythonic_fp/circulararray/fixed.pyi,sha256=HhAWh7hHl432wsvMUuTrlqgzZ7MSK7mpWF4k_Wq32Xk,2263
|
|
6
|
-
pythonic_fp/circulararray/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
-
pythonic_fp_circulararray-5.3.0.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
|
|
8
|
-
pythonic_fp_circulararray-5.3.0.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
9
|
-
pythonic_fp_circulararray-5.3.0.dist-info/METADATA,sha256=MZHH8D03wZ1d6iazBeOuQTTS0c63ajCzx9D6svbIRIE,2219
|
|
10
|
-
pythonic_fp_circulararray-5.3.0.dist-info/RECORD,,
|
{pythonic_fp_circulararray-5.3.0.dist-info → pythonic_fp_circulararray-5.3.2.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|