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
File without changes
@@ -0,0 +1,53 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Module helpers.py
4
+ ===========================================
5
+
6
+ Module with utility functions for handling memory allocation in the Data Structures of *PyDASA*.
7
+
8
+ Module with utility functions for handling data in the maps of *PyDASA*. Specifically for Separate Chaining and Linear Probing Hash Tables.
9
+
10
+ *IMPORTANT:* based on the implementations proposed by the following authors/books:
11
+
12
+ #. Algorithms, 4th Edition, Robert Sedgewick and Kevin Wayne.
13
+ #. Data Structure and Algorithms in Python, M.T. Goodrich, R. Tamassia, M.H. Goldwasser.
14
+ """
15
+ # python native modules
16
+ from typing import Hashable
17
+ # import math
18
+
19
+ # import global variables
20
+ from pydasa.structs.types.generics import VLD_IOTYPE_LT
21
+
22
+
23
+ def mad_hash(key: Hashable,
24
+ scale: int,
25
+ shift: int,
26
+ prime: int,
27
+ mcap: int) -> int:
28
+ """*mad_hash()* function to compress the indices of the Hash tables using the MAD (Multiply-Add-and-Divide) method.
29
+
30
+ MAD is defined as: mad_hash(y) = ((a*y + b) % p) % M, where:
31
+ a (scale) and b (shift) are random integers in the range [0,p-1], with a > 0
32
+ p (prime) is a prime number greater than M,
33
+ M (capacity) is the size of the table, prime
34
+
35
+ Args:
36
+ key (Hashable): key to calculate the index in the Hash table, Can be any native data type in Python or user-defined.
37
+ scale (int): line slope of the compression function.
38
+ shift (int): offset of the compression function.
39
+ prime (int): prime number much greater than the capacity of the Hash table.
40
+ mcap (int): size of the Hash table, it is a prime number to avoid collisions.
41
+
42
+ Returns:
43
+ int: the index of the element in the Hash table.
44
+ """
45
+ # TODO data should be hashable?
46
+ # data types are (dict, list, set, tuple)
47
+ if isinstance(key, VLD_IOTYPE_LT) or isinstance(key, dict):
48
+ key = str(key)
49
+ # getting the hash from the key
50
+ hkey = hash(key)
51
+ # calculating the index with the MAD compression function
52
+ idx = int((abs(scale * hkey + shift) % prime) % mcap)
53
+ return idx
@@ -0,0 +1,149 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Module math.py
4
+ ===========================================
5
+
6
+ Module with math functions for finding prime numbers and calculating factorials. in *PyDASA*.
7
+
8
+ Module with math functions for handling data in the for Separate Chaining Hash Table.
9
+
10
+ *IMPORTANT:* based on the implementations proposed by the following authors/books:
11
+
12
+ #. Algorithms, 4th Edition, Robert Sedgewick and Kevin Wayne.
13
+ #. Data Structure and Algorithms in Python, M.T. Goodrich, R. Tamassia, M.H. Goldwasser.
14
+
15
+ *NOTE:* code contributed by Sanjit_Prasad in https://www.geeksforgeeks.org/prime-numbers/
16
+ """
17
+ # python native modules
18
+ import math
19
+ from typing import Union, Optional
20
+
21
+
22
+ def is_prime(n: int) -> bool:
23
+ """*is_prime()* checks if a number is prime or not. Original code from Sanjit_Prasad.
24
+
25
+ Args:
26
+ n (int): number to check if it is prime.
27
+
28
+ Returns:
29
+ bool: True if the number is prime, False otherwise.
30
+ """
31
+ # we asume that the number is prime
32
+ # Corner cases
33
+ # check if n is 1 or 0
34
+ prime = True
35
+ if n < 2:
36
+ return False
37
+
38
+ # checking if n is 2 or 3
39
+ if n < 4:
40
+ return prime
41
+
42
+ # checking if n is divisible by 2 or 3
43
+ if n % 2 == 0 or n % 3 == 0:
44
+ return False
45
+
46
+ # checking if n is divisible by 5 to to square root of n
47
+ for i in range(5, int(math.sqrt(n) + 1), 6):
48
+ if n % i == 0 or n % (i + 2) == 0:
49
+ return False
50
+ # return True if the number is prime
51
+ return prime
52
+
53
+
54
+ def next_prime(n: int) -> int:
55
+ """*next_prime()* returns the next prime number greater than n.
56
+
57
+ Args:
58
+ n (int): number to check if it is prime.
59
+
60
+ Returns:
61
+ int: the next prime number greater than n.
62
+ """
63
+ # base case
64
+ if n < 2:
65
+ return 2
66
+
67
+ # working with the next odd number
68
+ prime = n
69
+ found = False
70
+
71
+ # Loop continuously until isPrime returns
72
+ while not found:
73
+ prime += 1
74
+ # True for a prime number greater than n
75
+ if is_prime(prime) is True:
76
+ found = True
77
+ # return the next prime number to n
78
+ return prime
79
+
80
+
81
+ def previous_prime(n: int) -> int:
82
+ """*previous_prime()* returns the previous prime number less than n.
83
+
84
+ Args:
85
+ n (int): number to check if it is prime.
86
+
87
+ Returns:
88
+ int: the previous prime number less than n.
89
+ """
90
+ # base case
91
+ if n < 2:
92
+ return 2
93
+
94
+ # working with the next odd number
95
+ prime = n
96
+ found = False
97
+
98
+ # Loop continuously until isPrime returns
99
+ while not found:
100
+ prime -= 1
101
+ # True for a prime number greater than n
102
+ if is_prime(prime) is True:
103
+ found = True
104
+ # return the previous prime number to n
105
+ return prime
106
+
107
+
108
+ def gfactorial(x: Union[int, float],
109
+ prec: Optional[int] = None) -> Union[int, float]:
110
+ """*gfactorial()* calculates the factorial of a number, including support for floats less than 1.0.
111
+
112
+ - For integers n ≥ 0: Returns n! (n factorial).
113
+ - For floats x: Returns Γ(x+1) (gamma function).
114
+
115
+ Args:
116
+ x (Union[int, float]): The number to compute the factorial for.
117
+ prec (Optional[int], optional): precision, or the number of decimal places to round the result to. Defaults to None.
118
+
119
+ Raises:
120
+ ValueError: If x is a negative integer.
121
+
122
+ Returns:
123
+ Union[int, float]: The factorial of x. Returns an integer for integer inputs ≥ 0, and a float for float inputs or integers < 0.
124
+
125
+ Examples:
126
+ >>> gfactorial(5)
127
+ 120
128
+ >>> gfactorial(0)
129
+ 1
130
+ >>> gfactorial(0.5) # Equivalent to Γ(1.5) = 0.5 * Γ(0.5) = 0.5 * √Pi
131
+ 0.8862269254527579
132
+ >>> gfactorial(-0.5) # Equivalent to Γ(0.5) = √Pi
133
+ 1.7724538509055159
134
+ """
135
+ if isinstance(x, int) and x >= 0:
136
+ # Standard factorial for non-negative integers
137
+ result = math.factorial(x)
138
+ elif isinstance(x, int) and x < 0:
139
+ # Factorial is not defined for negative integers
140
+ raise ValueError("Factorial is not defined for negative integers")
141
+ else:
142
+ # For floats, use the gamma function: Γ(x+1)
143
+ result = math.gamma(x + 1)
144
+
145
+ # Apply precision if specified
146
+ if prec is not None:
147
+ result = round(result, prec)
148
+
149
+ return result
@@ -0,0 +1,54 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Module memory.py
4
+ ===========================================
5
+
6
+ Module with utility functions for handling memory allocation in the Data Structures of *PyDASA*.
7
+
8
+ *IMPORTANT:* based on the implementations proposed by the following authors/books:
9
+
10
+ #. Algorithms, 4th Edition, Robert Sedgewick and Kevin Wayne.
11
+ #. Data Structure and Algorithms in Python, M.T. Goodrich, R. Tamassia, M.H. Goldwasser.
12
+ """
13
+ # python native modules
14
+ import sys
15
+ from typing import Type
16
+
17
+ # dataclases module handles the creation of classes with slots and fields
18
+ import dataclasses
19
+
20
+ # import global variables
21
+ from pydasa.structs.types.generics import T
22
+
23
+
24
+ def mem_slot(cls: Type[T]) -> Type[T]:
25
+ """*mem_slot()* is a decorator that converts a class into a dataclass with slots.
26
+
27
+ Args:
28
+ cls (Type[T]): class to convert into a dataclass with slots.
29
+
30
+ Raises:
31
+ TypeError: if the cls is not a class type.
32
+ RuntimeError: if the Python version is less than 3.10.
33
+
34
+ Returns:
35
+ Type[T]: A dataclass with slots.
36
+ """
37
+ # TODO check validity of this decorator
38
+ # TODO integrate with the dataclass decorator
39
+ if not isinstance(cls, type):
40
+ raise TypeError(f"Invalid class: {cls}, class must be a type")
41
+
42
+ # Check Python version for native slots support
43
+ if sys.version_info >= (3, 10):
44
+ # Use native slots support
45
+ if dataclasses.is_dataclass(cls):
46
+ # Already a dataclass, need to recreate with slots
47
+ return dataclasses.dataclass(cls, slots=True)
48
+ else:
49
+ return dataclasses.dataclass(cls, slots=True)
50
+ else: # type: ignore[unreachable]
51
+ _msg = "mem_slot requires Python 3.10+ for native support. "
52
+ _msg += f"Current version: {sys.version_info.major}."
53
+ _msg += f"{sys.version_info.minor}"
54
+ raise RuntimeError(_msg)
File without changes
@@ -0,0 +1,131 @@
1
+ # -*- coding: utf-8 -*-
2
+ # FIXME old code, remove when tests are finished
3
+ """
4
+ Module default.py
5
+ ===========================================
6
+
7
+ Module for default global variables and comparison functions for use by all *PyDASA* and its Data Structures.
8
+
9
+ *IMPORTANT:* based on the implementations proposed by the following authors/books:
10
+
11
+ #. Algorithms, 4th Edition, Robert Sedgewick and Kevin Wayne.
12
+ #. Data Structure and Algorithms in Python, M.T. Goodrich, R. Tamassia, M.H. Goldwasser.
13
+ """
14
+
15
+
16
+ # python native modules
17
+ from dataclasses import dataclass
18
+ from typing import Any
19
+
20
+ # custom modules
21
+
22
+ # import global variables
23
+
24
+ # valid data types for the node
25
+ # :data: VLD_DTYPE_LT
26
+ VLD_DTYPE_LT: tuple = (
27
+ int,
28
+ float,
29
+ str,
30
+ bool,
31
+ dict,
32
+ list,
33
+ tuple,
34
+ set,
35
+ dataclass,
36
+ )
37
+ """
38
+ Native data types in Python that are comparable in the structures.
39
+ """
40
+
41
+
42
+ def dflt_cmp_function_lt(elm1: Any, elm2: Any, key: str) -> int:
43
+ """*dflt_cmp_function_lt()* Compare two elements of the ADT List (ArrayList, SingleLinked, DoubleLinked). They can be of Python native or user-defined.
44
+
45
+ Args:
46
+ elm1 (Any): First element to compare.
47
+ elm2 (Any): Second element to compare.
48
+ key (str): Key for comparing dictionary elements.
49
+
50
+ Raises:
51
+ TypeError: If elements are of different types or not comparable.
52
+ KeyError: If the key is not found in dictionary elements.
53
+ TypeError: If elements are not of built-in comparable types.
54
+
55
+ Returns:
56
+ int: -1 if elm1 < elm2, 0 if elm1 == elm2, 1 if elm1 > elm2.
57
+ """
58
+
59
+ val1, val2 = None, None
60
+ # if elements are of different types, raise error
61
+ if type(elm1) is not type(elm2):
62
+ _msg = "Invalid comparison between "
63
+ _msg += f"{type(elm1)} and {type(elm2)} elements."
64
+ raise TypeError(_msg)
65
+
66
+ # if both elements are dictionaries and a key is provided
67
+ if key and isinstance(elm1, dict) and isinstance(elm2, dict):
68
+ val1, val2 = elm1.get(key), elm2.get(key)
69
+ if val1 is None or val2 is None:
70
+ _msg = f"Invalid key: {key}, Key not found in one or both elements."
71
+ raise KeyError(_msg)
72
+
73
+ # if both elements are built-in comparable types
74
+ elif isinstance(elm1, VLD_DTYPE_LT) and isinstance(elm2, VLD_DTYPE_LT):
75
+ val1, val2 = elm1, elm2
76
+
77
+ # otherwise, raise error
78
+ else:
79
+ _msg = f"Elements of type {type(elm1)} are not comparable "
80
+ _msg += f"with elements of type {type(elm2)}."
81
+ raise TypeError(_msg)
82
+
83
+ # Simplified comparison: returns -1, 0, or 1
84
+ # quivalent to the comparison as if, elif, and else statements
85
+ return (val1 > val2) - (val1 < val2)
86
+
87
+
88
+ def dflt_cmp_function_ht(ekey1: Any, entry2, key: str, ) -> int:
89
+ """*dflt_cmp_function_ht()* Compare the entries of the ADT Map (Hash Table). can be of Python native or user-defined.
90
+
91
+ Args:
92
+ ekey1 (Any): Key of the first entry (key-value pair) to compare.
93
+ entry2 (MapEntry): Second entry (key-value pair) to compare.
94
+ key (str): Key for comparing dictionary elements.
95
+
96
+ Raises:
97
+ TypeError: If the keys are of different types or not comparable.
98
+ KeyError: If the key is not found in dictionary elements.
99
+ TypeError: If keys are not of built-in comparable types.
100
+
101
+ Returns:
102
+ int: -1 if ekey1 < ekey2, 0 if ekey1 == ekey2, 1 if ekey1 > ekey2.
103
+ """
104
+ # Extract keys from entries
105
+ ekey2 = entry2.key
106
+
107
+ # if keys are of different types, raise error
108
+ if type(ekey1) is not type(ekey2):
109
+ _msg = "Invalid comparison between "
110
+ _msg += f"{type(ekey1)} and {type(ekey2)} elements."
111
+ raise TypeError(_msg)
112
+
113
+ # if both keys are dictionaries and a key is provided
114
+ if key and isinstance(ekey1, dict) and isinstance(ekey2, dict):
115
+ val1, val2 = ekey1.get(key), ekey2.get(key)
116
+ if val1 is None or val2 is None:
117
+ _msg = f"Invalid key: '{key}', Key not found in one or both dictionary elements"
118
+ raise KeyError(_msg)
119
+
120
+ # if both keys are built-in comparable types
121
+ elif isinstance(ekey1, VLD_DTYPE_LT) and isinstance(ekey2, VLD_DTYPE_LT):
122
+ val1, val2 = ekey1, ekey2
123
+
124
+ # otherwise, raise error
125
+ else:
126
+ _msg = f"Elements of type {type(ekey1)} are not comparable "
127
+ _msg += f"with elements of type {type(ekey2)}."
128
+ raise TypeError(_msg)
129
+
130
+ # Simplified comparison: returns -1, 0, or 1
131
+ return (val1 > val2) - (val1 < val2)
@@ -0,0 +1,54 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Module generics.py
4
+ ===========================================
5
+
6
+ Module for default generic dataclass and global constants for use by all *PyDASA* and its Data Structures.
7
+
8
+ *IMPORTANT:* based on the implementations proposed by the following authors/books:
9
+
10
+ #. Algorithms, 4th Edition, Robert Sedgewick and Kevin Wayne.
11
+ #. Data Structure and Algorithms in Python, M.T. Goodrich, R. Tamassia, M.H. Goldwasser.
12
+ """
13
+
14
+ # python native modules
15
+ from typing import TypeVar
16
+
17
+ # custom modules
18
+
19
+ # import global variables
20
+
21
+ # Type for the element stored in the dataclass
22
+ # :data: T: TypeVar
23
+ T = TypeVar("T")
24
+ """
25
+ Type for creating Generics dataclasses in data structure classes, methods, and attrs.
26
+
27
+ NOTE: used for type hinting only in generics dataclasses.
28
+ """
29
+
30
+
31
+ # default key for comparing dictionaries
32
+ # :data: DFLT_DICT_KEY
33
+ DFLT_DICT_KEY: str = "_idx"
34
+ """
35
+ Default field for comparing dictionaries in the structures.
36
+ """
37
+
38
+ # allowed input/output types for the ADTs
39
+ # :data: VLD_IOTYPE_LT
40
+ VLD_IOTYPE_LT: tuple = (
41
+ list,
42
+ tuple,
43
+ set,
44
+ )
45
+ """
46
+ Allowed input/output types for loading and saving data in the ADTs with the *load* and *save* file methods.
47
+ """
48
+
49
+ # default big prime number for MAD compression in hash tables
50
+ # :data: DFLT_PRIME
51
+ DFLT_PRIME: int = 109345121
52
+ """
53
+ Default big prime number for the MAD compression function in hash tables.
54
+ """
File without changes