Тема: [Пост] Калькулятор який "знає" послідовність математичних дій
Зробив калькуляторі який зможе порахувати
1) (4/9/4-(52/462*(-9*(6*5-6-8*(47/5*(8-9)*8)))))-6*9-6+3+5*5-9-.83
2) 7-9*(4/(5*(5-3)*(4*4)))*8
3) 7-(1-1)+(-1)
та інше що використовує цілі, або з плаваючою точкою числа.
Мат. операції *,/,-,+.
Дужки (,)
Метод calculate отримує вираз як вхідні дані, встановлює початкову позицію на 0, а потім викликає метод parse_expression для розбору та обчислення виразу.
Метод parse_expression спочатку викликає метод parse_term для отримання значення лівого операнда. Потім він перевіряє, чи є в виразі ще оператори і якщо вони є або '+' або '-', то він викликає відповідний метод (parse_term для '+' та '-' операторів) для розбору правого операнда, а потім виконує відповідну операцію. Він продовжує це робити, доки всі оператори виразу не будуть оброблені та оцінені.
Метод parse_term спочатку викликає метод parse_factor для отримання значення лівого операнда. Потім він перевіряє, чи є в виразі ще оператори і якщо вони є або '*' або '/', то він викликає відповідний метод (parse_factor для '*' та '/' операторів) для розбору правого операнда, а потім виконує відповідну операцію. Він продовжує це робити, доки всі оператори виразу не будуть оброблені.
Метод parse_factor спочатку перевіряє, чи поточний символ у виразі є '('. Якщо це так, то він викликає метод parse_expression для обробки вкладеного в дужки підвиразу. Якщо поточний символ є '-', він встановлює значення як від'ємне і викликає метод parse_number для розбору числа. В іншому випадку він викликає метод parse_number для розбору числа.
Метод parse_number знаходить початок числа та продовжує пересувати позицію, доки не досягне кінця числа. Потім він повертає число у форматі float. Якщо число не знайдено, він створює ValueError.
class Calculator:
def calculate(self, expr):
self.expr = expr
self.pos = 0
return self.parse_expression()
def parse_expression(self):
value = self.parse_term()
while self.pos < len(self.expr) and self.expr[self.pos] in '+-':
op = self.expr[self.pos]
self.pos += 1
if op == '+':
value += self.parse_term()
else:
value -= self.parse_term()
return value
def parse_term(self):
value = self.parse_factor()
while self.pos < len(self.expr) and self.expr[self.pos] in '*/':
op = self.expr[self.pos]
self.pos += 1
if op == '*':
value *= self.parse_factor()
else:
value /= self.parse_factor()
return value
def parse_factor(self):
if self.expr[self.pos] == '(':
self.pos += 1
value = self.parse_expression()
if self.expr[self.pos] != ')':
raise ValueError("Expected ')' at position " + str(self.pos))
self.pos += 1
else:
if self.expr[self.pos] == '-':
self.pos += 1
value = -self.parse_number()
else:
value = self.parse_number()
return value
def parse_number(self):
start = self.pos
while self.pos < len(self.expr) and (self.expr[self.pos].isdigit() or self.expr[self.pos] == '.'):
self.pos += 1
if start == self.pos:
raise ValueError("Invalid number at position " + str(start))
return float(self.expr[start:self.pos])
calc = Calculator()
print(calc.calculate("(4/9/4-(52/462*(-9*(6*5-6-8*(47/5*(8-9)*8)))))-6*9-6+3+5*5-9-.83"))