Source code for kyu_2.evaluate_mathematical_expression.evaluate

"""
Evaluate mathematical expression.

Given a mathematical expression as a
string you must return the result as a number.
"""

#  Created by Egor Kostan.
#  GitHub: https://github.com/ikostan
#  LinkedIn: https://www.linkedin.com/in/egor-kostan/

OPERATORS = ['*', '/', '+', '-']


[docs]def calculate(i: int, char: str, strings: list): a = float(strings[i - 1]) b = float(strings[i + 1]) if char == '*': strings[i] = str(a * b) if char == '/': strings[i] = str(a / b) del strings[i + 1] del strings[i - 1]
[docs]def process_math_expression(string: str, operators: list) -> str: strings = [s for s in string.split(' ') if s != '+'] while any((True if s in operators else False) for s in strings): for i, char in enumerate(strings): if char in operators: calculate(i, char, strings) break return ' '.join(strings)
[docs]def normalize_string(string: str) -> str: strings = list() string_temp = ''.join([s for s in string if s != ' ']) while string_temp != '': temp = '' for i, s in enumerate(string_temp): if s.isdigit(): temp += s if s in '()': if temp != '': strings.append(temp) strings.append(s) if i + 1 < len(string_temp): string_temp = string_temp[i + 1:] else: string_temp = '' break if s in OPERATORS: if temp != '': strings.append(temp) strings.append(s) if i + 1 < len(string_temp): string_temp = string_temp[i + 1:] break if i == len(string_temp) - 1: if temp != '': strings.append(temp) string_temp = '' return ' '.join([s for s in strings if s != ''])
[docs]def process_brakets(string): strings = string.split(' ') while '(' in strings: start = ([i for i, strg in enumerate(strings) if strg == '('])[-1] end = strings[start:].index(')') + start if len(strings[start + 1: end]) < 3: del strings[end] del strings[start] if len(strings[start + 1: end]) > 2: temp = ' '.join(strings[start + 1: end]) temp = process_duplicate_minus(temp) temp = process_math_expression(temp, ['*', '/']) temp = str(sum([float(t) for t in temp.split() if t != '+'])) tmp_strings = strings[:start] tmp_strings.append(temp) if end < len(strings) - 1: tmp_strings += strings[end + 1:] strings = tmp_strings return ' '.join(strings)
[docs]def process_duplicate_minus(string: str) -> str: done = False strings = string.split(' ') while not done: done = True for i, s in enumerate(strings): if s == '-': if strings[i + 1] == '-': done = False strings[i] = '+' del strings[i + 1] break elif any([(True if t.isdigit() else False) for t in strings[i + 1]]): done = False strings[i] = str(float(strings[i + 1]) * (-1)) del strings[i + 1] break if s == '+': if strings[i + 1] == '-': done = False del strings[i] break return ' '.join([s for s in strings if s != ''])
[docs]def calc(string: str) -> float: string = normalize_string(string) string = ' '.join(string.split('+')) string = process_brakets(string) string = process_duplicate_minus(string) string = process_math_expression(string, ['*', '/']) string = str(sum([float(s) for s in string.split(' ')])) return float(string)