def test_eq(self):
        """Tests the eq function"""

        stack_one = sa.StackArray()
        stack_one.push(1)
        stack_one.push(2)
        stack_one.push(3)

        stack_two = sa.StackArray()
        stack_two.push(1)
        stack_two.push(2)

        self.assertFalse(stack_one == stack_two)
        stack_two.push(3)

        stack_three = sa.StackArray()
        stack_three.push(3)
        stack_three.push(2)
        stack_three.push(1)

        not_stack = 1

        self.assertTrue(stack_one == stack_two)
        self.assertFalse(stack_one == not_stack)
        self.assertFalse(stack_one == stack_three)
    def test_pop(self):
        """Tests the pop function"""

        test_stack = sa.StackArray()
        test_stack.push(1)
        test_stack.push(2)
        test_stack.push(3)

        empty_stack = sa.StackArray()

        pop_val = test_stack.pop()
        self.assertEqual(3, pop_val)
        self.assertEqual(2, test_stack.num_items)

        self.assertRaises(IndexError, empty_stack.pop)
    def test_peek(self):
        """Tests the peek function"""

        test_stack = sa.StackArray()
        test_stack.push(1)
        test_stack.push(2)
        test_stack.push(3)
        test_stack.push(4)

        empty_stack = sa.StackArray()

        self.assertEqual(4, test_stack.peek())
        self.assertEqual(4, test_stack.peek())

        self.assertRaises(IndexError, empty_stack.peek)
    def test_push(self):
        """Tests the push function"""

        test_stack = sa.StackArray()
        test_stack.push(1)
        test_stack.push(2)
        test_stack.push(3)
        self.assertEqual(1, test_stack.arr[0])
        self.assertEqual(3, test_stack.arr[2])
    def test_repr(self):
        """Tests the repr function"""

        test_stack = sa.StackArray()
        test_stack.push(1)
        test_stack.push(2)
        test_stack.push(3)

        expected_str = '1 2 3'
        test_str = repr(test_stack)
        self.assertEqual(expected_str, test_str)
    def test_size(self):
        """Tests the size function"""

        test_stack = sa.StackArray()
        test_stack.push(1)
        test_stack.push(2)
        self.assertEqual(2, test_stack.size())
        test_stack.peek()
        self.assertEqual(2, test_stack.size())
        test_stack.pop()
        self.assertEqual(1, test_stack.size())
    def test_is_empty(self):
        """Tests the is_empty function"""

        test_stack = sa.StackArray()
        self.assertTrue(test_stack.is_empty())
        test_stack.push(1)
        test_stack.push(2)
        self.assertFalse(test_stack.is_empty())
        test_stack.pop()
        test_stack.pop()
        self.assertTrue(test_stack.is_empty())
def postfix_eval(postfix):
    """Function to evaluate a postfix expression
    Args:
        postfix(str): The postfix expression
    Returns:
        float: The value of the evaluated expression
    """

    current_token = ''
    operators = {'+', '-', '*', '/', '^'}
    rpn_stack = sa.StackArray()

    postfix += ' '

    for char in postfix:

        if char != ' ':
            current_token += str(char)

        if char == ' ':

            try:
                float(current_token)
                rpn_stack.push(float(current_token))
            except ValueError:
                if current_token in operators:
                    val1 = rpn_stack.pop()
                    val2 = rpn_stack.pop()
                    if current_token == '^':
                        out_val = val2**val1

                    elif current_token == '+':
                        out_val = val1 + val2

                    elif current_token == '-':
                        out_val = val2 - val1

                    elif current_token == '*':
                        out_val = val2 * val1

                    else:
                        try:
                            out_val = val2 / val1
                        except ZeroDivisionError:
                            raise ValueError('Dividing by Zero')

                    rpn_stack.push(out_val)
                else:
                    raise ValueError("Invalid Token")

            current_token = ''

    return rpn_stack.pop()
    def test_enlarge(self):
        """Tests the enlarge function"""

        test_stack = sa.StackArray()
        test_stack.push(0)
        self.assertEqual(test_stack.capacity, 2)
        test_stack.push(1)
        self.assertEqual(test_stack.capacity, 4)
        test_stack.push(2)
        self.assertEqual(test_stack.capacity, 4)
        test_stack.push(3)
        self.assertEqual(test_stack.capacity, 8)
    def test_shrink(self):
        """Tests the shrink function"""

        test_stack = sa.StackArray()
        test_stack.push(1)
        test_stack.push(2)
        test_stack.push(3)
        test_stack.push(4)
        test_stack.push(1)
        test_stack.push(2)
        test_stack.pop()
        test_stack.pop()
        test_stack.pop()
        test_stack.pop()
        self.assertEqual(4, test_stack.capacity)
def prefix_to_postfix(prefix):
    """Function to convert a prefix expression to postfix
    Args:
        prefix(str): The prefix expression
    Returns:
        str: the converted postfix string
    """

    operators = {'+', '-', '*', '/', '^'}
    current_token = ""
    operand_stack = sa.StackArray()

    prefix = ' ' + prefix

    for char in prefix[::-1]:
        if char != ' ':
            current_token += char

        if char == ' ':

            try:
                float(current_token)
                current_token = current_token[::-1]
                operand_stack.push(current_token)
            except ValueError:
                if current_token in operators:
                    op1 = operand_stack.pop()
                    op2 = operand_stack.pop()
                    out_str = str(op1) + ' ' + str(op2) + ' ' + str(
                        current_token)
                    operand_stack.push(out_str)
                else:
                    raise ValueError("Invalid token:" + current_token)

            current_token = ""

    rpn_expr = operand_stack.pop()
    return rpn_expr
def infix_to_postfix(infix):
    """Function to convert an infix expression to postfix
    Args:
        infix(str): The infix expression
    Returns:
        str: the postfix string of the converted expression
    """

    rpn_expr = ""
    operators = {'+', '-', '*', '/', '^'}
    output_stack = sa.StackArray()
    current_token = ""
    operator_stack = sa.StackArray()

    op_precedence = {'+': 1, '-': 1, '*': 2, '/': 2, '^': 3, '(': 0}

    association = {
        '+': 'left',
        '-': 'left',
        '*': 'left',
        '/': 'left',
        '^': 'right'
    }

    infix += ' '

    for char in infix:

        # Code to process characters to find individual tokens
        if char != ' ':
            current_token += char
        else:

            # If current token is number, push it to the output stack
            try:
                float(current_token)
                output_stack.push(current_token)
            except ValueError:

                if current_token in operators and \
                        (operator_stack.is_empty() or operator_stack.peek() == '('):
                    operator_stack.push(current_token)
                    current_token = ''
                if current_token == '(':
                    operator_stack.push(current_token)
                    current_token = ''
                if current_token == ')':
                    while operator_stack.peek() != '(':
                        output_stack.push(operator_stack.pop())
                    operator_stack.pop()
                    current_token = ''
                if current_token != '' and \
                        (op_precedence[current_token] > op_precedence[operator_stack.peek()]):
                    operator_stack.push(current_token)
                    current_token = ''
                if current_token != '' and \
                        (op_precedence[current_token] == op_precedence[operator_stack.peek()]):
                    if association[current_token] == 'left':
                        output_stack.push(operator_stack.pop())
                        operator_stack.push(current_token)
                    if association[current_token] == 'right':
                        operator_stack.push(current_token)
                if current_token != '' and \
                        (op_precedence[current_token] < op_precedence[operator_stack.peek()]):
                    while not operator_stack.is_empty() and \
                            (op_precedence[current_token] <= op_precedence[operator_stack.peek()]):
                        output_stack.push(operator_stack.pop())
                    operator_stack.push(current_token)

            current_token = ""

    while not operator_stack.is_empty():
        output_stack.push(operator_stack.pop())

    while output_stack.size() > 1:
        rpn_expr = output_stack.pop() + rpn_expr
        rpn_expr = ' ' + rpn_expr
    rpn_expr = output_stack.pop() + rpn_expr

    return rpn_expr