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.
Files changed (58) hide show
  1. pydasa/__init__.py +103 -0
  2. pydasa/_version.py +6 -0
  3. pydasa/analysis/__init__.py +0 -0
  4. pydasa/analysis/scenario.py +584 -0
  5. pydasa/analysis/simulation.py +1158 -0
  6. pydasa/context/__init__.py +0 -0
  7. pydasa/context/conversion.py +11 -0
  8. pydasa/context/system.py +17 -0
  9. pydasa/context/units.py +15 -0
  10. pydasa/core/__init__.py +15 -0
  11. pydasa/core/basic.py +287 -0
  12. pydasa/core/cfg/default.json +136 -0
  13. pydasa/core/constants.py +27 -0
  14. pydasa/core/io.py +102 -0
  15. pydasa/core/setup.py +269 -0
  16. pydasa/dimensional/__init__.py +0 -0
  17. pydasa/dimensional/buckingham.py +728 -0
  18. pydasa/dimensional/fundamental.py +146 -0
  19. pydasa/dimensional/model.py +1077 -0
  20. pydasa/dimensional/vaschy.py +633 -0
  21. pydasa/elements/__init__.py +19 -0
  22. pydasa/elements/parameter.py +218 -0
  23. pydasa/elements/specs/__init__.py +22 -0
  24. pydasa/elements/specs/conceptual.py +161 -0
  25. pydasa/elements/specs/numerical.py +469 -0
  26. pydasa/elements/specs/statistical.py +229 -0
  27. pydasa/elements/specs/symbolic.py +394 -0
  28. pydasa/serialization/__init__.py +27 -0
  29. pydasa/serialization/parser.py +133 -0
  30. pydasa/structs/__init__.py +0 -0
  31. pydasa/structs/lists/__init__.py +0 -0
  32. pydasa/structs/lists/arlt.py +578 -0
  33. pydasa/structs/lists/dllt.py +18 -0
  34. pydasa/structs/lists/ndlt.py +262 -0
  35. pydasa/structs/lists/sllt.py +746 -0
  36. pydasa/structs/tables/__init__.py +0 -0
  37. pydasa/structs/tables/htme.py +182 -0
  38. pydasa/structs/tables/scht.py +774 -0
  39. pydasa/structs/tools/__init__.py +0 -0
  40. pydasa/structs/tools/hashing.py +53 -0
  41. pydasa/structs/tools/math.py +149 -0
  42. pydasa/structs/tools/memory.py +54 -0
  43. pydasa/structs/types/__init__.py +0 -0
  44. pydasa/structs/types/functions.py +131 -0
  45. pydasa/structs/types/generics.py +54 -0
  46. pydasa/validations/__init__.py +0 -0
  47. pydasa/validations/decorators.py +510 -0
  48. pydasa/validations/error.py +100 -0
  49. pydasa/validations/patterns.py +32 -0
  50. pydasa/workflows/__init__.py +1 -0
  51. pydasa/workflows/influence.py +497 -0
  52. pydasa/workflows/phenomena.py +529 -0
  53. pydasa/workflows/practical.py +765 -0
  54. pydasa-0.4.7.dist-info/METADATA +320 -0
  55. pydasa-0.4.7.dist-info/RECORD +58 -0
  56. pydasa-0.4.7.dist-info/WHEEL +5 -0
  57. pydasa-0.4.7.dist-info/licenses/LICENSE +674 -0
  58. 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