pythonic-fp-circulararray 5.3.1__py3-none-any.whl → 5.3.3__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 -2
- pythonic_fp/circulararray/__init__.pyi +0 -0
- pythonic_fp/circulararray/auto.py +54 -77
- pythonic_fp/circulararray/auto.pyi +7 -67
- pythonic_fp/circulararray/fixed.py +55 -81
- pythonic_fp/circulararray/fixed.pyi +6 -63
- {pythonic_fp_circulararray-5.3.1.dist-info → pythonic_fp_circulararray-5.3.3.dist-info}/METADATA +8 -8
- pythonic_fp_circulararray-5.3.3.dist-info/RECORD +11 -0
- pythonic_fp_circulararray-5.3.1.dist-info/RECORD +0 -10
- {pythonic_fp_circulararray-5.3.1.dist-info → pythonic_fp_circulararray-5.3.3.dist-info}/WHEEL +0 -0
- {pythonic_fp_circulararray-5.3.1.dist-info → pythonic_fp_circulararray-5.3.3.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
|
|
@@ -25,7 +29,6 @@
|
|
|
25
29
|
+-------------------------------------+-------------------------------------------+
|
|
26
30
|
| **pythonic_fp.circulararray.fixed** | Fixed storage capacity circular array. |
|
|
27
31
|
+-------------------------------------+-------------------------------------------+
|
|
28
|
-
|
|
29
32
|
"""
|
|
30
33
|
|
|
31
34
|
__author__ = 'Geoffrey R. Scheller'
|
|
File without changes
|
|
@@ -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
|
|
@@ -21,36 +25,26 @@
|
|
|
21
25
|
- iterable, can safely mutate while iterators continue iterating over previous state
|
|
22
26
|
- comparisons compare identity before equality, like builtins
|
|
23
27
|
- in boolean context, falsy when empty, otherwise truthy
|
|
24
|
-
- factory function ca produces a variable storage capacity circular array from its arguments
|
|
28
|
+
- factory function ``ca`` produces a variable storage capacity circular array from its arguments
|
|
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
|
-
"""
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
:param items: optional iterable to initial populate circular array
|
|
52
|
-
:raises TypeError: if items is not Iterable
|
|
53
|
-
|
|
45
|
+
"""
|
|
46
|
+
:param items: Optional iterable to initial populate circular array.
|
|
47
|
+
:raises TypeError: When ``items`` not Iterable.
|
|
54
48
|
"""
|
|
55
49
|
if items is None:
|
|
56
50
|
self._items: list[I | None] = [None, None]
|
|
@@ -312,10 +306,9 @@ class CA[I]():
|
|
|
312
306
|
return True
|
|
313
307
|
|
|
314
308
|
def pushl(self, *items: I) -> None:
|
|
315
|
-
"""Push items
|
|
316
|
-
|
|
317
|
-
:param items: items pushed onto circular array from left
|
|
309
|
+
"""Push ``items`` on from left.
|
|
318
310
|
|
|
311
|
+
:param items: Items pushed onto circular array from left (front).
|
|
319
312
|
"""
|
|
320
313
|
for item in items:
|
|
321
314
|
if self._cnt == self._cap:
|
|
@@ -331,10 +324,9 @@ class CA[I]():
|
|
|
331
324
|
)
|
|
332
325
|
|
|
333
326
|
def pushr(self, *items: I) -> None:
|
|
334
|
-
"""Push items
|
|
335
|
-
|
|
336
|
-
:param items: items pushed onto circular array from right
|
|
327
|
+
"""Push ``items`` on from right.
|
|
337
328
|
|
|
329
|
+
:param items: Items pushed onto circular array from right (rear).
|
|
338
330
|
"""
|
|
339
331
|
for item in items:
|
|
340
332
|
if self._cnt == self._cap:
|
|
@@ -349,12 +341,11 @@ class CA[I]():
|
|
|
349
341
|
self._cnt + 1,
|
|
350
342
|
)
|
|
351
343
|
|
|
352
|
-
def popl(self) -> I
|
|
353
|
-
"""Pop item off left side
|
|
354
|
-
|
|
355
|
-
:return: item popped from left side of circular array
|
|
356
|
-
:raises ValueError: when called on an empty circular array
|
|
344
|
+
def popl(self) -> I:
|
|
345
|
+
"""Pop single item off from left side.
|
|
357
346
|
|
|
347
|
+
:returns: Item popped from left side (front) of circular array.
|
|
348
|
+
:raises ValueError: When called on an empty circular array.
|
|
358
349
|
"""
|
|
359
350
|
if self._cnt > 1:
|
|
360
351
|
(
|
|
@@ -387,12 +378,11 @@ class CA[I]():
|
|
|
387
378
|
raise ValueError(msg)
|
|
388
379
|
return cast(I, d)
|
|
389
380
|
|
|
390
|
-
def popr(self) -> I
|
|
391
|
-
"""Pop item off right
|
|
392
|
-
|
|
393
|
-
:return: item popped from right side of circular array
|
|
394
|
-
:raises ValueError: when called on an empty circular array
|
|
381
|
+
def popr(self) -> I:
|
|
382
|
+
"""Pop single item off from right.
|
|
395
383
|
|
|
384
|
+
:returns: Item popped from right side (rear) of circular array.
|
|
385
|
+
:raises ValueError: When called on an empty circular array.
|
|
396
386
|
"""
|
|
397
387
|
if self._cnt > 1:
|
|
398
388
|
(
|
|
@@ -427,11 +417,10 @@ class CA[I]():
|
|
|
427
417
|
|
|
428
418
|
def popld(self, default: I) -> I:
|
|
429
419
|
"""Pop one item from left side of the circular array, provide
|
|
430
|
-
a mandatory default value. "Safe" version of popl
|
|
431
|
-
|
|
432
|
-
:param default: item returned if circular array is empty
|
|
433
|
-
:return: item popped from left side or default item if empty
|
|
420
|
+
a mandatory default value. "Safe" version of ``popl``.
|
|
434
421
|
|
|
422
|
+
:param default: Item returned if circular array is empty.
|
|
423
|
+
:returns: Item popped from left side or default item if empty.
|
|
435
424
|
"""
|
|
436
425
|
try:
|
|
437
426
|
return self.popl()
|
|
@@ -440,11 +429,10 @@ class CA[I]():
|
|
|
440
429
|
|
|
441
430
|
def poprd(self, default: I) -> I:
|
|
442
431
|
"""Pop one item from right side of the circular array, provide
|
|
443
|
-
a mandatory default value. "Safe" version of popr
|
|
444
|
-
|
|
445
|
-
:param default: item returned if circular array is empty
|
|
446
|
-
:return: item popped from right side or default item if empty
|
|
432
|
+
a mandatory default value. "Safe" version of ``popr``.
|
|
447
433
|
|
|
434
|
+
:param default: Item returned if circular array is empty.
|
|
435
|
+
:returns: Item popped from right side or default item if empty.
|
|
448
436
|
"""
|
|
449
437
|
try:
|
|
450
438
|
return self.popr()
|
|
@@ -454,9 +442,8 @@ class CA[I]():
|
|
|
454
442
|
def poplt(self, maximum: int) -> tuple[I, ...]:
|
|
455
443
|
"""Pop multiple items from left side of circular array.
|
|
456
444
|
|
|
457
|
-
:param maximum:
|
|
458
|
-
:
|
|
459
|
-
|
|
445
|
+
:param maximum: Maximum number of items to pop, may pop less if not enough items.
|
|
446
|
+
:returns: Tuple of items in the order popped, left to right.
|
|
460
447
|
"""
|
|
461
448
|
item_list: list[I] = []
|
|
462
449
|
|
|
@@ -473,9 +460,8 @@ class CA[I]():
|
|
|
473
460
|
def poprt(self, maximum: int) -> tuple[I, ...]:
|
|
474
461
|
"""Pop multiple items from right side of circular array.
|
|
475
462
|
|
|
476
|
-
:param maximum:
|
|
477
|
-
:
|
|
478
|
-
|
|
463
|
+
:param maximum: Maximum number of items to pop, may pop less if not enough items.
|
|
464
|
+
:returns: Tuple of items in the order popped, right to left.
|
|
479
465
|
"""
|
|
480
466
|
item_list: list[I] = []
|
|
481
467
|
while maximum > 0:
|
|
@@ -488,10 +474,9 @@ class CA[I]():
|
|
|
488
474
|
return tuple(item_list)
|
|
489
475
|
|
|
490
476
|
def rotl(self, n: int = 1) -> None:
|
|
491
|
-
"""Rotate items left.
|
|
492
|
-
|
|
493
|
-
:param n: number of times to shift elements to the left
|
|
477
|
+
"""Rotate items to the left.
|
|
494
478
|
|
|
479
|
+
:param n: Number of times to shift elements to the left.
|
|
495
480
|
"""
|
|
496
481
|
if self._cnt < 2:
|
|
497
482
|
return
|
|
@@ -499,10 +484,9 @@ class CA[I]():
|
|
|
499
484
|
self.pushr(self.popl())
|
|
500
485
|
|
|
501
486
|
def rotr(self, n: int = 1) -> None:
|
|
502
|
-
"""Rotate items right.
|
|
503
|
-
|
|
504
|
-
:param n: number of times to shift elements to the right
|
|
487
|
+
"""Rotate items to the right.
|
|
505
488
|
|
|
489
|
+
:param n: Number of times to shift elements to the right.
|
|
506
490
|
"""
|
|
507
491
|
if self._cnt < 2:
|
|
508
492
|
return
|
|
@@ -510,22 +494,20 @@ class CA[I]():
|
|
|
510
494
|
self.pushl(self.popr())
|
|
511
495
|
|
|
512
496
|
def map[U](self, f: Callable[[I], U]) -> "CA[U]":
|
|
513
|
-
"""Apply function f over the circular array's contents
|
|
514
|
-
|
|
515
|
-
:param f: callable from type I to type U
|
|
516
|
-
:return: new circular array instance
|
|
497
|
+
"""Apply function ``f`` over the circular array's contents.
|
|
517
498
|
|
|
499
|
+
:param f: Callable from type ``I`` to type ``U``.
|
|
500
|
+
:returns: New auto-resizing circular array instance.
|
|
518
501
|
"""
|
|
519
502
|
return CA(map(f, self))
|
|
520
503
|
|
|
521
|
-
def foldl[L](self, f: Callable[[L, I], L], start: L | None = None) -> L
|
|
504
|
+
def foldl[L](self, f: Callable[[L, I], L], start: L | None = None) -> L:
|
|
522
505
|
"""Fold left with a function and optional starting item.
|
|
523
506
|
|
|
524
|
-
:param f: first argument to f is for the accumulator
|
|
525
|
-
:param start:
|
|
526
|
-
:
|
|
527
|
-
:raises ValueError:
|
|
528
|
-
|
|
507
|
+
:param f: Folding function, first argument to ``f`` is for the accumulator.
|
|
508
|
+
:param start: Optional starting item.
|
|
509
|
+
:returns: Reduced value produced by the left fold.
|
|
510
|
+
:raises ValueError: When circular array empty and no starting item given.
|
|
529
511
|
"""
|
|
530
512
|
if self._cnt == 0:
|
|
531
513
|
if start is None:
|
|
@@ -544,14 +526,13 @@ class CA[I]():
|
|
|
544
526
|
acc = f(acc, d)
|
|
545
527
|
return acc
|
|
546
528
|
|
|
547
|
-
def foldr[R](self, f: Callable[[I, R], R], start: R | None = None) -> R
|
|
529
|
+
def foldr[R](self, f: Callable[[I, R], R], start: R | None = None) -> R:
|
|
548
530
|
"""Fold right with a function and an optional starting item.
|
|
549
531
|
|
|
550
|
-
:param f: second argument to f is for the accumulator
|
|
551
|
-
:param start:
|
|
552
|
-
:
|
|
553
|
-
:raises ValueError:
|
|
554
|
-
|
|
532
|
+
:param f: Folding function, second argument to ``f`` is for the accumulator.
|
|
533
|
+
:param start: Optional starting item.
|
|
534
|
+
:returns: Reduced value produced by the right fold.
|
|
535
|
+
:raises ValueError: When circular array empty and no starting item given.
|
|
555
536
|
"""
|
|
556
537
|
if self._cnt == 0:
|
|
557
538
|
if start is None:
|
|
@@ -573,8 +554,7 @@ class CA[I]():
|
|
|
573
554
|
def capacity(self) -> int:
|
|
574
555
|
"""Return current storage capacity of the circular array.
|
|
575
556
|
|
|
576
|
-
:
|
|
577
|
-
|
|
557
|
+
:returns: Current storage capacity.
|
|
578
558
|
"""
|
|
579
559
|
return self._cap
|
|
580
560
|
|
|
@@ -595,8 +575,7 @@ class CA[I]():
|
|
|
595
575
|
def fraction_filled(self) -> float:
|
|
596
576
|
"""Find fraction of the storage capacity which is filled.
|
|
597
577
|
|
|
598
|
-
:
|
|
599
|
-
|
|
578
|
+
:returns: The ratio count/capacity.
|
|
600
579
|
"""
|
|
601
580
|
return self._cnt / self._cap
|
|
602
581
|
|
|
@@ -605,8 +584,7 @@ class CA[I]():
|
|
|
605
584
|
storage capacity. To just compact the circular array, do not
|
|
606
585
|
provide ``minimum_capacity``.
|
|
607
586
|
|
|
608
|
-
:param minimum_capacity:
|
|
609
|
-
|
|
587
|
+
:param minimum_capacity: Minimum storage capacity to compact the circular array.
|
|
610
588
|
"""
|
|
611
589
|
self._compact_storage_capacity()
|
|
612
590
|
if (min_cap := minimum_capacity) > self._cap:
|
|
@@ -624,8 +602,7 @@ class CA[I]():
|
|
|
624
602
|
def ca[T](*items: T) -> CA[T]:
|
|
625
603
|
"""Produce circular array from a variable number of arguments.
|
|
626
604
|
|
|
627
|
-
:param items:
|
|
628
|
-
:
|
|
629
|
-
|
|
605
|
+
:param items: Initial items for a new auto-resizing circular array.
|
|
606
|
+
:returns: New variable storage capacity circular array.
|
|
630
607
|
"""
|
|
631
608
|
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
|
|
@@ -20,24 +24,17 @@
|
|
|
20
24
|
- iterable, can safely mutate while iterators continue iterating over previous state
|
|
21
25
|
- comparisons compare identity before equality, like builtins
|
|
22
26
|
- in boolean context, falsy when either empty or full, otherwise truthy
|
|
23
|
-
- factory function caf produces a fixed storage capacity circular array from its arguments
|
|
27
|
+
- factory function ``caf`` produces a fixed storage capacity circular array from its arguments
|
|
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,13 +42,10 @@ class CAF[I]():
|
|
|
45
42
|
items: Iterable[I] | None = None,
|
|
46
43
|
capacity: int = 2
|
|
47
44
|
) -> None:
|
|
48
|
-
"""
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
:
|
|
52
|
-
:param capacity: fixed storage capacity of circular array
|
|
53
|
-
:raises TypeError: if items is not Iterable
|
|
54
|
-
|
|
45
|
+
"""
|
|
46
|
+
:param items: Optional iterable to initial populate circular array.
|
|
47
|
+
:param capacity: Fixed storage capacity of circular array.
|
|
48
|
+
:raises TypeError: When ``items`` not Iterable,
|
|
55
49
|
"""
|
|
56
50
|
capacity = max(2, capacity)
|
|
57
51
|
if items is None:
|
|
@@ -203,11 +197,10 @@ class CAF[I]():
|
|
|
203
197
|
return True
|
|
204
198
|
|
|
205
199
|
def pushl(self, item: I) -> None:
|
|
206
|
-
"""Push
|
|
207
|
-
|
|
208
|
-
:param item: single item pushed onto circular array from left
|
|
209
|
-
:raises ValueError: when called on a full CAF
|
|
200
|
+
"""Push ``item`` on from left.
|
|
210
201
|
|
|
202
|
+
:param item: Single item pushed onto circular array from left (front).
|
|
203
|
+
:raises ValueError: When called on a full ``CAF``.
|
|
211
204
|
"""
|
|
212
205
|
if self._cnt == self._cap:
|
|
213
206
|
msg = 'Method pushl called on a full CAF'
|
|
@@ -224,11 +217,10 @@ class CAF[I]():
|
|
|
224
217
|
)
|
|
225
218
|
|
|
226
219
|
def pushr(self, item: I) -> None:
|
|
227
|
-
"""Push
|
|
228
|
-
|
|
229
|
-
:param item: single item pushed onto circular array from right
|
|
230
|
-
:raises ValueError: when called on a full fixed storage capacity circular array
|
|
220
|
+
"""Push ``item`` on from Right.
|
|
231
221
|
|
|
222
|
+
:param item: Single ``item`` pushed onto circular array from right (rear).
|
|
223
|
+
:raises ValueError: When called on a full fixed storage capacity circular array.
|
|
232
224
|
"""
|
|
233
225
|
if self._cnt == self._cap:
|
|
234
226
|
msg = 'Method pushr called on a full CAF'
|
|
@@ -244,12 +236,11 @@ class CAF[I]():
|
|
|
244
236
|
self._cnt + 1,
|
|
245
237
|
)
|
|
246
238
|
|
|
247
|
-
def popl(self) -> I
|
|
248
|
-
"""Pop item off left side
|
|
249
|
-
|
|
250
|
-
:return: item popped from left side of circular array
|
|
251
|
-
:raises ValueError: when called on an empty circular array
|
|
239
|
+
def popl(self) -> I:
|
|
240
|
+
"""Pop single item off from left side.
|
|
252
241
|
|
|
242
|
+
:returns: Item popped from left side (front) of circular array.
|
|
243
|
+
:raises ValueError: When called on an empty circular array.
|
|
253
244
|
"""
|
|
254
245
|
if self._cnt > 1:
|
|
255
246
|
(
|
|
@@ -282,12 +273,11 @@ class CAF[I]():
|
|
|
282
273
|
raise ValueError(msg)
|
|
283
274
|
return cast(I, d)
|
|
284
275
|
|
|
285
|
-
def popr(self) -> I
|
|
286
|
-
"""Pop item off right side
|
|
287
|
-
|
|
288
|
-
:return: item popped from right side of circular array
|
|
289
|
-
:raises ValueError: when called on an empty circular array
|
|
276
|
+
def popr(self) -> I:
|
|
277
|
+
"""Pop single item off from right side.
|
|
290
278
|
|
|
279
|
+
:returns: Item popped from right side (rear) of circular array.
|
|
280
|
+
:raises ValueError: When called on an empty circular array.
|
|
291
281
|
"""
|
|
292
282
|
if self._cnt > 1:
|
|
293
283
|
(
|
|
@@ -324,13 +314,8 @@ class CAF[I]():
|
|
|
324
314
|
"""Pop one item from left side of the circular array, provide
|
|
325
315
|
a mandatory default value. "Safe" version of popl.
|
|
326
316
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
a mandatory default value. "Safe" version of popl.
|
|
330
|
-
|
|
331
|
-
:param default: item returned if circular array is empty
|
|
332
|
-
:return: item popped from left side or default item if empty
|
|
333
|
-
|
|
317
|
+
:param default: Item returned if circular array is empty.
|
|
318
|
+
:returns: Item popped from left side or default item if empty.
|
|
334
319
|
"""
|
|
335
320
|
try:
|
|
336
321
|
return self.popl()
|
|
@@ -341,9 +326,8 @@ class CAF[I]():
|
|
|
341
326
|
"""Pop one item from right side of the circular array, provide
|
|
342
327
|
a mandatory default value. "Safe" version of popr.
|
|
343
328
|
|
|
344
|
-
:param default:
|
|
345
|
-
:
|
|
346
|
-
|
|
329
|
+
:param default: Item returned if circular array is empty.
|
|
330
|
+
:returns: Item popped from right side or default item if empty.
|
|
347
331
|
"""
|
|
348
332
|
try:
|
|
349
333
|
return self.popr()
|
|
@@ -353,9 +337,8 @@ class CAF[I]():
|
|
|
353
337
|
def poplt(self, maximum: int) -> tuple[I, ...]:
|
|
354
338
|
"""Pop multiple items from left side of circular array.
|
|
355
339
|
|
|
356
|
-
:param maximum:
|
|
357
|
-
:
|
|
358
|
-
|
|
340
|
+
:param maximum: Maximum number of items to pop, may pop less if not enough items.
|
|
341
|
+
:returns: Tuple of items in the order popped, left to right.
|
|
359
342
|
"""
|
|
360
343
|
item_list: list[I] = []
|
|
361
344
|
|
|
@@ -372,9 +355,8 @@ class CAF[I]():
|
|
|
372
355
|
def poprt(self, maximum: int) -> tuple[I, ...]:
|
|
373
356
|
"""Pop multiple items from right side of circular array.
|
|
374
357
|
|
|
375
|
-
:param maximum:
|
|
376
|
-
:
|
|
377
|
-
|
|
358
|
+
:param maximum: Maximum number of items to pop, may pop less if not enough items.
|
|
359
|
+
:returns: Tuple of items in the order popped, right to left.
|
|
378
360
|
"""
|
|
379
361
|
item_list: list[I] = []
|
|
380
362
|
while maximum > 0:
|
|
@@ -387,10 +369,9 @@ class CAF[I]():
|
|
|
387
369
|
return tuple(item_list)
|
|
388
370
|
|
|
389
371
|
def rotl(self, n: int = 1) -> None:
|
|
390
|
-
"""Rotate items left.
|
|
391
|
-
|
|
392
|
-
:param n: number of times to shift elements to the left
|
|
372
|
+
"""Rotate items to the left.
|
|
393
373
|
|
|
374
|
+
:param n: Number of times to shift elements to the left.
|
|
394
375
|
"""
|
|
395
376
|
if self._cnt < 2:
|
|
396
377
|
return
|
|
@@ -398,10 +379,9 @@ class CAF[I]():
|
|
|
398
379
|
self.pushr(self.popl())
|
|
399
380
|
|
|
400
381
|
def rotr(self, n: int = 1) -> None:
|
|
401
|
-
"""Rotate items right.
|
|
402
|
-
|
|
403
|
-
:param n: number of times to shift elements to the right
|
|
382
|
+
"""Rotate items to the right.
|
|
404
383
|
|
|
384
|
+
:param n: Number of times to shift elements to the right.
|
|
405
385
|
"""
|
|
406
386
|
if self._cnt < 2:
|
|
407
387
|
return
|
|
@@ -409,22 +389,20 @@ class CAF[I]():
|
|
|
409
389
|
self.pushl(self.popr())
|
|
410
390
|
|
|
411
391
|
def map[U](self, f: Callable[[I], U]) -> "CAF[U]":
|
|
412
|
-
"""Apply function f over the circular array's contents,
|
|
413
|
-
|
|
414
|
-
:param f: callable from type I to type U
|
|
415
|
-
:return: new fixed circular array instance
|
|
392
|
+
"""Apply function ``f`` over the circular array's contents,
|
|
416
393
|
|
|
394
|
+
:param f: Callable from type ``I`` to type ``U``.
|
|
395
|
+
:returns: New fixed capacity circular array instance.
|
|
417
396
|
"""
|
|
418
397
|
return CAF(map(f, self), self._cap)
|
|
419
398
|
|
|
420
|
-
def foldl[L](self, f: Callable[[L, I], L], start: L | None = None) -> L
|
|
399
|
+
def foldl[L](self, f: Callable[[L, I], L], start: L | None = None) -> L:
|
|
421
400
|
"""Fold left with a function and optional stating item.
|
|
422
401
|
|
|
423
|
-
:param f: first argument to f is for the accumulator
|
|
424
|
-
:param start:
|
|
425
|
-
:
|
|
426
|
-
:raises ValueError:
|
|
427
|
-
|
|
402
|
+
:param f: Folding function, first argument to ``f`` is for the accumulator.
|
|
403
|
+
:param start: Optional starting item.
|
|
404
|
+
:returns: Reduced value produced by the left fold.
|
|
405
|
+
:raises ValueError: When circular array empty and no starting item given.
|
|
428
406
|
"""
|
|
429
407
|
if self._cnt == 0:
|
|
430
408
|
if start is None:
|
|
@@ -443,14 +421,13 @@ class CAF[I]():
|
|
|
443
421
|
acc = f(acc, d)
|
|
444
422
|
return acc
|
|
445
423
|
|
|
446
|
-
def foldr[R](self, f: Callable[[I, R], R], start: R | None = None) -> R
|
|
424
|
+
def foldr[R](self, f: Callable[[I, R], R], start: R | None = None) -> R:
|
|
447
425
|
"""Fold right with a function and an optional starting item.
|
|
448
426
|
|
|
449
|
-
:param f: second argument to f is for the accumulator
|
|
450
|
-
:param start:
|
|
451
|
-
:
|
|
452
|
-
:raises ValueError:
|
|
453
|
-
|
|
427
|
+
:param f: Folding function, second argument to ``f`` is for the accumulator.
|
|
428
|
+
:param start: Optional starting item.
|
|
429
|
+
:returns: Reduced value produced by the right fold.
|
|
430
|
+
:raises ValueError: When circular array empty and no starting item given.
|
|
454
431
|
"""
|
|
455
432
|
if self._cnt == 0:
|
|
456
433
|
if start is None:
|
|
@@ -472,8 +449,7 @@ class CAF[I]():
|
|
|
472
449
|
def capacity(self) -> int:
|
|
473
450
|
"""Return fixed storage capacity of the circular array.
|
|
474
451
|
|
|
475
|
-
:
|
|
476
|
-
|
|
452
|
+
:returns: Fixed storage capacity.
|
|
477
453
|
"""
|
|
478
454
|
return self._cap
|
|
479
455
|
|
|
@@ -494,8 +470,7 @@ class CAF[I]():
|
|
|
494
470
|
def fraction_filled(self) -> float:
|
|
495
471
|
"""Find fraction of the storage capacity which is filled.
|
|
496
472
|
|
|
497
|
-
:
|
|
498
|
-
|
|
473
|
+
:returns: The ratio count/capacity.
|
|
499
474
|
"""
|
|
500
475
|
return self._cnt / self._cap
|
|
501
476
|
|
|
@@ -503,9 +478,8 @@ class CAF[I]():
|
|
|
503
478
|
def caf[T](*items: T, capacity: int = 2) -> CAF[T]:
|
|
504
479
|
"""Produce a circular array from a variable number of arguments.
|
|
505
480
|
|
|
506
|
-
:param items:
|
|
507
|
-
:param capacity:
|
|
508
|
-
:
|
|
509
|
-
|
|
481
|
+
:param items: Initial items for a new fixed capacity :circular array.
|
|
482
|
+
:param capacity: The minimum storage capacity to set.
|
|
483
|
+
:returns: New fixed storage capacity circular array.
|
|
510
484
|
"""
|
|
511
485
|
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.1.dist-info → pythonic_fp_circulararray-5.3.3.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.3
|
|
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
|
|
@@ -16,13 +16,13 @@ Classifier: Typing :: Typed
|
|
|
16
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
|
-
Project-URL: Documentation, https://grscheller.github.io/pythonic-fp/circulararray/development/build/html/
|
|
20
|
-
Project-URL: Homepage, https://github.com/grscheller/pythonic-fp/blob/main/README.
|
|
19
|
+
Project-URL: Documentation, https://grscheller.github.io/pythonic-fp/circulararray/development/build/html/index.html
|
|
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
28
|
`pythonic-fp-circulararray
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
pythonic_fp/circulararray/__init__.py,sha256=uR0KASmw1Zraz9l3VPbqPm9WUKzWk-0_tUGT0opabzQ,1515
|
|
2
|
+
pythonic_fp/circulararray/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
pythonic_fp/circulararray/auto.py,sha256=_rZhOsC3PGs97j15qM4vXpkpRDTfVkxEGwYyBi9uAQU,19334
|
|
4
|
+
pythonic_fp/circulararray/auto.pyi,sha256=yfQ2kzIiXFb2Bpg3cMwHwv2oSlyOUMTgmdPZM_-oU_8,1669
|
|
5
|
+
pythonic_fp/circulararray/fixed.py,sha256=nzwPnaVOh-KKv503_c--f_m0SkOaUI6mSe1Bo5WACCA,15316
|
|
6
|
+
pythonic_fp/circulararray/fixed.pyi,sha256=y_7eMvH18B1lpLPp2P-VkN-xcQVKJn6cOisp9LSBBRk,1362
|
|
7
|
+
pythonic_fp/circulararray/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
pythonic_fp_circulararray-5.3.3.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
|
|
9
|
+
pythonic_fp_circulararray-5.3.3.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
10
|
+
pythonic_fp_circulararray-5.3.3.dist-info/METADATA,sha256=rdgGmosD6wF1Cfye7QBuZJXGnjs3uDgPzmYYvVpUx-M,2180
|
|
11
|
+
pythonic_fp_circulararray-5.3.3.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.1.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
|
|
8
|
-
pythonic_fp_circulararray-5.3.1.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
9
|
-
pythonic_fp_circulararray-5.3.1.dist-info/METADATA,sha256=C0ZzZsk64VYRXKGUl2wWd5IoVfT5S7hp9eYQvjHYztE,2219
|
|
10
|
-
pythonic_fp_circulararray-5.3.1.dist-info/RECORD,,
|
{pythonic_fp_circulararray-5.3.1.dist-info → pythonic_fp_circulararray-5.3.3.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|