Прикреплённый файл «re_calc.py»

Загрузка

   1 #!/usr/bin/env python
   2 # coding: utf
   3 '''
   4 Разбить целочисленное арифметическое выражение на составные части и вычислить его. Для решения этой задачи удобно использовать re.split(), в котором регулярное выражение-разделитель забрано в скобки, тогда результатом будет список вида ["строка_не_разделителей","строка_разделителей","строка_не_разделителей","строка_разделителей"…].
   5 
   6 Для операций «+», «-», «*» и «/» с учётом приоритета, скобок и обработкой ошибок
   7 '''
   8 import re, sys
   9 
  10 __Debug, __Errors = False, 0
  11 def Debug(*args):
  12     "Сообщение об ошибке"
  13     if __Debug: print >> sys.stderr, "###\t"," ".join((str(a) for a in args))
  14 
  15 Sentence = re.sub(r"\s","",("".join(sys.argv[1:]))) # удаляем разделители
  16 Debug("start:",Sentence)
  17 if Sentence.startswith("."):    # Включить отладку
  18     Sentence=Sentence[1:]
  19     __Debug=True
  20     try:
  21         Debug("ANSWER:",eval(Sentence))
  22     except:
  23         Debug("ANSWER: invalid syntax")
  24 
  25 def evalP2(simple):
  26     "Вычисление умножения и деления"
  27     All = re.split("([*/])",simple)
  28     Debug("P2:",simple)
  29     while len(All)>2:
  30         a,op,b=All[:3]      # операнд, операция, операнд
  31         Debug("\tP2:",a,op,b)
  32         if not re.match("\d+$",a): raise SyntaxError, "invalid '{0}'".format(a)
  33         if not re.match("\d+$",b): raise SyntaxError, "invalid '{0}'".format(b)
  34         if   op=="*": All[:3]=[str(int(a)*int(b))]
  35         elif op=="/": All[:3]=[str(int(a)/int(b))]
  36         else: raise SyntaxError, "invalid operation '{0}'".format(op)
  37     if len(All)>1: raise SyntaxError, "cannot calculate */ '{0}'".format(All)
  38     return "".join(All)
  39 
  40 def evalP(simple):
  41     "Вычисление выражения без скобок"
  42     All = re.split("([+-])",simple)
  43     Debug("P1:",All)
  44     while len(All)>2:
  45         a,op,b=All[:3]
  46         a,b=evalP2(a),evalP2(b)        # вычислить умножение и деление
  47         Debug("\tP1:",a,op,b)
  48         if not re.match("\d+$",a): raise SyntaxError, "invalid '{0}'".format(a)
  49         if not re.match("\d+$",b): raise SyntaxError, "invalid '{0}'".format(b)
  50         if   op=="+": All[:3]=[str(int(a)+int(b))]
  51         elif op=="-": All[:3]=[str(int(a)-int(b))]
  52         else: raise SyntaxError, "invalid operation '{0}'".format(op)
  53         Debug("\tP1:",All)
  54     if len(All)>1: raise SyntaxError, "cannot calculate +- '{0}'".format(All)
  55     return "".join(All)
  56 
  57 def evalW(simple):
  58     global __Errors
  59     try:
  60         return evalP(simple)
  61     except Exception, Exc:
  62         __Errors+=1
  63         print >> sys.stderr, Exc
  64         return "0"
  65 
  66 # Избавимся от скобок: вычислим выражение внутри них
  67 while "(" in Sentence:
  68     All = re.split(r"\(([^()]+)\)",Sentence)
  69     Debug("Deleting ()",All)
  70     if len(All)<2:
  71         print >> sys.stderr, "No pair for '('"
  72         break
  73     for i in xrange(1,len(All),2):
  74         All[i]=evalW(All[i])
  75     Sentence = "".join(All)
  76 res=evalW(Sentence)
  77 if not __Errors: print res

Прикреплённые файлы

Для ссылки на прикреплённый файл в тексте страницы напишите attachment:имяфайла, как показано ниже в списке файлов. Не используйте URL из ссылки «[получить]», так как он чисто внутренний и может измениться.

Вам нельзя прикреплять файлы к этой странице.