-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprocess.py
More file actions
153 lines (126 loc) · 4.97 KB
/
process.py
File metadata and controls
153 lines (126 loc) · 4.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
"""Function to __process calculations"""
from math import pow, pi, e
from tkinter import Tk, Frame, Label, RAISED, Entry, Button, INSERT, SUNKEN, Event
from decimal import Decimal as Dec
def _replace_symbols(text: str):
"""Replace pi with the actual value of pi, etc"""
symbols = {"π": pi, "℮": e}
for key, value in symbols.items():
text = text.replace(key, str(value))
return text
def _needs_processing(text: str):
"""Figure out if an expression needs processing"""
symbols = ["+", "-", "*", "/", "^"]
for symbol in symbols:
if symbol in text:
return True
return False
def _get_operation(text: str):
"""Get the first operation needed"""
for character in text:
if character == "^":
return "^"
symbols_1 = ["*", "/"]
symbols_2 = ["+", "-"]
for character in text:
for symbol in symbols_1:
if character == symbol:
return symbol
# Program will only get to this point if no operation from ^ or * or / has
# been found yet
for character in text:
for symbol in symbols_2:
if character == symbol:
return symbol
# Program will only get to this point if there are no operations left
return None
class Calculator:
"""A class to manage the calculator"""
def __init__(self):
self.window = Tk()
self.window.resizable(False, False)
self.window.size()
self.window.bind("<Return>", self._update_calculation)
self.calculation = Entry(
master=self.window,
relief=RAISED
)
self.calculation.place(x=10, y=10, width=180)
self.result = Label(
master=self.window,
text=self._calculate(text=self.calculation.get()),
relief=SUNKEN
)
self.result.place(x=10, y=45, width=180)
self.pi_button = Button(master=self.window, text="π")
self.pi_button.place(x=10, y=80, width=85)
self.pi_button.bind("<Button-1>", self._insert_pi)
self.e_button = Button(master=self.window, text="℮")
self.e_button.place(x=100, y=80, width=85)
self.e_button.bind("<Button-1>", self._insert_e)
def _update_calculation(self, _):
"""Update the calculation result"""
self.result["text"] = self._calculate(self.calculation.get())
def _subprocess(self, texts: list):
"""Subprocess all operations"""
new_texts = []
for expression in texts:
if _needs_processing(expression):
expression = self._process(expression)
new_texts.append(float(expression))
return new_texts
def _process_multiplication(self, text: str):
"""Process a single multiplication statement."""
texts = self._subprocess(text.split("*", maxsplit=1))
return float(Dec(str(texts[0])) * Dec(str(texts[1])))
def _process_division(self, text: str):
"""Process a single division statement."""
texts = self._subprocess(text.split("/", maxsplit=1))
return float(Dec(str(texts[0])) / Dec(str(texts[1])))
def _process_addition(self, text: str):
"""Process a single addition statement."""
texts = self._subprocess(text.split("+", maxsplit=1))
return float(Dec(str(texts[0])) + Dec(str(texts[1])))
def _process_subtraction(self, text: str):
"""Process a single subtraction statement."""
texts = self._subprocess(text.split("-", maxsplit=1))
return float(Dec(str(texts[0])) - Dec(str(texts[1])))
def _process_powers(self, text: str):
"""Process a single logarithmic statement."""
texts = self._subprocess(text.split("^", maxsplit=1))
return pow(texts[0], texts[1])
def _process(self, text: str):
"""Process an expression"""
operation = _get_operation(text)
if operation == "*":
return self._process_multiplication(text)
elif operation == "/":
return self._process_division(text)
elif operation == "+":
return self._process_addition(text)
elif operation == "-":
return self._process_subtraction(text)
elif operation == "^":
return self._process_powers(text)
return text
def _calculate(self, text: str):
"""Convert numbers that end in .0 to an int"""
text = _replace_symbols(text)
try:
num = self._process(text)
float(num)
except ArithmeticError:
if self.calculation.get() == "":
return ""
return "Whoops! Math Error!"
except ValueError:
if self.calculation.get() == "":
return ""
return "Whoops! Syntax Error!"
return str(num).rstrip(".0")
def _insert_pi(self, _):
self.calculation.insert(INSERT, "π")
def _insert_e(self, _):
self.calculation.insert(INSERT, "℮")
if __name__ == "__main__":
Calculator().window.mainloop()