pythonic-fp.splitends 2.0.0__py3-none-any.whl → 2.0.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/splitends/__init__.py +5 -4
- pythonic_fp/splitends/splitend.py +31 -15
- pythonic_fp/splitends/splitend_node.py +24 -13
- {pythonic_fp_splitends-2.0.0.dist-info → pythonic_fp_splitends-2.0.2.dist-info}/METADATA +6 -6
- pythonic_fp_splitends-2.0.2.dist-info/RECORD +11 -0
- pythonic_fp_splitends-2.0.0.dist-info/RECORD +0 -11
- {pythonic_fp_splitends-2.0.0.dist-info → pythonic_fp_splitends-2.0.2.dist-info}/WHEEL +0 -0
- {pythonic_fp_splitends-2.0.0.dist-info → pythonic_fp_splitends-2.0.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2024-
|
|
1
|
+
# Copyright 2024-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.
|
|
@@ -26,12 +26,13 @@ node is at the bottom of the stack and can not be "snipped" or "cut" off.
|
|
|
26
26
|
A ``SplitEnd`` can be duplicated onto a compatible root node. By compatible, the
|
|
27
27
|
new root must contain data that compares as equal to the old root node.
|
|
28
28
|
|
|
29
|
-
TODO
|
|
30
|
-
hashable. The ``scalp.add(d)`` method will return the unique root node with data
|
|
29
|
+
**TODO:** A ``scalp`` is a container of root nodes all of whose contained data must
|
|
30
|
+
be hashable. The ``scalp.add(d)`` method will return the unique root node with data
|
|
31
31
|
that compares as equal to ``d``, or create a new root node if such a contained node
|
|
32
32
|
does not exist.
|
|
33
|
+
|
|
33
34
|
"""
|
|
34
35
|
|
|
35
36
|
__author__ = 'Geoffrey R. Scheller'
|
|
36
|
-
__copyright__ = 'Copyright (c) 2023-
|
|
37
|
+
__copyright__ = 'Copyright (c) 2023-2026 Geoffrey R. Scheller'
|
|
37
38
|
__license__ = 'Apache License 2.0'
|
|
@@ -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.
|
|
@@ -14,27 +14,29 @@
|
|
|
14
14
|
|
|
15
15
|
"""
|
|
16
16
|
Class SplitEnds
|
|
17
|
-
|
|
17
|
+
---------------
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
.. admonition:: LIFO stacks safely sharing immutable data.
|
|
20
20
|
|
|
21
|
-
- each ``SplitEnd`` is a very simple stateful (mutable) LIFO stack
|
|
22
|
-
- data can be either "extended" to or "snipped" off the "end"
|
|
23
|
-
- the "root" of a ``SplitEnd``
|
|
24
|
-
|
|
25
|
-
-
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
21
|
+
- each ``SplitEnd`` is a very simple stateful (mutable) LIFO stack
|
|
22
|
+
- data can be either "extended" to or "snipped" off the "end"
|
|
23
|
+
- the "root" of a ``SplitEnd``
|
|
24
|
+
|
|
25
|
+
- it is fixed and cannot be removed from the ``SplitEnd``
|
|
26
|
+
|
|
27
|
+
- different mutable split ends can safely share the same "tail"
|
|
28
|
+
- each ``SplitEnd`` sees itself as a singularly linked list
|
|
29
|
+
- bush-like datastructures can be formed using multiple ``SplitEnds``
|
|
30
|
+
- the ``SplitEnd.split`` and ``len`` methods are O(1)
|
|
31
|
+
- in boolean context returns true if the ``SplitEnd`` is not just its "root"
|
|
30
32
|
|
|
31
33
|
"""
|
|
32
34
|
|
|
33
35
|
from collections.abc import Callable, Iterator
|
|
34
|
-
from pythonic_fp.iterables.folding import reduce_left, fold_left
|
|
35
36
|
from typing import cast, Final, overload
|
|
36
|
-
from pythonic_fp.queues.lifo import LIFOQueue
|
|
37
37
|
from pythonic_fp.gadgets.sentinels.flavored import Sentinel
|
|
38
|
+
from pythonic_fp.iterables.folding import reduce_left, fold_left
|
|
39
|
+
from pythonic_fp.queues.lifo import LIFOQueue
|
|
38
40
|
from .splitend_node import SENode
|
|
39
41
|
|
|
40
42
|
__all__ = ['SplitEnd']
|
|
@@ -52,6 +54,7 @@ class SplitEnd[D]:
|
|
|
52
54
|
"""
|
|
53
55
|
:param root_data: Irremovable initial data at bottom of stack.
|
|
54
56
|
:param data: Removable data to be pushed onto splitend stack.
|
|
57
|
+
|
|
55
58
|
"""
|
|
56
59
|
if root is _sentinel:
|
|
57
60
|
if ds:
|
|
@@ -83,6 +86,7 @@ class SplitEnd[D]:
|
|
|
83
86
|
def __bool__(self) -> bool:
|
|
84
87
|
"""
|
|
85
88
|
:returns: ``True`` is ``SplitEnd`` is not just its root node.
|
|
89
|
+
|
|
86
90
|
"""
|
|
87
91
|
return bool(self._end)
|
|
88
92
|
|
|
@@ -121,6 +125,7 @@ class SplitEnd[D]:
|
|
|
121
125
|
|
|
122
126
|
:param num: Optional number of nodes to cut, default is entire stack.
|
|
123
127
|
:returns: Tuple of data cut off from end.
|
|
128
|
+
|
|
124
129
|
"""
|
|
125
130
|
if num is None or num > self._count:
|
|
126
131
|
num = self._count
|
|
@@ -146,6 +151,7 @@ class SplitEnd[D]:
|
|
|
146
151
|
extension.
|
|
147
152
|
|
|
148
153
|
:param ds: data to extend the splitend
|
|
154
|
+
|
|
149
155
|
"""
|
|
150
156
|
for d in ds:
|
|
151
157
|
node = SENode(d, self._end)
|
|
@@ -155,12 +161,14 @@ class SplitEnd[D]:
|
|
|
155
161
|
"""Return the data at end (top) of SplitEnd without consuming it.
|
|
156
162
|
|
|
157
163
|
:returns: The data at the end of the SplitEnd.
|
|
164
|
+
|
|
158
165
|
"""
|
|
159
166
|
return self._end.data()
|
|
160
167
|
|
|
161
168
|
def root(self) -> SENode[D]:
|
|
162
169
|
"""
|
|
163
170
|
:returns: The root SENode node of the SplitEnd.
|
|
171
|
+
|
|
164
172
|
"""
|
|
165
173
|
return self._root
|
|
166
174
|
|
|
@@ -172,12 +180,16 @@ class SplitEnd[D]:
|
|
|
172
180
|
Two nodes are compatible root nodes if and only if
|
|
173
181
|
|
|
174
182
|
- they are both actually root nodes
|
|
175
|
-
|
|
183
|
+
|
|
184
|
+
- which implies that their previous nodes are themselves
|
|
185
|
+
|
|
176
186
|
- their data compare as equal
|
|
187
|
+
|
|
177
188
|
- comparing by identity is too strong for some use cases
|
|
178
189
|
|
|
179
190
|
:returns: New SplitEnd with the same data and the new ``root``.
|
|
180
191
|
:raises ValueError: If new and original root nodes are not compatible.
|
|
192
|
+
|
|
181
193
|
"""
|
|
182
194
|
if not root:
|
|
183
195
|
msg = 'New root node is not a root node.'
|
|
@@ -197,6 +209,7 @@ class SplitEnd[D]:
|
|
|
197
209
|
"""Snip data off tip of SplitEnd. Just return data if tip is root.
|
|
198
210
|
|
|
199
211
|
:returns: Data snipped off tip, just return root data if at root.
|
|
212
|
+
|
|
200
213
|
"""
|
|
201
214
|
if self._count > 1:
|
|
202
215
|
data, self._end, self._count = self._end.both() + (self._count - 1,)
|
|
@@ -209,6 +222,7 @@ class SplitEnd[D]:
|
|
|
209
222
|
"""Split the end and add more data.
|
|
210
223
|
|
|
211
224
|
:returns: New instance, same data nodes plus additional ones on end.
|
|
225
|
+
|
|
212
226
|
"""
|
|
213
227
|
se: SplitEnd[D] = SplitEnd(self._root.data())
|
|
214
228
|
se._count, se._end, se._root = self._count, self._end, self._root
|
|
@@ -226,6 +240,7 @@ class SplitEnd[D]:
|
|
|
226
240
|
:param f: Folding function, first argument is for the accumulator.
|
|
227
241
|
:param init: Optional initial starting value for the fold.
|
|
228
242
|
:returns: Reduced value folding from tip to root in natural LIFO order.
|
|
243
|
+
|
|
229
244
|
"""
|
|
230
245
|
if init is None:
|
|
231
246
|
return self._end.fold(f) # type: ignore
|
|
@@ -242,6 +257,7 @@ class SplitEnd[D]:
|
|
|
242
257
|
:param f: Folding function, first argument is for the accumulator.
|
|
243
258
|
:param init: Optional initial starting value for the fold.
|
|
244
259
|
:returns: Reduced value folding from root to tip.
|
|
260
|
+
|
|
245
261
|
"""
|
|
246
262
|
if init is None:
|
|
247
263
|
return cast(T, reduce_left(reversed(self), cast(Callable[[D, D], D], f)))
|
|
@@ -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.
|
|
@@ -14,20 +14,25 @@
|
|
|
14
14
|
|
|
15
15
|
"""
|
|
16
16
|
Class SENode
|
|
17
|
-
|
|
17
|
+
------------
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
.. admonition:: Used to make inwardly directed bush-like graphs
|
|
20
20
|
|
|
21
|
-
- designed so multiple splitends can safely share the same data
|
|
22
|
-
- nodes always contain data
|
|
23
|
-
- data node ``SENode[D]`` make up end-to-root singularly linked lists
|
|
24
|
-
- two nodes compare as equal if
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
-
|
|
29
|
-
-
|
|
30
|
-
|
|
21
|
+
- designed so multiple splitends can safely share the same data
|
|
22
|
+
- nodes always contain data
|
|
23
|
+
- data node ``SENode[D]`` make up end-to-root singularly linked lists
|
|
24
|
+
- two nodes compare as equal if
|
|
25
|
+
|
|
26
|
+
- both their previous Nodes are the same
|
|
27
|
+
- their data compare as equal
|
|
28
|
+
|
|
29
|
+
- a root node is a node whose previous node is itself
|
|
30
|
+
|
|
31
|
+
- root nodes mark the bottom of splitend stacks
|
|
32
|
+
|
|
33
|
+
- more than one node can point to the same proceeding node
|
|
34
|
+
|
|
35
|
+
- forming bush like graphs
|
|
31
36
|
|
|
32
37
|
"""
|
|
33
38
|
|
|
@@ -72,6 +77,7 @@ class SENode[D]:
|
|
|
72
77
|
"""
|
|
73
78
|
Two ``SENodes`` nodes are equal if their previous nodes are the
|
|
74
79
|
same object and their data compare as equal.
|
|
80
|
+
|
|
75
81
|
"""
|
|
76
82
|
if not isinstance(other, type(self)):
|
|
77
83
|
return False
|
|
@@ -86,6 +92,7 @@ class SENode[D]:
|
|
|
86
92
|
"""Peak at data and previous node, if a root then data and self.
|
|
87
93
|
|
|
88
94
|
:returns: tuple of type tuple[D, SENode[D]]
|
|
95
|
+
|
|
89
96
|
"""
|
|
90
97
|
return self._data, self._prev
|
|
91
98
|
|
|
@@ -93,6 +100,7 @@ class SENode[D]:
|
|
|
93
100
|
"""Peak at data.
|
|
94
101
|
|
|
95
102
|
:returns: The data stored in the ``SENode``.
|
|
103
|
+
|
|
96
104
|
"""
|
|
97
105
|
return self._data
|
|
98
106
|
|
|
@@ -100,6 +108,7 @@ class SENode[D]:
|
|
|
100
108
|
"""Peak at previous node.
|
|
101
109
|
|
|
102
110
|
:returns: The previous node stored in the ``SENode``.
|
|
111
|
+
|
|
103
112
|
"""
|
|
104
113
|
return self._prev
|
|
105
114
|
|
|
@@ -108,6 +117,7 @@ class SENode[D]:
|
|
|
108
117
|
|
|
109
118
|
:param data: Data for new node to contain.
|
|
110
119
|
:returns: New ``SENode`` whose previous node is the current node.
|
|
120
|
+
|
|
111
121
|
"""
|
|
112
122
|
return cast(Self, SENode(data, self))
|
|
113
123
|
|
|
@@ -122,6 +132,7 @@ class SENode[D]:
|
|
|
122
132
|
:param f: Folding function, first argument is for accumulated value.`
|
|
123
133
|
:param init: Optional initial starting value for the fold.
|
|
124
134
|
:returns: Reduced value folded from end to root in natural LIFO order.
|
|
135
|
+
|
|
125
136
|
"""
|
|
126
137
|
if init is not _sentinel:
|
|
127
138
|
acc = cast(T, init)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pythonic-fp-splitends
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.2
|
|
4
4
|
Summary: Mutable stack objects that can safely share data.
|
|
5
5
|
Keywords: SplitEnd,lifo,stack
|
|
6
6
|
Author-email: "Geoffrey R. Scheller" <geoffrey@scheller.com>
|
|
@@ -14,9 +14,9 @@ Classifier: Operating System :: OS Independent
|
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.13
|
|
15
15
|
Classifier: Typing :: Typed
|
|
16
16
|
License-File: LICENSE
|
|
17
|
-
Requires-Dist: pythonic-fp-fptools>=5.
|
|
18
|
-
Requires-Dist: pythonic-fp-iterables>=5.1.
|
|
19
|
-
Requires-Dist: pythonic-fp-queues>=5.1.
|
|
17
|
+
Requires-Dist: pythonic-fp-fptools>=5.2.0
|
|
18
|
+
Requires-Dist: pythonic-fp-iterables>=5.1.3
|
|
19
|
+
Requires-Dist: pythonic-fp-queues>=5.1.1
|
|
20
20
|
Requires-Dist: pytest>=8.4.1 ; extra == "test"
|
|
21
21
|
Project-URL: Changelog, https://github.com/grscheller/pythonic-fp-splitends/blob/main/CHANGELOG.rst
|
|
22
22
|
Project-URL: Documentation, https://grscheller.github.io/pythonic-fp/splitends/development/build/html/
|
|
@@ -45,7 +45,7 @@ between themselves.
|
|
|
45
45
|
|
|
46
46
|
Part of the
|
|
47
47
|
`pythonic-fp
|
|
48
|
-
<https://grscheller.github.io/pythonic-fp
|
|
48
|
+
<https://grscheller.github.io/pythonic-fp>`_
|
|
49
49
|
PyPI projects.
|
|
50
50
|
|
|
51
51
|
Documentation
|
|
@@ -53,7 +53,7 @@ Documentation
|
|
|
53
53
|
|
|
54
54
|
Documentation for this project is hosted on
|
|
55
55
|
`GitHub Pages
|
|
56
|
-
<https://grscheller.github.io/pythonic-fp/splitends
|
|
56
|
+
<https://grscheller.github.io/pythonic-fp/splitends>`_.
|
|
57
57
|
|
|
58
58
|
Copyright and License
|
|
59
59
|
---------------------
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
pythonic_fp/splitends/__init__.py,sha256=T3FgFehJkrlKx2OKHJJETDcEJ_2nKfyl96wTb4Nw6Fw,1780
|
|
2
|
+
pythonic_fp/splitends/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
pythonic_fp/splitends/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
pythonic_fp/splitends/splitend.py,sha256=TkLQ5o4-SCnnC_HTpda6cSotaxyQ6aNbc8DB81qNqSI,8317
|
|
5
|
+
pythonic_fp/splitends/splitend.pyi,sha256=OdTRATFXX5smbpwc8wm3gt4yyeTd_kN8VbMeNYl2Cho,1193
|
|
6
|
+
pythonic_fp/splitends/splitend_node.py,sha256=0Qz_oIvwbvtlYZOD-tZ0lD4PxMRysFPkBNPTBkGdkQk,4306
|
|
7
|
+
pythonic_fp/splitends/splitend_node.pyi,sha256=TozeGg4lmjMf0UPfZRTxRJR2kRpq0053VjbjIBUeosk,705
|
|
8
|
+
pythonic_fp_splitends-2.0.2.dist-info/licenses/LICENSE,sha256=IJMkVWQUVy-SonK6SMaMotDQ6Zb-lVi2bUTiGp1GUO8,10774
|
|
9
|
+
pythonic_fp_splitends-2.0.2.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
10
|
+
pythonic_fp_splitends-2.0.2.dist-info/METADATA,sha256=l9gYIuYaAd9pIQwLAe_6AHnSjowRzx6JKsV4uxtI6dQ,2381
|
|
11
|
+
pythonic_fp_splitends-2.0.2.dist-info/RECORD,,
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
pythonic_fp/splitends/__init__.py,sha256=mydkUVuGD_Ns3G4LYgOQvPfTxMCkCkFwC3oZFDHnRmM,1775
|
|
2
|
-
pythonic_fp/splitends/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
-
pythonic_fp/splitends/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
pythonic_fp/splitends/splitend.py,sha256=XQ4-1x8lW5i480YHjBcwAhh4ddxtPF7KsIrMnbaM8Ks,8242
|
|
5
|
-
pythonic_fp/splitends/splitend.pyi,sha256=OdTRATFXX5smbpwc8wm3gt4yyeTd_kN8VbMeNYl2Cho,1193
|
|
6
|
-
pythonic_fp/splitends/splitend_node.py,sha256=rNjGU8VqhOo6AFa-R6zcOrrAtfIpzkzI9ulsa8iRg2w,4252
|
|
7
|
-
pythonic_fp/splitends/splitend_node.pyi,sha256=TozeGg4lmjMf0UPfZRTxRJR2kRpq0053VjbjIBUeosk,705
|
|
8
|
-
pythonic_fp_splitends-2.0.0.dist-info/licenses/LICENSE,sha256=IJMkVWQUVy-SonK6SMaMotDQ6Zb-lVi2bUTiGp1GUO8,10774
|
|
9
|
-
pythonic_fp_splitends-2.0.0.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
10
|
-
pythonic_fp_splitends-2.0.0.dist-info/METADATA,sha256=LMjr3oM6p1DbZhL9f6mAvd8gDDa5klTdA8IiJiFdn_w,2435
|
|
11
|
-
pythonic_fp_splitends-2.0.0.dist-info/RECORD,,
|
|
File without changes
|
{pythonic_fp_splitends-2.0.0.dist-info → pythonic_fp_splitends-2.0.2.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|