-
Notifications
You must be signed in to change notification settings - Fork 4
/
calculator.py
99 lines (83 loc) · 3.31 KB
/
calculator.py
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
import math
import numpy
import re as regex
sanetize = lambda a : float(a)
functions = {
# Programming functions
'abs': lambda a : abs(sanetize(a)),
'floor': lambda a : math.floor(sanetize(a)),
'ceil': lambda a : math.ceil(sanetize(a)),
'round': lambda a : math.floor(sanetize(a) + 0.5),
# Logarithmic functions
'log': lambda a : math.log10(sanetize(a)),
'ln': lambda a : math.log(sanetize(a)),
'exp': lambda a : math.exp(sanetize(a)),
# Trigonometric functions
'rad': lambda a : math.radians(sanetize(a)),
'deg': lambda a : math.degrees(sanetize(a)),
'sin': lambda a : math.sin(sanetize(a)),
'asin': lambda a : math.asin(sanetize(a)),
'cos': lambda a : math.cos(sanetize(a)),
'acos': lambda a : math.acos(sanetize(a)),
'tan': lambda a : math.tan(sanetize(a)),
'atan': lambda a : math.atan(sanetize(a))
}
symbols = {
'%': lambda a, b : sanetize(a) % sanetize(b),
'\\': lambda a, b : sanetize(a) ** (1.0 / sanetize(b)),
'^': lambda a, b : sanetize(a) ** sanetize(b),
'/': lambda a, b : sanetize(a) / sanetize(b),
'*': lambda a, b : sanetize(a) * sanetize(b),
'-': lambda a, b : sanetize(a) - sanetize(b),
'+': lambda a, b : sanetize(a) + sanetize(b),
'=': lambda a, b : 1 if sanetize(a) == sanetize(b) else 0,
'!': lambda a, b : 0 if sanetize(a) == sanetize(b) else 1,
'<': lambda a, b : 1 if sanetize(a) < sanetize(b) else 0,
'>': lambda a, b : 1 if sanetize(a) > sanetize(b) else 0
}
def format(text):
return regex.findall(
# Locate a number or
"((?<![0-9])[-]?[0-9]*[.]?[0-9]+|" +
# a symbol or,
"[><!=+\-*/^\\\\%]|" +
# a function.
"[a-z]+)"
, text)
def calc(text):
split = format(text)
array = numpy.array(split)
# Iterate over functions available.
for function in functions:
count = split.count(function)
for _ in range(count):
# Find all function indices.
indices = numpy.where(array == function)[0]
for index in indices:
result = functions[function](split[index + 1])
text = text.replace(function + " " + split[index + 1], str(result)).replace(function + split[index + 1], str(result))
split = format(text)
array = numpy.array(split)
# Iterate over symbols available.
for symbol in symbols:
count = split.count(symbol)
for _ in range(count):
# Find all symbol indices.
indices = numpy.where(array == symbol)[0]
for index in indices:
result = symbols[symbol](split[index - 1], split[index + 1])
text = text.replace(split[index - 1] + " " + symbol + " " + split[index + 1], str(result)).replace(split[index - 1] + symbol + split[index + 1], str(result))
split = format(text)
array = numpy.array(split)
return text
def main():
while True:
text = "".join(input(">> ").split())
if text.upper() == "EXIT": break
for _ in range(text.count("(")):
start = text.rfind("(") + 1
result = text[start:text.find(")", start)]
text = text.replace("(" + result + ")", ("*" if text[start - 2].isdigit() else "") + str(calc(result)))
print(calc(text))
if __name__ == "__main__":
main()