/
EquationParse.py
112 lines (94 loc) · 2.68 KB
/
EquationParse.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
100
101
102
103
104
105
106
107
108
109
110
111
112
'''
This was a fun little task from another group. Write a function to compute these expressions, without using exec/eval. You may assume the strings contain only integers and the 4 basic operators, + - * /
You may assume that each string holds a valid expression.
'''
import re
explist = ["4 + 5 - 2 * 3 + 6 + 4*3 - 8 / 2",
"18 + 67 / 4 - 80 * 155", "15 + 78 * 178 - 90",
"157*45-78/88",
"4 + 4 * 2 / ( 1 - 5 )",
"4.5 - .75 + 2.25 * 4",
]
def parse_equation(equ : str):
''' Accept an expression in infix notation
and convert it to postfix notation so
that it can be easily evaluated.
Operations supported are:
+, -, *, /, and ()
input: a text sring containing the
equation to be evaluated. It is
assumed that the equation is
syntactly correct, and in
infix notation.
output: a list containing the postfix
equation, broken down into
individual tokens.
'''
pres = {"+": 5, "-": 5,
"*": 10, "/": 10,
"^": 15,
"(": -1, ")": -1, }
output = []
stack = []
state = "operand"
input = re.findall(r'[.0-9]+|\D',
equ.replace(" ",""),
re.ASCII)
while input:
atom = input.pop(0)
if atom not in pres:
output.append(atom)
else:
if len(stack) == 0:
stack.append(atom)
else:
if atom == "(":
stack.append(atom)
elif atom == ")":
while stack[-1] != "(":
output.append(stack.pop())
stack.pop()
else:
while len(stack) > 0 and pres[atom] <= pres[stack[-1]]:
output.append(stack.pop())
stack.append(atom)
while len(stack) > 0:
output.append(stack.pop())
return output
def process_postfix(equ : list):
''' Given a list of tokens in postfix
order, return the result of the
equation.
input: a list containing an
equation in postfix order.
output: the float result of
evaluating the equation.
'''
operation = {"+": float.__add__,
"-": float.__sub__,
"*": float.__mul__,
"/": float.__truediv__, }
stack = []
while len(equ) > 0:
atom = equ.pop(0)
if re.match(r"[.0-9]+", atom):
stack.append(atom)
else:
x = float(stack.pop())
y = float(stack.pop())
stack.append(str(operation[atom](y, x)))
return stack.pop()
if __name__ == "__main__":
for e in explist:
''' show the equation to be evaluated,
show the result of passing it
to eval, then show the result of
calling parse_equation() and
process_postfix().
'''
print(e)
print("eval = ", eval(e))
postfix = parse_equation(e)
result = process_postfix(postfix)
print("=", result)
print()