pydasa 0.4.7__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.
- pydasa/__init__.py +103 -0
- pydasa/_version.py +6 -0
- pydasa/analysis/__init__.py +0 -0
- pydasa/analysis/scenario.py +584 -0
- pydasa/analysis/simulation.py +1158 -0
- pydasa/context/__init__.py +0 -0
- pydasa/context/conversion.py +11 -0
- pydasa/context/system.py +17 -0
- pydasa/context/units.py +15 -0
- pydasa/core/__init__.py +15 -0
- pydasa/core/basic.py +287 -0
- pydasa/core/cfg/default.json +136 -0
- pydasa/core/constants.py +27 -0
- pydasa/core/io.py +102 -0
- pydasa/core/setup.py +269 -0
- pydasa/dimensional/__init__.py +0 -0
- pydasa/dimensional/buckingham.py +728 -0
- pydasa/dimensional/fundamental.py +146 -0
- pydasa/dimensional/model.py +1077 -0
- pydasa/dimensional/vaschy.py +633 -0
- pydasa/elements/__init__.py +19 -0
- pydasa/elements/parameter.py +218 -0
- pydasa/elements/specs/__init__.py +22 -0
- pydasa/elements/specs/conceptual.py +161 -0
- pydasa/elements/specs/numerical.py +469 -0
- pydasa/elements/specs/statistical.py +229 -0
- pydasa/elements/specs/symbolic.py +394 -0
- pydasa/serialization/__init__.py +27 -0
- pydasa/serialization/parser.py +133 -0
- pydasa/structs/__init__.py +0 -0
- pydasa/structs/lists/__init__.py +0 -0
- pydasa/structs/lists/arlt.py +578 -0
- pydasa/structs/lists/dllt.py +18 -0
- pydasa/structs/lists/ndlt.py +262 -0
- pydasa/structs/lists/sllt.py +746 -0
- pydasa/structs/tables/__init__.py +0 -0
- pydasa/structs/tables/htme.py +182 -0
- pydasa/structs/tables/scht.py +774 -0
- pydasa/structs/tools/__init__.py +0 -0
- pydasa/structs/tools/hashing.py +53 -0
- pydasa/structs/tools/math.py +149 -0
- pydasa/structs/tools/memory.py +54 -0
- pydasa/structs/types/__init__.py +0 -0
- pydasa/structs/types/functions.py +131 -0
- pydasa/structs/types/generics.py +54 -0
- pydasa/validations/__init__.py +0 -0
- pydasa/validations/decorators.py +510 -0
- pydasa/validations/error.py +100 -0
- pydasa/validations/patterns.py +32 -0
- pydasa/workflows/__init__.py +1 -0
- pydasa/workflows/influence.py +497 -0
- pydasa/workflows/phenomena.py +529 -0
- pydasa/workflows/practical.py +765 -0
- pydasa-0.4.7.dist-info/METADATA +320 -0
- pydasa-0.4.7.dist-info/RECORD +58 -0
- pydasa-0.4.7.dist-info/WHEEL +5 -0
- pydasa-0.4.7.dist-info/licenses/LICENSE +674 -0
- pydasa-0.4.7.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Module ndlt.py
|
|
4
|
+
===========================================
|
|
5
|
+
|
|
6
|
+
Module to represent the **Node** data structure for the **Linked List** and **Doubly Linked List** in *PyDASA*.
|
|
7
|
+
|
|
8
|
+
Classes:
|
|
9
|
+
**Node**: Base class for creating Single Linked List Node or **SLNode** and Double Linked List Node or **DLNode**.
|
|
10
|
+
**SLNode**: Implements a single linked list node with data and next node reference.
|
|
11
|
+
**DLNode**: Implements a double linked list node with data, next node, and previous node references.
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
*IMPORTANT:* based on the implementations proposed by the following authors/books:
|
|
15
|
+
|
|
16
|
+
# . Algorithms, 4th Edition, Robert Sedgewick and Kevin Wayne.
|
|
17
|
+
# . Data Structure and Algorithms in Python, M.T. Goodrich, R. Tamassia, M.H. Goldwasser.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
# native python modules
|
|
21
|
+
# import dataclass for defining the node class
|
|
22
|
+
from dataclasses import dataclass
|
|
23
|
+
# import modules for defining the Node type
|
|
24
|
+
from typing import Generic, Optional
|
|
25
|
+
# import inspect for getting the name of the current function
|
|
26
|
+
import inspect
|
|
27
|
+
|
|
28
|
+
# custom modules
|
|
29
|
+
# generic error handling and type checking
|
|
30
|
+
from pydasa.validations.error import handle_error as error
|
|
31
|
+
from pydasa.structs.types.generics import T
|
|
32
|
+
# import global variables
|
|
33
|
+
|
|
34
|
+
# checking custom modules
|
|
35
|
+
assert error
|
|
36
|
+
assert T
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dataclass
|
|
40
|
+
class Node(Generic[T]):
|
|
41
|
+
"""**Node** base class for creating Single Linked List Node or **SLNode** and Double Linked List Node or **DLNode**. Fundamental for the **Linked List** and **Doubly Linked List** data structures.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
Generic (T): Generic type for a Python data structure.
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
Node: A node object with the following attributes:
|
|
48
|
+
- `_data`: The data stored in the node.
|
|
49
|
+
"""
|
|
50
|
+
# optional information of any type
|
|
51
|
+
# :attr: _data
|
|
52
|
+
_data: Optional[T] = None
|
|
53
|
+
"""
|
|
54
|
+
data stored in the node. By default, it is set to None.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
def _error_handler(self, err: Exception) -> None:
|
|
58
|
+
"""*_error_handler()* function that handles the errors that can occur in the *Node*.
|
|
59
|
+
|
|
60
|
+
if an error occurs in *SingleLinkedList*, it formats the error according to the context (package/module/class), the function (method) that generated it, and sends it to the upper component in the *DataStruct* hierarchy to handle it as the user considers appropriate.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
err (Exception): Exception that occurred in the *Node*.
|
|
64
|
+
"""
|
|
65
|
+
# TODO check utility of this error handling
|
|
66
|
+
_context = self.__class__.__name__
|
|
67
|
+
_function_name = "unknown"
|
|
68
|
+
frame = inspect.currentframe()
|
|
69
|
+
if frame is not None:
|
|
70
|
+
if frame.f_back is not None:
|
|
71
|
+
_function_name = frame.f_back.f_code.co_name
|
|
72
|
+
else:
|
|
73
|
+
_function_name = "unknown"
|
|
74
|
+
error(_context, _function_name, err)
|
|
75
|
+
|
|
76
|
+
def _validate_type(self, elm: Optional[T]) -> bool:
|
|
77
|
+
"""*_validate_type()* function that checks if the type of the element is the same as the type of the *Node*.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
elm (Optional[T]): element to be processed in the *Node*.
|
|
81
|
+
- *T*: Type of the element to be processed in the *Node*.
|
|
82
|
+
|
|
83
|
+
Raises:
|
|
84
|
+
TypeError: error if the type of the element to be added is not the same as the type of the elements already contained in the *Node*.
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
bool: True if the type of the element is the same as the type of the *Node*. False otherwise.
|
|
88
|
+
"""
|
|
89
|
+
_result: bool = True
|
|
90
|
+
if elm is not None and self._data is not None and not isinstance(elm, type(self._data)):
|
|
91
|
+
_msg = f"Invalid data type: {type(elm)} "
|
|
92
|
+
_msg += f"Node configured with {type(self._data)}"
|
|
93
|
+
raise TypeError(_msg)
|
|
94
|
+
return _result
|
|
95
|
+
|
|
96
|
+
@property
|
|
97
|
+
def data(self) -> T: # Optional[T]:
|
|
98
|
+
"""*data* Property to read the data in the *Node*. Acts as a getter (*get()*) for the *_data* attribute.
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
T: data stored in the *Node*.
|
|
102
|
+
"""
|
|
103
|
+
# return self._data
|
|
104
|
+
if self._data is None:
|
|
105
|
+
raise ValueError("Node data has not been initialized")
|
|
106
|
+
return self._data
|
|
107
|
+
|
|
108
|
+
@data.setter
|
|
109
|
+
def data(self, data: T) -> None:
|
|
110
|
+
"""*data* Property to write the data in the *Node*. Acts as a setter (*set()*) for the *_data* attribute.
|
|
111
|
+
|
|
112
|
+
Args:
|
|
113
|
+
data (T): data to be set in the *Node*.
|
|
114
|
+
"""
|
|
115
|
+
if self._data is not None:
|
|
116
|
+
self._validate_type(data)
|
|
117
|
+
self._data = data
|
|
118
|
+
|
|
119
|
+
def __str__(self) -> str:
|
|
120
|
+
"""*__str__()* function to return a string representation of the *Node*. It also extendes for the *SLNode* and *DLNode* classes.
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
str: string representation of the *Node*.
|
|
124
|
+
"""
|
|
125
|
+
_attr_lt = []
|
|
126
|
+
for attr, value in vars(self).items():
|
|
127
|
+
# Skip private attributes starting with "__"
|
|
128
|
+
if attr.startswith("__"):
|
|
129
|
+
continue
|
|
130
|
+
# Format callable attributes
|
|
131
|
+
if callable(value):
|
|
132
|
+
value = f"{value.__name__}{inspect.signature(value)}"
|
|
133
|
+
# Format attribute name and value
|
|
134
|
+
_attr_name = attr.lstrip("_")
|
|
135
|
+
_attr_lt.append(f"{_attr_name}={repr(value)}")
|
|
136
|
+
# Format the string representation of Node class
|
|
137
|
+
_str = f"{self.__class__.__name__}({', '.join(_attr_lt)})"
|
|
138
|
+
return _str
|
|
139
|
+
|
|
140
|
+
def __repr__(self) -> str:
|
|
141
|
+
"""*__repr__()* function to return a string representation of the *Node*. It also extendes for the *SLNode* and *DLNode* classes.
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
str: string representation of the *Node*.
|
|
145
|
+
"""
|
|
146
|
+
return self.__str__()
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
@dataclass
|
|
150
|
+
class SLNode(Node[T]):
|
|
151
|
+
"""**SLNode** class for creating a Single Linked List Node. Inherits from the **Node** class. Fundamental for the **Linked List** data structure.
|
|
152
|
+
|
|
153
|
+
Args:
|
|
154
|
+
Node (dataclass): **Node** base class for creating single and double linked nodes.
|
|
155
|
+
Generic (T): Generic type for a Python data structure.
|
|
156
|
+
|
|
157
|
+
Returns:
|
|
158
|
+
SLNode: A single linked node object with the following attributes:
|
|
159
|
+
- `_data`: The data stored in the node.
|
|
160
|
+
- `_next`: The next node of the same type.
|
|
161
|
+
"""
|
|
162
|
+
# optional reference to the next node of the same type
|
|
163
|
+
# :attr: _next
|
|
164
|
+
_next: Optional["SLNode[T]"] = None
|
|
165
|
+
"""
|
|
166
|
+
next node of the same type. By default, it is set to None.
|
|
167
|
+
"""
|
|
168
|
+
|
|
169
|
+
@property
|
|
170
|
+
def next(self) -> Optional["SLNode[T]"]:
|
|
171
|
+
""""*next()* Property to read the next node in the list. Acts as a getter (*get()*) for the *_next* attribute.
|
|
172
|
+
|
|
173
|
+
Returns:
|
|
174
|
+
Optional["SLNode[T]"]: reference to the next node of the list. If there is no next node, it returns None.
|
|
175
|
+
"""
|
|
176
|
+
return self._next
|
|
177
|
+
|
|
178
|
+
@next.setter
|
|
179
|
+
def next(self, node: Optional["SLNode[T]"]) -> None:
|
|
180
|
+
"""*next()* Property to write the next node in the list. Acts as a setter (*set()*) for the *_next* attribute.
|
|
181
|
+
|
|
182
|
+
Args:
|
|
183
|
+
node (Optional["SLNode[T]"]): reference to the next node of the list.
|
|
184
|
+
"""
|
|
185
|
+
if node is not None:
|
|
186
|
+
self._validate_type(node.data)
|
|
187
|
+
self._next = node
|
|
188
|
+
|
|
189
|
+
def __str__(self) -> str:
|
|
190
|
+
"""*__str__()* function to return a string representation of the *SLNode*. It also extends the *Node* class.
|
|
191
|
+
|
|
192
|
+
Returns:
|
|
193
|
+
str: string representation of the *SLNode*.
|
|
194
|
+
"""
|
|
195
|
+
_str = super().__str__()
|
|
196
|
+
return _str
|
|
197
|
+
|
|
198
|
+
def __repr__(self) -> str:
|
|
199
|
+
"""*__repr__()* function to return a string representation of the *SLNode*. It also extends the *Node* class.
|
|
200
|
+
|
|
201
|
+
Returns:
|
|
202
|
+
str: string representation of the *SLNode*.
|
|
203
|
+
"""
|
|
204
|
+
_str = super().__repr__()
|
|
205
|
+
return _str
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
@dataclass
|
|
209
|
+
class DLNode(SLNode[T]):
|
|
210
|
+
"""**DLNode** class for creating a Double Linked List Node. Inherits from the **SLNode** class. Fundamental for the **Doubly Linked List** data structure.
|
|
211
|
+
|
|
212
|
+
Args:
|
|
213
|
+
SLNode (dataclass): **SLNode** class for creating a single linked list node.
|
|
214
|
+
Generic (T): Generic type for a Python data structure.
|
|
215
|
+
|
|
216
|
+
Returns:
|
|
217
|
+
DLNode: A double linked node object with the following attributes:
|
|
218
|
+
- `_data`: The data stored in the node.
|
|
219
|
+
- `_next`: The next node of the same type.
|
|
220
|
+
- `_prev`: The previous node of the same type.
|
|
221
|
+
"""
|
|
222
|
+
# optional reference to the previous node of the same type
|
|
223
|
+
# :attr: _prev
|
|
224
|
+
_prev: Optional["DLNode[T]"] = None
|
|
225
|
+
|
|
226
|
+
@property
|
|
227
|
+
def prev(self) -> Optional["DLNode[T]"]:
|
|
228
|
+
"""*prev()* Property to read the previous node in the list. Acts as a getter (*get()*) for the *_prev* attribute.
|
|
229
|
+
|
|
230
|
+
Returns:
|
|
231
|
+
node (Optional["DLNode[T]"]): reference to the previous node of the list.
|
|
232
|
+
"""
|
|
233
|
+
return self._prev
|
|
234
|
+
|
|
235
|
+
@prev.setter
|
|
236
|
+
def prev(self, node: Optional["DLNode[T]"]) -> None:
|
|
237
|
+
"""*prev()* Property to write the previous node in the list. Acts as a setter (*set()*) for the *_prev* attribute.
|
|
238
|
+
|
|
239
|
+
Args:
|
|
240
|
+
node (Optional["DLNode[T]"]): reference to the previous node of the list.
|
|
241
|
+
"""
|
|
242
|
+
if node is not None:
|
|
243
|
+
self._validate_type(node.data)
|
|
244
|
+
self._prev = node
|
|
245
|
+
|
|
246
|
+
def __str__(self) -> str:
|
|
247
|
+
"""*__str__()* function to return a string representation of the *DLNode*. It also extends the *Node* class.
|
|
248
|
+
|
|
249
|
+
Returns:
|
|
250
|
+
str: string representation of the *DLNode*.
|
|
251
|
+
"""
|
|
252
|
+
_str = super().__str__()
|
|
253
|
+
return _str
|
|
254
|
+
|
|
255
|
+
def __repr__(self) -> str:
|
|
256
|
+
"""*__repr__()* function to return a string representation of the *DLNode*. It also extends the *Node* class.
|
|
257
|
+
|
|
258
|
+
Returns:
|
|
259
|
+
str: string representation of the *DLNode*.
|
|
260
|
+
"""
|
|
261
|
+
_str = super().__repr__()
|
|
262
|
+
return _str
|