Advertisement
EditorRUS

Mathematical Expression Parser

Aug 7th, 2018
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.45 KB | None | 0 0
  1. class MathematicalTree:
  2.     def __init__(self, expression):
  3.         expression = expression.replace(' ', '')
  4.         tokens = MathematicalTree._tokenify(expression)
  5.         tokens = MathematicalTree._parse(tokens, ('^',)) # Exponential group
  6.         tokens = MathematicalTree._parse(tokens, ('*', '/')) # Multiplicative group
  7.         tokens = MathematicalTree._parse(tokens, ('+', '-')) # Additive group
  8.  
  9.         # And figure out the root
  10.         for node in tokens:
  11.             if not node.parent:
  12.                 self.root = node
  13.    
  14.     @staticmethod
  15.     def _tokenify(expression):
  16.         return [
  17.             MathematicalTreeNode(float(''.join(characters))) if part_of_number else next(characters)
  18.             for part_of_number, characters in it.groupby(expression,
  19.                                                          MathematicalTree._is_part_of_num)
  20.         ]
  21.  
  22.     @staticmethod
  23.     def _is_part_of_num(character):
  24.         return character in digits or character == '.'
  25.  
  26.     @staticmethod
  27.     def _parse(tokens, signs):
  28.         new_tokens = []
  29.         tokens = tokens.copy()
  30.  
  31.         for index, token in enumerate(tokens):
  32.             if token in signs:
  33.                 prev_node = new_tokens[-1]
  34.                 next_node = tokens[index+1]
  35.                 new_node = MathematicalTreeNode(
  36.                     token,
  37.                     prev_node,
  38.                     next_node
  39.                 )
  40.                 new_tokens.append(new_node)
  41.  
  42.                 prev_node.parent = new_node
  43.                 next_node.parent = new_node
  44.  
  45.                 new_tokens.pop(-2)
  46.                 tokens.pop(index+1)
  47.             else:
  48.                 new_tokens.append(token)
  49.  
  50.         return new_tokens
  51.    
  52.     def calculate(self):
  53.         return self.root.calculate()
  54.        
  55. class MathematicalTreeNode:
  56.     OPERATOR_MAP = {
  57.         '+': op.add,
  58.         '-': op.sub,
  59.         '*': op.mul,
  60.         '/': op.truediv,
  61.         '^': op.pow
  62.     }
  63.     def __init__(self, value, left=None, right=None):
  64.         self.value = value
  65.         self.left = left
  66.         self.right = right
  67.         self.parent = None # To simplify the search of root node
  68.  
  69.     def calculate(self):
  70.         if not self.left:
  71.             return self.value
  72.        
  73.         result = MathematicalTreeNode.OPERATOR_MAP[self.value](self.left.calculate(),
  74.                                                                self.right.calculate())
  75.        
  76.         return result
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement