-
Notifications
You must be signed in to change notification settings - Fork 0
/
calculator v 1.py
100 lines (77 loc) · 3.18 KB
/
calculator v 1.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
import re
# https://www.codewars.com/kata/5235c913397cbf2508000048/train/python
# что-то придумать с дробными и отрицательными числами
# не работает нормально с отрицательными и дробными
'[\/\+\*\-\(\)]' # all operators
'\(.+\)' # expression in brackets
'\d+ [\/\*] \d+' # expression for mult and div
'\d+ [\+\-] \d+' # expression for mult and div
def div(operand_left, operand_right):
return operand_left // operand_right
def mult(operand_left, operand_right):
return operand_left * operand_right
def add(operand_left, operand_right):
return operand_left + operand_right
def sub(operand_left, operand_right):
return operand_left - operand_right
def search_in_brackets(s):
left = re.search(r'\(', s).span()[0]
right = left + 1
flag = 1
for i in range(right, len(s)+1):
print(s[i: len(s)+1])
if s[right] == ')':
flag -= 1
elif s[right] == '(':
flag += 1
right = i
if flag == 0:
return left, right
class Calculator(object):
operations = {'*': mult, '/': div, '+': add, '-': sub}
def evaluate(self, string):
oper = re.findall(r'[\/\+\*\-\(\)]', string)
if len(re.findall(r'[\/\+\*\-]', string)) > len(re.findall(r'\d+', string)):
return string
if len(oper) < 1:
return int(string)
elif len(oper) == 1:
nums = re.findall(r'\d+', string)
return int(self.operations[oper[0]](int(nums[0]), int(nums[1])))
while re.search(r'\(.+\)', string) is not None:
rng = search_in_brackets(string)
string = string[:rng[0]] + str(self.evaluate(string[rng[0]+1:rng[1]-1])) + string[rng[1]:]
oper = re.findall(r'[\/\+\*\-\(\)]', string)
if len(oper) < 1:
return int(string)
elif len(oper) == 1:
nums = re.findall(r'\d+', string)
return int(self.operations[oper[0]](int(nums[0]), int(nums[1])))
while re.search(r'\d+ [\/\*] \d+', string) is not None:
rng = re.search(r'\d+ [\/\*] \d+', string).span()
string = string[:rng[0]] + str(self.evaluate(string[rng[0]:rng[1]])) + string[rng[1]:]
if len(oper) < 1:
return int(string)
elif len(oper) == 1:
nums = re.findall(r'\d+', string)
return int(self.operations[oper[0]](int(nums[0]), int(nums[1])))
while re.search(r'\d+ [\+\-] \d+', string) is not None:
rng = re.search(r'\d+ [\+\-] \d+', string).span()
string = string[:rng[0]] + str(self.evaluate(string[rng[0]:rng[1]])) + string[rng[1]:]
return int(string)
calc = Calculator()
# simple test
print(calc.evaluate('2 + 2'))
print(calc.evaluate('9 / 3'))
print(calc.evaluate('7 * 3'))
print(calc.evaluate('8 - 2'))
# mul and division test
print(calc.evaluate('9 / 3 * 4'))
print(calc.evaluate('7 * 3 * 2 / 6'))
# brackets with mul and div
print(calc.evaluate('9 / (3 * 3)'))
print(calc.evaluate('54 / (3 * (10 / 5))'))
# add and sub
print(calc.evaluate('7 + 3 - 2 + 6'))
print(calc.evaluate('54 - (3 + (10 / 5))'))
print(calc.evaluate('2 / 2 + 3 * 4 - 6'))