def stack_split(s1): """ ------------------------------------------------------- Splits the given stack into separate stacks. Given stack is empty when function is done. Items are alternately pushed onto the returned stacks. Order is not significant. Use: s2, s3 = stack_split(s1) ------------------------------------------------------- Preconditions: s1 - the stack to split into two parts (Stack) Postconditions: returns s2 - contains alternating values from given stack (Stack) s3 - contains other alternating values from given stack (Stack) ------------------------------------------------------- """ s2 = Stack() s3 = Stack() while s1.is_empty() != True: s2.push(s1.pop()) if s1.is_empty() != True: s3.push(s1.pop()) return s2, s3
def test_is_empty(self): stack1 = Stack(5) stack2 = Stack(3, [8, 12, 52]) self.assertTrue(stack1.is_empty()) self.assertFalse(stack2.is_empty()) stack1.push(5) self.assertFalse(stack1.is_empty())
def test_is_empty(self): """Creating and testing empty stack""" stack = Stack(5) self.assertEquals(stack.is_empty(), True) """Testing non-empty stack""" stack2 = Stack(5, [5, 4, 3, 2]) self.assertEquals(stack2.is_empty(), False)
def test_eq(self): stack1 = Stack(5) stack2 = Stack(5) stack3 = Stack(10) stack4 = Stack(5,[1, 2]) self.assertEqual(stack1, stack2) self.assertNotEqual(stack1, stack3) self.assertNotEqual(stack1, stack4)
def test2(self): stack2 = Stack(5) stack2.push(3) stacktest = Stack(0) self.assertEqual(stack2.pop(), 3) with self.assertRaises(IndexError): #checks for exception stacktest.pop() with self.assertRaises(IndexError): #checks for exception stacktest.peek()
def test_is_full(self): """Creating and testing full stack""" stack = Stack(6, [5, 4, 3, 2, 1, 0]) self.assertEquals(stack.is_full(), True) """Testing non-full stacks""" stack2 = Stack(6) self.assertEquals(stack2.is_full(), False) stack3 = Stack(6, [1]) self.assertEquals(stack3.is_full(), False)
def test_size(self): stack1 = Stack(5) stack2 = Stack(3, [8, 12, 52]) self.assertEqual(stack1.size(), 0) self.assertEqual(stack2.size(), 3) stack1.push(5) self.assertEqual(stack1.size(), 1) stack2.pop() self.assertEqual(stack2.size(), 2)
def test_is_full(self): stack1 = Stack(2) stack2 = Stack(3, [8, 12, 52]) self.assertFalse(stack1.is_full()) self.assertTrue(stack2.is_full()) stack1.push(5) self.assertFalse(stack1.is_full()) stack1.push(99) self.assertTrue(stack1.is_full())
def test3(self): stack3 = Stack(3) stack3.push(7) stack3.push(6) stack3.push(5) stacktest = Stack(0) self.assertEqual(stack3.peek(), 5) self.assertEqual(stack3.size(), 3) self.assertFalse(stack3.is_empty()) self.assertTrue(stacktest.is_empty())
def test_init(self): stack = Stack(5) self.assertEqual(stack.items, [None]*5) self.assertEqual(stack.capacity, 5) stack = Stack(5, [1, 2]) self.assertEqual(stack.items[0:2], [1, 2]) self.assertEqual(stack.capacity, 5) with self.assertRaises(IndexError): Stack(5, [1, 2, 3, 4, 5, 6])
def test_peek(self): """Cant peek if you're empty *points finger at own head*, peek returns index error""" stack = Stack(5, []) with self.assertRaises(IndexError): stack.peek() """Testing non-empty stacks. Peek returns the item & does not remove item from stack""" stack.push(-1000) self.assertEqual(stack.__repr__(), "Stack(5, [-1000])") self.assertEqual(stack.peek(), -1000) self.assertEqual(stack.__repr__(), "Stack(5, [-1000])") stack2 = Stack(5, [1, 2, 3, 4, 5]) self.assertEqual(stack2.__repr__(), "Stack(5, [1, 2, 3, 4, 5])") self.assertEqual(stack2.peek(), 5) self.assertEqual(stack2.__repr__(), "Stack(5, [1, 2, 3, 4, 5])")
def test_pop(self): """Empty stack will return indexError when popping""" stack = Stack(5, []) with self.assertRaises(IndexError): stack.pop() """Testing non-empty stacks, item is removed from the stack""" stack.push(-1000) self.assertEqual(stack.__repr__(), "Stack(5, [-1000])") self.assertEqual(stack.pop(), -1000) self.assertEqual(stack.__repr__(), "Stack(5, [])") stack2 = Stack(5, [1, 2, 3, 4, 5]) self.assertEqual(stack2.__repr__(), "Stack(5, [1, 2, 3, 4, 5])") self.assertEqual(stack2.pop(), 5) self.assertEqual(stack2.__repr__(), "Stack(5, [1, 2, 3, 4])")
def prefix_to_postfix(input_str): '''Converts a prefix expression to an equivalent postfix expression Input argument: a string containing a prefix expression where tokens are space separated. Tokens are either operators + - * / ** >> << parentheses ( ) or numbers Returns a String containing a postfix expression(tokens are space separated)''' op_lst = ["+", "-", "*", "/", "**"] #list of operators val_lst = input_str.split(" ") #list of individual tokens val_lst.reverse() stack = Stack(len(input_str)) #stack to push and pop our values if input_str == '': return '' for i in val_lst: if i not in op_lst: try: #checks validity of tokens a = float(i) if str(abs(int(a))).isdigit( ): #if i is a number i is pushed on to stack stack.push(i) except ValueError: #if cant't be casted as a float then its invalid raise PostfixFormatException("Invalid token") elif i in op_lst: try: #checks to see if theres enough items to concatenate val1 = stack.pop() val2 = stack.pop() except IndexError: #if an index error is raised from the stack then theres not enough items raise PostfixFormatException("Invalid Prefix Expression") result = str(val1) + " " + str(val2) + " " + i stack.push(result) if stack.size() == 1: return str(stack.pop()) else: #not enough operators raise PostfixFormatException("Invalid Prefix Expression")
def test1(self): stack1 = Stack(1) stack1.push(2) self.assertFalse(stack1.is_empty()) self.assertTrue(stack1.is_full()) with self.assertRaises(IndexError): #checks for exception stack1.push(1)
def test_simple(self): stack = Stack(5) stack.push(0) self.assertFalse(stack.is_empty()) self.assertFalse(stack.is_full()) self.assertEqual(stack.size(), 1) stack.push(4) stack.push(9) self.assertEqual(stack.size(), 3) stack.push(8) stack.push(7) with self.assertRaises(IndexError): stack.push(6) stack.pop() self.assertEqual(stack.size(), 4) self.assertEqual(stack.peek(), 8) stack.pop() stack.pop() stack.pop() self.assertEqual(stack.pop(), 0) self.assertEqual(stack.size(), 0) with self.assertRaises(IndexError): stack.pop() with self.assertRaises(IndexError): stack.peek()
def prefix_to_postfix(input_str): # Converts a prefix expression to an equivalent postfix expression # Input argument: a string containing a prefix expression where tokens are # space separated. Tokens are either operators + - * / ^ parentheses ( ) or numbers # Returns a String containing a postfix expression(tokens are space separated) #Delimiter + Reverse prefixString = list(reversed(input_str.split(" "))) #Stack setup with capacity equal to len of list prefixStack = Stack(len(prefixString)) #For each element in the list for token in prefixString: #Token checker if token in "*/+-^**>><<": #Pops top 2 then assembles as postfix numberOne = prefixStack.pop() numberTwo = prefixStack.pop() tempString = numberOne + " " + numberTwo + " " + token #Pushes string back on the the stack prefixStack.push(tempString) else: prefixStack.push(token) #Returns the string accumulator return prefixStack.peek()
def test_simple(self): stack = Stack(5) self.assertRaises(IndexError, stack.pop) stack.push(0) self.assertFalse(stack.is_empty()) self.assertFalse(stack.is_full()) self.assertEqual(stack.size(),1)
def prefix_to_postfix(input_str): """Converts a prefix expression to an equivalent postfix expression""" """Input argument: a string containing a prefix expression where tokens are space separated. Tokens are either operators + - * / ** parentheses ( ) or numbers Returns a String containing a postfix expression(tokens are space separated)""" stack = Stack(30) operators = ['+', '-', '*', '/', '**'] input = input_str.split() result = "" # Reversing the order input_reverse = input[::-1] # iterating through individual tokens for item in input_reverse: # if token is operator if item in operators: a = stack.pop() b = stack.pop() temp = a + b + item stack.push(temp) else: stack.push(item) # printing final output while not stack.is_empty(): result = result + stack.pop() return " ".join(result)
def postfix_eval(input_str): inputList = input_str.split() postStack = Stack(30) for character in inputList: try: float(character) except: if character not in ['<<', '>>', '**', '*', '/', '+', '-']: raise PostfixFormatException("Invalid token") else: pass for item in inputList: try: postStack.push(int(item)) except ValueError: try: postStack.push(float(item)) except: if postStack.size() >= 2: postStack.push( doMath(postStack.pop(), postStack.pop(), item)) else: raise PostfixFormatException('Insufficient operands') if postStack.size() != 1: raise PostfixFormatException("Too many operands") return postStack.pop()
def infix_to_postfix(input_str): """Converts an infix expression to an equivalent postfix expression""" """Input argument: a string containing an infix expression where tokens are space separated. Tokens are either operators + - * / ** parentheses ( ) or numbers Returns a String containing a postfix expression """ output = [] stack = Stack(30) input = input_str.split() for item in input: if item.isnumeric(): output.append(item) elif item == '(': stack.push(item) elif item == ')': while ((not stack.is_empty()) and (stack.peek() != '(')): val1 = stack.pop() output.append(val1) try: stack.pop() except: raise PostfixFormatException("Insufficient operands") # an operator is encountered else: while ((not stack.is_empty()) and orderOfOperations(stack, item)): output.append(stack.pop()) stack.push(item) # pop all the operator from the stack while not stack.is_empty(): output.append(stack.pop()) return " ".join(output)
def prefix_to_postfix(input_str): # creates a stack to store operators, operands, and joined expressions stack = Stack(30) # change the input string to a list of input operands and operators input_list = input_str.split() # creates a list to store the postfix expression output_list = [] # steps through the input list in reverse for i in input_list[::-1]: # adds operands to the stack try: float(i) stack.push(i) except ValueError: # checks if i is an operator if i in ["+", "-", "*", "/", "**", "(", "<<", ">>"]: # removes the top two values of the stack and adds the operator i to the end val1 = stack.pop() val2 = stack.pop() add = val1 + " " + val2 + " " + i # adds the new expression to the stack stack.push(add) # after the loop goes through the entire input string, # all items in the stack are popped and added to the output postfix expression while stack.size() != 0: output_list.append(stack.pop()) # joins the list of output characters into a string output = ' '.join(output_list) # returns the postfix expression return output
def postfix(s): """ ------------------------------------------------------- Evaluates a postfix expression string ------------------------------------------------------- Preconditions: s - the postfix string to evaluate. Tokens are separated by spaces. Valid operators are +, -, *, /, **, %. Operands are assumed to be float. (str) Postconditions: Returns: answer - the result of evaluating s, None if the stack does not contain exactly one float value after evaluating s (float) ------------------------------------------------------- """ temp = '' stack = Stack() for i in range(len(s)): if s[i].isdigit() == True: temp += s[i] elif s[i] == " ": if s[i - 1] not in OP: stack.push(temp) temp = '' elif s[i] in OP: value1 = str(stack.pop()) value2 = str(stack.pop()) answer = eval(value2 + s[i] + value1) stack.push(answer) temp = '' return answer
def infix_to_postfix(input_str): """Converts an infix expression to an equivalent postfix expression""" inputList = input_str.split() rpnString = '' infixStack = Stack(30) for item in inputList: try: if item.isdigit() == True: num = int(item) else: num = float(item) rpnString += item + ' ' except: if item == '(': infixStack.push(item) elif item == ')': while infixStack.peek() != '(': rpnString += infixStack.pop() + ' ' infixStack.pop() else: if infixStack.size() > 0: o1 = item o2 = infixStack.peek() if checkPrec(o1, o2) == False and o2 != '(': rpnString += item + ' ' + infixStack.pop() + ' ' else: rpnString += infixStack.pop() + ' ' infixStack.push(item) else: infixStack.push(item) for i in range(infixStack.size()): rpnString += infixStack.pop() + ' ' rpnString = rpnString[:-1] return rpnString
def infix_to_postfix(input_str): """Converts an infix expression to an equivalent postfix expression""" """Input argument: a string containing an infix expression where tokens are space separated. Tokens are either operators + - * / ^ parentheses ( ) or numbers Returns a String containing a postfix expression """ stack = Stack(30) tokens = input_str.split(" ") RPN = "" for token in tokens: if is_int(token) or is_float(token): if RPN == "": RPN = token else: RPN = RPN + " " + token elif token == "(": stack.push(token) elif token == ")": while stack.peek() != "(": RPN = RPN + " " + stack.pop() stack.pop() elif is_operator(token): while (stack.is_empty() == False) and is_operator( stack.peek()) and has_precedence(token, stack.peek()): RPN = RPN + " " + stack.pop() stack.push(token) while stack.size() > 0: RPN = RPN + " " + str(stack.pop()) return RPN
def prefix_to_postfix(input_str): """Converts a prefix expression to an equivalent postfix expression""" """Input argument: a string containing a prefix expression where tokens are space separated. Tokens are either operators + - * / ^ parentheses ( ) or numbers Returns a String containing a postfix expression(tokens are space separated)""" s = Stack(30) tokens = input_str.split() i = len(tokens) - 1 operators = ['+', '-', '*', '/', '<<', '>>', '**'] if input_str == '': return '' while i >= 0: char = tokens[i] if char.lstrip('-').replace('.', '', 1).isdigit(): s.push(char) i -= 1 elif char in operators: op1 = s.pop() op2 = s.pop() inf = op1 + ' ' + op2 + ' ' + char s.push(inf) i -= 1 else: break return s.pop()
def infix_to_postfix(input_str): """Converts an infix expression to an equivalent postfix expression""" """Input argument: a string containing an infix expression where tokens are space separated. Tokens are either operators + - * / ^ parentheses ( ) or numbers Returns a String containing a postfix expression """ stack = Stack(30) # Stack of size 30 operators = ["(", ")", ">>", "<<", "**", "*", "/", "+", "-"] # Allowed operands final_list = "" first_run = True split_string = input_str.split( ) # Split input string into usable chunks in a list for val in split_string: # Run through every value in list in order if val == "(": stack.push("(") elif val == ")": popping = True while popping: popped_value = stack.pop() if popped_value == "(": popping = False else: final_list += " " + popped_value elif val in operators: popping = True while popping: if stack.is_empty(): popping = False elif stack.peek() == "(": popping = False elif (val == ">>" or val == "<<") and operators.index(stack.peek()) > 3: popping = False elif val == "**" and operators.index(stack.peek()) > 3: popping = False elif (val == "*" or val == "/") and operators.index(stack.peek()) > 6: popping = False else: final_list += " " + stack.pop() stack.push(val) else: if first_run: final_list += str(val) first_run = False else: final_list += " " + str(val) popping = True while popping: if stack.is_empty(): popping = False else: final_list += " " + stack.pop() return final_list
def postfix_eval(input_str): """Evaluates a postfix expression""" """Input argument: a string containing a postfix expression where tokens are space separated. Tokens are either operators + - * / ** or numbers Returns the result of the expression evaluation. Raises an PostfixFormatException if the input is not well-formed""" stack = Stack(30) input = input_str.split() for item in input: temp = item.replace('.', '', 1) temp = temp.replace('-', '', 1) if item.isalpha(): raise PostfixFormatException("Invalid token") elif temp.isdigit(): stack.push(item) else: if stack.num_items < 2: raise PostfixFormatException("Insufficient operands") val1 = stack.pop() val2 = stack.pop() if item == '/' and val1 == '0' or val1 == '0.0': raise ValueError if (item == '>>' or item == '<<') and (val1.find('.') != -1 or val2.find('.') != -1): raise PostfixFormatException("Illegal bit shift operand") stack.push(str(eval(val2 + item + val1))) res = stack.pop() if stack.num_items > 0: raise PostfixFormatException("Too many operands") if res.find('.') is not -1: return float(res) else: return int(res)
def testInfix(inputString): inputList = inputString.split() rpnString = '' infixStack = Stack(30) for item in inputList: if item.isdigit(): rpnString += item else: try: rpnString += str(float(item)) except: pass if infixStack.size() > 0: o1 = item o2 = infixStack.peek() if o1 != '**': if getPrecVal(o1) <= getPrecVal(o2) and infixStack.size() > 0: rpnString += infixStack.pop() elif o1 == '**': if getPrecVal(o1) < getPrecVal(o2) and infixStack.size() > 0: rpnString += infixStack.pop() infixStack.push(item) for i in range(infixStack.size()): rpnString += infixStack.pop() return rpnString
def infix_to_postfix(input_str): '''Converts an infix expression to an equivalent postfix expression Input argument: a string containing an infix expression where tokens are space separated. Tokens are either operators + - * / ** >> << parentheses ( ) or numbers Returns a String containing a postfix expression ''' operators = Stack(30) input_list = input_str.split(" ") postfix = "" for i in range(len(input_list)): type = type_check(input_list[i]) if type == 5: operators.push(input_list[i]) elif type == 6: while not operators.is_empty() and operators.peek() != "(": postfix += operators.pop() + " " operators.pop() elif type == 0: postfix += input_list[i] + " " else: if operators.is_empty(): operators.push(input_list[i]) else: while not operators.is_empty() and ( type <= type_check(operators.peek()) < 5 and not type == type_check(operators.peek()) == 3): postfix += operators.pop() + " " operators.push(input_list[i]) while not operators.is_empty(): postfix += operators.pop() + " " return postfix[:len(postfix) - 1]
def postfix_eval(input_str): """Evaluates a postfix expression""" """Input argument: a string containing a postfix expression where tokens are space separated. Tokens are either operators + - * / ^ or numbers Returns the result of the expression evaluation. Raises an PostfixFormatException if the input is not well-formed""" operators = ["<<", ">>", "**", "*", "/", "+", "-"] equation = input_str.split() stack = Stack(len(equation)) for i in range(len(equation)): if is_num(equation[i]): stack.push(equation[i]) elif equation[i] in operators: if stack.size() < 2: raise PostfixFormatException("Insufficient operands") first_num = stack.pop() second_num = stack.pop() if first_num == "0" and equation[i] == "/": raise ValueError try: total = eval(str(second_num) + str(equation[i]) + str(first_num)) except TypeError: raise PostfixFormatException("Illegal bit shift operand") stack.push(str(total)) else: raise PostfixFormatException("Invalid token") if stack.size() > 1: raise PostfixFormatException("Too many operands") if stack.size() == 0: return "" return float((stack.peek()))