SUBANGKAR

Expr-in-OOP

Apr 16th, 2021 (edited)
773
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import re
  2. from collections import deque
  3. from abc import ABC, abstractmethod
  4.  
  5.  
  6. class Operator(ABC):
  7.  
  8.     def __init__(self):
  9.         self.value = ''
  10.  
  11.     @abstractmethod
  12.     def operate(self, op1, op2):
  13.         pass
  14.  
  15.     @abstractmethod
  16.     def precedence(self) -> int:
  17.         pass
  18.  
  19.     def __repr__(self) -> str:
  20.         return self.value
  21.  
  22.  
  23. class Addition(Operator):
  24.     def __init__(self):
  25.         super().__init__()
  26.         self.value = '+'
  27.  
  28.     def operate(self, op1, op2):
  29.         return Operand(str(op1.getvalue() + op2.getvalue()))
  30.  
  31.     def precedence(self) -> int:
  32.         return 2
  33.  
  34.  
  35. class Multiplication(Operator):
  36.  
  37.     def __init__(self):
  38.         super().__init__()
  39.         self.value = '*'
  40.  
  41.     def operate(self, op1, op2):
  42.         return Operand(str(op1.getvalue() * op2.getvalue()))
  43.  
  44.     def precedence(self) -> int:
  45.         return 3
  46.  
  47.  
  48. class Division(Operator):
  49.  
  50.     def __init__(self):
  51.         super().__init__()
  52.         self.value = '/'
  53.  
  54.     def operate(self, op1, op2):
  55.         return Operand(str(op1.getvalue() / op2.getvalue()))
  56.  
  57.     def precedence(self) -> int:
  58.         return 4
  59.  
  60.  
  61. class Operand:
  62.     def __init__(self, value):
  63.         self.value = value
  64.  
  65.     def getvalue(self):
  66.         return float(self.value)
  67.  
  68.     def __repr__(self) -> str:
  69.         return self.value
  70.  
  71.  
  72. class Expression:
  73.  
  74.     def __init__(self, infixexpr: str, operators_cls: list) -> None:
  75.         self.postfixlist = None
  76.         self.infixexpr = infixexpr
  77.         # Precedence setting
  78.         self.op_to_cls = {str(op()): op() for op in operators_cls}
  79.         self.precedence = {str(v): v.precedence() for k, v in self.op_to_cls.items()}
  80.  
  81.     def infixToPostfixList(self) -> list:
  82.         infixexpr = self.infixexpr
  83.         opStack = deque()
  84.         postfixList = []
  85.         number_or_symbol = re.compile('(\d+|[^ 0-9])')
  86.         print(re.findall(number_or_symbol, infixexpr))
  87.  
  88.         for token in re.findall(number_or_symbol, infixexpr):
  89.             if token.isnumeric():
  90.                 postfixList.append(Operand(token))
  91.             elif token == '(':
  92.                 opStack.append(token)
  93.             elif token == ')':
  94.                 topToken = opStack.pop()
  95.                 while topToken != '(':
  96.                     postfixList.append(self.op_to_cls[topToken])
  97.                     topToken = opStack.pop()
  98.             else:
  99.                 while opStack and \
  100.                         (self.precedence[opStack[-1]] >= self.precedence[token]):
  101.                     postfixList.append(self.op_to_cls[opStack.pop()])
  102.                 opStack.append(token)
  103.  
  104.         while opStack:
  105.             postfixList.append(self.op_to_cls[opStack.pop()])
  106.         self.postfixlist = postfixList
  107.         return self.postfixlist
  108.  
  109.     def evaluate(self):
  110.         stack = deque()
  111.         for term in self.postfixlist:
  112.             print(stack, term)
  113.             if isinstance(term, Operand):
  114.                 stack.append(term)
  115.             elif isinstance(term, Operator):
  116.                 r = stack.pop()
  117.                 l = stack.pop()
  118.                 stack.append(term.operate(l, r))
  119.             else:
  120.                 print("Unknown:", term)
  121.         return stack.pop()
  122.  
  123.  
  124. if __name__ == '__main__':
  125.     operators = [Addition, Multiplication, Division]
  126.  
  127.     exp = "1+2+35/ 5+5*7"  # *35 1+2+35/ 5+5*7
  128.  
  129.     print(exp)
  130.     e = Expression(exp, operators)
  131.     print(e.infixToPostfixList())
  132.     print(e.evaluate())
  133.  
RAW Paste Data