Botcalculator 0.1.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.
@@ -0,0 +1,9 @@
1
+ Metadata-Version: 2.4
2
+ Name: Botcalculator
3
+ Version: 0.1.0
4
+ Summary: A modular CLI-based math engine
5
+ Author: Botgaming
6
+ Requires-Python: >=3.8
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Dynamic: license-file
@@ -0,0 +1,13 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ Botcalculator.egg-info/PKG-INFO
5
+ Botcalculator.egg-info/SOURCES.txt
6
+ Botcalculator.egg-info/dependency_links.txt
7
+ Botcalculator.egg-info/top_level.txt
8
+ Calculator/Arithmetic.py
9
+ Calculator/Exponents.py
10
+ Calculator/Main.py
11
+ Calculator/Trig.py
12
+ Calculator/Utilities.py
13
+ Calculator/__init__.py
@@ -0,0 +1 @@
1
+ Calculator
@@ -0,0 +1,10 @@
1
+ def add(a, b):
2
+ return(a + b)
3
+ def sub(a, b):
4
+ return(a - b)
5
+ def multiply(a, b):
6
+ return(a * b)
7
+ def divide(a, b):
8
+ if b == 0:
9
+ raise ZeroDivisionError("Can't divide by 0")
10
+ return a / b
@@ -0,0 +1,13 @@
1
+ import cmath
2
+ import math
3
+
4
+ def power(a, b):
5
+ return(a ** b)
6
+
7
+ def root(a, b):
8
+ if b == 0:
9
+ raise ValueError("Root degree can't be 0")
10
+ return cmath.pow(a, 1 / b)
11
+
12
+ def factorial(num):
13
+ return math.factorial(int(num))
@@ -0,0 +1,147 @@
1
+ import Arithmetic
2
+ import Exponents
3
+ import Trig
4
+ from dotenv import load_dotenv
5
+ import sys
6
+ import os
7
+ import curses
8
+
9
+ def main_menu(stdscr):
10
+ curses.curs_set(0)
11
+ current = 0
12
+ offset = 0
13
+
14
+ while True:
15
+ stdscr.clear()
16
+ height, width = stdscr.getmaxyx()
17
+
18
+ stdscr.addstr(0, 0, "Pick a Function", curses.A_BOLD)
19
+ stdscr.addstr(1, 0, "—" * 30)
20
+
21
+ visible_height = height - 4
22
+ visible_options = main_options[offset:offset + visible_height]
23
+
24
+ for i, opt in enumerate(visible_options):
25
+ y = i + 4
26
+ index = i + offset
27
+
28
+ text = f"> {opt} <" if index == current else f" {opt}"
29
+ stdscr.addstr(
30
+ y, 0,
31
+ text[:width-1],
32
+ curses.A_REVERSE if index == current else 0
33
+ )
34
+
35
+ key = stdscr.getch()
36
+
37
+ if key == curses.KEY_UP:
38
+ current = (current - 1) % len(main_options)
39
+ elif key == curses.KEY_DOWN:
40
+ current = (current + 1) % len(main_options)
41
+ elif key in (10, 13):
42
+ return main_options[current]
43
+
44
+ if current < offset:
45
+ offset = current
46
+ elif current >= offset + visible_height:
47
+ offset = current - visible_height + 1
48
+
49
+ def env_menu(stdscr):
50
+ curses.curs_set(0)
51
+ current = 0
52
+ offset = 0
53
+
54
+ while True:
55
+ stdscr.clear()
56
+ height, width = stdscr.getmaxyx()
57
+
58
+ stdscr.addstr(0, 0, "Import Numbers from env file?", curses.A_BOLD)
59
+ stdscr.addstr(1, 0, "—" * 30)
60
+
61
+ visible_height = height - 4
62
+ visible_options = env_options[offset:offset + visible_height]
63
+
64
+ for i, opt in enumerate(visible_options):
65
+ y = i + 4
66
+ index = i + offset
67
+
68
+ text = f"> {opt} <" if index == current else f" {opt}"
69
+ stdscr.addstr(
70
+ y, 0,
71
+ text[:width-1],
72
+ curses.A_REVERSE if index == current else 0
73
+ )
74
+
75
+ key = stdscr.getch()
76
+
77
+ if key == curses.KEY_UP:
78
+ current = (current - 1) % len(env_options)
79
+ elif key == curses.KEY_DOWN:
80
+ current = (current + 1) % len(env_options)
81
+ elif key in (10, 13):
82
+ return env_options[current]
83
+
84
+ if current < offset:
85
+ offset = current
86
+ elif current >= offset + visible_height:
87
+ offset = current - visible_height + 1
88
+ env_options = ["Y", "N"]
89
+ env = curses.wrapper(env_menu)
90
+ if env == "Y":
91
+ load_dotenv()
92
+ raw_A = os.getenv("A")
93
+ raw_B = os.getenv("B")
94
+
95
+ if raw_A is None or raw_B is None:
96
+ print("❌ Missing A or B in ENV")
97
+ sys.exit(1)
98
+
99
+ A = float(raw_A)
100
+ B = float(raw_B)
101
+
102
+ else:
103
+ A = float(input("Type the 1st number "))
104
+ B = float(input("Type the 2nd number "))
105
+
106
+ operations = {
107
+ "+": {"func": Arithmetic.add, "args": 2},
108
+ "-": {"func": Arithmetic.sub, "args": 2},
109
+ "x": {"func": Arithmetic.multiply, "args": 2},
110
+ "÷": {"func": Arithmetic.divide, "args": 2},
111
+ "^": {"func": Exponents.power, "args":2},
112
+ "root": {"func": Exponents.root, "args":2},
113
+ "Fac(!)": {"func": Exponents.factorial, "args": 1},
114
+ "sin": {"func": Trig.sin, "args": 1},
115
+ "cos": {"func": Trig.cos, "args": 1},
116
+ "tan": {"func": Trig.tan, "args": 1},
117
+ "csc": {"func": Trig.csc, "args": 1},
118
+ "sec": {"func": Trig.sec, "args": 1},
119
+ "cot": {"func": Trig.cot, "args": 1},
120
+ "arcsin": {"func": Trig.arcsin, "args": 1},
121
+ "arccos": {"func": Trig.arccos, "args": 1},
122
+ "arctan": {"func": Trig.arctan, "args": 1},
123
+ "arccsc": {"func": Trig.arccsc, "args": 1},
124
+ "arcsec": {"func": Trig.arcsec, "args": 1},
125
+ "arccot": {"func": Trig.arccot, "args": 1},
126
+ "sinh": {"func": Trig.sinh, "args": 1},
127
+ "cosh": {"func": Trig.cosh, "args": 1},
128
+ "tanh": {"func": Trig.tanh, "args": 1},
129
+ "csch": {"func": Trig.csch, "args": 1},
130
+ "sech": {"func": Trig.sech, "args": 1},
131
+ "coth": {"func": Trig.coth, "args": 1},
132
+ "arcsinh": {"func": Trig.arcsinh, "args": 1},
133
+ "arccosh": {"func": Trig.arccosh, "args": 1},
134
+ "arctanh": {"func": Trig.arctanh, "args": 1},
135
+ }
136
+ main_options = list(operations.keys())
137
+ inp = curses.wrapper(main_menu)
138
+ op = operations[inp]
139
+ func = op["func"]
140
+ arg_count = op["args"]
141
+
142
+ if arg_count == 2:
143
+ result = func(A, B)
144
+ else:
145
+ result = func(A)
146
+ if __name__ == "__main__":
147
+ print(result)
@@ -0,0 +1,96 @@
1
+ import cmath
2
+ import math
3
+ def sin(num):
4
+ return cmath.sin(math.radians(num))
5
+
6
+
7
+ def cos(num):
8
+ return cmath.cos(math.radians(num))
9
+
10
+
11
+ def tan(num):
12
+ if num % 180 == 90:
13
+ return "Undefined"
14
+
15
+ return cmath.tan(math.radians(num))
16
+
17
+ def csc(num):
18
+ s = math.sin(math.radians(num))
19
+ if abs(s) < 1e-10:
20
+ return "Undefined"
21
+ return 1 / s
22
+
23
+ def sec(num):
24
+ c = math.cos(math.radians(num))
25
+ if abs(c) < 1e-10:
26
+ return "Undefined"
27
+ return 1 / c
28
+
29
+ def cot(num):
30
+ t = math.tan(math.radians(num))
31
+ if abs(t) < 1e-10:
32
+ return "Undefined"
33
+ return 1 / t
34
+
35
+ def arcsin(num):
36
+ if num < -1 or num > 1:
37
+ return "Undefined"
38
+ return math.degrees(math.asin(num))
39
+
40
+ def arccos(num):
41
+ if num < -1 or num > 1:
42
+ return "Undefined"
43
+ return math.degrees(math.acos(num))
44
+
45
+ def arctan(num):
46
+ return math.degrees(math.atan(num))
47
+
48
+ def arccsc(num):
49
+ if abs(num) < 1:
50
+ return "Undefined"
51
+ return math.degrees(math.asin(1 / num))
52
+
53
+ def arcsec(num):
54
+ if abs(num) < 1:
55
+ return "Undefined"
56
+ return math.degrees(math.acos(1 / num))
57
+
58
+ def arccot(num):
59
+ if num == 0:
60
+ return 90.0
61
+ return math.degrees(math.atan(1 / num))
62
+
63
+ def sinh(x):
64
+ return math.sinh(x)
65
+
66
+ def cosh(x):
67
+ return math.cosh(x)
68
+
69
+ def tanh(x):
70
+ return math.tanh(x)
71
+
72
+ def csch(x):
73
+ if x == 0:
74
+ return "Undefined"
75
+ return 1 / math.sinh(x)
76
+
77
+ def sech(x):
78
+ return 1 / math.cosh(x)
79
+
80
+ def coth(x):
81
+ if x == 0:
82
+ return "Undefined"
83
+ return 1 / math.tanh(x)
84
+
85
+ def arcsinh(x):
86
+ return math.asinh(x)
87
+
88
+ def arccosh(x):
89
+ if x < 1:
90
+ return "Domain Error"
91
+ return math.acosh(x)
92
+
93
+ def arctanh(x):
94
+ if abs(x) >= 1:
95
+ return "Domain Error"
96
+ return math.atanh(x)
@@ -0,0 +1,25 @@
1
+ import numbers
2
+ import math
3
+
4
+ def round_up_decimal(n, decimals=0):
5
+ multiplier = 10**decimals
6
+ return math.ceil(n * multiplier) / multiplier
7
+
8
+ def format_result(result):
9
+ if not isinstance(result, numbers.Number):
10
+ return result
11
+
12
+ if isinstance(result, complex):
13
+ real = round(result.real, 10)
14
+ imag = round(result.imag, 10)
15
+
16
+ if abs(real) < 1e-10:
17
+ real = 0
18
+ if abs(imag) < 1e-10:
19
+ imag = 0
20
+
21
+ if real == 0:
22
+ return f"{imag}i"
23
+ return f"{real} + {imag}i"
24
+
25
+ return result
@@ -0,0 +1,3 @@
1
+ from .Arithmetic import *
2
+ from Exponents import *
3
+ from .Trig import *
File without changes
@@ -0,0 +1,9 @@
1
+ Metadata-Version: 2.4
2
+ Name: Botcalculator
3
+ Version: 0.1.0
4
+ Summary: A modular CLI-based math engine
5
+ Author: Botgaming
6
+ Requires-Python: >=3.8
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Dynamic: license-file
File without changes
@@ -0,0 +1,13 @@
1
+ [project]
2
+ name = "Botcalculator"
3
+ version = "0.1.0"
4
+ description = "A modular CLI-based math engine"
5
+ authors = [
6
+ { name="Botgaming" }
7
+ ]
8
+ readme = "README.md"
9
+ requires-python = ">=3.8"
10
+
11
+ [build-system]
12
+ requires = ["setuptools", "wheel"]
13
+ build-backend = "setuptools.build_meta"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+