pythonic-fp-circulararray 6.1.0__py3-none-any.whl → 6.2.0__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/.mypy_cache/.gitignore +2 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/@plugins_snapshot.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/__future__.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/__future__.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/_ast.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/_ast.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/_codecs.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/_codecs.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/_collections_abc.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/_collections_abc.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/_frozen_importlib.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/_frozen_importlib.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/_frozen_importlib_external.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/_frozen_importlib_external.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/_io.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/_io.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/_sitebuiltins.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/_sitebuiltins.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/_typeshed/__init__.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/_typeshed/__init__.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/_typeshed/importlib.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/_typeshed/importlib.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/_warnings.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/_warnings.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/abc.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/abc.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/ast.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/ast.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/builtins.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/builtins.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/circulararray/__init__.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/circulararray/__init__.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/circulararray/auto.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/circulararray/auto.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/circulararray/fixed.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/circulararray/fixed.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/codecs.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/codecs.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/collections/__init__.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/collections/__init__.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/collections/abc.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/collections/abc.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/contextlib.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/contextlib.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/dataclasses.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/dataclasses.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/email/__init__.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/email/__init__.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/email/_policybase.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/email/_policybase.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/email/charset.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/email/charset.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/email/contentmanager.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/email/contentmanager.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/email/errors.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/email/errors.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/email/header.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/email/header.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/email/message.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/email/message.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/email/policy.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/email/policy.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/enum.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/enum.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/genericpath.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/genericpath.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/importlib/__init__.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/importlib/__init__.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/importlib/_abc.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/importlib/_abc.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/importlib/_bootstrap.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/importlib/_bootstrap.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/importlib/_bootstrap_external.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/importlib/_bootstrap_external.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/importlib/abc.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/importlib/abc.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/importlib/machinery.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/importlib/machinery.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/importlib/metadata/__init__.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/importlib/metadata/__init__.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/importlib/metadata/_meta.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/importlib/metadata/_meta.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/importlib/readers.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/importlib/readers.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/importlib/resources/__init__.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/importlib/resources/__init__.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/importlib/resources/_common.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/importlib/resources/_common.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/importlib/resources/_functional.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/importlib/resources/_functional.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/importlib/resources/abc.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/importlib/resources/abc.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/io.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/io.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/os/__init__.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/os/__init__.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/os/path.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/os/path.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/pathlib/__init__.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/pathlib/__init__.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/posixpath.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/posixpath.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/re.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/re.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/resource.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/resource.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/sre_compile.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/sre_compile.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/sre_constants.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/sre_constants.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/sre_parse.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/sre_parse.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/subprocess.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/subprocess.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/sys/__init__.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/sys/__init__.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/sys/_monitoring.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/sys/_monitoring.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/types.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/types.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/typing.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/typing.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/typing_extensions.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/typing_extensions.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/warnings.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/warnings.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/zipfile/__init__.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/zipfile/__init__.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/zipfile/_path/__init__.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/zipfile/_path/__init__.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/zipimport.data.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.13/zipimport.meta.json +1 -0
- pythonic_fp/circulararray/.mypy_cache/3.14/cache.db +0 -0
- pythonic_fp/circulararray/.mypy_cache/CACHEDIR.TAG +3 -0
- pythonic_fp/circulararray/auto.py +197 -106
- pythonic_fp/circulararray/auto.pyi +3 -3
- pythonic_fp/circulararray/fixed.py +194 -110
- pythonic_fp/circulararray/fixed.pyi +5 -5
- {pythonic_fp_circulararray-6.1.0.dist-info → pythonic_fp_circulararray-6.2.0.dist-info}/METADATA +16 -30
- pythonic_fp_circulararray-6.2.0.dist-info/RECORD +145 -0
- pythonic_fp_circulararray-6.1.0.dist-info/RECORD +0 -11
- {pythonic_fp_circulararray-6.1.0.dist-info → pythonic_fp_circulararray-6.2.0.dist-info}/WHEEL +0 -0
- {pythonic_fp_circulararray-6.1.0.dist-info → pythonic_fp_circulararray-6.2.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
from collections.abc import Callable, Iterable, Iterator
|
|
16
|
-
from typing import
|
|
16
|
+
from typing import Final, cast, overload
|
|
17
|
+
|
|
17
18
|
from pythonic_fp.gadgets.sentinels.novalue import NoValue
|
|
18
19
|
|
|
19
20
|
__all__ = ['CAF', 'caf']
|
|
@@ -22,28 +23,33 @@ nada: Final[NoValue] = NoValue()
|
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
class CAF[X]:
|
|
25
|
-
|
|
26
26
|
"""
|
|
27
27
|
.. admonition:: Fixed storage capacity circular array CAF
|
|
28
28
|
|
|
29
29
|
- O(1) pops and pushes either end
|
|
30
30
|
- O(1) indexing, does not support slicing
|
|
31
31
|
- fixed total storage capacity
|
|
32
|
-
- iterable
|
|
32
|
+
- iterable (see __iter__ method below)
|
|
33
33
|
- comparisons compare identity before equality, like builtins
|
|
34
|
-
- in boolean context, falsy when either empty or full,
|
|
35
|
-
|
|
34
|
+
- in boolean context, falsy when either empty or full,
|
|
35
|
+
otherwise truthy
|
|
36
|
+
- function ``caf`` produces fixed capacity circular array
|
|
37
|
+
from arguments
|
|
36
38
|
|
|
37
39
|
"""
|
|
40
|
+
|
|
38
41
|
__slots__ = '_xs', '_cnt', '_cap', '_front', '_rear'
|
|
39
42
|
|
|
40
43
|
def __init__(self, *xs: Iterable[X], cap: int = 2) -> None:
|
|
41
44
|
"""
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
.. admonition:: initializer
|
|
46
|
+
|
|
47
|
+
Populate ``CAF`` with an optional iterable
|
|
48
|
+
from front (left) to rear (right).
|
|
49
|
+
|
|
50
|
+
:param xs: Takes an optional iterable parameter.
|
|
51
|
+
:raises ValueError: When more than one parameter is provided.
|
|
52
|
+
:raises TypeError: When passed a non-iterable parameter.
|
|
47
53
|
|
|
48
54
|
"""
|
|
49
55
|
cap = max(2, cap)
|
|
@@ -68,61 +74,48 @@ class CAF[X]:
|
|
|
68
74
|
self._rear = cnt - 1
|
|
69
75
|
|
|
70
76
|
def __bool__(self) -> bool:
|
|
77
|
+
"""
|
|
78
|
+
.. admonition:: bool
|
|
79
|
+
|
|
80
|
+
- falsy if either empty or full
|
|
81
|
+
- truthy otherwise
|
|
82
|
+
|
|
83
|
+
:returns: ``True`` when partially filled,
|
|
84
|
+
``False`` otherwise.
|
|
85
|
+
|
|
86
|
+
"""
|
|
71
87
|
return 0 < self._cnt < self._cap
|
|
72
88
|
|
|
73
89
|
def __len__(self) -> int:
|
|
90
|
+
"""
|
|
91
|
+
.. admonition:: length
|
|
92
|
+
|
|
93
|
+
Number of items in the ``CAF``.
|
|
94
|
+
|
|
95
|
+
:returns: The number of items in the ``CAF``.
|
|
96
|
+
|
|
97
|
+
"""
|
|
74
98
|
return self._cnt
|
|
75
99
|
|
|
76
|
-
def
|
|
100
|
+
def __iter__(self) -> Iterator[X]:
|
|
77
101
|
"""
|
|
78
|
-
.. admonition::
|
|
102
|
+
.. admonition:: iterate
|
|
79
103
|
|
|
80
|
-
|
|
104
|
+
Iterates circular array, left (front) to right (rear).
|
|
81
105
|
|
|
82
|
-
|
|
83
|
-
:returns: ``True`` if ``other`` is another ``CAF`` whose
|
|
84
|
-
contents compare as equal to the corresponding
|
|
85
|
-
contents of the ``CAF``, otherwise ``False``.
|
|
106
|
+
:yields: The ``CA`` contents front to rear.
|
|
86
107
|
|
|
87
|
-
|
|
88
|
-
if self is other:
|
|
89
|
-
return True
|
|
90
|
-
if not isinstance(other, type(self)):
|
|
91
|
-
return False
|
|
108
|
+
.. warning::
|
|
92
109
|
|
|
93
|
-
|
|
94
|
-
front1,
|
|
95
|
-
cnt1,
|
|
96
|
-
cap1,
|
|
97
|
-
front2,
|
|
98
|
-
cnt2,
|
|
99
|
-
cap2,
|
|
100
|
-
) = (
|
|
101
|
-
self._front,
|
|
102
|
-
self._cnt,
|
|
103
|
-
self._cap,
|
|
104
|
-
other._front,
|
|
105
|
-
other._cnt,
|
|
106
|
-
other._cap,
|
|
107
|
-
)
|
|
110
|
+
Not threadsafe, especially for long living iterators.
|
|
108
111
|
|
|
109
|
-
|
|
110
|
-
return False
|
|
112
|
+
.. tip::
|
|
111
113
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
is other._xs[(front2 + nn) % cap2]
|
|
116
|
-
):
|
|
117
|
-
continue
|
|
118
|
-
if (
|
|
119
|
-
self._xs[(front1 + nn) % cap1]
|
|
120
|
-
!= other._xs[(front2 + nn) % cap2]
|
|
121
|
-
):
|
|
122
|
-
return False
|
|
123
|
-
return True
|
|
114
|
+
Cache contents to make more thread tolerant. Put
|
|
115
|
+
a lock around circular array during caching process
|
|
116
|
+
to make threadsafe.
|
|
124
117
|
|
|
125
|
-
|
|
118
|
+
"""
|
|
126
119
|
if self._cnt > 0:
|
|
127
120
|
(
|
|
128
121
|
cap,
|
|
@@ -142,6 +135,24 @@ class CAF[X]:
|
|
|
142
135
|
yield cast(X, current_state[position])
|
|
143
136
|
|
|
144
137
|
def __reversed__(self) -> Iterator[X]:
|
|
138
|
+
"""
|
|
139
|
+
.. admonition:: reverse iterate
|
|
140
|
+
|
|
141
|
+
Iterates circular array, right (rear) to left (front).
|
|
142
|
+
|
|
143
|
+
:yields: The ``CAF`` contents rear to front.
|
|
144
|
+
|
|
145
|
+
.. warning
|
|
146
|
+
|
|
147
|
+
Not thread safe, especially for long living iterators.
|
|
148
|
+
|
|
149
|
+
.. tip::
|
|
150
|
+
|
|
151
|
+
Cache contents to make more thread tolerant. Put
|
|
152
|
+
a lock around circular array during caching process
|
|
153
|
+
to make threadsafe.
|
|
154
|
+
|
|
155
|
+
"""
|
|
145
156
|
if self._cnt > 0:
|
|
146
157
|
(
|
|
147
158
|
cap,
|
|
@@ -160,7 +171,57 @@ class CAF[X]:
|
|
|
160
171
|
position = (position - 1) % cap
|
|
161
172
|
yield cast(X, current_state[position])
|
|
162
173
|
|
|
174
|
+
def __eq__(self, other: object) -> bool:
|
|
175
|
+
"""
|
|
176
|
+
.. admonition:: equality comparison
|
|
177
|
+
|
|
178
|
+
Efficiently compare ``CAF`` to another object.
|
|
179
|
+
|
|
180
|
+
:param other: The object to be compared.
|
|
181
|
+
:returns: ``True`` if ``other`` is another ``CAF`` whose
|
|
182
|
+
contents compare as equal to the corresponding
|
|
183
|
+
contents of the ``CAF``, otherwise ``False``.
|
|
184
|
+
|
|
185
|
+
"""
|
|
186
|
+
if self is other:
|
|
187
|
+
return True
|
|
188
|
+
if not isinstance(other, type(self)):
|
|
189
|
+
return False
|
|
190
|
+
|
|
191
|
+
(
|
|
192
|
+
front1,
|
|
193
|
+
cnt1,
|
|
194
|
+
cap1,
|
|
195
|
+
front2,
|
|
196
|
+
cnt2,
|
|
197
|
+
cap2,
|
|
198
|
+
) = (
|
|
199
|
+
self._front,
|
|
200
|
+
self._cnt,
|
|
201
|
+
self._cap,
|
|
202
|
+
other._front,
|
|
203
|
+
other._cnt,
|
|
204
|
+
other._cap,
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
if cnt1 != cnt2:
|
|
208
|
+
return False
|
|
209
|
+
|
|
210
|
+
for nn in range(cnt1):
|
|
211
|
+
if self._xs[(front1 + nn) % cap1] is other._xs[(front2 + nn) % cap2]:
|
|
212
|
+
continue
|
|
213
|
+
if self._xs[(front1 + nn) % cap1] != other._xs[(front2 + nn) % cap2]:
|
|
214
|
+
return False
|
|
215
|
+
return True
|
|
216
|
+
|
|
163
217
|
def __getitem__(self, idx: int) -> X:
|
|
218
|
+
"""
|
|
219
|
+
.. admonition:: getitem
|
|
220
|
+
|
|
221
|
+
Fixed capacity circular arrays are indexable but
|
|
222
|
+
not sliceable.
|
|
223
|
+
|
|
224
|
+
"""
|
|
164
225
|
cnt = self._cnt
|
|
165
226
|
if 0 <= idx < cnt:
|
|
166
227
|
return cast(X, self._xs[(self._front + idx) % self._cap])
|
|
@@ -178,6 +239,13 @@ class CAF[X]:
|
|
|
178
239
|
raise IndexError(msg1 + msg2 + msg3)
|
|
179
240
|
|
|
180
241
|
def __setitem__(self, idx: int, val: X) -> None:
|
|
242
|
+
"""
|
|
243
|
+
.. admonition:: setitem
|
|
244
|
+
|
|
245
|
+
Fixed capacity circular arrays are indexable but
|
|
246
|
+
not sliceable.
|
|
247
|
+
|
|
248
|
+
"""
|
|
181
249
|
cnt = self._cnt
|
|
182
250
|
if 0 <= idx < cnt:
|
|
183
251
|
self._xs[(self._front + idx) % self._cap] = val
|
|
@@ -193,9 +261,16 @@ class CAF[X]:
|
|
|
193
261
|
raise IndexError(msg1 + msg2 + msg3)
|
|
194
262
|
|
|
195
263
|
def __delitem__(self, idx: int) -> None:
|
|
264
|
+
"""
|
|
265
|
+
.. admonition:: delitem
|
|
266
|
+
|
|
267
|
+
Fixed capacity circular arrays are indexable but
|
|
268
|
+
not sliceable.
|
|
269
|
+
|
|
270
|
+
"""
|
|
196
271
|
item_list = list(self)
|
|
197
272
|
del item_list[idx]
|
|
198
|
-
_ca = CAF(item_list, cap
|
|
273
|
+
_ca = CAF(item_list, cap=self._cap)
|
|
199
274
|
(
|
|
200
275
|
self._xs,
|
|
201
276
|
self._cnt,
|
|
@@ -211,38 +286,37 @@ class CAF[X]:
|
|
|
211
286
|
|
|
212
287
|
def __repr__(self) -> str:
|
|
213
288
|
"""
|
|
214
|
-
.. admonition::
|
|
289
|
+
.. admonition:: repr string
|
|
215
290
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
contents and "repr(xi)" is the repr-string for xi.
|
|
291
|
+
Construct string 'CAF(x₁, x₂, … xₙ)' where
|
|
292
|
+
x₁, x₂, … xₙ are the contents displayed with ``repr()``.
|
|
219
293
|
|
|
220
|
-
|
|
294
|
+
:returns: A string to reproduce the ``CAF``.
|
|
221
295
|
|
|
222
296
|
"""
|
|
223
297
|
return 'caf(' + ', '.join(map(repr, self)) + ')'
|
|
224
298
|
|
|
225
299
|
def __str__(self) -> str:
|
|
226
300
|
r"""
|
|
227
|
-
.. admonition::
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
where x1, x2, ..., xn are the circular array's
|
|
231
|
-
contents displayed as strings.
|
|
301
|
+
.. admonition:: user string
|
|
302
|
+
Construct string '(\|x₁, x₂, … xₙ\|)' where
|
|
303
|
+
x₁, x₂, ..., xₙ are the contents displayed with ``str()``.
|
|
232
304
|
|
|
233
|
-
|
|
305
|
+
:returns: A string meaningful to an end user.
|
|
234
306
|
|
|
235
307
|
"""
|
|
236
308
|
return '(|' + ', '.join(map(str, self)) + '|)'
|
|
237
309
|
|
|
238
310
|
def pushl(self, x: X) -> None:
|
|
239
311
|
"""
|
|
240
|
-
.. admonition::
|
|
312
|
+
.. admonition:: push left
|
|
241
313
|
|
|
242
314
|
Push single item from the left onto the ``CAF``.
|
|
243
315
|
|
|
244
|
-
|
|
245
|
-
|
|
316
|
+
:param x: Single item to be pushed onto the front of
|
|
317
|
+
the ``CAF`` from the left.
|
|
318
|
+
:raises ValueError: When called on a full fixed storage
|
|
319
|
+
capacity circular array.
|
|
246
320
|
|
|
247
321
|
"""
|
|
248
322
|
if self._cnt == self._cap:
|
|
@@ -261,12 +335,14 @@ class CAF[X]:
|
|
|
261
335
|
|
|
262
336
|
def pushr(self, x: X) -> None:
|
|
263
337
|
"""
|
|
264
|
-
.. admonition::
|
|
338
|
+
.. admonition:: push right
|
|
265
339
|
|
|
266
340
|
Push single item from the right onto the ``CAF``.
|
|
267
341
|
|
|
268
|
-
|
|
269
|
-
|
|
342
|
+
:param x: Single item to be pushed onto the rear of
|
|
343
|
+
the ``CAF`` from the right.
|
|
344
|
+
:raises ValueError: When called on a full fixed
|
|
345
|
+
storage capacity circular array.
|
|
270
346
|
|
|
271
347
|
"""
|
|
272
348
|
if self._cnt == self._cap:
|
|
@@ -285,12 +361,12 @@ class CAF[X]:
|
|
|
285
361
|
|
|
286
362
|
def popl(self) -> X:
|
|
287
363
|
"""
|
|
288
|
-
.. admonition::
|
|
364
|
+
.. admonition:: pop left
|
|
289
365
|
|
|
290
366
|
Pop a single items off the left side of the ``CAF``.
|
|
291
367
|
|
|
292
|
-
|
|
293
|
-
|
|
368
|
+
:returns: Item popped from left side (front) of the ``CAF``.
|
|
369
|
+
:raises ValueError: When called on an empty ``CAF``.
|
|
294
370
|
|
|
295
371
|
"""
|
|
296
372
|
if self._cnt > 1:
|
|
@@ -326,12 +402,12 @@ class CAF[X]:
|
|
|
326
402
|
|
|
327
403
|
def popr(self) -> X:
|
|
328
404
|
"""
|
|
329
|
-
.. admonition::
|
|
405
|
+
.. admonition:: pop right
|
|
330
406
|
|
|
331
407
|
Pop a single items off the right side of the ``CAF``.
|
|
332
408
|
|
|
333
|
-
|
|
334
|
-
|
|
409
|
+
:returns: Item popped from right side (rear) of the ``CAF``.
|
|
410
|
+
:raises ValueError: When called on an empty ``CAF``.
|
|
335
411
|
|
|
336
412
|
"""
|
|
337
413
|
if self._cnt > 1:
|
|
@@ -367,14 +443,14 @@ class CAF[X]:
|
|
|
367
443
|
|
|
368
444
|
def popld(self, default: X) -> X:
|
|
369
445
|
"""
|
|
370
|
-
.. admonition::
|
|
446
|
+
.. admonition:: pop Left with default
|
|
371
447
|
|
|
372
448
|
Pop a single items off the left side of the ``CAF``.
|
|
373
449
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
450
|
+
:param default: Default value to return if ``CAF`` is empty.
|
|
451
|
+
:returns: Item popped from left side (front) of the ``CAF``
|
|
452
|
+
if not empty, otherwise return the provided
|
|
453
|
+
default value.
|
|
378
454
|
|
|
379
455
|
"""
|
|
380
456
|
try:
|
|
@@ -384,14 +460,14 @@ class CAF[X]:
|
|
|
384
460
|
|
|
385
461
|
def poprd(self, default: X) -> X:
|
|
386
462
|
"""
|
|
387
|
-
.. admonition::
|
|
463
|
+
.. admonition:: pop Right with default
|
|
388
464
|
|
|
389
465
|
Pop a single items off the right side of the ``CAF``.
|
|
390
466
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
467
|
+
:param default: Default value to return if ``CAF`` is empty.
|
|
468
|
+
:returns: Item popped from right side (rear) of the ``CAF``
|
|
469
|
+
if not empty, otherwise return the provided
|
|
470
|
+
default value.
|
|
395
471
|
|
|
396
472
|
"""
|
|
397
473
|
try:
|
|
@@ -405,8 +481,9 @@ class CAF[X]:
|
|
|
405
481
|
|
|
406
482
|
Pop items off the left side of the ``CAF``.
|
|
407
483
|
|
|
408
|
-
|
|
409
|
-
|
|
484
|
+
:param maximum: Maximum number of items to pop,
|
|
485
|
+
may pop less if not enough items in ``CAF``.
|
|
486
|
+
:returns: A ``tuple`` of the items popped, left to right.
|
|
410
487
|
|
|
411
488
|
"""
|
|
412
489
|
xs: list[X] = []
|
|
@@ -427,8 +504,9 @@ class CAF[X]:
|
|
|
427
504
|
|
|
428
505
|
Pop items off the right side of the ``CAF``.
|
|
429
506
|
|
|
430
|
-
|
|
431
|
-
|
|
507
|
+
:param maximum: Maximum number of items to pop,
|
|
508
|
+
may pop less if not enough items in ``CAF``.
|
|
509
|
+
:returns: A ``tuple`` of the items popped, right to left.
|
|
432
510
|
|
|
433
511
|
"""
|
|
434
512
|
xs: list[X] = []
|
|
@@ -448,7 +526,8 @@ class CAF[X]:
|
|
|
448
526
|
Rotate contents of ``CAF`` to the left putting first
|
|
449
527
|
item onto rear.
|
|
450
528
|
|
|
451
|
-
|
|
529
|
+
:param n: Number of times to shift items left.
|
|
530
|
+
Default 1 time.
|
|
452
531
|
|
|
453
532
|
"""
|
|
454
533
|
if self._cnt < 2:
|
|
@@ -463,7 +542,8 @@ class CAF[X]:
|
|
|
463
542
|
Rotate contents of ``CAF`` to the right putting last
|
|
464
543
|
item onto front.
|
|
465
544
|
|
|
466
|
-
|
|
545
|
+
:param n: Number of times to shift items right.
|
|
546
|
+
Default 1 time.
|
|
467
547
|
|
|
468
548
|
"""
|
|
469
549
|
if self._cnt < 2:
|
|
@@ -477,11 +557,11 @@ class CAF[X]:
|
|
|
477
557
|
|
|
478
558
|
Apply function ``f`` over the circular array's contents.
|
|
479
559
|
|
|
480
|
-
|
|
481
|
-
|
|
560
|
+
:param f: Callable from type ``X`` to type ``Y``.
|
|
561
|
+
:returns: New fixed capacity circular array instance.
|
|
482
562
|
|
|
483
563
|
"""
|
|
484
|
-
return CAF(map(f, self), cap
|
|
564
|
+
return CAF(map(f, self), cap=self._cap)
|
|
485
565
|
|
|
486
566
|
@overload
|
|
487
567
|
def foldl[L](self, f: Callable[[X, X], X]) -> X: ...
|
|
@@ -494,10 +574,12 @@ class CAF[X]:
|
|
|
494
574
|
|
|
495
575
|
Fold ``CAF`` left with a function and optional starting item.
|
|
496
576
|
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
577
|
+
:param f: Folding function, first argument to ``f`` is for
|
|
578
|
+
the accumulator.
|
|
579
|
+
:param start: Optional starting item.
|
|
580
|
+
:returns: Reduced value produced by the left fold.
|
|
581
|
+
:raises ValueError: When circular array empty and ``start``
|
|
582
|
+
not given.
|
|
501
583
|
|
|
502
584
|
"""
|
|
503
585
|
if self._cnt == 0:
|
|
@@ -528,10 +610,12 @@ class CAF[X]:
|
|
|
528
610
|
|
|
529
611
|
Fold ``CAF`` right left with a function and optional starting item.
|
|
530
612
|
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
613
|
+
:param f: Folding function, second argument to ``f`` is for
|
|
614
|
+
the accumulator.
|
|
615
|
+
:param start: Optional starting item.
|
|
616
|
+
:returns: Reduced value produced by the right fold.
|
|
617
|
+
:raises ValueError: When circular array empty and ``start``
|
|
618
|
+
not given.
|
|
535
619
|
|
|
536
620
|
"""
|
|
537
621
|
if self._cnt == 0:
|
|
@@ -557,8 +641,7 @@ class CAF[X]:
|
|
|
557
641
|
|
|
558
642
|
Get the fixed storage capacity of the circular array.
|
|
559
643
|
|
|
560
|
-
|
|
561
|
-
:returns: Fixed storage capacity.
|
|
644
|
+
:returns: Fixed storage capacity.
|
|
562
645
|
|
|
563
646
|
"""
|
|
564
647
|
return self._cap
|
|
@@ -588,7 +671,7 @@ class CAF[X]:
|
|
|
588
671
|
|
|
589
672
|
Find fraction of the storage capacity which is filled.
|
|
590
673
|
|
|
591
|
-
|
|
674
|
+
:returns: The ratio count/capacity.
|
|
592
675
|
|
|
593
676
|
"""
|
|
594
677
|
return self._cnt / self._cap
|
|
@@ -598,11 +681,12 @@ def caf[T](*ts: T, cap: int = 2) -> CAF[T]:
|
|
|
598
681
|
"""
|
|
599
682
|
.. admonition:: Circular array factory function
|
|
600
683
|
|
|
601
|
-
Produce a circular array from
|
|
684
|
+
Produce a fixed capacity circular array from
|
|
685
|
+
a variable number of arguments.
|
|
602
686
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
687
|
+
:param ts: Initial items for a new fixed capacity circular array.
|
|
688
|
+
:param cap: The minimum storage capacity to set.
|
|
689
|
+
:returns: New fixed storage capacity circular array.
|
|
606
690
|
|
|
607
691
|
"""
|
|
608
692
|
return CAF(ts, cap=cap)
|
|
@@ -5,16 +5,16 @@ __all__ = ['CAF', 'caf']
|
|
|
5
5
|
|
|
6
6
|
class CAF[X]:
|
|
7
7
|
def __init__(self, *xs: Iterable[X], cap: int = 2) -> None: ...
|
|
8
|
-
def __iter__(self) -> Iterator[X]: ...
|
|
9
|
-
def __reversed__(self) -> Iterator[X]: ...
|
|
10
8
|
def __bool__(self) -> bool: ...
|
|
11
9
|
def __len__(self) -> int: ...
|
|
10
|
+
def __iter__(self) -> Iterator[X]: ...
|
|
11
|
+
def __reversed__(self) -> Iterator[X]: ...
|
|
12
|
+
def __eq__(self, other: object) -> bool: ...
|
|
12
13
|
def __getitem__(self, idx: int) -> X: ...
|
|
13
14
|
def __setitem__(self, idx: int, val: X) -> None: ...
|
|
14
15
|
def __delitem__(self, idx: int) -> None: ...
|
|
15
|
-
def
|
|
16
|
-
def
|
|
17
|
-
def pushr(self, item: X) -> None: ...
|
|
16
|
+
def pushl(self, x: X) -> None: ...
|
|
17
|
+
def pushr(self, x: X) -> None: ...
|
|
18
18
|
def popl(self) -> X: ...
|
|
19
19
|
def popr(self) -> X: ...
|
|
20
20
|
def popld(self, default: X) -> X: ...
|
{pythonic_fp_circulararray-6.1.0.dist-info → pythonic_fp_circulararray-6.2.0.dist-info}/METADATA
RENAMED
|
@@ -1,38 +1,39 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pythonic-fp-circulararray
|
|
3
|
-
Version: 6.
|
|
4
|
-
Summary: Circular
|
|
3
|
+
Version: 6.2.0
|
|
4
|
+
Summary: Circular array datastructures.
|
|
5
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.
|
|
8
|
-
Description-Content-Type: text/
|
|
7
|
+
Requires-Python: >=3.14
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
9
|
Classifier: Development Status :: 5 - Production/Stable
|
|
10
10
|
Classifier: Framework :: Pytest
|
|
11
11
|
Classifier: Intended Audience :: Developers
|
|
12
12
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
13
13
|
Classifier: Operating System :: OS Independent
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.14
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
15
16
|
Classifier: Typing :: Typed
|
|
16
17
|
License-File: LICENSE
|
|
17
18
|
Requires-Dist: pythonic-fp-gadgets>=4.0.2
|
|
18
|
-
|
|
19
|
-
Project-URL:
|
|
20
|
-
Project-URL: Documentation, https://grscheller.github.io/pythonic-fp/projects/circulararray.html
|
|
19
|
+
Project-URL: Changelog, https://github.com/grscheller/pythonic-fp-circulararray/blob/main/CHANGELOG.md
|
|
20
|
+
Project-URL: Documentation, https://grscheller.github.io/pythonic-fp-circulararray/release/html/
|
|
21
21
|
Project-URL: Homepage, https://grscheller.github.io/pythonic-fp/
|
|
22
22
|
Project-URL: Source, https://github.com/grscheller/pythonic-fp-circulararray
|
|
23
|
-
Provides-Extra: test
|
|
24
23
|
|
|
25
|
-
Pythonic FP - Circular Array
|
|
26
|
-
|
|
24
|
+
# Pythonic FP - Circular Array
|
|
25
|
+
|
|
26
|
+
Stateful circular array data structures.
|
|
27
27
|
|
|
28
28
|
PyPI project
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
[pythonic-fp-circulararray](https://pypi.org/project/pythonic-fp-circulararray).
|
|
30
|
+
Part of the
|
|
31
|
+
[pythonic-fp](https://grscheller.github.io/pythonic-fp/)
|
|
32
|
+
PyPI projects.
|
|
31
33
|
|
|
32
|
-
|
|
34
|
+
## Description
|
|
33
35
|
|
|
34
36
|
- variable storage capacity circular array
|
|
35
|
-
|
|
36
37
|
- O(1) pops either end
|
|
37
38
|
- O(1) amortized pushes either end
|
|
38
39
|
- O(1) indexing, fully supports slicing
|
|
@@ -41,9 +42,7 @@ Python module implementing stateful circular array data structures.
|
|
|
41
42
|
- comparisons compare identity before equality, like builtins
|
|
42
43
|
- in boolean context, falsy when empty, otherwise truthy
|
|
43
44
|
- function ``ca`` produces auto-resizing circular array from arguments
|
|
44
|
-
|
|
45
45
|
- fixed storage capacity circular array
|
|
46
|
-
|
|
47
46
|
- O(1) pops and pushes either end
|
|
48
47
|
- O(1) indexing, does not support slicing
|
|
49
48
|
- fixed total storage capacity
|
|
@@ -52,20 +51,7 @@ Python module implementing stateful circular array data structures.
|
|
|
52
51
|
- in boolean context, falsy when either empty or full, otherwise truthy
|
|
53
52
|
- function ``caf`` produces fixed capacity circular array from arguments
|
|
54
53
|
|
|
55
|
-
|
|
56
|
-
`pythonic-fp
|
|
57
|
-
<https://grscheller.github.io/pythonic-fp/>`_
|
|
58
|
-
PyPI projects.
|
|
59
|
-
|
|
60
|
-
Documentation
|
|
61
|
-
-------------
|
|
62
|
-
|
|
63
|
-
Documentation and other links for this project are hosted on
|
|
64
|
-
`GitHub Pages
|
|
65
|
-
<https://grscheller.github.io/pythonic-fp/projects/circulararray.html>`_.
|
|
66
|
-
|
|
67
|
-
Copyright and License
|
|
68
|
-
---------------------
|
|
54
|
+
## Copyright and License
|
|
69
55
|
|
|
70
56
|
Copyright (c) 2023-2026 Geoffrey R. Scheller. Licensed under the Apache
|
|
71
57
|
License, Version 2.0. See the LICENSE file for details.
|