def infix_to_postfix(infix_expr): """converts an infix expression to a postfix expression Args: infix_expr (str): the infix expression Returns: str: the postfix expression """ postfix_list = [] oper_stack = StackLinked() split_list = infix_expr.split() for item in split_list: if item in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" or item.isdigit(): postfix_list.append(item) elif item == '(': oper_stack.push(item) elif item == ')': top = oper_stack.pop() while top != '(': postfix_list.append(top) top = oper_stack.pop() elif item == "^" and oper_stack.peek() == "~": oper_stack.push(item) elif item == "~" and oper_stack.peek() == "~": oper_stack.push(item) else: while (not oper_stack.is_empty()) and \ (oper[oper_stack.peek()] >= oper[item]): postfix_list.append(oper_stack.pop()) oper_stack.push(item) while not oper_stack.is_empty(): postfix_list.append(oper_stack.pop()) return " ".join(postfix_list)
def infix_to_postfix(infix_expr): """converts an infix expression into a postfix expression Args: infix_expr (str): expression in infix notation only consisting of numbers (integers, reals, positive or negative), parentheses, and the operators separated by spaces. Returns: String: the postfix converted infix expression """ operators = {"*": 3, "/": 3, "+": 2, "-": 2, "^": 4, "~": 4, "(": 1} operator_stack = StackLinked() post_fix = [] infix = infix_expr.split() for i in infix: if is_number(i): post_fix.append(i) elif i == "(": operator_stack.push(i) elif i == ")": item = operator_stack.pop() while item != "(": post_fix.append(item) item = operator_stack.pop() else: while not operator_stack.is_empty() and \ (operators[operator_stack.peek()] > operators[i]): post_fix.append(operator_stack.pop()) operator_stack.push(i) while not operator_stack.is_empty(): post_fix.append(operator_stack.pop()) return " ".join(post_fix)
def test_stack_linked5(self): stack = StackLinked() for i in range(3): stack.push(i) val = stack.pop() stack.push(val) self.assertEqual(stack.pop(), 2) self.assertEqual(stack.peek(), 1) self.assertEqual(stack.pop(), 1)
def test_stack_linked3(self): stack = StackLinked() for i in range(3): stack.push(i) self.assertEqual(stack.size(), 3) self.assertFalse(stack.is_empty()) self.assertEqual(stack.pop(), 2) self.assertEqual(stack.pop(), 1) self.assertEqual(stack.pop(), 0) self.assertEqual(stack.size(), 0) self.assertTrue(stack.is_empty())
def test_stack_linked4(self): stack = StackLinked() for i in range(10): stack.push(i) for i in range(10): val = stack.pop() self.assertRaises(IndexError, stack.pop) self.assertRaises(IndexError, stack.peek)
def test_size(self): stk_a = StackLinked(4) stk_a.push(6) stk_a.push(7) stk_a.push(8) stk_a.push(9) self.assertTrue(stk_a.is_full()) with self.assertRaises(IndexError): stk_a.push(0) self.assertEqual(stk_a.size(), 4 ) self.assertEqual(stk_a.pop(), 9 ) self.assertEqual(stk_a.size(), 3 ) self.assertFalse(stk_a.is_empty())
def test_push(self): stk_a = StackLinked(4) stk_a.push(3) self.assertEqual(stk_a.peek(), 3 ) self.assertEqual(stk_a.pop(), 3 ) self.assertTrue(stk_a.is_empty())
def postfix_eval(postfix_expr): """evaluates a postfix expression into a value. Uses the postfix_valid function described below to check the validity of the expression Args: postfix_expr (str): an expression in postfix notation Returns: int/float: the solution to the postfix expression if valid Raises: SyntaxError: when the postfix expression is invalid ZeroDivisionError: when dividing by zero """ if not postfix_valid(postfix_expr): raise SyntaxError expr = postfix_expr.split() operands_stack = StackLinked() for i in expr: if is_number(i): operands_stack.push(float(i)) elif i == "^": exp = operands_stack.pop() item = operands_stack.pop() ** exp operands_stack.push(item) elif i == "*": item = operands_stack.pop() * operands_stack.pop() operands_stack.push(item) elif i == "/": div = operands_stack.pop() if div == 0: raise ZeroDivisionError item = operands_stack.pop() / div operands_stack.push(item) elif i == "+": item = operands_stack.pop() + operands_stack.pop() operands_stack.push(item) elif i == "-": sub2 = operands_stack.pop() item = operands_stack.pop() - sub2 operands_stack.push(item) elif i == "~": item = operands_stack.pop() * -1 operands_stack.push(item) return round(operands_stack.pop(), 2)