Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class MathematicalTree:
- def __init__(self, expression):
- expression = expression.replace(' ', '')
- tokens = MathematicalTree._tokenify(expression)
- tokens = MathematicalTree._parse(tokens, ('^',)) # Exponential group
- tokens = MathematicalTree._parse(tokens, ('*', '/')) # Multiplicative group
- tokens = MathematicalTree._parse(tokens, ('+', '-')) # Additive group
- # And figure out the root
- for node in tokens:
- if not node.parent:
- self.root = node
- @staticmethod
- def _tokenify(expression):
- return [
- MathematicalTreeNode(float(''.join(characters))) if part_of_number else next(characters)
- for part_of_number, characters in it.groupby(expression,
- MathematicalTree._is_part_of_num)
- ]
- @staticmethod
- def _is_part_of_num(character):
- return character in digits or character == '.'
- @staticmethod
- def _parse(tokens, signs):
- new_tokens = []
- tokens = tokens.copy()
- for index, token in enumerate(tokens):
- if token in signs:
- prev_node = new_tokens[-1]
- next_node = tokens[index+1]
- new_node = MathematicalTreeNode(
- token,
- prev_node,
- next_node
- )
- new_tokens.append(new_node)
- prev_node.parent = new_node
- next_node.parent = new_node
- new_tokens.pop(-2)
- tokens.pop(index+1)
- else:
- new_tokens.append(token)
- return new_tokens
- def calculate(self):
- return self.root.calculate()
- class MathematicalTreeNode:
- OPERATOR_MAP = {
- '+': op.add,
- '-': op.sub,
- '*': op.mul,
- '/': op.truediv,
- '^': op.pow
- }
- def __init__(self, value, left=None, right=None):
- self.value = value
- self.left = left
- self.right = right
- self.parent = None # To simplify the search of root node
- def calculate(self):
- if not self.left:
- return self.value
- result = MathematicalTreeNode.OPERATOR_MAP[self.value](self.left.calculate(),
- self.right.calculate())
- return result
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement