def test_queue(self): test_queue = Queue() for i in range(0, 5): test_queue.push(i) counter = 0 while test_queue.is_empty() is not True: self.assertTrue(test_queue.peek() == counter) test_queue.pop() counter += 1 self.assertTrue(test_queue.is_empty())
def shunting_yard(self, elements: Queue): """Does the shunting yard algorithm to produce something that is ready for rpn""" operator_stack = Stack() while not elements.is_empty(): element = elements.pop() if isinstance(element, numbers.Number): self.output_queue.push(element) elif isinstance(element, Function) or element == "(": operator_stack.push(element) elif element == ")": while operator_stack.peek() != "(": self.output_queue.push(operator_stack.pop()) # Pop ( if operator_stack.peek() == "(": operator_stack.pop() if not operator_stack.is_empty() and isinstance(operator_stack.peek(), Function): self.output_queue.push(operator_stack.pop()) elif isinstance(element, Operator): intermediate_storage = Stack() while ((not operator_stack.is_empty()) and (not operator_stack.peek() == "(") and operator_stack.peek().strength < element.strength): intermediate_storage.push(operator_stack.pop()) while not intermediate_storage.is_empty(): operator_stack.push(intermediate_storage.pop()) operator_stack.push(element) while not operator_stack.is_empty(): self.output_queue.push(operator_stack.pop())
def test_queue(self): """Test Queue class""" queue = Queue() for num in self.test_list: queue.push(num) index = 0 while not queue.is_empty(): num = queue.pop() self.assertEqual(num, self.test_list[index]) index += 1
class Calculator: def __init__(self): self.functions = { 'EXP': Function(numpy.exp), 'LOG': Function(numpy.log), 'SIN': Function(numpy.sin), 'COS': Function(numpy.cos), 'SQRT': Function(numpy.sqrt) } self.operators = { 'ADD': Operator(numpy.add, 0), 'PLUS': Operator(numpy.add, 0), 'MULTIPLY': Operator(numpy.multiply, 1), 'TIMES': Operator(numpy.multiply, 1), 'DIVIDE': Operator(numpy.divide, 1), 'SUBTRACT': Operator(numpy.subtract, 0), 'MINUS': Operator(numpy.subtract, 0) } self.output_queue = Queue() self.input_queue = Queue() def evaluate(self): """ ... """ stack = Stack() for i in range(self.output_queue.size()): element = self.output_queue.pop() if isinstance(element, numbers.Number): stack.push(element) elif isinstance(element, Function): num = stack.pop() calculated_value = element.execute(num) stack.push(calculated_value) elif isinstance(element, Operator): num1 = stack.pop() num2 = stack.pop() calculated_value = element.execute(num2, num1) stack.push(calculated_value) else: raise Exception("Wrong type in the output_queue") if stack.size() != 1: raise Exception("Stack should be of size 1.") return stack.pop() def convert_queue_to_rpn(self): """ ... """ operator_stack = Stack() for i in range(self.input_queue.size()): element = self.input_queue.pop() if isinstance(element, numbers.Number): self.output_queue.push(element) elif isinstance(element, Function): operator_stack.push(element) elif element == "(": operator_stack.push(element) elif element == ")": while operator_stack.peek() != "(": self.output_queue.push(operator_stack.pop()) operator_stack.pop() elif isinstance(element, Operator): while operator_stack.size() != 0: next_element = operator_stack.peek() if isinstance(next_element, Operator): if next_element.strength < element.strength: break elif next_element == "(": break self.output_queue.push(operator_stack.pop()) operator_stack.push(element) else: raise Exception("Wrong type in input queue") for i in range(operator_stack.size()): self.output_queue.push(operator_stack.pop()) def text_parser(self, text): """ parse text with regex """ text = text.replace(" ", "").upper() # Make match strings for regex functions = "|".join(["^" + func for func in self.functions.keys()]) operators = "|".join(["^" + func for func in self.operators.keys()]) parenthesis = "^[()]" nums = "^[-1234567890]+" while text != "": check_num = re.search(nums, text) # Check if number if check_num is not None: matched_num = check_num.__getitem__(0) self.input_queue.push(float(matched_num)) text = text[len(matched_num)::] continue check_par = re.search(parenthesis, text) # Check if parenthesis if check_par is not None: matched_par = check_par.__getitem__(0) self.input_queue.push(matched_par) text = text[1::] continue check_op = re.search(operators, text) # Check if operator if check_op is not None: matched_op = check_op.__getitem__(0) self.input_queue.push(self.operators[matched_op]) text = text[len(matched_op)::] continue check_func = re.search(functions, text) # Check if function if check_func is not None: matched_func = check_func.__getitem__(0) self.input_queue.push(self.functions[matched_func]) text = text[len(matched_func)::] continue return self.input_queue def calculate(self, input_str): """ Put everything together """ self.text_parser(input_str) self.convert_queue_to_rpn() return self.evaluate()
class Calculator(): def __init__(self): # Define the functions supported by linking them to Python # functions. These can be made elsewhere in the program, # or imported (e.g., from numpy) self.functions = { 'EXP': Function(numpy.exp), 'LOG': Function(numpy.log), 'SIN': Function(numpy.sin), 'COS': Function(numpy.cos), 'SQRT': Function(numpy.sqrt) } # Define the operators supported # Link them to Python functions (here: from numpy) self.operators = { 'PLUSS': Operator(numpy.add, 0), 'GANGE': Operator(numpy.multiply, 1), 'DELE': Operator(numpy.divide, 1), 'MINUS': Operator(numpy.subtract, 0) } # Define the output−queue . The parse text method fills this with RPN. # The evaluate_output_queue method evaluates it self.output_queue = Queue() self.input_queue = Queue() def evaluate_output_queue(self): if not isinstance(self.output_queue.peek(), Function) and not isinstance( self.output_queue.peek(), Operator): raise TypeError("This is not RPN") def RSAcalculation(self): sta = Stack() size = self.output_queue.size() for i in range(0, size): element = self.output_queue.pop() if isinstance(element, numbers.Number): sta.push(element) elif isinstance(element, Function): number = sta.pop() sta.push(element.execute(number)) else: #element er operator number2 = sta.pop() number1 = sta.pop() sta.push(element.execute(number1, number2)) return sta.pop() def to_RPN(self): op_stack = Stack() size_input = self.input_queue.size() for i in range(0, size_input): element = self.input_queue.peek() if isinstance(element, numbers.Number): self.output_queue.push(self.input_queue.pop()) elif isinstance(element, Function): op_stack.push(self.input_queue.pop()) elif element == "(": op_stack.push(self.input_queue.pop()) elif element == ")": el = op_stack.peek() while el != "(": self.output_queue.push(op_stack.pop()) el = op_stack.peek() op_stack.pop() self.input_queue.pop() elif isinstance(element, Operator): if not op_stack.is_empty(): el = op_stack.peek() while (isinstance(el, Operator) and el.strength >= element.strength) or isinstance( el, Function): self.output_queue.push(op_stack.pop()) if op_stack.is_empty(): break el = op_stack.peek() op_stack.push(self.input_queue.pop()) size_stack = op_stack.size() for i in range(0, size_stack): self.output_queue.push(op_stack.pop()) def textparser(self, input_txt): txt = input_txt.replace(" ", "").upper() nums = "^[-0123456789.]+" funcs = "|".join(["^" + func for func in self.functions]) ops = "|".join(["^" + op for op in self.operators]) parenths = r"^[\(\)]" while txt != "": check = re.search(nums, txt) if check is not None: txt = self.sub_string(txt, check.end) self.input_queue.push(float(check.group(0))) check = re.search(funcs, txt) if check is not None: txt = self.sub_string(txt, check.end) self.input_queue.push(self.functions[check.group(0)]) check = re.search(ops, txt) if check is not None: txt = self.sub_string(txt, check.end) self.input_queue.push(self.operators[check.group(0)]) check = re.search(parenths, txt) if check is not None: txt = self.sub_string(txt, check.end) self.input_queue.push(check.group(0)) def sub_string(self, string, end): if len(string) - 1 < end(0): return "" return string[end(0):] def calculate_expression(self, txt): self.textparser(txt) self.to_RPN() return self.RSAcalculation()
class calculator: def __init__(self): self.functions = { 'EXP': Function(numpy.exp), 'LOG': Function(numpy.log), 'SIN': Function(numpy.sin), 'COS': Function(numpy.cos), 'SQRT': Function(numpy.sqrt), 'SQUARE': Function(numpy.square) } self.operators = { 'PLUSS': Operator(numpy.add, 0), 'GANGE': Operator(numpy.multiply, 1), 'DELE': Operator(numpy.divide, 1), 'MINUS': Operator(numpy.subtract, 0) } self.output_queue = Queue() def RPN(self): stack = Stack() while not self.output_queue.is_empty(): ele = self.output_queue.pop() if isinstance(ele, float): stack.push(ele) elif ele in self.functions.keys(): ele2 = stack.pop() stack.push(self.functions[ele].execute(ele2)) elif ele in self.operators.keys(): ele2 = stack.pop() ele3 = stack.pop() stack.push(self.operators[ele].execute(ele3, ele2)) return stack.pop() def shunting_yard(self, string_regn): op_strong = "GANGE,DELE" op_stack = Stack() for ele in string_regn: if ele.isdigit() or ele[0] == '-': self.output_queue.push(float(ele)) elif ele in self.functions.keys() or ele == "(": op_stack.push(ele) elif ele == ")": num = op_stack.pop() while num != "(": self.output_queue.push(num) num = op_stack.pop() if ele in self.operators.keys(): peek = op_stack.peek() if peek: if peek in op_strong: self.output_queue.push(op_stack.pop()) op_stack.push(ele) # print(op_stack.items) # print(self.output_queue.items) while not op_stack.is_empty(): self.output_queue.push(op_stack.pop()) # print(self.output_queue.items) return self.RPN() def string_parser(self, text): text.replace(" ", "") regex = '[-A-Z/(*/)*a-z0-9]+' #regex = '[-A-Za-z0-9]+' list1 = re.findall(regex, text) list3 = re.findall('[/(*/)*]+', text) list2 = [] count_par = 0 for i in list1: if '(' in i: num = i.count('(') self.split_par(i, list2, '(', num, list3, count_par) count_par += 1 elif ')' in i: num = i.count(')') self.split_par(i, list2, ')', num, list3, count_par) count_par += 1 else: list2.append(i) # print(list2) return self.shunting_yard(list2) def split_par2(self, i, list2, par, num): start_par = i.split(par) count = 0 for ele in start_par: if ele != "": print(ele) list2.append(ele) for j in range(num): list2.append(par) count += 2 if count > len(start_par) + 1 + num: list2.pop(-1) return list2 def split_par(self, i, list2, par, num, list3, count_par): start_par = i.split(par) count = 0 for ele in start_par: if ele != "": list2.append(ele) for i in range(len(list3[count_par])): list2.append(par) count += 2 if count > len(start_par) + 1 + num: list2.pop(-1) return list2
class Calc: """Calcualtor for evaluation different expressions""" def __init__(self): self.functions = { 'EXP': Function(np.exp), 'LOG': Function(np.log), 'SIN': Function(np.sin), 'COS': Function(np.cos), 'SQRT': Function(np.sqrt) } self.operators = { 'PLUS': Operator(np.add, 0), 'ADD': Operator(np.add, 0), 'TIMES': Operator(np.multiply, 1), 'MULTIPLY': Operator(np.multiply, 1), 'DIVIDE': Operator(np.divide, 1), 'MINUS': Operator(np.subtract, 0), 'SUBTRACT': Operator(np.subtract, 0) } self.output_queue = Queue() def calculate_expression(self, text): """Takes an expression in human readable form and calculates the answer""" text = self.parse_text(text) self.shunting_yard(text) answer = self.rpn() return answer def parse_text(self, text): """Parses human readable text into something that is ready to be sorted by shunting_yard""" text = text.replace(" ", "").upper() index = 0 shunting_yard_ready = Queue() while index < len(text): text = text[index:] # Check for number match = re.search("^[-0123456789.]+", text) if match is not None: shunting_yard_ready.push(float(match.group(0))) index = match.end(0) continue # Check for function match = re.search("|".join(["^" + func for func in self.functions.keys()]), text) if match is not None: shunting_yard_ready.push(self.functions[match.group(0)]) index = match.end(0) continue # Check for operator match = re.search("|".join(["^" + op for op in self.operators.keys()]), text) if match is not None: shunting_yard_ready.push(self.operators[match.group(0)]) index = match.end(0) continue # Check for paranthases match = re.search("^[()]", text) if match is not None: shunting_yard_ready.push(match.group(0)) index = match.end(0) continue return shunting_yard_ready def shunting_yard(self, elements: Queue): """Does the shunting yard algorithm to produce something that is ready for rpn""" operator_stack = Stack() while not elements.is_empty(): element = elements.pop() if isinstance(element, numbers.Number): self.output_queue.push(element) elif isinstance(element, Function) or element == "(": operator_stack.push(element) elif element == ")": while operator_stack.peek() != "(": self.output_queue.push(operator_stack.pop()) # Pop ( if operator_stack.peek() == "(": operator_stack.pop() if not operator_stack.is_empty() and isinstance(operator_stack.peek(), Function): self.output_queue.push(operator_stack.pop()) elif isinstance(element, Operator): intermediate_storage = Stack() while ((not operator_stack.is_empty()) and (not operator_stack.peek() == "(") and operator_stack.peek().strength < element.strength): intermediate_storage.push(operator_stack.pop()) while not intermediate_storage.is_empty(): operator_stack.push(intermediate_storage.pop()) operator_stack.push(element) while not operator_stack.is_empty(): self.output_queue.push(operator_stack.pop()) def rpn(self): """Evaluates self.output_queue in RPN""" intermediate_storage = Stack() while not self.output_queue.is_empty(): item = self.output_queue.pop() if isinstance(item, numbers.Number): intermediate_storage.push(item) elif isinstance(item, Function): result = item.execute(intermediate_storage.pop()) intermediate_storage.push(result) elif isinstance(item, Operator): operand1 = intermediate_storage.pop() operand2 = intermediate_storage.pop() result = item.execute(operand2, operand1) intermediate_storage.push(result) return intermediate_storage.pop()