-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathevaluate_expression.py
70 lines (50 loc) · 1.89 KB
/
evaluate_expression.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
"""
Evaluate the value of an arithmetic expression in Reverse Polish Notation.
Valid operators are +, -, *, /. Each operand may be an integer or
another expression.
["2", "1", "+", "3", "*"] -> ((2 + 1) * 3) -> 9
["4", "13", "5", "/", "+"] -> (4 + (13 / 5)) -> 6
"""
def is_operand(expr):
return expr in ['+', '-', '/', '*']
def eval(left, right, op):
if op == '+':
return left + right
elif op == "-":
return left - right
elif op == "/":
return left / right
elif op == "*":
return left * right
else:
raise ValueError('Operand {} not supported'.format(op))
def eval_reverse_polish_notation(notation):
numbers = []
for expr in notation:
if is_operand(expr):
right = numbers.pop()
left = numbers.pop()
result = eval(left, right, expr)
numbers.append(result)
else:
numbers.append(int(expr))
return numbers.pop()
eval_rpn = eval_reverse_polish_notation
def test_simple_expression():
assert eval_rpn(["2", "1", "+"]) == 3
def test_reducable_expression():
assert eval_rpn(["2", "1", "+", "3", "*"]) == 9
def test_complex_reducable_expression():
assert eval_rpn(["4", "13", "5", "/", "+"]) == 6
assert eval_rpn(["4", "13", "3", "+", "5", "/", "+"]) == 7
def test_long_expression():
assert eval_rpn([
"-2", "-1", "2", "+", "-1", "-", "-", "2", "-2", "1",
"-", "+", "-", "-2", "-2", "-", "-1", "2", "-2", "-", "-2", "-1", "+",
"1", "1", "-", "-1", "+", "1", "*", "*", "2", "+", "*", "-", "-2", "1",
"-2", "*", "+", "-2", "*", "1", "*", "-", "*", "*"]) == 0
def test_minus_expression():
assert eval_rpn([
"1", "-1", "2", "+", "2", "-", "-1", "1", "*", "-", "-2", "*", "*",
"2", "-2", "-2", "*", "-", "+", "-2", "1", "-", "1", "-", "*", "2",
"-", "-1", "2", "1", "*", "*", "-"]) == 8