4
\$\begingroup\$

This is a calculator I created. It can take all basic operators, including brackets. I am a beginner with Python so I want to know what can I do better next time I write something similar.

def eval(expression):
    current = 0
    while current < len(expression):
        x = expression[current]
        if x == '(':
            levels = 1
            inside = ''
            while levels:
                current+=1
                x = expression[current]
                if x == ')':
                    levels -= 1
                    if not levels:
                        expression = expression.replace('('+inside+')',str(eval(inside)))
                        current -= (len(inside)+2)
                    else:
                        inside+=')'
                elif x == '(':
                    levels+=1
                    inside+=x
                else:
                    inside+=x
        current+=1
    expressions = list(filter(None,expression.replace('+-','-').replace('-','+-').split('+')))
    ret = 0
    for exp in expressions:
        if exp.find('*') == -1 and exp.find('/') == -1:
            ret+=int(exp)
            continue
        op = '*'
        expret = 1
        exp +='*1'
        while exp.find('*') > -1 or  exp.find('/') > -1:
            next_mult = exp.find('*')
            next_div = exp.find('/')
            if next_mult > -1 and (next_mult < next_div or next_div==-1):
                expret = multdiv(expret,op,float(exp[:next_mult]))
                op = '*'
                exp = exp[next_mult+1:]
            elif next_div < next_mult:
                expret = multdiv(expret,op,float(exp[:next_div]))
                op = '/'
                exp = exp[next_div+1:]
        ret += expret
    return ret
def multdiv(num1,op,num2):
    if op == '*':
        return num1*num2
    return num1/num2

print(eval(input()))
\$\endgroup\$
  • \$\begingroup\$ Crashes for 1 + -3 \$\endgroup\$ – Martin R Sep 11 '18 at 17:24
  • \$\begingroup\$ See this answer for some advice on writing an expression evaluator. \$\endgroup\$ – Gareth Rees Sep 11 '18 at 18:46
  • \$\begingroup\$ eval('(1*1)')ValueError: invalid literal for int() with base 10: '1.0' \$\endgroup\$ – Gareth Rees Sep 12 '18 at 15:46