ilyakharlamov

https://avva.livejournal.com/3098662.html

Mar 20th, 2018
193
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 1.62 KB | None | 0 0
  1. import operator as O
  2. import re
  3.  
  4. ops = {}
  5. ops["+"] = O.add
  6. ops["-"] = O.sub
  7. ops["*"] = O.mul
  8. ops["/"] = O.div
  9. ops["^"] = O.pow
  10.  
  11. re_ops = "[%s]" % "\\".join([" "]+ops.keys())[1:]
  12.  
  13.  
  14. class OpIsNotSupported(Exception):
  15.     pass
  16.  
  17.  
  18. def calc(fst, op, snd):
  19.     print "calc, %s %s %s" % (fst, op, snd)
  20.     if op not in ops:
  21.         raise OpIsNotSupported(op)
  22.     return ops[op](fst, snd)
  23.  
  24. increment = lambda x, y: ((x or 0)*10) + int(y)
  25.  
  26.  
  27. def expr_wo_brackets(s):
  28.     (fst,  op, snd) = [None]*3
  29.     (fstsign, sndsign) = (1, 1)
  30.     for c in s:
  31.         if c == "-" and op and snd is None:
  32.             sndsign = -1
  33.         elif c == "-" and fst is None:
  34.             fstsign = -1
  35.         elif '0' <= c <= '9':
  36.             if op is None:
  37.                 fst = increment(fst, c)
  38.             else:
  39.                 snd = increment(snd, c)
  40.         elif re.match(re_ops, c):
  41.             if snd is not None:
  42.                 fst = calc(fstsign * fst, op, sndsign * snd)
  43.                 op = c
  44.                 snd = None
  45.                 (fstsign, sndsign) = (1, 1)
  46.             else:
  47.                 op = c
  48.         else:
  49.             raise OpIsNotSupported(c)
  50.     return calc(fstsign * fst, op, sndsign*snd) if snd else fstsign * fst
  51.  
  52.  
  53. def validate(s):
  54.     diff = re.sub("\d+|%s|\(|\)" % re_ops, "", s)
  55.     if diff:
  56.         raise OpIsNotSupported(diff[0])
  57.  
  58.  
  59. def calculator(s):
  60.     s = s.replace("(-(", "(0-(")
  61.     validate(s)
  62.     while "(" in s:
  63.         s = re.sub("\((\-?\d+(%s\-?\d+)*)\)" % re_ops, lambda m: `expr_wo_brackets(m.group(1))`, s)
  64.     return expr_wo_brackets(s)
  65.  
  66.  
  67. print calculator("100/(8^2+6^(-(-2)))-1")
Add Comment
Please, Sign In to add comment