Exemple #1
0
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
Exemple #2
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"""
    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()))
Exemple #3
0
 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()
Exemple #4
0
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
Exemple #5
0
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)
Exemple #8
0
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)
Exemple #9
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 (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()
Exemple #10
0
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))
Exemple #11
0
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
Exemple #12
0
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))
Exemple #15
0
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
Exemple #16
0
 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)
Exemple #17
0
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)
Exemple #18
0
 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)
Exemple #19
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())
Exemple #20
0
 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)
Exemple #21
0
 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)
Exemple #22
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()
Exemple #23
0
 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)
Exemple #24
0
 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)
Exemple #25
0
 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
Exemple #27
0
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
Exemple #28
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
    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")
Exemple #29
0
 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