Move History

Fork Selected
  • Description

    Parses an expression.

    Code
    def parse(expr): #The main parser
      ps = 0 #Number of open parentheses
      cval = 0 #Current value
      op = "+" #Current operation
      accum = "" #Accumulating value
      for i in range(len(expr)):
        c = expr[i]
        if c in ["+","-"] and not ps: #Operation not inside parens
          if op=="+": #Addition
            cval+=parse_fact(accum)
          else: #Subtraction
            cval-=parse_fact(accum)
          accum = "" #Reset the value
          op = c #New operation once that was calculated
        else:
          if c=="(": ps+=1 #Open paren
          if c==")": ps-=1 #Close paren
          accum+=c #Add a character to accumulating value
      if op=="+": #Do the operation one more time
        cval+=parse_fact(accum)
      else:
        cval-=parse_fact(accum)
      return cval
    def parse_fact(term):
      ps = 0
      cval = 1
      op = "*"
      accum = ""
      for i in range(len(term)):
        c = term[i]
        if c in ["*","/"] and not ps:
          if op=="*":
            cval*=parse_val(accum)
          else:
            cval/=parse_val(accum)
          accum = ""
          op = c
        else:
          if c=="(": ps+=1
          if c==")": ps-=1
          accum+=c
      if op=="*":
        cval*=parse_val(accum)
      else:
        cval/=parse_val(accum)
      return cval
    def parse_val(val):
      if val[0] == "(": #Parenthetical expression
        return parse(val[1:-1]) #Cut off parentheses and reevaluate
      else:
        return float(val) #Not parenthetical
    Test Cases
    test.expect(parse("5")==5,"FAILED TEST CASE 1 (5)")
    test.expect(parse("5+5")==10,"FAILED TEST CASE 2 (5+5)")
    test.expect(parse("5*5")==25,"FAILED TEST CASE 3 (5*5)")
    test.expect(parse("5*5+5")==30,"FAILED TEST CASE 4 (5*5+5)")
    test.expect(parse("5*5+5/5")==26,"FAILED TEST CASE 5 (5*5+5/5)")
    test.expect(parse("5*(5+5)/5")==10,"FAILED TEST CASE 6 (5*(5+5)/5)")
    test.expect(parse("5*(5+(10/2))/5")==10,"FAILED TEST CASE 7 (5*(5+(10/2))/5)")
    test.expect(parse("(60/5)-4/29-61+96")==46.86206896551724,"FAILED TEST CASE 8")