From 85d61366a7d4593f0504da68741f0429389fea66 Mon Sep 17 00:00:00 2001 From: Garritt McCune Date: Fri, 24 Apr 2020 01:38:36 -0500 Subject: [PATCH] Updated the calc_engine to use the deque object for its main token listing. Added more robust support for the power operator. --- calc_engine.py | 93 +++++++++++++++++++++++++++++++------------------- 1 file changed, 58 insertions(+), 35 deletions(-) diff --git a/calc_engine.py b/calc_engine.py index 2a29ab9..e981078 100644 --- a/calc_engine.py +++ b/calc_engine.py @@ -1,16 +1,12 @@ import ptoken import tokenizer -import queue import copy -import collections.deque +from collections import deque debug = True def calculate_results(tokens): - q = convert_to_queue(tokens) - tokenizer.print_token_list(tokens) - - return process_tokens(q, True) + return process_tokens(convert_to_deque(tokens), True) def process_tokens(tokens, top_level = False): pending_operations = [] @@ -19,12 +15,23 @@ def process_tokens(tokens, top_level = False): p_ops_ran = False while True: - if tokens.empty(): + if not tokens: break - tokenizer.print_token_list(pending_operations) - token = tokens.get() + + token = tokens.popleft() if not top_level and token.type == ptoken.TokenType.exp_end: + + if tokens: + look_ahead = tokens[0] + + if look_ahead.type == ptoken.TokenType.power: + tokens.popleft() + two_ahead = tokens.popleft() + + tmp = process_tokens(convert_to_deque(pending_operations)) + power = 5 + running_total = operate(tmp, two_ahead.value, look_ahead.type) break if token.type == ptoken.TokenType.exp_start: @@ -32,25 +39,25 @@ def process_tokens(tokens, top_level = False): pending_operations.append(ptoken.Token(tmp, ptoken.TokenType.constant)) elif token.type == ptoken.TokenType.power: - look_ahead = tokens.get() + look_ahead = tokens.popleft() pending_operations.append(ptoken.Token(operate(pending_operations.pop().value, look_ahead.value, token.type), ptoken.TokenType.constant)) elif token.type == ptoken.TokenType.add or token.type == ptoken.TokenType.subtract: - if len(pending_operations) > 0 and p_ops_ran: - tmp = convert_to_queue(pending_operations) + if pending_operations and p_ops_ran: + tmp = convert_to_deque(pending_operations) previous_token = None while True: - if tmp.empty(): + if not tmp: break - tmp_token = tmp.get() + tmp_token = tmp.popleft() if tmp_token.type == ptoken.TokenType.constant: previous_token = tmp_token elif tmp_token.type == ptoken.TokenType.add or tmp_token.type == ptoken.TokenType.subtract: - look_ahead = tmp.get() + look_ahead = tmp.popleft() running_total = operate(previous_token.value, look_ahead.value, tmp_token.type) @@ -59,7 +66,6 @@ def process_tokens(tokens, top_level = False): pending_operations = [] pending_operations.append(previous_token) pending_operations.append(token) - #tokenizer.print_token_list(pending_operations) p_ops_ran = False elif token.type == ptoken.TokenType.constant: @@ -67,39 +73,51 @@ def process_tokens(tokens, top_level = False): p_ops_ran = False elif token.type == ptoken.TokenType.multiply or token.type == ptoken.TokenType.divide: - look_ahead = tokens.get() + look_behind = pending_operations.pop() + look_ahead = tokens.popleft() + two_ahead = tokens[0] if look_ahead.type == ptoken.TokenType.exp_start: look_ahead = ptoken.Token(process_tokens(tokens), ptoken.TokenType.constant) - look_behind = pending_operations.pop() + if two_ahead.type == ptoken.TokenType.power: + tokens.popleft() + three_ahead = tokens.popleft() + + if three_ahead.type != ptoken.TokenType.exp_start: + look_ahead = ptoken.Token(operate(look_ahead.value, three_ahead.value, two_ahead.type), ptoken.TokenType.constant) + else: + tmp = process_tokens(tokens) + look_ahead = ptoken.Token(operate(look_ahead.value, tmp, two_ahead.type), ptoken.TokenType.constant) running_total = operate(look_behind.value, look_ahead.value, token.type) pending_operations.append(ptoken.Token(running_total, ptoken.TokenType.constant)) p_ops_ran = True - - #tokenizer.print_token_list(pending_operations) - if len(pending_operations) > 0: - running_total = handle_pending(convert_to_queue(pending_operations)) + #tokenizer.print_token_list(pending_operations) + + if pending_operations and power == 0: + if len(pending_operations) == 1 and power == 0: + return float(pending_operations.pop().value) + return handle_pending(convert_to_deque(pending_operations)) return running_total - +#handle add/sub def handle_pending(tokens): running_total = 0 previous_token = None while True: - if tokens.empty(): + if not tokens: break - tmp_token = tokens.get() + tmp_token = tokens.popleft() if tmp_token.type == ptoken.TokenType.constant: previous_token = tmp_token elif tmp_token.type == ptoken.TokenType.add or tmp_token.type == ptoken.TokenType.subtract: - look_ahead = tokens.get() + look_ahead = tokens.popleft() running_total = operate(previous_token.value, look_ahead.value, tmp_token.type) @@ -107,13 +125,22 @@ def handle_pending(tokens): return running_total -def convert_to_queue(tokens): +'''def convert_to_queue(tokens): q = queue.Queue() for tk in tokens: q.put(ptoken.Token(tk.value, tk.type)) - return q + return q''' + +def convert_to_deque(tokens): + deq = deque() + + for tk in tokens: + deq.append(tk) + + return deq + def operate(n1, n2, tokenType): n1 = float(n1) @@ -138,15 +165,11 @@ def operate(n1, n2, tokenType): raise TypeError("Invalid operator value " + str(tokenType) + ".", tokenType) def print_t(tokens): - tmp = queue.Queue() + tmp = copy.deepcopy(tokens) while True: - if tokens.empty(): + if not tmp: break - token = tokens.get() - + token = tmp.popleft() print("%s" %(token.value), end = "") - tmp.put(token) print() - - return tmp