pythonic-fp-queues 5.1.1__py3-none-any.whl → 5.1.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/queues/__init__.py +6 -14
- pythonic_fp/queues/de.py +103 -36
- pythonic_fp/queues/fifo.py +76 -28
- pythonic_fp/queues/lifo.py +65 -25
- {pythonic_fp_queues-5.1.1.dist-info → pythonic_fp_queues-5.1.2.dist-info}/METADATA +15 -11
- pythonic_fp_queues-5.1.2.dist-info/RECORD +13 -0
- pythonic_fp_queues-5.1.1.dist-info/RECORD +0 -13
- {pythonic_fp_queues-5.1.1.dist-info → pythonic_fp_queues-5.1.2.dist-info}/WHEEL +0 -0
- {pythonic_fp_queues-5.1.1.dist-info → pythonic_fp_queues-5.1.2.dist-info}/licenses/LICENSE +0 -0
pythonic_fp/queues/__init__.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2023-
|
|
1
|
+
# Copyright 2023-2026 Geoffrey R. Scheller
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -16,21 +16,13 @@
|
|
|
16
16
|
Queues
|
|
17
17
|
------
|
|
18
18
|
|
|
19
|
-
.. admonition:: Stateful Queues
|
|
19
|
+
.. admonition:: Stateful Queues
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
empowers you to do, but what it prevents you from doing to yourself.
|
|
21
|
+
By limiting how their data can be accessed, each queue type
|
|
22
|
+
supports different algorithmic use cases.
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
+=========================+===========+==========================+
|
|
28
|
-
| pythonic_fp.queues.fifo | FIFOQueue | First-In-First-Out Queue |
|
|
29
|
-
+-------------------------+-----------+--------------------------+
|
|
30
|
-
| pythonic_fp.queues.lifo | LIFOQueue | Last-In-First-Out Queue |
|
|
31
|
-
+-------------------------+-----------+--------------------------+
|
|
32
|
-
| pythonic_fp.queues.de | DEQueue | Double-Ended Queue |
|
|
33
|
-
+-------------------------+-----------+--------------------------+
|
|
24
|
+
Sometimes the power of a data structure comes not what it empowers
|
|
25
|
+
you to do, but what it prevents you from doing to yourself.
|
|
34
26
|
|
|
35
27
|
"""
|
|
36
28
|
|
pythonic_fp/queues/de.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2023-
|
|
1
|
+
# Copyright 2023-2026 Geoffrey R. Scheller
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -21,14 +21,18 @@ __all__ = ['DEQueue', 'de_queue']
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
class DEQueue[D]:
|
|
24
|
-
"""
|
|
24
|
+
"""
|
|
25
|
+
.. admonition:: DEQueue
|
|
26
|
+
|
|
27
|
+
Stateful Double-Ended (DE) Queue data structure.
|
|
25
28
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
- has a left and a right side
|
|
30
|
+
- O(1) pops each end
|
|
31
|
+
- O(1) amortized pushes each end
|
|
32
|
+
- O(1) length determination
|
|
33
|
+
- in a Boolean context, truthy if not empty, falsy if empty
|
|
34
|
+
- will automatically increase storage capacity when needed
|
|
35
|
+
- neither indexable nor sliceable by design
|
|
32
36
|
|
|
33
37
|
"""
|
|
34
38
|
|
|
@@ -36,9 +40,10 @@ class DEQueue[D]:
|
|
|
36
40
|
|
|
37
41
|
def __init__(self, *dss: Iterable[D]) -> None:
|
|
38
42
|
"""
|
|
39
|
-
:param dss:
|
|
40
|
-
|
|
41
|
-
:raises
|
|
43
|
+
:param dss: Takes 0 or 1 iterable parameters. Populates
|
|
44
|
+
queue from the iterable left to right.
|
|
45
|
+
:raises TypeError: When passed a non-iterable parameter.
|
|
46
|
+
:raises ValueError: When more than one parameter is given.
|
|
42
47
|
|
|
43
48
|
"""
|
|
44
49
|
if (size := len(dss)) > 1:
|
|
@@ -47,6 +52,12 @@ class DEQueue[D]:
|
|
|
47
52
|
self._ca = CA(dss[0]) if size == 1 else CA()
|
|
48
53
|
|
|
49
54
|
def __bool__(self) -> bool:
|
|
55
|
+
"""
|
|
56
|
+
.. admonition:: Truthiness
|
|
57
|
+
|
|
58
|
+
Queue truthy when non-empty, falsy when empty.
|
|
59
|
+
|
|
60
|
+
"""
|
|
50
61
|
return len(self._ca) > 0
|
|
51
62
|
|
|
52
63
|
def __len__(self) -> int:
|
|
@@ -58,9 +69,25 @@ class DEQueue[D]:
|
|
|
58
69
|
return self._ca == other._ca
|
|
59
70
|
|
|
60
71
|
def __iter__(self) -> Iterator[D]:
|
|
72
|
+
"""
|
|
73
|
+
.. admonition:: Iteration
|
|
74
|
+
|
|
75
|
+
Iterate over current state left to right.
|
|
76
|
+
|
|
77
|
+
:returns: An iterator of the data.
|
|
78
|
+
|
|
79
|
+
"""
|
|
61
80
|
return iter(list(self._ca))
|
|
62
81
|
|
|
63
82
|
def __reversed__(self) -> Iterator[D]:
|
|
83
|
+
"""
|
|
84
|
+
.. admonition:: Iteration
|
|
85
|
+
|
|
86
|
+
Iterate over current state right to left.
|
|
87
|
+
|
|
88
|
+
:returns: An iterator of the data.
|
|
89
|
+
|
|
90
|
+
"""
|
|
64
91
|
return reversed(list(self._ca))
|
|
65
92
|
|
|
66
93
|
def __repr__(self) -> str:
|
|
@@ -72,33 +99,46 @@ class DEQueue[D]:
|
|
|
72
99
|
return '>< ' + ' | '.join(map(str, self)) + ' ><'
|
|
73
100
|
|
|
74
101
|
def copy(self) -> 'DEQueue[D]':
|
|
75
|
-
"""
|
|
102
|
+
"""
|
|
103
|
+
.. admonition:: Shallow copy
|
|
76
104
|
|
|
77
|
-
|
|
105
|
+
Make a shallow copy of the queue.
|
|
106
|
+
|
|
107
|
+
:returns: Shallow copy of the ``DEQueue``.
|
|
78
108
|
|
|
79
109
|
"""
|
|
80
110
|
return DEQueue(self._ca)
|
|
81
111
|
|
|
82
112
|
def pushl(self, *ds: D) -> None:
|
|
83
|
-
"""
|
|
113
|
+
"""
|
|
114
|
+
.. admonition:: Push left
|
|
84
115
|
|
|
85
|
-
|
|
116
|
+
Push data onto left side of ``DEQueue``.
|
|
117
|
+
|
|
118
|
+
:param ds: Data to be pushed onto ``DEQueue`` from the left.
|
|
86
119
|
|
|
87
120
|
"""
|
|
88
121
|
self._ca.pushl(*ds)
|
|
89
122
|
|
|
90
123
|
def pushr(self, *ds: D) -> None:
|
|
91
|
-
"""
|
|
124
|
+
"""
|
|
125
|
+
.. admonition:: Push right
|
|
126
|
+
|
|
127
|
+
Push data onto right side of ``DEQueue``.
|
|
92
128
|
|
|
93
|
-
:param ds:
|
|
129
|
+
:param ds: Data to be pushed onto ``DEQueue`` from the right.
|
|
94
130
|
|
|
95
131
|
"""
|
|
96
132
|
self._ca.pushr(*ds)
|
|
97
133
|
|
|
98
134
|
def popl(self) -> MayBe[D]:
|
|
99
|
-
"""
|
|
135
|
+
"""
|
|
136
|
+
.. admonition:: Pop left
|
|
137
|
+
|
|
138
|
+
Pop next item from left side ``DEQueue``, if it exists.
|
|
100
139
|
|
|
101
|
-
:returns: MayBe of popped item if queue was not empty,
|
|
140
|
+
:returns: ``MayBe`` of popped item if queue was not empty,
|
|
141
|
+
empty ``MayBe`` otherwise.
|
|
102
142
|
|
|
103
143
|
"""
|
|
104
144
|
if self._ca:
|
|
@@ -106,9 +146,13 @@ class DEQueue[D]:
|
|
|
106
146
|
return MayBe()
|
|
107
147
|
|
|
108
148
|
def popr(self) -> MayBe[D]:
|
|
109
|
-
"""
|
|
149
|
+
"""
|
|
150
|
+
.. admonition:: Pop right
|
|
151
|
+
|
|
152
|
+
Pop next item off right side ''DEQueue``, if it exists.
|
|
110
153
|
|
|
111
|
-
:returns: MayBe of popped item if queue was not empty,
|
|
154
|
+
:returns: ``MayBe`` of popped item if queue was not empty,
|
|
155
|
+
empty ``MayBe`` otherwise.
|
|
112
156
|
|
|
113
157
|
"""
|
|
114
158
|
if self._ca:
|
|
@@ -116,9 +160,13 @@ class DEQueue[D]:
|
|
|
116
160
|
return MayBe()
|
|
117
161
|
|
|
118
162
|
def peakl(self) -> MayBe[D]:
|
|
119
|
-
"""
|
|
163
|
+
"""
|
|
164
|
+
.. admonition:: Peak left
|
|
120
165
|
|
|
121
|
-
|
|
166
|
+
Peak left side of ``DEQueue``. Does not consume item.
|
|
167
|
+
|
|
168
|
+
:returns: ``MayBe`` of leftmost item if queue not empty,
|
|
169
|
+
empty ``MayBe`` otherwise.
|
|
122
170
|
|
|
123
171
|
"""
|
|
124
172
|
if self._ca:
|
|
@@ -126,9 +174,13 @@ class DEQueue[D]:
|
|
|
126
174
|
return MayBe()
|
|
127
175
|
|
|
128
176
|
def peakr(self) -> MayBe[D]:
|
|
129
|
-
"""
|
|
177
|
+
"""
|
|
178
|
+
.. admonition:: Peak right
|
|
130
179
|
|
|
131
|
-
|
|
180
|
+
Peak right side of ``DEQueue``. Does not consume item.
|
|
181
|
+
|
|
182
|
+
:returns: ``MayBe`` of rightmost item if queue not empty,
|
|
183
|
+
empty ``MayBe`` otherwise.
|
|
132
184
|
|
|
133
185
|
"""
|
|
134
186
|
if self._ca:
|
|
@@ -141,11 +193,15 @@ class DEQueue[D]:
|
|
|
141
193
|
def foldl[L](self, f: Callable[[L, D], L], start: L) -> MayBe[L]: ...
|
|
142
194
|
|
|
143
195
|
def foldl[L](self, f: Callable[[L, D], L], start: L | None = None) -> MayBe[L]:
|
|
144
|
-
"""
|
|
196
|
+
"""
|
|
197
|
+
.. admonition:: Fold left
|
|
198
|
+
|
|
199
|
+
Reduce ``DEQueue`` left to right.
|
|
145
200
|
|
|
146
201
|
:param f: Reducing function, first argument is for accumulator.
|
|
147
202
|
:param start: Optional starting value.
|
|
148
|
-
:returns: MayBe of reduced value with f, empty MayBe if
|
|
203
|
+
:returns: ``MayBe`` of reduced value with f, empty ``MayBe`` if
|
|
204
|
+
queue empty and no starting value given.
|
|
149
205
|
|
|
150
206
|
"""
|
|
151
207
|
if start is None:
|
|
@@ -160,11 +216,15 @@ class DEQueue[D]:
|
|
|
160
216
|
def foldr[R](self, f: Callable[[D, R], R], start: R) -> MayBe[R]: ...
|
|
161
217
|
|
|
162
218
|
def foldr[R](self, f: Callable[[D, R], R], start: R | None = None) -> MayBe[R]:
|
|
163
|
-
"""
|
|
219
|
+
"""
|
|
220
|
+
.. admonition:: Fold right
|
|
221
|
+
|
|
222
|
+
Reduce ``DEQueue`` right to left.
|
|
164
223
|
|
|
165
224
|
:param f: Reducing function, second argument is for accumulator.
|
|
166
225
|
:param start: Optional starting value.
|
|
167
|
-
:returns: MayBe of reduced value with f, empty MayBe if
|
|
226
|
+
:returns: ``MayBe`` of reduced value with f, empty ``MayBe`` if
|
|
227
|
+
queue empty and no starting value given.
|
|
168
228
|
|
|
169
229
|
"""
|
|
170
230
|
if start is None:
|
|
@@ -174,24 +234,31 @@ class DEQueue[D]:
|
|
|
174
234
|
return MayBe(self._ca.foldr(f, start))
|
|
175
235
|
|
|
176
236
|
def map[U](self, f: Callable[[D], U]) -> 'DEQueue[U]':
|
|
177
|
-
"""
|
|
237
|
+
"""
|
|
238
|
+
.. admonition:: Map
|
|
239
|
+
|
|
240
|
+
Map left to right.
|
|
178
241
|
|
|
179
|
-
|
|
242
|
+
.. tip::
|
|
180
243
|
|
|
181
|
-
|
|
244
|
+
Order map done does not matter if ``f`` is pure.
|
|
182
245
|
|
|
183
246
|
:param f: Function to map over queue.
|
|
184
|
-
:returns: New DEQueue instance, retain original order.
|
|
247
|
+
:returns: New ``DEQueue`` instance, retain original order.
|
|
185
248
|
|
|
186
249
|
"""
|
|
187
250
|
return DEQueue(map(f, self._ca))
|
|
188
251
|
|
|
189
252
|
|
|
190
253
|
def de_queue[D](*ds: D) -> DEQueue[D]:
|
|
191
|
-
"""
|
|
254
|
+
"""
|
|
255
|
+
.. admonition:: Create DEQueue
|
|
256
|
+
|
|
257
|
+
Factory function to create a ``DEQueue``
|
|
258
|
+
instance from the function's arguments.
|
|
192
259
|
|
|
193
|
-
:param ds: Initial
|
|
194
|
-
:returns:
|
|
260
|
+
:param ds: Initial data to be pushed on right to left.
|
|
261
|
+
:returns: A new ``DEQueue`` instance.
|
|
195
262
|
|
|
196
263
|
"""
|
|
197
264
|
return DEQueue(ds)
|
pythonic_fp/queues/fifo.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2023-
|
|
1
|
+
# Copyright 2023-2026 Geoffrey R. Scheller
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -21,14 +21,17 @@ __all__ = ['FIFOQueue', 'fifo_queue']
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
class FIFOQueue[D]:
|
|
24
|
-
"""
|
|
24
|
+
"""
|
|
25
|
+
.. admonition:: FIFOQueue
|
|
26
|
+
|
|
27
|
+
Stateful First-In-First-Out (FIFO) Queue data structure.
|
|
25
28
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
- O(1) pops
|
|
30
|
+
- O(1) amortized pushes
|
|
31
|
+
- O(1) length determination
|
|
32
|
+
- in a Boolean context, truthy if not empty, falsy if empty
|
|
33
|
+
- will automatically increase storage capacity when needed
|
|
34
|
+
- neither indexable nor sliceable by design
|
|
32
35
|
|
|
33
36
|
"""
|
|
34
37
|
|
|
@@ -36,8 +39,10 @@ class FIFOQueue[D]:
|
|
|
36
39
|
|
|
37
40
|
def __init__(self, *dss: Iterable[D]) -> None:
|
|
38
41
|
"""
|
|
39
|
-
:param dss: Takes
|
|
40
|
-
|
|
42
|
+
:param dss: Takes 0 or 1 iterable parameters. Populates
|
|
43
|
+
queue from the iterable in FIFO order.
|
|
44
|
+
:raises TypeError: When passed a non-iterable parameter.
|
|
45
|
+
:raises ValueError: When more than one parameter is given.
|
|
41
46
|
|
|
42
47
|
"""
|
|
43
48
|
if (size := len(dss)) > 1:
|
|
@@ -46,6 +51,12 @@ class FIFOQueue[D]:
|
|
|
46
51
|
self._ca = CA(dss[0]) if size == 1 else CA()
|
|
47
52
|
|
|
48
53
|
def __bool__(self) -> bool:
|
|
54
|
+
"""
|
|
55
|
+
.. admonition:: Truthiness
|
|
56
|
+
|
|
57
|
+
``FIFOQueue`` truthy when non-empty, falsy when empty.
|
|
58
|
+
|
|
59
|
+
"""
|
|
49
60
|
return len(self._ca) > 0
|
|
50
61
|
|
|
51
62
|
def __len__(self) -> int:
|
|
@@ -57,6 +68,14 @@ class FIFOQueue[D]:
|
|
|
57
68
|
return self._ca == other._ca
|
|
58
69
|
|
|
59
70
|
def __iter__(self) -> Iterator[D]:
|
|
71
|
+
"""
|
|
72
|
+
.. admonition:: Iteration
|
|
73
|
+
|
|
74
|
+
Iterate over current state in natural FIFO order.
|
|
75
|
+
|
|
76
|
+
:returns: An iterator of the data.
|
|
77
|
+
|
|
78
|
+
"""
|
|
60
79
|
return iter(list(self._ca))
|
|
61
80
|
|
|
62
81
|
def __repr__(self) -> str:
|
|
@@ -68,25 +87,35 @@ class FIFOQueue[D]:
|
|
|
68
87
|
return '<< ' + ' < '.join(map(str, self)) + ' <<'
|
|
69
88
|
|
|
70
89
|
def copy(self) -> 'FIFOQueue[D]':
|
|
71
|
-
"""
|
|
90
|
+
"""
|
|
91
|
+
.. admonition:: Shallow copy
|
|
92
|
+
|
|
93
|
+
Make a shallow copy of the ``FIFOQueue``.
|
|
72
94
|
|
|
73
|
-
:returns: Shallow copy of the FIFOQueue
|
|
95
|
+
:returns: Shallow copy of the ``FIFOQueue``.
|
|
74
96
|
|
|
75
97
|
"""
|
|
76
98
|
return FIFOQueue(self._ca)
|
|
77
99
|
|
|
78
100
|
def push(self, *ds: D) -> None:
|
|
79
|
-
"""
|
|
101
|
+
"""
|
|
102
|
+
.. admonition:: Push
|
|
80
103
|
|
|
81
|
-
|
|
104
|
+
Push data items onto ``FIFOQueue``.
|
|
105
|
+
|
|
106
|
+
:param ds: Items to be pushed onto ''FIFOQueue''.
|
|
82
107
|
|
|
83
108
|
"""
|
|
84
109
|
self._ca.pushr(*ds)
|
|
85
110
|
|
|
86
111
|
def pop(self) -> MayBe[D]:
|
|
87
|
-
"""
|
|
112
|
+
"""
|
|
113
|
+
.. admonition:: Pop
|
|
88
114
|
|
|
89
|
-
|
|
115
|
+
Pop oldest data item off of ``FIFOQueue``.
|
|
116
|
+
|
|
117
|
+
:returns: ``MayBe`` of popped data item if ``FIFOQueue``
|
|
118
|
+
was not empty, empty ``MayBe`` otherwise.
|
|
90
119
|
|
|
91
120
|
"""
|
|
92
121
|
if self._ca:
|
|
@@ -94,9 +123,13 @@ class FIFOQueue[D]:
|
|
|
94
123
|
return MayBe()
|
|
95
124
|
|
|
96
125
|
def peak_last_in(self) -> MayBe[D]:
|
|
97
|
-
"""
|
|
126
|
+
"""
|
|
127
|
+
.. admonition:: Peak last
|
|
98
128
|
|
|
99
|
-
|
|
129
|
+
Peak at newest item on ``FIFOQueue``.
|
|
130
|
+
|
|
131
|
+
:returns: ``MayBe`` of newest item on ``FIFOQueue``,
|
|
132
|
+
empty ``MayBe`` if ``FIFOQueue`` empty.
|
|
100
133
|
|
|
101
134
|
"""
|
|
102
135
|
if self._ca:
|
|
@@ -104,9 +137,13 @@ class FIFOQueue[D]:
|
|
|
104
137
|
return MayBe()
|
|
105
138
|
|
|
106
139
|
def peak_next_out(self) -> MayBe[D]:
|
|
107
|
-
"""
|
|
140
|
+
"""
|
|
141
|
+
.. admonition:: Peak next out
|
|
142
|
+
|
|
143
|
+
Peak at oldest data item on ``FIFOQueue``.
|
|
108
144
|
|
|
109
|
-
:returns: MayBe of oldest item on
|
|
145
|
+
:returns: ``MayBe`` of oldest item on ``FIFOQueue``,
|
|
146
|
+
empty ``MayBe`` if ``FIFOueue`` empty.
|
|
110
147
|
|
|
111
148
|
"""
|
|
112
149
|
if self._ca:
|
|
@@ -119,11 +156,15 @@ class FIFOQueue[D]:
|
|
|
119
156
|
def fold[T](self, f: Callable[[T, D], T], start: T) -> MayBe[T]: ...
|
|
120
157
|
|
|
121
158
|
def fold[T](self, f: Callable[[T, D], T], start: T | None = None) -> MayBe[T]:
|
|
122
|
-
"""
|
|
159
|
+
"""
|
|
160
|
+
.. admonition:: Fold
|
|
161
|
+
|
|
162
|
+
Reduces ``FIFOQueue`` in natural FIFO Order, oldest to newest.
|
|
123
163
|
|
|
124
164
|
:param f: Reducing function, first argument is for accumulator.
|
|
125
165
|
:param start: Optional starting value.
|
|
126
|
-
:returns: MayBe of reduced value, empty MayBe if
|
|
166
|
+
:returns: ``MayBe`` of reduced value, empty ``MayBe`` if ``FIFOQueue``
|
|
167
|
+
empty and no starting value given.
|
|
127
168
|
|
|
128
169
|
"""
|
|
129
170
|
if start is None:
|
|
@@ -133,20 +174,27 @@ class FIFOQueue[D]:
|
|
|
133
174
|
return MayBe(self._ca.foldl(f, start))
|
|
134
175
|
|
|
135
176
|
def map[U](self, f: Callable[[D], U]) -> 'FIFOQueue[U]':
|
|
136
|
-
"""
|
|
177
|
+
"""
|
|
178
|
+
.. admonition:: Map
|
|
137
179
|
|
|
138
|
-
|
|
139
|
-
|
|
180
|
+
Map ``f`` over the ``FIFOQueue``, retain original order.
|
|
181
|
+
|
|
182
|
+
:param f: Function to map over ``FIFOQueue``.
|
|
183
|
+
:returns: New ``FIFOQueue`` instance.
|
|
140
184
|
|
|
141
185
|
"""
|
|
142
186
|
return FIFOQueue(map(f, self._ca))
|
|
143
187
|
|
|
144
188
|
|
|
145
189
|
def fifo_queue[D](*ds: D) -> FIFOQueue[D]:
|
|
146
|
-
"""
|
|
190
|
+
"""
|
|
191
|
+
.. admonition:: Create FIFOQueue
|
|
192
|
+
|
|
193
|
+
Factory function to create an ``FIFOQueue``
|
|
194
|
+
instance from the function's arguments.
|
|
147
195
|
|
|
148
|
-
:param ds: Initial
|
|
149
|
-
:returns: FIFOQueue
|
|
196
|
+
:param ds: Initial data to be pushed on in FIFO order.
|
|
197
|
+
:returns: New ``FIFOQueue`` instance.
|
|
150
198
|
|
|
151
199
|
"""
|
|
152
200
|
return FIFOQueue(ds)
|
pythonic_fp/queues/lifo.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2023-
|
|
1
|
+
# Copyright 2023-2026 Geoffrey R. Scheller
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -22,22 +22,27 @@ __all__ = ['LIFOQueue', 'lifo_queue']
|
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
class LIFOQueue[D]:
|
|
25
|
-
"""
|
|
25
|
+
"""
|
|
26
|
+
.. admonition:: LIFOQueue
|
|
27
|
+
|
|
28
|
+
Stateful Last-In-First-Out (LIFO) Queue data structure.
|
|
26
29
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
- O(1) pops
|
|
31
|
+
- O(1) amortized pushes
|
|
32
|
+
- O(1) length determination
|
|
33
|
+
- in a Boolean context, true if not empty, false if empty
|
|
34
|
+
- will automatically increase storage capacity when needed
|
|
35
|
+
- neither indexable nor sliceable by design
|
|
33
36
|
|
|
34
37
|
"""
|
|
35
38
|
__slots__ = ('_ca',)
|
|
36
39
|
|
|
37
40
|
def __init__(self, *dss: Iterable[D]) -> None:
|
|
38
41
|
"""
|
|
39
|
-
:param dss: Takes
|
|
40
|
-
|
|
42
|
+
:param dss: Takes 0 or 1 iterable parameters. Populates
|
|
43
|
+
queue from the iterable in LIFO order.
|
|
44
|
+
:raises TypeError: When passed a non-iterable parameter.
|
|
45
|
+
:raises ValueError: When more than one parameter is given.
|
|
41
46
|
|
|
42
47
|
"""
|
|
43
48
|
if (size := len(dss)) > 1:
|
|
@@ -46,6 +51,12 @@ class LIFOQueue[D]:
|
|
|
46
51
|
self._ca = CA(dss[0]) if size == 1 else CA()
|
|
47
52
|
|
|
48
53
|
def __bool__(self) -> bool:
|
|
54
|
+
"""
|
|
55
|
+
.. admonition:: Truthiness
|
|
56
|
+
|
|
57
|
+
``LIFOQueue`` truthy when non-empty, falsy when empty.
|
|
58
|
+
|
|
59
|
+
"""
|
|
49
60
|
return len(self._ca) > 0
|
|
50
61
|
|
|
51
62
|
def __len__(self) -> int:
|
|
@@ -57,6 +68,14 @@ class LIFOQueue[D]:
|
|
|
57
68
|
return self._ca == other._ca
|
|
58
69
|
|
|
59
70
|
def __iter__(self) -> Iterator[D]:
|
|
71
|
+
"""
|
|
72
|
+
.. admonition:: Iteration
|
|
73
|
+
|
|
74
|
+
Iterate over current state in natural LIFO order.
|
|
75
|
+
|
|
76
|
+
:returns: Iterator of the data.
|
|
77
|
+
|
|
78
|
+
"""
|
|
60
79
|
return reversed(list(self._ca))
|
|
61
80
|
|
|
62
81
|
def __repr__(self) -> str:
|
|
@@ -68,9 +87,12 @@ class LIFOQueue[D]:
|
|
|
68
87
|
return '|| ' + ' > '.join(map(str, self)) + ' ><'
|
|
69
88
|
|
|
70
89
|
def copy(self) -> 'LIFOQueue[D]':
|
|
71
|
-
"""
|
|
90
|
+
"""
|
|
91
|
+
.. admonition:: Shallow copy
|
|
72
92
|
|
|
73
|
-
|
|
93
|
+
Make a shallow copy of the ``LIFOQueue``.
|
|
94
|
+
|
|
95
|
+
:returns: Shallow copy of the ``LIFOQueue``.
|
|
74
96
|
|
|
75
97
|
"""
|
|
76
98
|
return LIFOQueue(reversed(self._ca))
|
|
@@ -78,15 +100,19 @@ class LIFOQueue[D]:
|
|
|
78
100
|
def push(self, *ds: D) -> None:
|
|
79
101
|
"""Push items onto LIFOQueue.
|
|
80
102
|
|
|
81
|
-
:param ds: Items to be pushed onto LIFOQueue
|
|
103
|
+
:param ds: Items to be pushed onto ``LIFOQueue``.
|
|
82
104
|
|
|
83
105
|
"""
|
|
84
106
|
self._ca.pushr(*ds)
|
|
85
107
|
|
|
86
108
|
def pop(self) -> MayBe[D]:
|
|
87
|
-
"""
|
|
109
|
+
"""
|
|
110
|
+
.. admonition:: Pop
|
|
111
|
+
|
|
112
|
+
Pop newest data item off of ``LIFOQueue``.
|
|
88
113
|
|
|
89
|
-
:returns: MayBe of popped item if
|
|
114
|
+
:returns: ``MayBe`` of popped data item if ``LIFOQueue``
|
|
115
|
+
was not empty, empty `MayBe` otherwise.
|
|
90
116
|
|
|
91
117
|
"""
|
|
92
118
|
if self._ca:
|
|
@@ -94,9 +120,12 @@ class LIFOQueue[D]:
|
|
|
94
120
|
return MayBe()
|
|
95
121
|
|
|
96
122
|
def peak(self) -> MayBe[D]:
|
|
97
|
-
"""
|
|
123
|
+
"""
|
|
124
|
+
.. admonition:: Peak last
|
|
125
|
+
|
|
126
|
+
Peak at newest item on ``LIFOQueue``.
|
|
98
127
|
|
|
99
|
-
:returns: MayBe of newest item on queue, empty MayBe if queue empty.
|
|
128
|
+
:returns: ``MayBe`` of newest item on queue, empty ``MayBe`` if queue empty.
|
|
100
129
|
|
|
101
130
|
"""
|
|
102
131
|
if self._ca:
|
|
@@ -109,11 +138,15 @@ class LIFOQueue[D]:
|
|
|
109
138
|
def fold[T](self, f: Callable[[T, D], T], start: T) -> MayBe[T]: ...
|
|
110
139
|
|
|
111
140
|
def fold[T](self, f: Callable[[T, D], T], start: T | None = None) -> MayBe[T]:
|
|
112
|
-
"""
|
|
141
|
+
"""
|
|
142
|
+
.. admonition:: Fold
|
|
143
|
+
|
|
144
|
+
Reduces ``LIFOQUEUE`` in natural LIFO Order, newest to oldest.
|
|
113
145
|
|
|
114
146
|
:param f: Reducing function, first argument is for accumulator.
|
|
115
147
|
:param start: Optional starting value.
|
|
116
|
-
:returns: MayBe of reduced value, empty MayBe if
|
|
148
|
+
:returns: ``MayBe`` of reduced value, empty ``MayBe`` if ``LIFOQueue``
|
|
149
|
+
empty and no starting value given.
|
|
117
150
|
|
|
118
151
|
"""
|
|
119
152
|
if start is None:
|
|
@@ -123,20 +156,27 @@ class LIFOQueue[D]:
|
|
|
123
156
|
return MayBe(self._ca.foldr(swap(f), start))
|
|
124
157
|
|
|
125
158
|
def map[U](self, f: Callable[[D], U]) -> 'LIFOQueue[U]':
|
|
126
|
-
"""
|
|
159
|
+
"""
|
|
160
|
+
.. admonition:: Map
|
|
161
|
+
|
|
162
|
+
Map ``f`` over the ``LIFOQueue``, retain original order.
|
|
127
163
|
|
|
128
|
-
:param f: Function to map over
|
|
129
|
-
:returns: New LIFOQueue instance.
|
|
164
|
+
:param f: Function to map over ``LIFOQueue``.
|
|
165
|
+
:returns: New ``LIFOQueue`` instance.
|
|
130
166
|
|
|
131
167
|
"""
|
|
132
168
|
return LIFOQueue(reversed(CA(map(f, reversed(self._ca)))))
|
|
133
169
|
|
|
134
170
|
|
|
135
171
|
def lifo_queue[D](*ds: D) -> LIFOQueue[D]:
|
|
136
|
-
"""
|
|
172
|
+
"""
|
|
173
|
+
.. admonition:: Create LIFOQueue
|
|
174
|
+
|
|
175
|
+
Factory function to create an ``LIFOQUEUE``
|
|
176
|
+
instance from the function's arguments.
|
|
137
177
|
|
|
138
|
-
:param ds:
|
|
139
|
-
:returns: LIFOQueue
|
|
178
|
+
:param ds: Items pushed onto queue in LIFO order.
|
|
179
|
+
:returns: New ``LIFOQueue`` instance.
|
|
140
180
|
|
|
141
181
|
"""
|
|
142
182
|
return LIFOQueue(ds)
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pythonic-fp-queues
|
|
3
|
-
Version: 5.1.
|
|
3
|
+
Version: 5.1.2
|
|
4
4
|
Summary: Queues
|
|
5
5
|
Keywords: queue,fifo,lifo,dqueue
|
|
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
|
|
11
11
|
Classifier: Intended Audience :: Developers
|
|
12
12
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
13
13
|
Classifier: Operating System :: OS Independent
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
15
15
|
Classifier: Typing :: Typed
|
|
16
16
|
License-File: LICENSE
|
|
17
|
-
Requires-Dist: pythonic-fp-circulararray>=6.0.
|
|
17
|
+
Requires-Dist: pythonic-fp-circulararray>=6.0.4
|
|
18
18
|
Requires-Dist: pythonic-fp-fptools>=5.2.0
|
|
19
19
|
Requires-Dist: pytest>=8.4.1 ; extra == "test"
|
|
20
20
|
Project-URL: Changelog, https://github.com/grscheller/pythonic-fp-queues/blob/main/CHANGELOG.rst
|
|
21
|
-
Project-URL: Documentation, https://grscheller.github.io/pythonic-fp/queues
|
|
22
|
-
Project-URL: Homepage, https://grscheller.github.io/pythonic-fp/
|
|
21
|
+
Project-URL: Documentation, https://grscheller.github.io/pythonic-fp/projects/queues.html
|
|
22
|
+
Project-URL: Homepage, https://grscheller.github.io/pythonic-fp/
|
|
23
23
|
Project-URL: Source, https://github.com/grscheller/pythonic-fp-queues
|
|
24
24
|
Provides-Extra: test
|
|
25
25
|
|
|
@@ -27,8 +27,8 @@ Pythonic FP - Queues
|
|
|
27
27
|
====================
|
|
28
28
|
|
|
29
29
|
PyPI project
|
|
30
|
-
`pythonic-fp
|
|
31
|
-
<https://pypi.org/project/pythonic-fp
|
|
30
|
+
`pythonic-fp-queues
|
|
31
|
+
<https://pypi.org/project/pythonic-fp-queues>`_.
|
|
32
32
|
|
|
33
33
|
+-------------------------+-----------+--------------------------+
|
|
34
34
|
| module | class | name |
|
|
@@ -42,19 +42,23 @@ PyPI project
|
|
|
42
42
|
|
|
43
43
|
Part of the
|
|
44
44
|
`pythonic-fp
|
|
45
|
-
<https://grscheller.github.io/pythonic-fp
|
|
45
|
+
<https://grscheller.github.io/pythonic-fp/>`_
|
|
46
46
|
PyPI projects.
|
|
47
47
|
|
|
48
48
|
Documentation
|
|
49
49
|
-------------
|
|
50
50
|
|
|
51
|
+
Documentation and other links for this project are hosted on
|
|
52
|
+
`GitHub Pages
|
|
53
|
+
<https://grscheller.github.io/pythonic-fp/projects/queues.html>`_.
|
|
54
|
+
|
|
51
55
|
Documentation for this project is hosted on
|
|
52
56
|
`GitHub Pages
|
|
53
|
-
<https://grscheller.github.io/pythonic-fp/
|
|
57
|
+
<https://grscheller.github.io/pythonic-fp-queues/development/html/>`_.
|
|
54
58
|
|
|
55
59
|
Copyright and License
|
|
56
60
|
---------------------
|
|
57
61
|
|
|
58
|
-
Copyright (c) 2023-
|
|
62
|
+
Copyright (c) 2023-2026 Geoffrey R. Scheller. Licensed under the Apache
|
|
59
63
|
License, Version 2.0. See the LICENSE file for details.
|
|
60
64
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
pythonic_fp/queues/__init__.py,sha256=NOkkXOQaHmiemvY4Ke5ZdFJCl3_P3bmV87Xz5Y-R9cU,1028
|
|
2
|
+
pythonic_fp/queues/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
pythonic_fp/queues/de.py,sha256=hRFeogJ4XuXRFV4xOpD3mLoNo1jklP4uT5Ilrw-PiJg,7456
|
|
4
|
+
pythonic_fp/queues/de.pyi,sha256=db74UiSLFme25Yhc28Hhw3EKb2GfvU4wNBJtkTlr_e4,1150
|
|
5
|
+
pythonic_fp/queues/fifo.py,sha256=EvZub5bRsW3xqCbREKz8dXIt3heBmzsDOzJQuF6Mm30,5728
|
|
6
|
+
pythonic_fp/queues/fifo.pyi,sha256=19TGU3Qg91hCLo5A-5p9vmREcl38EUWhIAvJZtlb1eA,885
|
|
7
|
+
pythonic_fp/queues/lifo.py,sha256=_uBM9XnZMm-OYEDhAHPdcHBy_C6h2d0B0dTpoXaJ62A,5348
|
|
8
|
+
pythonic_fp/queues/lifo.pyi,sha256=HdJ-t7R2w3VfCT06raCTXespdUZfpBgMepBlcxDvyuk,832
|
|
9
|
+
pythonic_fp/queues/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
+
pythonic_fp_queues-5.1.2.dist-info/licenses/LICENSE,sha256=IJMkVWQUVy-SonK6SMaMotDQ6Zb-lVi2bUTiGp1GUO8,10774
|
|
11
|
+
pythonic_fp_queues-5.1.2.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
12
|
+
pythonic_fp_queues-5.1.2.dist-info/METADATA,sha256=fzVKSB2LG3S9c78klIzZ6zvaH1JT4mfRa6NZzZiD7d0,2350
|
|
13
|
+
pythonic_fp_queues-5.1.2.dist-info/RECORD,,
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
pythonic_fp/queues/__init__.py,sha256=MDXOn4_zIir0vvzaDpodmSCHN1usLSIqebEpFI9TPhQ,1625
|
|
2
|
-
pythonic_fp/queues/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
-
pythonic_fp/queues/de.py,sha256=EApnwnvGmOrzvbx0MEhspp_wlDtqMuJlJKPRip1b4hY,6084
|
|
4
|
-
pythonic_fp/queues/de.pyi,sha256=db74UiSLFme25Yhc28Hhw3EKb2GfvU4wNBJtkTlr_e4,1150
|
|
5
|
-
pythonic_fp/queues/fifo.py,sha256=aj34iqFfh4YTHKG9_QEZpSvnUdzkng-IeCjZQxOuWQ8,4602
|
|
6
|
-
pythonic_fp/queues/fifo.pyi,sha256=19TGU3Qg91hCLo5A-5p9vmREcl38EUWhIAvJZtlb1eA,885
|
|
7
|
-
pythonic_fp/queues/lifo.py,sha256=gvrZKgUbBVNA1I03Q1AGh8rLBOzmnpI2herrjCTzR7A,4414
|
|
8
|
-
pythonic_fp/queues/lifo.pyi,sha256=HdJ-t7R2w3VfCT06raCTXespdUZfpBgMepBlcxDvyuk,832
|
|
9
|
-
pythonic_fp/queues/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
-
pythonic_fp_queues-5.1.1.dist-info/licenses/LICENSE,sha256=IJMkVWQUVy-SonK6SMaMotDQ6Zb-lVi2bUTiGp1GUO8,10774
|
|
11
|
-
pythonic_fp_queues-5.1.1.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
12
|
-
pythonic_fp_queues-5.1.1.dist-info/METADATA,sha256=ODc-wRv37wtjI64ZGS8nAHus6xgh4KQCzQgeuzOVWrY,2218
|
|
13
|
-
pythonic_fp_queues-5.1.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|