Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import ast
- import os
- class Empty(Exception):
- pass
- class Stack:
- def __init__(self):
- self._data = []
- def __len__(self):
- return len(self._data)
- def __str__(self):
- return str(self._data)
- def is_empty(self):
- return len(self._data) == 0
- def push(self, e):
- self._data.append(e)
- def top(self):
- if self.is_empty():
- raise Empty('Stack is empty')
- return self._data[-1]
- def pop(self):
- if self.is_empty():
- raise Empty('Stack is empty')
- return self._data.pop()
- def string_check(string):
- parentheses_stack = Stack()
- parentheses_count = 0
- operators_count = 0
- operands_count = 0
- try:
- for lexeme in string:
- if lexeme == '(':
- parentheses_stack.push('(')
- parentheses_count += 1
- elif lexeme == ')':
- parentheses_stack.pop()
- elif lexeme in [str(a) for a in range(0, 10)]:
- operands_count += 1
- elif lexeme in ['+', '-', '*', '/']:
- if parentheses_stack.is_empty():
- print('Not a valid expression, brackets mismatched.')
- return False
- operators_count += 1
- except Empty:
- print('Tried to close parenthesis which was not open')
- return False
- if not parentheses_stack.is_empty(): # there are open brackets
- print('Not a valid expression, brackets mismatched.')
- return False
- if operators_count + 1 < operands_count:
- print('Not a valid expression, operator missing.')
- return False
- if parentheses_count != operators_count:
- print('Not a valid expression, wrong number of operands.')
- return False
- return True
- def input_correct_expression():
- mathematical_expression = input("\nEnter a mathematical expression: ")
- while not string_check(mathematical_expression):
- mathematical_expression = input("\nEnter a VALID mathematical expression: ")
- return mathematical_expression
- def eval_expression(expression):
- print("\n" + str(expression) + " = " + str(eval(expression)))
- with open('cache.txt', 'w+') as file_cache:
- file_cache.write("")
- # Flushes cache.txt out of its contents once a new expression is entered
- def show_children(node, level=0):
- def print_operator(operator, lvl):
- operator = str(operator)
- print((lvl - 2) * " ", operator)
- with open('cache.txt', 'a+') as file_cache:
- file_cache.write((lvl - 2) * " " + " " + operator + "\n")
- if isinstance(node, ast.Num):
- num_node = (level + 2) * " " + " --" + str(node.n)
- print(num_node)
- with open('cache.txt', 'a+') as file:
- file.write(str(num_node) + '\n')
- else:
- if "Add" in str(node):
- print_operator("-- +", level)
- elif "Sub" in str(node):
- print_operator("-- -", level)
- elif "Div" in str(node):
- print_operator("-- /", level)
- elif "Mul" in str(node):
- print_operator("-- *", level)
- elif "BinOp" in str(node) or "Expression" in str(node):
- pass
- else:
- print(level * " ", end=" ")
- print(str(node))
- for child in ast.iter_child_nodes(node):
- show_children(child, level + 4)
- def draw_tree(expression):
- print("\n\nBinary tree of the expression '" + str(expression) + "':\n")
- show_children(ast.parse(expression, "", "eval"))
- def save(content):
- if content not in open('saved_expressions.txt').read():
- choice = None
- print("\nDo you want to save " + str(content) + " in saved_expressions.txt?")
- while choice not in ['y', 'n']:
- choice = input("y/n: ", )
- if choice == 'y':
- with open('saved_expressions.txt', 'a+') as file:
- file.write(str(content) + '\n')
- else:
- pass
- print('\n' + '-' * 64)
- def load():
- if os.stat('saved_expressions.txt').st_size != 0:
- print("\nWould you like to load a saved expression?")
- choice = None
- while choice not in ['y', 'n']:
- choice = input("y/n: ", )
- print()
- if choice == 'n':
- return input_correct_expression()
- else:
- print("0 - Cached expression")
- lines_list = open('saved_expressions.txt').read().splitlines()
- for index, filename in enumerate(lines_list):
- print(index + 1, "-", filename)
- file_number = None
- while file_number not in range(-1, len(lines_list)):
- file_number = int(input("\nEnter a number: ")) - 1
- if file_number == -1:
- cached_list = open('cache.txt').read().splitlines()
- for line in cached_list:
- print(line)
- run()
- return lines_list[file_number]
- else:
- return input_correct_expression()
- def run():
- exp = load()
- eval_expression(exp)
- draw_tree(exp)
- save(exp)
- while True:
- run()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement