SciMatic 1.0.0__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.
scimatic-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 TheCursedOne
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,94 @@
1
+ Metadata-Version: 2.4
2
+ Name: SciMatic
3
+ Version: 1.0.0
4
+ Summary: A Python library for mathematics, science calculations, and experimental mathematical functions.
5
+ Author: TheCursedOne
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 TheCursedOne
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Repository, https://github.com/bingchiliingsacker-dot/SciMatic
29
+ Requires-Python: >=3.9
30
+ Description-Content-Type: text/markdown
31
+ License-File: LICENSE
32
+ Dynamic: license-file
33
+
34
+ # SciMatic
35
+
36
+ **SciMatic** is a **lightweight** and **readable**, python-only library that focuses on mathematics and scientific concepts such as **algebra, momentum and impulse, statistics, and many more** will be added.
37
+
38
+ # Features
39
+
40
+ ## Algebra.py
41
+ •Quadratic Equations/Inequalities
42
+
43
+ •Pythagorean Theorem
44
+
45
+ ## convenient_utils.py
46
+ •General-use parser(can be used for non-math related activities)
47
+
48
+ •Operator - A type annotation.
49
+
50
+ ## errors.py
51
+ •CaseError - For if someone tried a case that is out of the list of cases.
52
+
53
+ •TrigonometryError - If no real triangle is formed, raise this.
54
+
55
+ •NegativeDiscriminantError - Raises if a quadratic formulas discriminant is less than 0.
56
+
57
+ •VariableError - If a > 0, raise this.
58
+
59
+ •ComparisonError - If the value is not a comparison, this error is raised.
60
+
61
+ •ConstantError - If the statistics k is not in the range of possible k.
62
+
63
+ •DataError - If a data array is too short for process, raise this.
64
+
65
+ •ModeError - For the parser. Raises if the chosen mode is not in the modes array.
66
+
67
+ ## statistics.py
68
+ •Quartiles
69
+
70
+ •Deciles
71
+
72
+ •Percentiles
73
+
74
+ •Median
75
+
76
+ ## Geometry.py
77
+ •The Law of Sine
78
+
79
+ •The Law of Cosine
80
+
81
+ ## niche.py
82
+ •Fibonacci sequence
83
+
84
+ •Collatz Conjecture
85
+
86
+ •Ackermann Function
87
+
88
+ # Scientific
89
+ - A branch of SciMatic that does scientific calculations
90
+
91
+ ## mechanics.py
92
+ •momentum - calculates momentum
93
+
94
+ •Impulse - calculates impulse
@@ -0,0 +1,61 @@
1
+ # SciMatic
2
+
3
+ **SciMatic** is a **lightweight** and **readable**, python-only library that focuses on mathematics and scientific concepts such as **algebra, momentum and impulse, statistics, and many more** will be added.
4
+
5
+ # Features
6
+
7
+ ## Algebra.py
8
+ •Quadratic Equations/Inequalities
9
+
10
+ •Pythagorean Theorem
11
+
12
+ ## convenient_utils.py
13
+ •General-use parser(can be used for non-math related activities)
14
+
15
+ •Operator - A type annotation.
16
+
17
+ ## errors.py
18
+ •CaseError - For if someone tried a case that is out of the list of cases.
19
+
20
+ •TrigonometryError - If no real triangle is formed, raise this.
21
+
22
+ •NegativeDiscriminantError - Raises if a quadratic formulas discriminant is less than 0.
23
+
24
+ •VariableError - If a > 0, raise this.
25
+
26
+ •ComparisonError - If the value is not a comparison, this error is raised.
27
+
28
+ •ConstantError - If the statistics k is not in the range of possible k.
29
+
30
+ •DataError - If a data array is too short for process, raise this.
31
+
32
+ •ModeError - For the parser. Raises if the chosen mode is not in the modes array.
33
+
34
+ ## statistics.py
35
+ •Quartiles
36
+
37
+ •Deciles
38
+
39
+ •Percentiles
40
+
41
+ •Median
42
+
43
+ ## Geometry.py
44
+ •The Law of Sine
45
+
46
+ •The Law of Cosine
47
+
48
+ ## niche.py
49
+ •Fibonacci sequence
50
+
51
+ •Collatz Conjecture
52
+
53
+ •Ackermann Function
54
+
55
+ # Scientific
56
+ - A branch of SciMatic that does scientific calculations
57
+
58
+ ## mechanics.py
59
+ •momentum - calculates momentum
60
+
61
+ •Impulse - calculates impulse
@@ -0,0 +1,18 @@
1
+ [build-system]
2
+ requires = ['setuptools>=61']
3
+ build-backend = 'setuptools.build_meta'
4
+
5
+ [project]
6
+ name = 'SciMatic'
7
+ version = '1.0.0'
8
+ description = 'A Python library for mathematics, science calculations, and experimental mathematical functions.'
9
+ readme = 'README.md'
10
+ requires-python = '>=3.9'
11
+ license = {file = 'LICENSE'}
12
+
13
+ authors = [
14
+ {name = 'TheCursedOne'}
15
+ ]
16
+
17
+ [project.urls]
18
+ Repository = 'https://github.com/bingchiliingsacker-dot/SciMatic'
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,94 @@
1
+ Metadata-Version: 2.4
2
+ Name: SciMatic
3
+ Version: 1.0.0
4
+ Summary: A Python library for mathematics, science calculations, and experimental mathematical functions.
5
+ Author: TheCursedOne
6
+ License: MIT License
7
+
8
+ Copyright (c) 2026 TheCursedOne
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Repository, https://github.com/bingchiliingsacker-dot/SciMatic
29
+ Requires-Python: >=3.9
30
+ Description-Content-Type: text/markdown
31
+ License-File: LICENSE
32
+ Dynamic: license-file
33
+
34
+ # SciMatic
35
+
36
+ **SciMatic** is a **lightweight** and **readable**, python-only library that focuses on mathematics and scientific concepts such as **algebra, momentum and impulse, statistics, and many more** will be added.
37
+
38
+ # Features
39
+
40
+ ## Algebra.py
41
+ •Quadratic Equations/Inequalities
42
+
43
+ •Pythagorean Theorem
44
+
45
+ ## convenient_utils.py
46
+ •General-use parser(can be used for non-math related activities)
47
+
48
+ •Operator - A type annotation.
49
+
50
+ ## errors.py
51
+ •CaseError - For if someone tried a case that is out of the list of cases.
52
+
53
+ •TrigonometryError - If no real triangle is formed, raise this.
54
+
55
+ •NegativeDiscriminantError - Raises if a quadratic formulas discriminant is less than 0.
56
+
57
+ •VariableError - If a > 0, raise this.
58
+
59
+ •ComparisonError - If the value is not a comparison, this error is raised.
60
+
61
+ •ConstantError - If the statistics k is not in the range of possible k.
62
+
63
+ •DataError - If a data array is too short for process, raise this.
64
+
65
+ •ModeError - For the parser. Raises if the chosen mode is not in the modes array.
66
+
67
+ ## statistics.py
68
+ •Quartiles
69
+
70
+ •Deciles
71
+
72
+ •Percentiles
73
+
74
+ •Median
75
+
76
+ ## Geometry.py
77
+ •The Law of Sine
78
+
79
+ •The Law of Cosine
80
+
81
+ ## niche.py
82
+ •Fibonacci sequence
83
+
84
+ •Collatz Conjecture
85
+
86
+ •Ackermann Function
87
+
88
+ # Scientific
89
+ - A branch of SciMatic that does scientific calculations
90
+
91
+ ## mechanics.py
92
+ •momentum - calculates momentum
93
+
94
+ •Impulse - calculates impulse
@@ -0,0 +1,15 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ src/SciMatic.egg-info/PKG-INFO
5
+ src/SciMatic.egg-info/SOURCES.txt
6
+ src/SciMatic.egg-info/dependency_links.txt
7
+ src/SciMatic.egg-info/top_level.txt
8
+ src/scimatic/__init__.py
9
+ src/scimatic/algebra.py
10
+ src/scimatic/convenient_utils.py
11
+ src/scimatic/errors.py
12
+ src/scimatic/geometry.py
13
+ src/scimatic/niche.py
14
+ src/scimatic/statistics.py
15
+ src/scimatic/scientific/mechanics.py
@@ -0,0 +1 @@
1
+ scimatic
@@ -0,0 +1,18 @@
1
+ from . import algebra
2
+ from . import geometry
3
+ from . import statistics
4
+ from . import convenient_utils
5
+ from . import errors
6
+ from . import niche
7
+ from .scientific import mechanics
8
+
9
+ '''
10
+ SciMatic
11
+ A lightweight Python library for
12
+ mathematics, science calculations,
13
+ anf experimental functions.
14
+ '''
15
+
16
+ __version__ = '1.0.0'
17
+ __author__ = 'Th3Curs3dOn3'
18
+ __license__ = 'MIT'
@@ -0,0 +1,166 @@
1
+ import math
2
+ from .errors import NegativeDiscriminantError, ComparisonError, VariableError
3
+ from .convenient_utils import Operator
4
+
5
+ def quadratic_equation(
6
+ a: int,
7
+ b: int,
8
+ c: int,
9
+ x: int,
10
+ print_result: bool = False
11
+ ) -> int | None:
12
+
13
+ result = a * x**2 + b * x + c
14
+
15
+ if print_result:
16
+ print(result)
17
+ return result
18
+
19
+
20
+ def quadratic_formula(
21
+ a: int,
22
+ b: int,
23
+ c: int,
24
+ print_result: bool = False,
25
+ vietas_formula: bool = False
26
+ ) -> int | None:
27
+
28
+ discriminant = b**2 - 4 * a * c
29
+
30
+ if discriminant < 0:
31
+ if print_result:
32
+ print('No real solution...')
33
+ else:
34
+ raise NegativeDiscriminantError('The given integers does not produce a real solution.')
35
+ return None
36
+
37
+ x1 = (-b + math.sqrt(discriminant)) / (2 * a)
38
+ x2 = (-b - math.sqrt(discriminant)) / (2 * a)
39
+
40
+ if print_result:
41
+ print(f'x = {x1}, x = {x2}')
42
+ if vietas_formula:
43
+ print(f'x1 + x2 = {x1 + x2}')
44
+ if vietas_formula:
45
+ return x1, x2, x1 + x2
46
+
47
+ return x1, x2
48
+
49
+ def quadratic_inequality(
50
+ a: int,
51
+ b: int,
52
+ c: int,
53
+ symbol: Operator,
54
+ print_result: bool = False
55
+ ) -> int | None:
56
+ symbol_list = ['>', '<', '>=', '<=']
57
+
58
+ if symbol not in symbol_list:
59
+ raise ComparisonError()
60
+
61
+ if a == 0:
62
+ raise VariableError()
63
+
64
+
65
+ discriminant = b**2 - 4 * a * c
66
+
67
+ if discriminant < 0:
68
+ if print_result:
69
+ print('No real solution...')
70
+ else:
71
+ raise NegativeDiscriminantError()
72
+ return None
73
+
74
+ elif discriminant == 0:
75
+ x = (-b + math.sqrt(discriminant)) / (2 * a)
76
+
77
+ if print_result:
78
+ print('One real solution...')
79
+ print(f'x = {x}')
80
+ return x
81
+
82
+ else:
83
+ x1 = (-b + math.sqrt(discriminant)) / (2 * a)
84
+ x2 = (-b - math.sqrt(discriminant)) / (2 * a)
85
+
86
+ x1, x2 = sorted([x1, x2])
87
+
88
+ parabola = a > 0
89
+
90
+ def for_loop(x1, x2):
91
+ testpoint1 = x1 - 1
92
+ testpoint2 = (x1 + x2) / 2
93
+ testpoint3 = x2 + 1
94
+ test_points = [testpoint1, testpoint2, testpoint3]
95
+
96
+ torf = []
97
+
98
+ for point in test_points:
99
+ if symbol == '>':
100
+ torf.append((a * point**2 + b * point + c) > 0)
101
+ elif symbol == '<':
102
+ torf.append((a * point**2 + b * point + c) < 0)
103
+ elif symbol == '>=':
104
+ torf.append((a * point**2 + b * point + c) >= 0)
105
+ else:
106
+ torf.append((a * point**2 + b * point + c) <= 0)
107
+
108
+ return torf
109
+
110
+ if parabola:
111
+ torf = for_loop(x1, x2)
112
+
113
+ if symbol == '>':
114
+ answer = f'x < {x1} or x > {x2}'
115
+ elif symbol == '>=':
116
+ answer = f'x <= {x1} or x >= {x2}'
117
+ elif symbol == '<':
118
+ answer = f'{x1} < x < {x2}'
119
+ else:
120
+ answer = f'{x1} <= x <= {x2}'
121
+
122
+ if print_result:
123
+ print(answer)
124
+ return answer
125
+
126
+ else:
127
+ torf = for_loop(x1, x2)
128
+
129
+ if symbol == '>':
130
+ answer = f'{x1} < x < {x2}'
131
+ elif symbol == '>=':
132
+ answer = f'{x1} <= x <= {x2}'
133
+ elif symbol == '<':
134
+ answer = f'x < {x1} or x > {x2}'
135
+ else:
136
+ answer = f'x <= {x1} or x >= {x2}'
137
+
138
+ if print_result:
139
+ print(answer)
140
+ return answer
141
+
142
+ def pythagorean_theorem(
143
+ a: int | float,
144
+ b: int | float,
145
+ c: int | float | None = None,
146
+ print_result: bool = True
147
+ ) -> int | float | None:
148
+
149
+ if c is not None:
150
+ c_square = a**2 + b**2
151
+
152
+ if c**2 == (a**2 + b**2):
153
+ output = True
154
+ else:
155
+ output = False
156
+
157
+ if print_result:
158
+ print(f'{c}^2 = {a}^2 + {b}^2')
159
+ print(output)
160
+ return output, c_square
161
+
162
+ else:
163
+ c_square = math.sqrt(a**2 + b**2)
164
+ if print_result:
165
+ print(f'sqrt({a}^2 + {b}^2) = {c_square}')
166
+ return c_square
@@ -0,0 +1,60 @@
1
+ from typing import Literal
2
+ from .errors import ModeError
3
+
4
+
5
+ Operator = Literal['+', '-', '×', '•', '*', '^', '÷', '/', '//', '%', '!', '|', '(', ')', '<', '>', '<=', '>=', '==', '=', '!=', '≈', '≠']
6
+
7
+ def parser(
8
+ raw_syntax: str,
9
+ mode: str = 'letter',
10
+ print_result: bool = True
11
+ ) -> list[int] | list[str] | None:
12
+
13
+ modes = ['letter', 'word', 'token']
14
+ processor = []
15
+ output = []
16
+ token_output = []
17
+ word = ''
18
+
19
+ if mode not in modes:
20
+ raise ModeError(f'Mode is not in modes: {modes}')
21
+
22
+ for letter in raw_syntax:
23
+ processor.append(letter)
24
+
25
+ if mode == modes[0]:
26
+ for p in processor:
27
+ if p == ' ':
28
+ continue
29
+ output.append(p)
30
+
31
+ else:
32
+ for p in processor:
33
+ if p == ' ':
34
+ if word:
35
+ output.append(word)
36
+ word = ''
37
+ continue
38
+
39
+ word += p
40
+
41
+ if word:
42
+ output.append(word)
43
+
44
+ if mode == modes[2]:
45
+ for o in output:
46
+ try:
47
+ syn = int(o)
48
+ except ValueError:
49
+ try:
50
+ syn = float(o)
51
+ except ValueError:
52
+ syn = o
53
+
54
+ token_output.append(syn)
55
+
56
+ output = token_output
57
+
58
+ if print_result:
59
+ print(output)
60
+ return output
@@ -0,0 +1,30 @@
1
+ class CaseError(Exception):
2
+ def __init__(self, message='Case is not defined.'):
3
+ super().__init__(message)
4
+
5
+ class TrigonometryError(Exception):
6
+ def __init__(self, message='No such valid triangle.'):
7
+ super().__init__(message)
8
+
9
+ class NegativeDiscriminantError(Exception):
10
+ def __init__(self, message='Type \'Discriminant\' is less than Zero. Therefore, equation has no real roots.'):
11
+ super().__init__(message)
12
+
13
+ class VariableError(Exception):
14
+ def __init__(self, message='Variable is more than 0.'):
15
+ super().__init__(message)
16
+
17
+ class ComparisonError(Exception):
18
+ def __init__(self, message='Comparison operand not found.'):
19
+ super().__init__(message)
20
+
21
+ class ConstantError(Exception):
22
+ def __init__(self, message='Invalid constant.'):
23
+ super().__init__(message)
24
+
25
+ class DataError(Exception):
26
+ def __init__(self, message='Data cannot be used.'):
27
+ super().__init__(message)
28
+
29
+ class ModeError(Exception):
30
+ pass
@@ -0,0 +1,148 @@
1
+ import math
2
+ from .errors import CaseError, TrigonometryError
3
+
4
+
5
+ def sin_law(
6
+ case: str,
7
+ a: int | float,
8
+ b: int | float,
9
+ c: int | float,
10
+ print_result: bool = False
11
+ ) -> int | float | list[dict[str, int | float]] | None:
12
+
13
+ cases = ['SAA', 'AAS', 'ASA', 'SSA']
14
+
15
+ if case not in cases:
16
+ raise CaseError(f'Parameter \'case\' must be: {cases}.')
17
+
18
+ known_items = [a, b, c]
19
+
20
+ for var in known_items:
21
+ if not isinstance(var, int) or isinstance(var, float):
22
+ raise ValueError('Invalid variables.')
23
+
24
+ if case == cases[1]:
25
+ a, c = c, a
26
+ case = cases[0]
27
+
28
+ if case == cases[0]:
29
+ B = 180 - (b + c)
30
+
31
+ A = c
32
+ C = b
33
+
34
+ sidec = (a * math.sin(math.radians(C))) / (math.sin(math.radians(A)))
35
+
36
+ sideb = (a * math.sin(math.radians(B))) / (math.sin(math.radians(A)))
37
+
38
+ if print_result:
39
+ print(f'Angle B: {B}, Side C: {sidec}, Side B: {sideb}')
40
+ return B, sidec, sideb
41
+
42
+ elif case == cases[2]:
43
+ A = 180 - (a + c)
44
+
45
+ B = c
46
+ C = a
47
+
48
+ sidec = (b * math.sin(math.radians(C))) / (math.sin(math.radians(A)))
49
+
50
+ sideb = (b * math.sin(math.radians(B))) / (math.sin(math.radians(A)))
51
+
52
+ if print_result:
53
+ print(f'Angle B: {B}, Side C: {sidec}, Side B: {sideb}')
54
+ return B, sidec, sideb
55
+
56
+ else:
57
+ A = c
58
+
59
+ try:
60
+ B1 = math.degrees(math.asin((b * math.sin(math.radians(A))) / a))
61
+ except ValueError:
62
+ if print_result:
63
+ print('No real triangle is formed...')
64
+ else:
65
+ raise TrigonometryError
66
+ return
67
+
68
+ B2 = 180 - B1
69
+
70
+ valid_case = [False, False]
71
+
72
+ if A + B1 < 180:
73
+ valid_case[0] = True
74
+
75
+ if A + B2 < 180:
76
+ valid_case[1] = True
77
+
78
+ output1 = []
79
+ output2 = []
80
+
81
+ for i, triangle in enumerate(valid_case):
82
+ if not triangle:
83
+ continue
84
+
85
+ B = B1 if i == 0 else B2
86
+
87
+ C = 180 - (A + B)
88
+
89
+ sideb = (a * math.sin(math.radians(B))) / (math.sin(math.radians(A)))
90
+
91
+ if i == 0:
92
+ output1.append({
93
+ 'angle B': B1,
94
+ 'angle C': C,
95
+ 'side b': sideb
96
+ })
97
+ else:
98
+ output2.append({
99
+ 'angle B': B2,
100
+ 'angle C': C,
101
+ 'side b': sideb
102
+ })
103
+
104
+ if print_result:
105
+ print(output1)
106
+ print(output2)
107
+ return output1, output2
108
+
109
+
110
+ def cos_law(
111
+ case: str,
112
+ a: int | float,
113
+ b: int | float,
114
+ c: int | float,
115
+ print_result: bool = False
116
+ ) -> int | float | None:
117
+
118
+ cases = ['SSS', 'SAS']
119
+
120
+ if case not in cases:
121
+ raise CaseError(f'Parameter \'case\' must be: {cases}.')
122
+
123
+ known_items = [a, b, c]
124
+
125
+ for var in known_items:
126
+ if not isinstance(var, (int, float)):
127
+ raise ValueError('Invalid variables.')
128
+
129
+ if case == cases[0]:
130
+ A = math.degrees(math.acos((b**2 + c**2 - a**2) / (2 * b * c)))
131
+ B = math.degrees(math.acos((a**2 + c**2 - b**2) / (2 * a * c)))
132
+ C = 180 - (A + B)
133
+
134
+ if print_result:
135
+ print(f'Angle A: {A}, Angle B: {B}, Angle C: {C}')
136
+ return A, B, C
137
+
138
+ else:
139
+ C = b
140
+ sidec = math.sqrt(a**2 + c**2 - 2 * a * c * math.cos(math.radians(C)))
141
+
142
+ A = math.degrees(math.acos((c**2 + sidec**2 - a**2) / (2 * c * sidec)))
143
+
144
+ B = 180 - (A + C)
145
+
146
+ if print_result:
147
+ print(f'Side c: {sidec}, Angle A: {A}, Angle B: {B}')
148
+ return sidec, A, B
@@ -0,0 +1,50 @@
1
+ def fibonacci(
2
+ value: int,
3
+ ):
4
+ a, b = 0, 1
5
+
6
+ i = 0
7
+
8
+ while i <= value:
9
+ yield a
10
+ a, b = b, a + b
11
+ i += 1
12
+
13
+ def collatz(
14
+ value: int,
15
+ print_result: bool = False
16
+ ) -> list[int]:
17
+
18
+ sequence = [value]
19
+
20
+ for var in sequence:
21
+ if var % 2 == 0:
22
+ new_value = var // 2
23
+ else:
24
+ new_value = (3 * var) + 1
25
+
26
+ sequence.append(new_value)
27
+
28
+ if new_value == 1:
29
+ break
30
+
31
+ if print_result:
32
+ print(sequence)
33
+ return sequence
34
+
35
+ def ackermann(
36
+ array: list,
37
+ m: int,
38
+ n: int
39
+ ):
40
+ if m > 3:
41
+ print('The value of m is too high for python. If you want to have a niche that does not grow that quickly, I will recommend TREE.')
42
+ return
43
+ array.append((m, n))
44
+
45
+ if m == 0:
46
+ return n + 1
47
+ elif n == 0:
48
+ return ackermann(array, m - 1, 1)
49
+ else:
50
+ return ackermann(array, m - 1, ackermann(array, m, n - 1))
@@ -0,0 +1,39 @@
1
+ def momentum(
2
+ mass: int | float,
3
+ velocity: int | float,
4
+ print_result: bool = False
5
+ ) -> int | float | None:
6
+
7
+ p = mass * velocity
8
+
9
+ if print_result:
10
+ print(f'Momentum: {p}kg•m/s')
11
+ return p
12
+
13
+ def impulse(
14
+ force: int | float,
15
+ initial_time: int | float,
16
+ final_time: int | float,
17
+ print_result: bool = False,
18
+ return_deltat: bool = False
19
+ ) -> int | float | None:
20
+
21
+ if initial_time >= final_time:
22
+ raise ValueError
23
+
24
+ delta_t = final_time - initial_time
25
+
26
+ J = force * delta_t
27
+
28
+ delta = '\u0394'
29
+
30
+ if print_result:
31
+ if not return_deltat:
32
+ print(f'Impulse: {J}N•s')
33
+ else:
34
+ print(f'Impulse: {J}N•s, {delta}t: {delta_t}s')
35
+
36
+ if return_deltat:
37
+ return J, delta_t
38
+ else:
39
+ return J
@@ -0,0 +1,230 @@
1
+ import math
2
+ from .errors import NegativeDiscriminantError, VariableError, ConstantError, ComparisonError, DataError
3
+
4
+ def quartile(
5
+ raw_data: list[int],
6
+ k: int,
7
+ print_result: bool = False
8
+ ) -> int:
9
+
10
+ constant_check = [1, 2, 3]
11
+
12
+ if k not in constant_check:
13
+ raise ConstantError
14
+
15
+ if len(raw_data) <= 1:
16
+ raise DataError('Raw data is too short.')
17
+
18
+ processed_data = sorted(raw_data)
19
+
20
+ n = 0
21
+
22
+ for data in processed_data:
23
+ n += 1
24
+
25
+ formula = k * (n + 1) / 4
26
+ syntax_list = []
27
+ is_float = False
28
+
29
+ formula = str(formula)
30
+
31
+ if print_result:
32
+ print(formula)
33
+
34
+ for f in formula:
35
+ if f == '.':
36
+ is_float = True
37
+ continue
38
+
39
+ f = int(f)
40
+
41
+ syntax_list.append(f)
42
+
43
+ if is_float:
44
+ position1 = syntax_list[0]
45
+ position2 = position1 + 1
46
+
47
+ lower_value = processed_data[position1 - 1]
48
+ higher_value = processed_data[position2 - 1]
49
+
50
+ formula = lower_value + float(f'0.{syntax_list[1]}') * (higher_value - lower_value)
51
+
52
+ if print_result:
53
+ print(f'Q{k} = {k}({n} + 1) / 4')
54
+ print(formula)
55
+ return formula
56
+
57
+ def decile(
58
+ raw_data: int,
59
+ k: int,
60
+ print_result: bool = False
61
+ ) -> int | None:
62
+
63
+ constant_check = [1, 2, 3, 4, 5, 6, 7, 8, 9]
64
+
65
+ if k not in constant_check:
66
+ raise ConstantError
67
+
68
+ if len(raw_data) < 10:
69
+ raise DataError('Raw data is too short.')
70
+
71
+
72
+ processed_data = sorted(raw_data)
73
+
74
+ n = 0
75
+
76
+ for data in processed_data:
77
+ n += 1
78
+
79
+ formula = k * (n + 1) / 10
80
+ syntax_list = []
81
+ is_float = False
82
+
83
+ formula = str(formula)
84
+
85
+ if print_result:
86
+ print(formula)
87
+
88
+ for f in formula:
89
+ if f == '.':
90
+ is_float = True
91
+ continue
92
+
93
+ f = int(f)
94
+
95
+ syntax_list.append(f)
96
+
97
+ if is_float:
98
+ position1 = syntax_list[0]
99
+ position2 = position1 + 1
100
+
101
+ lower_value = processed_data[position1 - 1]
102
+ higher_value = processed_data[position2 - 1]
103
+
104
+ formula = lower_value + float(f'0.{syntax_list[1]}') * (higher_value - lower_value)
105
+
106
+ if print_result:
107
+ print(f'D{k} = {k}({n} + 1) / 10')
108
+ print(formula)
109
+ return formula
110
+
111
+ def percentile(
112
+ raw_data: int,
113
+ k: int,
114
+ print_result: bool = False
115
+ ) -> int | None:
116
+
117
+ constant_check = []
118
+
119
+ for i in range(100):
120
+ if i == 0:
121
+ continue
122
+
123
+ constant_check.append(i)
124
+
125
+
126
+
127
+ if k not in constant_check:
128
+ raise ConstantError
129
+
130
+ if len(raw_data) < 10:
131
+ raise DataError('Raw data is too short.')
132
+
133
+ processed_data = sorted(raw_data)
134
+
135
+ if print_result:
136
+ print(processed_data)
137
+
138
+ n = 0
139
+
140
+ for data in processed_data:
141
+ n += 1
142
+
143
+ formula = k * (n + 1) / 100
144
+ syntax_list = []
145
+ is_float = False
146
+
147
+ formula = str(formula)
148
+
149
+ if print_result:
150
+ print(formula)
151
+
152
+ for f in formula:
153
+ if f == '.':
154
+ is_float = True
155
+ continue
156
+
157
+ f = int(f)
158
+
159
+ syntax_list.append(f)
160
+
161
+ if is_float:
162
+ position1 = syntax_list[0]
163
+ position2 = position1 + 1
164
+
165
+ lower_value = processed_data[position1 - 1]
166
+ higher_value = processed_data[position2 - 1]
167
+
168
+ formula = lower_value + float(f'0.{syntax_list[1]}') * (higher_value - lower_value)
169
+
170
+ if print_result:
171
+ print(f'P{k} = {k}({n} + 1) / 100')
172
+ print(formula)
173
+ return formula
174
+
175
+ def median(
176
+ raw_data: list[int],
177
+ print_result: bool = False
178
+ ) -> int | None:
179
+
180
+ processed_data = sorted(raw_data)
181
+
182
+ if len(raw_data) <= 1:
183
+ raise DataError('Raw data is too short.')
184
+
185
+ n = 0
186
+
187
+ for data in processed_data:
188
+ n += 1
189
+
190
+ position = (n + 1) / 2
191
+
192
+ syntax_list = []
193
+
194
+ num = ''
195
+
196
+ position = str(position)
197
+
198
+ is_float = False
199
+
200
+ for p in position:
201
+ if p == '.':
202
+ is_float = True
203
+ syntax_list.append(num)
204
+ continue
205
+
206
+ num += p
207
+
208
+ syntax_list.append(num)
209
+
210
+ position = float(position)
211
+
212
+ if position.is_integer():
213
+ formula = processed_data[int(position) - 1]
214
+
215
+ else:
216
+ position1 = int(position)
217
+ position2 = position1 + 1
218
+
219
+ lower_value = processed_data[position1 - 1]
220
+ higher_value = processed_data[position2 - 1]
221
+
222
+ fraction = position - position1
223
+
224
+ formula = lower_value + fraction * (higher_value - lower_value)
225
+
226
+ if print_result:
227
+ print(processed_data)
228
+ print('Position:', position)
229
+ print('Median', formula)
230
+ return position, formula