structures-detroix23 0.0.3__tar.gz

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.
File without changes
@@ -0,0 +1,24 @@
1
+ Metadata-Version: 2.4
2
+ Name: structures_detroix23
3
+ Version: 0.0.3
4
+ Summary: Python structures.
5
+ Author-email: Detroix23 <detroix23@gmail.com>
6
+ License-Expression: CC-BY-4.0
7
+ Project-URL: Repository, https://github.com/Detroix23/py_structures
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Operating System :: OS Independent
10
+ Classifier: Natural Language :: English
11
+ Requires-Python: >=3.12
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE.md
14
+ Dynamic: license-file
15
+
16
+ # Data structures.
17
+
18
+ Classes:
19
+ - Chained lists (algorithmically);
20
+ - Stack;
21
+ - Queue;
22
+ - Doubly-chained lists;
23
+ - Tree;
24
+ - Graphs;
@@ -0,0 +1,9 @@
1
+ # Data structures.
2
+
3
+ Classes:
4
+ - Chained lists (algorithmically);
5
+ - Stack;
6
+ - Queue;
7
+ - Doubly-chained lists;
8
+ - Tree;
9
+ - Graphs;
@@ -0,0 +1,27 @@
1
+ [project]
2
+ name = "structures_detroix23"
3
+ version = "0.0.3"
4
+ description = "Python structures."
5
+ authors = [
6
+ { name="Detroix23", email="detroix23@gmail.com" }
7
+ ]
8
+ readme = "README.md"
9
+ requires-python = ">=3.12"
10
+ classifiers = [
11
+ "Programming Language :: Python :: 3",
12
+ "Operating System :: OS Independent",
13
+ "Natural Language :: English",
14
+ ]
15
+ dependencies = [
16
+ ]
17
+ license = "CC-BY-4.0"
18
+ license-files = [
19
+ "LICENSE.md"
20
+ ]
21
+
22
+ [project.urls]
23
+ Repository = "https://github.com/Detroix23/py_structures"
24
+
25
+ [build-system]
26
+ requires = ["setuptools"]
27
+ build-backend = "setuptools.build_meta"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,15 @@
1
+ # type: ignore
2
+ """
3
+ # Data structures.
4
+ /src/structures_detroix23/__init__.py
5
+ """
6
+
7
+ from structures_detroix23.modules import (
8
+ base,
9
+ cell,
10
+ dynamic_list,
11
+ graphs,
12
+ nodes,
13
+ result,
14
+ types,
15
+ )
@@ -0,0 +1,130 @@
1
+ """
2
+ # Data structures.
3
+ /src/structures_detroix23/__main__.py
4
+ Main file.
5
+ """
6
+
7
+ import sys
8
+
9
+ from structures_detroix23.modules import (
10
+ base,
11
+ cell,
12
+ dynamic_list,
13
+ nodes,
14
+ )
15
+
16
+ def test_chain1() -> None:
17
+ """
18
+ Main chained list test entry point.
19
+ """
20
+ print("\n(?) main.test_chain1() Start.")
21
+
22
+ base.verbose_assert_eq(cell.Cell(1).to_list(), [1])
23
+
24
+ assert (cell.Cell(1, cell.Cell(2, cell.Cell(3)))).to_list() == [1, 2, 3]
25
+
26
+ c3: cell.Cell[int] = cell.new_from([1, 2, 3, 4])
27
+ assert c3.to_list() == [1, 2, 3, 4]
28
+
29
+ base.verbose_assert_eq(c3.go(0).value, 1)
30
+ base.verbose_assert_eq(c3.go(1).value, 2)
31
+ base.verbose_assert_eq(c3.go(2).value, 3)
32
+ base.verbose_assert_eq(c3.go(3).value, 4)
33
+
34
+ print("(?) main.test_chain1() Passed.\n")
35
+ return
36
+
37
+ def test_list1() -> None:
38
+ print("\n(?) main.test_chain1() Start.")
39
+
40
+ c1: cell.Cell[int] = cell.new_from([3, 4, 5])
41
+
42
+ l1: dynamic_list.DynamicList[int] = dynamic_list.DynamicList()
43
+ l1.append(1)
44
+ l1.append(2)
45
+ l1.push(c1)
46
+
47
+ print(f"l1={l1}, len={len(l1)}, l={l1.to_list()}")
48
+
49
+ l2: dynamic_list.DynamicList[int] = dynamic_list.DynamicList()
50
+ print(f"l2={l2}, len={len(l2)}, l={l2.to_list()}")
51
+
52
+ l3: dynamic_list.DynamicList[int] = dynamic_list.DynamicList()
53
+ l3.append(1)
54
+ print(f"l3={l3}, len={len(l3)}, l={l3.to_list()}")
55
+
56
+ print("(?) main.test_chain1() Passed.\n")
57
+ return
58
+
59
+ def test_graph1() -> None:
60
+ """
61
+ Test nodes and graphs.
62
+ """
63
+ n1 = nodes.Node("A")
64
+ n2 = nodes.Node("B")
65
+ n3 = nodes.Node("C")
66
+ n4 = nodes.Node("D")
67
+
68
+ print(n1)
69
+ print(n2)
70
+ print(n3)
71
+ print(n4)
72
+
73
+ n1.batch_next((
74
+ (n1, 1),
75
+ (n2, 2),
76
+ (n3, 2),
77
+ (n4, 5)
78
+ ))
79
+
80
+ n1.batch_previous((
81
+ (n3, 4),
82
+ (n4, 1)
83
+ ))
84
+
85
+ n4.batch_next((
86
+ (n2, 2),
87
+ (n3, 1),
88
+ ))
89
+
90
+ print(n1, n1.display(' '))
91
+
92
+
93
+
94
+
95
+ def help() -> str:
96
+ return """## Help.
97
+
98
+ ### Arguments.
99
+ `--test` | `-t`: Launch testing;
100
+
101
+ """
102
+
103
+ def test() -> None:
104
+ print("## Tests.")
105
+
106
+ # test_chain1()
107
+ # test_list1()
108
+
109
+ test_graph1()
110
+
111
+ return
112
+
113
+ def main() -> None:
114
+ print("# Data structures.")
115
+
116
+ arguments: list[str] = sys.argv
117
+
118
+ if len(arguments) == 1:
119
+ print("\nUser selected no arguments.\n")
120
+
121
+ print(help())
122
+ return
123
+
124
+ for argument in arguments:
125
+ if argument in {"--test", "-t"}:
126
+ test()
127
+
128
+ return
129
+
130
+ main()
@@ -0,0 +1,4 @@
1
+ """
2
+ # Data structures.
3
+ /src/structures_detroix23/modules/__init__.py
4
+ """
@@ -0,0 +1,18 @@
1
+ """
2
+ # Data structures.
3
+ /src/structures_detroix23/modules/base.py.
4
+ Base.
5
+ """
6
+
7
+ from typing import Any
8
+
9
+ def verbose_assert_eq(a: Any, b: Any) -> bool:
10
+ """
11
+ Compare 2 values.
12
+ - raise `AssertionError` if not equal, and prints the values.
13
+ - returns `True` if passed.
14
+ """
15
+ if a != b:
16
+ raise AssertionError(f"(X) verbose_assert_eq(a={a}, b={b}) `a` != `b`.")
17
+ else:
18
+ return True
@@ -0,0 +1,99 @@
1
+ """
2
+ # Data structures.
3
+ /src/structures_detroix23/modules/chain.py
4
+ """
5
+
6
+ from typing import Optional, TypeVar, Generic
7
+
8
+ _T_CELL = TypeVar("_T_CELL")
9
+
10
+ class Cell(Generic[_T_CELL]):
11
+ """
12
+ Define a cell from a chained list.
13
+ """
14
+ _value: _T_CELL
15
+ _following: Optional['Cell[_T_CELL]']
16
+
17
+ def __init__(self, value: _T_CELL, following: Optional['Cell[_T_CELL]'] = None) -> None:
18
+ self._value = value
19
+ self._following = following
20
+
21
+ def __str__(self) -> str:
22
+ display: list[str] = []
23
+ current: Optional[Cell[_T_CELL]] = self.clone()
24
+ while current is not None:
25
+ display.append(str(current.value))
26
+ current = current.following
27
+
28
+ return f"<{', '.join(display)}>"
29
+
30
+ def __repr__(self) -> str:
31
+ return f"chain.Cell(value={self.value}, following={repr(self.following)})"
32
+
33
+ def clone(self) -> 'Cell[_T_CELL]':
34
+ return Cell(
35
+ value=self.value,
36
+ following=self.following,
37
+ )
38
+
39
+ @property
40
+ def value(self) -> _T_CELL:
41
+ """
42
+ Get the read-only `value` of the cell.
43
+ """
44
+ return self._value
45
+
46
+ @property
47
+ def following(self) -> Optional['Cell[_T_CELL]']:
48
+ """
49
+ Get the read-only `following` next cell. Return `None` if has no following.
50
+ """
51
+ return self._following
52
+
53
+ def set_following(self, new: 'Cell[_T_CELL]') -> None:
54
+ """
55
+ Set the `following` to a `new` cell.
56
+ """
57
+ print(f"(?) set_following={new}")
58
+ self._following = new
59
+
60
+
61
+ def to_list(self) -> list[_T_CELL]:
62
+ """
63
+ Returns a `list[_T_CELL]` of the values.
64
+ """
65
+ current: Cell[_T_CELL] = self.clone()
66
+ l: list[_T_CELL] = [current.value]
67
+
68
+ while current.following is not None:
69
+ current = current.following
70
+ l.append(current.value)
71
+
72
+ return l
73
+
74
+ def go(self, steps: int) -> 'Cell[_T_CELL]':
75
+ """
76
+ Move up `steps` times, and return the `Cell`.
77
+ Throws an `IndexError` if the index is out of range.
78
+ """
79
+ current: Cell[_T_CELL] = self.clone()
80
+
81
+ while steps > 0:
82
+ if current.following is None:
83
+ raise IndexError(f"(X) - modules.chain.Cell.go - Index out of range. steps={steps}, cell={repr(current)}")
84
+ current = current.following
85
+
86
+ steps -= 1
87
+
88
+ return current
89
+
90
+ def new_from(values: list[_T_CELL]) -> 'Cell[_T_CELL]':
91
+ """
92
+ Generate a chained list from a given `values` list.
93
+ """
94
+ values.reverse()
95
+ current: Cell[_T_CELL] = Cell(values[0])
96
+ for value in values[1:]:
97
+ current = Cell(value, current)
98
+
99
+ return current
@@ -0,0 +1,105 @@
1
+ """
2
+ # Data structures.
3
+ /src/structures_detroix23/modules/dynamic_list.py
4
+ """
5
+
6
+ from typing import Optional, TypeVar, Generic
7
+
8
+ from structures_detroix23.modules import (
9
+ cell,
10
+ )
11
+
12
+ _T_LIST = TypeVar("_T_LIST")
13
+
14
+ class DynamicList(Generic[_T_LIST]):
15
+ """
16
+ # `DynamicList`.
17
+ """
18
+ data: Optional[cell.Cell[_T_LIST]]
19
+
20
+ def __init__(self, data: Optional[cell.Cell[_T_LIST]] = None) -> None:
21
+ self.data = data
22
+
23
+ def __len__(self) -> int:
24
+ counter: int = 0
25
+
26
+ if self.data is not None:
27
+ current: cell.Cell[_T_LIST] = self.data
28
+ counter += 1
29
+
30
+ while current.following is not None:
31
+ current = current.following
32
+ counter += 1
33
+
34
+ return counter
35
+
36
+ def __repr__(self) -> str:
37
+ if self.is_empty():
38
+ return f"DynamicList(None)"
39
+ else:
40
+ return f"DynamicList({repr(self.data)})"
41
+
42
+ def __str__(self) -> str:
43
+ if self.is_empty():
44
+ return f"List<>"
45
+ else:
46
+ return f"List{self.data}"
47
+
48
+ def is_empty(self) -> bool:
49
+ """
50
+ Return `True` if the list is empty.
51
+ """
52
+ return self.data is None
53
+
54
+ def to_list(self) -> list[_T_LIST]:
55
+ if self.data is None:
56
+ return []
57
+
58
+ current: cell.Cell[_T_LIST] = self.data
59
+ l: list[_T_LIST] = [current.value]
60
+
61
+ while current.following is not None:
62
+ current = current.following
63
+ l.append(current.value)
64
+
65
+ return l
66
+
67
+ def get_last(self) -> cell.Cell[_T_LIST]:
68
+ """
69
+ Get a reference to the last `Cell` of the list.
70
+
71
+ Raises a `ValueError` if the list is empty.
72
+ """
73
+ if self.data is None:
74
+ raise ValueError(f"(X) modules.dynamic_list.DynamicList.get_last() list ({self}) is empty.")
75
+
76
+ current: cell.Cell[_T_LIST] = self.data
77
+
78
+ while current.following is not None:
79
+ current = current.following
80
+
81
+ return current
82
+
83
+
84
+ def push(self, new: cell.Cell[_T_LIST]) -> None:
85
+ """
86
+ Add a `Cell` to the `following` of the last current `Cell`.
87
+ """
88
+ if self.data is None:
89
+ self.data = new
90
+
91
+ else:
92
+ last = self.get_last()
93
+ print(f"(?) last={last}", end=" ")
94
+ last.set_following(new)
95
+ print(f"(?) last={last}, self.get_last={self.get_last()}")
96
+
97
+
98
+ def append(self, value: _T_LIST) -> None:
99
+ """
100
+ Add an item `value` to the end of the list.
101
+
102
+ Creates a new `Cell` englobing the `value.
103
+ """
104
+ self.push(cell.Cell(value, None))
105
+
@@ -0,0 +1,56 @@
1
+ """
2
+ # Data structures.
3
+ /src/structures_detroix23/modules/graphs.py
4
+ """
5
+
6
+ from typing import Optional
7
+
8
+ from structures_detroix23.modules import (
9
+ nodes,
10
+ )
11
+
12
+ class Graph:
13
+ """
14
+ Describe abstractly the base of any `Graph` representation.
15
+ """
16
+ register: list[nodes.Node]
17
+
18
+ def __init__(
19
+ self,
20
+ register: Optional[list[nodes.Node]]
21
+ ) -> None:
22
+ self.register = register if register is not None else []
23
+
24
+
25
+ class Explorer:
26
+ """
27
+ Allows the exploring of a graph without infinite recursion.
28
+ """
29
+ graph: Graph
30
+ current: nodes.Node
31
+ seen: set[nodes.Node]
32
+
33
+ def __init__(self, graph: Graph, current: nodes.Node) -> None:
34
+ self.graph = graph
35
+ self.current = current
36
+ self.seen = set()
37
+
38
+
39
+ def move(self, destination: nodes.Node) -> bool:
40
+ """
41
+ Move to a `Node`. Return `True` if succeed, `False` if:
42
+ - is not reachable from `current`,
43
+ - has already been `seen`.
44
+ """
45
+ if (
46
+ destination in self.current.get_next().keys()
47
+ and destination not in self.seen
48
+ ):
49
+ self.current = destination
50
+ return True
51
+
52
+ return False
53
+
54
+
55
+
56
+
@@ -0,0 +1,173 @@
1
+ """
2
+ # Data structures.
3
+ /src/structures_detroix23/modules/nodes.py.
4
+ """
5
+
6
+ from typing import Optional, Self, Iterable
7
+
8
+ from structures_detroix23.modules.types import Weight
9
+
10
+ class Node:
11
+ """
12
+ # `Node`.
13
+ Define a named cell, holding no value except:
14
+ - `_name`: `str`, a globally unique name.
15
+ - `_previous`: `dict['Node', Weight]`, containing as many references to other nodes.
16
+ - `_next`: `dict['Node', Weight]`, containing as many references to other nodes.
17
+
18
+ Class variables:
19
+ - `last_id`: `int`, store the last created id, to ensure uniqueness.
20
+ """
21
+ _last_id: int = 0
22
+
23
+ _id: int
24
+ _name: str
25
+ _previous: dict['Node', Weight]
26
+ _next: dict['Node', Weight]
27
+
28
+ def __new__(
29
+ cls,
30
+ name: str,
31
+ previous: Optional[dict['Node', Weight]] = None,
32
+ next: Optional[dict['Node', Weight]] = None,
33
+ ) -> Self:
34
+ new: Self = super(Node, cls).__new__(cls)
35
+
36
+ new._id = Node._last_id
37
+ Node._last_id += 1
38
+
39
+ return new
40
+
41
+ def __init__(
42
+ self,
43
+ name: str,
44
+ previous: Optional[dict['Node', Weight]] = None,
45
+ next: Optional[dict['Node', Weight]] = None,
46
+ ) -> None:
47
+ """
48
+ Instantiate a new `Node`.
49
+ - `name` must be unique globally.
50
+ """
51
+ self._name = name
52
+ self._previous = previous if previous is not None else {}
53
+ self._next = next if next is not None else {}
54
+
55
+ def __hash__(self) -> int:
56
+ return self.get_id()
57
+
58
+ def __repr__(self) -> str:
59
+ return f"Node(name={self._name}, id={self._id}, previous={self._previous}, next={self._next})"
60
+
61
+ def __str__(self) -> str:
62
+ return f"{self._name}"
63
+
64
+ def get_id(self) -> int:
65
+ """
66
+ Returns the unique, read-only `_id` of the `Node`.
67
+ """
68
+ return self._id
69
+
70
+ def get_name(self) -> str:
71
+ """
72
+ Returns the read-only `_name` of the `Node`.
73
+ """
74
+ return self._name
75
+
76
+ def get_previous(self) -> dict['Node', Weight]:
77
+ """
78
+ Returns the read-only `_previous` of the `Node`.
79
+ """
80
+ return self._previous
81
+
82
+ def get_next(self) -> dict['Node', Weight]:
83
+ """
84
+ Returns the read-only `_next` of the `Node`.
85
+ """
86
+ return self._next
87
+
88
+ def set_previous(self, node: 'Node', weight: Weight) -> None:
89
+ """
90
+ Create or update in `previous` the `node` with `weight`.
91
+ """
92
+ self._previous[node] = weight
93
+
94
+ def set_next(self, node: 'Node', weight: Weight) -> None:
95
+ """
96
+ Create or update in `next` the `node` with `weight`.
97
+ """
98
+ self._next[node] = weight
99
+
100
+ def batch_previous(self, nodes: Iterable[tuple['Node', Weight]]) -> None:
101
+ """
102
+ Update multiple `nodes` in `previous`, from an `Iterable` of `(Node, Weight)`.
103
+ """
104
+ for node, weight in nodes:
105
+ self.set_previous(node, weight)
106
+
107
+ def batch_next(self, nodes: Iterable[tuple['Node', Weight]]) -> None:
108
+ """
109
+ Update multiple `nodes` in `next`, from an `Iterable` of `(Node, Weight)`.
110
+ """
111
+ for node, weight in nodes:
112
+ self.set_next(node, weight)
113
+
114
+
115
+ def remove_previous(self, node: 'Node') -> Optional[Weight]:
116
+ """
117
+ Remove the given `node` from `previous`.
118
+
119
+ Return the weight, or `None` if `node` didn't existed.
120
+ """
121
+ self._previous.pop(node, None)
122
+
123
+ def remove_next(self, node: 'Node') -> Optional[Weight]:
124
+ """
125
+ Remove the given `node` from `next`.
126
+
127
+ Return the weight, or `None` if `node` didn't existed.
128
+ """
129
+ self._next.pop(node, None)
130
+
131
+ def display(
132
+ self,
133
+ tab: str,
134
+ level: int = 0,
135
+ seen: Optional[set['Node']] = None,
136
+ ) -> str:
137
+ """
138
+ Multiple line readable representation of the `Node`.
139
+ """
140
+ seen_current: set[Node] = seen if seen is not None else set[Node]()
141
+
142
+ return "\n".join([
143
+ "{",
144
+ f"{tab * (level + 1)}previous: {pretty(self.get_previous(), seen_current, tab, level + 1)},",
145
+ f"{tab * (level + 1)}next: {pretty(self.get_next(), seen_current, tab, level + 1)},",
146
+ f"{tab * level}" + "}"
147
+ ])
148
+
149
+ def pretty(
150
+ iterable: dict['Node', Weight],
151
+ seen: set['Node'],
152
+ tab: str = "\t",
153
+ level: int = 0,
154
+ ) -> str:
155
+ """
156
+ Return a pretty formatted line broken string of a `dict`.
157
+ """
158
+
159
+ lines: list[str] = ["{"]
160
+
161
+ if len(iterable) == 0:
162
+ return "{}"
163
+
164
+ for node, weight in iterable.items():
165
+ if node in seen:
166
+ lines.append(f"{tab * (level + 1)}{node}: {weight}")
167
+ else:
168
+ seen.add(node)
169
+ lines.append(f"{tab * (level + 1)}{node}: {weight}, {node.display(tab, level + 1, seen)}")
170
+
171
+ lines.append(tab * level + "}")
172
+
173
+ return "\n".join(lines)
@@ -0,0 +1,60 @@
1
+ """
2
+ # Data structures.
3
+ /src/structures_detroix23/modules/nodes.py.
4
+ """
5
+
6
+ from typing import Optional, TypeVar, Generic
7
+
8
+ _T_RESULT_ERROR = TypeVar("_T_RESULT_ERROR")
9
+ _T_RESULT_OK = TypeVar("_T_RESULT_OK")
10
+
11
+
12
+ class UnwrapException(Exception):
13
+ """
14
+ # `UnwrapException`.
15
+ Raised when trying to unwrap a `Result` containing an error.
16
+ """
17
+ message: str
18
+
19
+ def __init__(self, message: str) -> None:
20
+ super().__init__(message)
21
+ self.message = message
22
+
23
+ def __str__(self) -> str:
24
+ return super().__str__()
25
+
26
+
27
+ class Result(Generic[_T_RESULT_OK, _T_RESULT_ERROR]):
28
+ """
29
+ # `Result`.
30
+ Rust like `Result`, containing or an error, or a success value.
31
+
32
+ Define 2 generics:
33
+ 1. `_T_RESULT_OK`,
34
+ 2. `_T_RESULT_ERROR`.
35
+ """
36
+ ok: Optional[_T_RESULT_OK]
37
+ error: Optional[_T_RESULT_ERROR]
38
+
39
+ def __init__(
40
+ self,
41
+ ok: Optional[_T_RESULT_OK],
42
+ error: Optional[_T_RESULT_ERROR]
43
+ ) -> None:
44
+ self.ok = ok
45
+ self.error = error
46
+
47
+ def unwrap(self) -> _T_RESULT_OK:
48
+ """
49
+ Return the `ok` value. If there is an `error, raise an `UnwrapException`.
50
+ """
51
+ if self.error is not None or self.ok is None:
52
+ raise UnwrapException(str(self.error))
53
+
54
+ return self.ok
55
+
56
+ def is_ok(self) -> bool:
57
+ """
58
+ Return `True` if no error.
59
+ """
60
+ return self.error is None and self.ok is not None
@@ -0,0 +1,8 @@
1
+ """
2
+ # Data structures.
3
+ /src/structures_detroix23/modules/types.py
4
+ """
5
+
6
+ from typing import Union
7
+
8
+ Weight = Union[int, float]
@@ -0,0 +1,24 @@
1
+ Metadata-Version: 2.4
2
+ Name: structures_detroix23
3
+ Version: 0.0.3
4
+ Summary: Python structures.
5
+ Author-email: Detroix23 <detroix23@gmail.com>
6
+ License-Expression: CC-BY-4.0
7
+ Project-URL: Repository, https://github.com/Detroix23/py_structures
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Operating System :: OS Independent
10
+ Classifier: Natural Language :: English
11
+ Requires-Python: >=3.12
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE.md
14
+ Dynamic: license-file
15
+
16
+ # Data structures.
17
+
18
+ Classes:
19
+ - Chained lists (algorithmically);
20
+ - Stack;
21
+ - Queue;
22
+ - Doubly-chained lists;
23
+ - Tree;
24
+ - Graphs;
@@ -0,0 +1,17 @@
1
+ LICENSE.md
2
+ README.md
3
+ pyproject.toml
4
+ src/structures_detroix23/__init__.py
5
+ src/structures_detroix23/__main__.py
6
+ src/structures_detroix23.egg-info/PKG-INFO
7
+ src/structures_detroix23.egg-info/SOURCES.txt
8
+ src/structures_detroix23.egg-info/dependency_links.txt
9
+ src/structures_detroix23.egg-info/top_level.txt
10
+ src/structures_detroix23/modules/__init__.py
11
+ src/structures_detroix23/modules/base.py
12
+ src/structures_detroix23/modules/cell.py
13
+ src/structures_detroix23/modules/dynamic_list.py
14
+ src/structures_detroix23/modules/graphs.py
15
+ src/structures_detroix23/modules/nodes.py
16
+ src/structures_detroix23/modules/result.py
17
+ src/structures_detroix23/modules/types.py