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 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()))
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 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 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 test_size(self): """Testing empty stack""" stack = Stack(3, []) self.assertEqual(stack.size(), 0) """testing non-empty stack""" stack.push(2) self.assertEqual(stack.size(), 1) self.assertNotEqual(stack.size(), stack.capacity)
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 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 + - * / ** << >> or numbers (integers or floats) Returns a String containing a postfix expression """ stack_hold = Stack(30) tokens = input_str.split() precedence = { '(': 5, ')': 5, '+': 4, '-': 4, '*': 3, '/': 3, '**': 2, '<<': 1, '>>': 1 } stack = [] if len(input_str) == 0: return '' for i in range(len(tokens)): if numeric(tokens[i]) is True: stack.append(tokens[i]) elif tokens[i] == '(': stack_hold.push(tokens[i]) elif tokens[i] == ')': while stack_hold.peek() != '(': stack.append(stack_hold.pop()) stack_hold.pop() elif precedence[tokens[i]] == 2: for k in range(stack_hold.size()): if precedence[stack_hold.items[k]] < precedence[tokens[i]]: stack.append(stack_hold.pop()) else: break stack_hold.push(tokens[i]) elif tokens[i] in precedence: for j in range(stack_hold.size(), 0, -1): if precedence[stack_hold.items[j - 1]] <= precedence[tokens[i]]: stack.append(stack_hold.pop()) else: break stack_hold.push(tokens[i]) while stack_hold.size() > 0: stack.append(stack_hold.pop()) return ' '.join(stack)
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 (integers or floats) Returns the result of the expression evaluation. Raises an PostfixFormatException if the input is not well-formed""" stack_hold = Stack(30) operator = ['+', '-', '/', '*', '>>', '<<', '**'] tokens = input_str.split() if len(input_str) == 0: raise PostfixFormatException('Insufficient operands') for i in tokens: if i in operator: if stack_hold.size() < 2: raise PostfixFormatException('Insufficient operands') num2 = stack_hold.pop() num1 = stack_hold.pop() if i == '+': stack_hold.push(float(num1) + float(num2)) elif i == '-': stack_hold.push(float(num1) - float(num2)) elif i == '*': stack_hold.push(float(num1) * float(num2)) elif i == '/': try: stack_hold.push(float(num1) / float(num2)) except ValueError: raise ZeroDivisionError elif i == '**': stack_hold.push(float(num1)**float(num2)) elif i == '<<': try: stack_hold.push(int(num1) << int(num2)) except ValueError: raise PostfixFormatException('Illegal bit shift operand') elif i == '>>': try: stack_hold.push(int(num1) >> int(num2)) except ValueError: raise PostfixFormatException('Illegal bit shift operand') elif i not in operator: try: stack_hold.push(float(i)) except ValueError: raise PostfixFormatException('Invalid token') if stack_hold.size() > 1: raise PostfixFormatException('Too many operands') return stack_hold.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 """ order_of_op = { '<<' : 4, '>>' : 4, '**' : 3, '*' : 2, '/' : 2, '+' : 1, '-' : 1, '(' : 0, ')' : 0 } rpn_exp = [] equation = input_str.split(' ') stack = Stack(len(equation)) for i in range(len(equation)): if len(input_str) == 0: return "" if is_num(equation[i]): rpn_exp.append(equation[i]) elif equation[i] == '(': stack.push(equation[i]) elif equation[i] == ')': while stack.peek() != '(': rpn_exp.append(stack.pop()) stack.pop() elif order_of_op[equation[i]] == 3: for j in range(stack.size()): if order_of_op[equation[i]] < order_of_op[stack.items[j]]: rpn_exp.append(stack.pop()) else: break stack.push(equation[i]) elif equation[i] in order_of_op: for k in range(stack.size(), 0, -1): if order_of_op[equation[i]] <= order_of_op[stack.items[k-1]]: rpn_exp.append(stack.pop()) else: break stack.push(equation[i]) while stack.size() != 0: rpn_exp.append(stack.pop()) return(' '.join(rpn_exp))
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 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 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 (integers or floats) Returns the result of the expression evaluation. Raises an PostfixFormatException if the input is not well-formed""" if input_str is None: raise PostfixFormatException # create list of operands and operators term_list = input_str.split() # initialize stack large enough to contain all operands operand_stack = Stack(2 * len(term_list) // 3 + 1) # iterate over term_list for term in term_list: # check for operatorm, evaluate operators on A & B if True if operator_present(term) is True: if operand_stack.size() < 2: raise PostfixFormatException("Insufficient operands") B = operand_stack.pop() A = operand_stack.pop() operand_stack.push(calculate( A, # A B, # B term) # operator ) # check for operand, push to stack if True elif operand_present(term) is True: operand_stack.push(term) else: raise PostfixFormatException("Invalid token") if len(term_list) % 3 != 0: raise PostfixFormatException("Too many operands") return operand_stack.pop()
def infix_to_postfix(input_str): """Converts an infix expression to an equivalent postfix expression""" RPN_list=[] s=Stack(30) str_list=input_str.split() for thing in str_list: if isNumber(thing): RPN_list.append(thing) elif thing == '(': s.push(thing) elif thing == ')': while s.peek()!= '(' and not s.is_empty(): RPN_list.append(s.pop()) s.pop() #exponential has highest precedence elif thing == '^': s.push(thing) elif thing == "*" or thing == "/": try: if s.peek() == "*" or s.peek() == "/" or s.peek() == "^" : while not s.is_empty() and s.peek() == "*" or s.peek() == "/" or s.peek() == "^": RPN_list.append(s.pop()) except: pass s.push(thing) elif thing == "+" or thing == "-": while not s.is_empty() and s.peek() != '(': RPN_list.append(s.pop()) s.push(thing) while s.size()!=0: RPN_list.append(s.pop()) return (' '.join(RPN_list))
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 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 infix_to_postfix(input_str): """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 """ s = Stack(30) output = [] ops1 = ['+', '*', '**', '<<'] ops2 = ['-', '/', '**', '>>'] for i in input_str.split(): try: if '.' in i: output.append(str(float(i))) else: output.append(str(int(i))) except ValueError: if s.is_empty(): s.push(i) elif i == '(': s.push('(') elif i == ')': c = s.peek() while c != '(': output.append(s.pop()) c = s.peek() s.pop() else: op = s.peek() if op != '(': x = ops1.index(i) if i in ops1 else ops2.index(i) y = ops1.index(op) if op in ops1 else ops2.index(op) if x > y: s.push(i) if x == y: if i == '**' and op == '**': s.push(i) else: output.append(s.pop()) s.push(i) if x < y: while x <= y: try: if i == '**' and op == '**': break else: output.append(s.pop()) op = s.peek() y = ops1.index( op) if op in ops1 else ops2.index(op) except IndexError: break except ValueError: break s.push(i) else: s.push(i) for i in range(s.size()): output.append(s.pop()) return ' '.join(output)
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(1) self.assertEqual(stack.pop(), 1) self.assertEqual(stack.peek(), 0)
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 test2(self): stack = Stack(4) self.assertTrue(stack.is_empty()) stack.push(None) stack.push(4) stack.push(1) stack.push(7) self.assertTrue(stack.is_full()) self.assertEqual(stack.pop(), 7) self.assertEqual(stack.size(), 3)
def test4(self): stack = Stack(3) stack.push(None) self.assertEqual(stack.peek(), None) stack.push(3) stack.push(-2) stack.pop() stack.pop() stack.pop() self.assertEqual(stack.size(), 0)
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 #Delimiter postfixList = input_str.split(" ") #Creates Stack with capacity of the lenght of the delimited list postfixStack = Stack(len(postfixList)) #For each element in the pfList for token in postfixList: try: #Try to push to stack if it is a number postfixStack.push(ast.literal_eval(token)) except: #If a 'normal' operator is encountered if token in "*/+-^**": try: #Pops the top two numbers on the stack then applies the #token operator with pfMath() numberTwo = postfixStack.pop() numberOne = postfixStack.pop() postfixStack.push(pfMath(token, numberOne, numberTwo)) except: #Checks for div 0 otherwise raises Insufficient operands if numberTwo == 0: raise ValueError("Undefined: Can't Divide By 0") else: raise PostfixFormatException("Insufficient operands") #For bit shift elif token in "<<>>": try: #Attemps to pop top two on the stack numberShifter = postfixStack.pop() numberBase = postfixStack.pop() #Left bit Shift if token == "<<": postfixStack.push(numberBase << numberShifter) #Right bit Shift else: postfixStack.push(numberBase >> numberShifter) #Can't bit shift raise error except: raise PostfixFormatException("Illegal bit shift operand") #Not a token or number else: raise PostfixFormatException("Invalid token") #End of postfixList checks what is on the stack if postfixStack.size() != 1: raise PostfixFormatException("Too many operands") #Returns the evaluated postfix return postfixStack.pop()
def test_simple(self): stack = Stack(5) self.assertTrue(stack.is_empty()) stack.push(0) self.assertFalse(stack.is_empty()) self.assertFalse(stack.is_full()) stack.push(1) stack.push(2) stack.push(3) stack.push(4) self.assertTrue(stack.is_full()) self.assertEqual(stack.size(), 5)
def test_linked(self): stack = Stack(10) stack.push('a') stack.pop() self.assertEqual(stack.size(),0) self.assertTrue(stack.is_empty()) stack.push('a') stack.push('b') stack.push('c') stack.push('d') stack.push('e') stack.push('f') stack.push('g') stack.push('h') stack.push('i') stack.push('j') self.assertTrue(stack.is_full()) self.assertRaises(IndexError, stack.push,'k') stack.pop() self.assertEqual(stack.peek(), 'i') self.assertEqual(stack.size(), 9)
def test_simple_1(self): stack = Stack(3) self.assertRaises(IndexError, stack.peek) stack.push(0) stack.push(1) stack.push(2) self.assertRaises(IndexError, stack.push, 3) self.assertTrue(stack.is_full()) self.assertEqual(stack.size(),3) stack.pop() stack.pop() self.assertEqual(stack.pop(), 0)
def prefix_to_postfix( input_str ): # prefix requires that all operators precede the two operands that they work on """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 + - * / ** << >> or numbers (integers or floats) Returns a String containing a postfix expression(tokens are space separated)""" if input_str is None: raise ValueError # split input string into list term_list = input_str.split() #print("TERM LIST ",term_list) # initialize output list output_list = [] #print("OUT SIZE ", len(output_list)) # initialize operator stack operator_stack = Stack(len(term_list) // 3 + 1) for i in range(len(term_list)): term = term_list[i] # prefix should begin with an operator otherwise raise Exception if i == 0: if operator_present(term) is True: operator_stack.push(term) else: raise PostfixFormatException() # Check for operator elif operator_present(term): operator_stack.push(term) # check for operand elif operand_present(term): output_list.append(term) # if previous two terms in output list were operands, pop operator stack to output list once if operand_present(term_list[i - 1]): output_list.append(operator_stack.pop()) # for every three operands there should be an additional operator if operand_present( term_list[i - 3]) and operator_stack.size() != 0: output_list.append(operator_stack.pop()) while operator_stack.size() != 0: output_list.append(operator_stack.pop()) new_str = (" ".join(output_list)) #print("NEW STR ", new_str) return new_str
def postfix_eval(input_str): """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""" sep = input_str.split(" ") stack = Stack(len(sep)+1) # bad practice but safe for char in sep: if num(char): stack.push(intorfloat(char)) elif opp(char): if stack.size() < 2: raise PostfixFormatException('Insufficient operands') above = stack.pop() below = stack.pop() stack.push(do(above, below, char)) else: raise PostfixFormatException("Invalid token") if stack.size() > 1: raise PostfixFormatException("Too many operands") final = stack.pop() final = int(final) if final % 1 == 0 else final return final
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 DO NOT USE PYTHON'S EVAL FUNCTION!!!''' op_lst = ["+", "-", "*", "/", "**"] #list of operators val_lst = input_str.split(" ") #list of individual tokens stack = Stack(len(input_str)) #stack to push and pop our values if input_str == "": return "" #basecase for i in val_lst: #loops throught the input string if i not in op_lst: try: #checks validity of tokens if i.isdigit(): #if i is a digit i is pushed on to stack stack.push(int(i)) else: #pushes it as float stack.push(float(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 values to do operation val2 = stack.pop() val1 = stack.pop() except IndexError: #if an index error is raised from the stack then theres not enough values raise PostfixFormatException("Insufficient operands") if i == "+": result = val1 + val2 stack.push(result) if i == "-": result = val1 - val2 stack.push(result) if i == "/": if val2 == 0: raise ValueError("float division by 0") else: result = val1 / val2 stack.push(result) if i == "*": result = val1 * val2 stack.push(result) if i == "**": result = val1**val2 stack.push(result) if stack.size() == 1: return stack.pop() else: #if stack has more than one item left after iteration of val_Lst then too many operands raise PostfixFormatException("Too many operands")
def test_simple(self): stack = Stack(5) self.assertTrue(stack.is_empty()) stack.push(0) self.assertFalse(stack.is_empty()) self.assertFalse(stack.is_full()) self.assertEqual(stack.size(), 1) stack.push(1) self.assertEqual(stack.size(), 2) self.assertEqual(stack.capacity, 5) self.assertEqual(stack.peek(), 1) self.assertEqual(stack.pop(), 1) self.assertEqual(stack.size(), 1) for i in range(4): stack.push(1) with self.assertRaises(IndexError): stack.push(1) with self.assertRaises(IndexError): s = Stack(1) s.pop() with self.assertRaises(IndexError): e = Stack(1) e.peek() self.assertTrue(stack.is_full())
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 """ s = Stack(30) post = '' tokens = input_str.split() op_prec = {'+': 1, '-': 1, '*': 2, '/': 2, '**': 3, '<<': 4, '>>': 4} operators = ['+', '-', '*', '/', '**', '<<', '>>'] if input_str == '': return '' for char in tokens: if post == '' and char.lstrip('-').replace('.', '', 1).isdigit(): post += char elif char.lstrip('-').replace('.', '', 1).isdigit(): post += ' ' + char elif char == '(': s.push(char) elif char in operators: if not s.is_empty(): o2 = s.peek() while s.size() > 0: o2 = s.peek() if o2 == '(': break if char == '**': if op_prec[char] < op_prec[o2]: post += ' ' + s.pop() else: break elif op_prec[char] <= op_prec[o2]: post += ' ' + s.pop() else: break s.push(char) elif char == ')': o2 = s.peek() while o2 != '(': post += ' ' + s.pop() if not s.is_empty(): o2 = s.peek() s.pop() while not s.is_empty(): post += ' ' + s.pop() return post