def parseTree(expression):
    tokens = expression.split()
    tree_holder = Stack()
    main_tree = BinaryTree('')
    tree_holder.push(main_tree)
    currentTree = main_tree
    for val in tokens:
        if val == '(':
            currentTree.add_left('')
            tree_holder.push(currentTree)
            currentTree = currentTree.get_left()

        elif val not in '+-*/':
            currentTree.set_root_val(val)
            parent = tree_holder.pop()
            currentTree = parent

        elif val in '+-*/':
            currentTree.set_root_val(val)
            currentTree.add_right('')
            tree_holder.push(currentTree)
            currentTree = currentTree.get_right()

        elif val == ')':
            currentTree = tree_holder.pop()
        else:
            raise ValueError

    return main_tree
Exemplo n.º 2
0
    def randomize(maze):
        stack = Stack()
        current = maze.board[0][0]
        visited_count = 0

        while True:
            q = current.get_random_nbr()
            if not current.visited:
                visited_count += 1

            current.visited = True
            if q is None:
                if stack.size > 0:
                    current = stack.pop()
                else:
                    raise StopIteration()
            else:
                next, x = q
                stack.push(current)
                current.unlock(x)
                next.unlock((x + 2) % 4)
                current = next

            if visited_count >= maze.length * maze.height:
                raise StopIteration()

            yield current
    def insert_node(self, node):
        lessFreq_stack = Stack()

        while self.stack.num_elements>0 and self.stack.top().get_freq() < node.get_freq():
            lessFreq_stack.push(self.stack.pop())

        self.stack.push(node)

        while lessFreq_stack.num_elements>0:
            self.stack.push(lessFreq_stack.pop())
Exemplo n.º 4
0
class TowersOfHanoi(object):
    """
    Towers of Hanoi
    """
    def __init__(self, num_discs=3, verbose=True):
        self.tower_1 = Stack()
        self.tower_2 = Stack()
        self.tower_3 = Stack()
        self.num_discs = num_discs
        self.verbose = verbose
        # Initialize tower
        for disc in range(self.num_discs, 0, -1):
            self.tower_1.push(disc)
        # Counter for number of recursive calls needed to solve
        self._num_steps = 0

    def __repr__(self):
        out = ''
        for i in range(self.num_discs):
            for tower in self.towers:
                if len(tower) <= i:
                    out += "|"
                else:
                    out += str(tower[i])
                out += "\t"
            out += "\n"
        # Flip UD
        return "\n".join(out.split("\n")[::-1])

    @property
    def towers(self):
        return (self.tower_1, self.tower_2, self.tower_3)

    def _step(self, begin, end, temp, disc):
        """
        Recursive solution to towers of Hanoi.

        If verbose is True, print out state of towers at every step
        """
        if disc == 1:
            end.push(begin.pop())
        else:
            self._step(begin, temp, end, disc - 1)
            self._step(begin, end, temp, 1)
            self._step(temp, end, begin, disc - 1)
        self._num_steps += 1
        if self.verbose:
            print("Step %i:" %(self._num_steps))
            print(self)

    def solve(self):
        """
        Kick-off recursive solution chain.
        """
        self._step(self.tower_1, self.tower_3, self.tower_2, self.num_discs)
Exemplo n.º 5
0
 def __init__(self, num_discs=3, verbose=True):
     self.tower_1 = Stack()
     self.tower_2 = Stack()
     self.tower_3 = Stack()
     self.num_discs = num_discs
     self.verbose = verbose
     # Initialize tower
     for disc in range(self.num_discs, 0, -1):
         self.tower_1.push(disc)
     # Counter for number of recursive calls needed to solve
     self._num_steps = 0
Exemplo n.º 6
0
 def traverse_df_po_generator(self, root=None): #deep-first tree traversing
     if root is None : root = self.root 
     stack = Stack.Stack([root]) ; register = Stack.Stack([len(root.nodes)])
     while register.top() :
         register.decr() ; node = root.nodes[register.top()] ; register.push(len(node.nodes))
         while node != root :      
             if register.top() :
                 register.decr() ; stack.push(node) 
                 node = node.nodes[register.top()] ; register.push(len(node.nodes))
             else              :
                 yield node ; node = stack.pop() ; register.dlt()
     yield root 
Exemplo n.º 7
0
def evaluate_postfix(expr):

    if len(expr) == 0:
        return "Expression is invalid"

    nums = Stack()

    for char in expr:
        if char in "+*-":
            num1 = nums.pop()
            num2 = nums.pop()
            if char == "+":
                subtotal = num1 + num2
            elif char == "*":
                subtotal = num1 * num2
            elif char == "-":
                subtotal = num2 - num1
            nums.push(subtotal)
        else:
            nums.push(int(char))

    if len(nums._items) > 1:
        return "Expression is invalid"

    return nums.pop()
Exemplo n.º 8
0
    def dft(self, starting_vertex_id):
        """
        Traverse and print each vertex in depth-first order (DFT) beginning from starting_vertex.
        """
        # Initialize empty stack and set of visited nodes:
        stack = Stack()
        visited = set()

        # Check if provided starting vertex is in our graph:
        if starting_vertex_id in self.vertices.keys():
            # If so, add starting vertex to stack:
            stack.push(starting_vertex_id)
        else:
            return IndexError(
                f"Provided starting vertex {starting_vertex_id} does not exist in graph!"
            )

        # Process all vertices via BFT:
        while stack.size() > 0:
            # Get next vertex to process as first item in stack:
            current_vertex = stack.pop()
            # If the current vertex has not already been visited+processed, process it:
            if current_vertex not in visited:
                # Process current vertex:
                print(current_vertex)
                # Add adjacent vertices to stack for future processing:
                for adjacent_vertex in self.get_neighbors(current_vertex):
                    stack.push(adjacent_vertex)
                # Mark current vertex as "visited" by adding to our set of visited vertices:
                visited.add(current_vertex)
    def sort_frequencies(self):

        freq_dict ={i:0 for i in set(self.data)}
        for i in self.data:
            freq_dict[i]+=1

        sorted_freq = sorted(freq_dict.items(), #Sort: more frequent first
            key=lambda x: (x[1],x[0]), reverse=True)

        stack = Stack() #Push most frequent firts

        [stack.push(Node(freq = x[1], char= x[0]))  for x in sorted_freq]
        #print(stack.arr)
        #print('top stack:', stack.top())

        return stack
Exemplo n.º 10
0
def buildParseTree(fpexp):
	exp_list = fpexp.split() # split the expression in a list wth the delimateur being space
	stack = Stack()
	current_node = BinaryTree('')

	tokens = ['+', '-', '/', '*']

	#stack.push(current_node)
	
	for char in exp:

		if char == '(':

			current_node.insertLeft('')
			S.push(current_node) # push parent into the stack
			current_node = current_node.leftChild

		elif char.isdigit():

			current_node.key = int(char)

			current_node = S.pop()

		elif char in tokens:
			current_node.insertRight('')
			current_node.key = char
			S.push(current_node)
			current_node = current_node.rightChild

		elif char == ')':
			current_node = S.pop()

		else:
			raise ValueError
Exemplo n.º 11
0
def revstring(mystr):
    """
    :type mystr: string
    :rtype: string
    use Stack Last In First Out feature to reverse a string
    """
    aStack = Stack()

    for i in list(mystr):
        aStack.push(i)

    revstr = ""

    while not aStack.isEmpty():
        revstr += aStack.pop()

    return revstr
    def get_digits(self):
        """
        This pushes numbers in stack. Then it converts that stack into a dictionary value with an alphabetic key.

        The reason we do this is that the calculations function cannot handle multiple digits because it is
        processing each element by character. For example, 2 + 2 can be processed but 10 + 10 cannot because it would
        be expecting a + - * / operator between the 1 and the 0.

        It is easier to have proxy variables, such as A + B rather than 10 + 10, and use that to pull dictionary values.
        The result would look like self.numbers.get('A') + self.numbers.get('B') with the self.numbers dictionary
        looking like {'A': 10, 'B': 10}. The calculator would read this as 10 + 10 without issue.

        Thus, the purpose of this function is to build that self.numbers dictionary and build self.final_infix with
        alphabetical variables substituting multi-digit numbers. self.final_infix is a word that looks like 'A+B'.
        """
        operands = Stack()
        alphabet_num = 65

        for char in self.infix_split:
            if char in '0123456789.':
                operands.push(char)
            elif not operands.isempty():
                alphabet = chr(alphabet_num)
                alphabet_num += 1
                number = ''
                # Converts number into a dictionary item.
                while not operands.isempty():
                    number = operands.pop() + number
                self.numbers[alphabet] = number
                self.final_infix += alphabet + char
            else:
                self.final_infix += char
Exemplo n.º 13
0
 def dfs(self):
     self.clear()
     self._display_grid()
     # frontier is where we've yet to go
     frontier: Stack[Node[T]] = Stack()
     frontier.push(Node(self.start, None))
     # explored is where we've been
     explored: Set[T] = {self.start}
     self.step(frontier, explored, None)
Exemplo n.º 14
0
def test_stacks_to_queues():
    print('{}'.format('-' * 20))
    print('Start of Task 1 Testing (stacks_to_queues):\n')

    cases = [[1, 2, 3], [], [10, 20], [100, 200, 300, 400]]
    sizes = [3, 1, 2, 4]
    master_stack1 = Stack(len(cases))
    for i in range(len(cases) - 1, -1, -1):
        stack = Stack(sizes[i])
        for item in cases[i]:
            stack.push(item)
        master_stack1.push(stack)

    print('master_stack before calling function:')
    print(master_stack1)
    print()

    print('master_queue1 after calling function:')
    master_queue1 = stacks_to_queues(master_stack1)
    print(master_queue1)
    print()

    print('Verity that master_stack1 is empty after calling function:')
    print(master_stack1)

    print()
    print('Verifying Sizes:')
    counter = 0
    while not master_queue1.is_empty():
        print('Queue {} size = {}'.format(counter,
                                          master_queue1.remove()._size))
        counter += 1
    print()

    master_queue2 = stacks_to_queues(Stack(5))
    print('Contents of master_queue if master_stack is empty: {}'.format(
        master_queue2))
    print('Size of master_queue2 = {}'.format(master_queue2._size))
    print()

    master_queue3 = stacks_to_queues(Queue(5))
    print('Contents of master_queue if master_stack is invalid: {}'.format(
        master_queue3))
    print('Size of master_queue3 = {}'.format(master_queue2._size))
    print()

    print('End of Task 1 testing')
    print('{}\n'.format('-' * 20))
    return
Exemplo n.º 15
0
def test_stack():
	stack = Stack()
	stack.push(3)
	stack.push(2)
	assert stack.peek() == 2
	assert stack.pop() == 2
	assert stack.pop() == 3
	assert stack.is_empty()
Exemplo n.º 16
0
 def test_pop(self):
     """
         Test Case to test the pop operation
     """
     stack = Stack()
     stack.push(1)
     num = stack.pop()
     self.assertEqual(num, 1)
     stack.push(2)
     stack.push(3)
     num = stack.pop()
     self.assertEqual(num, 3)
Exemplo n.º 17
0
 def test_dfs_assert_equal_return_lists(self):
     visited_list, path_list = dfs(self.grid,
                                   self.start,
                                   self.end,
                                   _stack=Stack())
     self.assertEqual(
         visited_list, self.dfs_correct_returns["visited_list"],
         "tested visited_list is not equal to correct visited list")
     self.assertEqual(path_list, self.dfs_correct_returns["path_list"],
                      "tested path_list is not equal to correct path list")
Exemplo n.º 18
0
 def execute_df(self, root=None, exec_pr=Tree._func_pass, exec_in=Tree._func_pass, exec_po=Tree._func_pass, **kwargs): #deep-first tree traversing
     if root is None : root = self.root
     exec_pr(root, **kwargs) #pre-order call
     stack = Stack.Stack([root]) ; register = Stack.Stack([len(root.nodes)])
     if not len(root.nodes) : exec_in(root,  **kwargs) #in-order call 
     while register.top() :
         if register.top() == len(root.nodes) - 1 : exec_in(root, **kwargs) #in-order call
         register.decr() ; node = root.nodes[register.top()] ; register.push(len(node.nodes))
         exec_pr(node, **kwargs) #pre-order call 
         while node != root :
             if not len(node.nodes) or register.top() == len(node.nodes) - 1 : exec_in(node, **kwargs) #in-order call 
             if register.top() :
                 register.decr() ; stack.push(node) ; node = node.nodes[register.top()] ; register.push(len(node.nodes))
             else              :
                 exec_po(node, **kwargs) #post-order call
                 node = stack.pop() ; register.dlt()
     exec_po(root, **kwargs) #post-order call 
     
     
Exemplo n.º 19
0
def bfs(initial, goal_test, successors):
    """
    Breadth-first search.

    Parameters
    ----------
    initial : Generic
        Starting point of the search.
    goal_test : Callable
        Callable returing boolean value indicating search success.
    successors : Callable
        Callable returning list of next possible locations in search space.

    Returns
    -------
    found : Generic
        Node corresponding to successful goal_test.
        Returns None if search fails.
    """
    # References to candidate and previously-explored nodes in search space
    frontier = Queue()
    explored = Stack()

    # Initialize candidate search locations with initial condition
    frontier.push(Node(initial, None))

    # Continue search as long as their are candidates in the search space
    while not frontier.empty:
        current_node = frontier.pop()
        current_state = current_node.state
        # If current node meets goal, then search completes successfully
        if goal_test(current_state):
            return current_node
        # Populate next step in search
        for child in successors(current_state):
            # Skip previously-explored states
            if child in explored: 
                continue
            explored.push(child)
            frontier.push(Node(child, current_node))
    # Search terminates without finding goal
    return None
Exemplo n.º 20
0
    def test_pop_on_empty_stack(self):
        """
            Test Case to test pop operation on Empty Stack
        """
        stack = Stack()
        stack.push(1)
        stack.pop()
        self.assertEqual(stack.length, 0, STACK_SIZE_ZERO_MSG)

        # Stack should be empty after one push and one pop operation
        # Should raise EmptyStackException on pop()
        with self.assertRaises(exceptions.EmptyStackException):
            stack.pop()
Exemplo n.º 21
0
 def test_size(self):
     """
         Test Case to check the size of the stack after push and pop operations
     """
     stack = Stack()
     self.assertEqual(stack.length, 0, STACK_SIZE_ZERO_MSG)
     stack.push(1)
     self.assertEqual(stack.length, 1, INCORRECT_STACK_SIZE_MSG)
     stack.push(2)
     stack.push(3)
     self.assertEqual(stack.length, 3, INCORRECT_STACK_SIZE_MSG)
     stack.pop()
     self.assertEqual(stack.length, 2, INCORRECT_STACK_SIZE_MSG)
Exemplo n.º 22
0
def postfixEval(postfixExpr):
    operandStack = Stack()
    tokenList = postfixExpr.split()

    for token in tokenList:
        if token.isdigit():
            operandStack.push(int(token))
        else:
            operand2 = operandStack.pop()
            operand1 = operandStack.pop()
            result = doMath(token, operand1, operand2)
            operandStack.push(result)
    return operandStack.pop()
Exemplo n.º 23
0
def test_push():
    stack, arr = Stack(), []
    assert(stack.is_empty())
    for expected in range(ITERS):
        stack.push(expected)
        arr = [expected] + arr
        actual = stack.peek()
        assert(len(stack) == len(arr))
        assert(expected == actual)
        assert(not stack.is_empty())
Exemplo n.º 24
0
def dfs(graph: Graph, start_node: str, target_node: str, visited_nodes: set):
    stack = Stack()
    stack.push(start_node)

    while not stack.is_empty():
        current = stack.pop()
        if current == target_node:
            return True

        adj = graph.get_edges_node(current)
        for node in adj:
            if node not in visited_nodes:
                stack.push(node)
    return False
def parChecker(symbolString):
    '''
    in: a string containing all symbols
    return: boolean, true for balaced, vice versa
    Completed extended parenthesis checker for: [,{,(,),},]
    '''
    leftPar = Stack()
    strList = list(symbolString)
    balanced = True
    symbol = {'[':']','{':'}','(':')'}
    i = 0
    
    while i < len(symbolString) and balanced:

        if strList[i] in ['[','(','{']:
            leftPar.push(strList[i])
            
        else:
            if leftPar.isEmpty():
                balanced = False
                
            else:
                if not strList[i] == symbol[leftPar.pop()]:
                    balanced = False
        i += 1
    
    if not leftPar.isEmpty():
        balanced = False
    
    
    return balanced
Exemplo n.º 26
0
def baseConverter(decNumber,base):
    '''
    decNumber: decimal number
    base: int between 2 and 16
    
    Algorithm for binary conversion can easily be extended to perform the 
    conversion for any base. In computer science it is common to use a number
    of different encodings. The most common of these are binary, octal (base 8)
    , and hexadecimal (base 16).
    '''
    
    baseNumber = ''
    reminders = Stack()
    
    while decNumber > 0:
        reminders.push(decNumber%base)
        decNumber = decNumber//base
    
    while not reminders.isEmpty():
        baseNumber += str(reminders.pop())
    
    return baseNumber
Exemplo n.º 27
0
    def attempt_2(self, head: ListNode, k: int) -> ListNode:
        """
        Better solution: Insert all elements into a stack and pop k elements. The last popped is returned.
        Don't need to know the length of the list in this algorithm.
        :param head: head of list
        :param k: parameter, k
        :return: returns the k'th to last element
        :Time: O(N)
        :Space: O(N)
        """
        stack = Stack()
        curr = head
        while curr is not None:
            stack.push(curr)
            curr = curr.next

        ret_val = None
        for i in range(k):
            popped = stack.pop()
            if i == k - 1:
                ret_val = popped

        return ret_val
Exemplo n.º 28
0
    def setUp(self):

        self.grid = np.genfromtxt("data_np.txt", delimiter=",", dtype=np.int)
        self.start = (4, 0)
        self.end = (0, 4)

        self.dfs_correct_returns = {
            "visited_list": [(4, 0), (4, 1), (4, 2), (4, 3), (4, 4), (3, 4),
                             (3, 3), (3, 2), (2, 3), (2, 4), (1, 4), (0, 4)],
            "path_list": [(0, 4), (1, 4), (2, 4), (2, 3), (3, 3), (3, 4),
                          (4, 4), (4, 3), (4, 2), (4, 1), (4, 0)]
        }
        self.bfs_correct_returns = {
            "visited_list": [(4, 0), (3, 0), (4, 1), (4, 2), (3, 2), (4, 3),
                             (3, 3), (4, 4), (2, 3), (3, 4), (2, 4), (1, 4),
                             (0, 4)],
            "path_list": [(0, 4), (1, 4), (2, 4), (2, 3), (3, 3), (3, 2),
                          (4, 2), (4, 1), (4, 0)]
        }

        self.a_star_correct_returns = {
            "visited_list": [(4, 0), (3, 0), (4, 1), (3, 2), (2, 3), (1, 4),
                             (0, 4)],
            "path_list": [(0, 4), (1, 4), (2, 3), (3, 2), (4, 1), (4, 0)]
        }

        self.test_nodes = [
            Node(self.grid, (4, 0), cost=0, heuristic=12),
            Node(self.grid, (3, 0), cost=10, heuristic=10),
            Node(self.grid, (4, 1), cost=10, heuristic=8)
        ]

        self.maze = Maze(self.grid)
        self.priority_queue = PriorityQueue()
        self.stack = Stack()
        self.queue = Queue()
        self.visited = VisitedNodes()
Exemplo n.º 29
0
 def test_push(self):
     """
         Test Case to test the push operation
     """
     stack = Stack()
     stack.push(1)
     self.assertEqual(stack.top, 1)
     stack.push(2)
     stack.push(3)
     self.assertEqual(stack.top, 3)
def paranthesis_checker(string):
    stack = Stack()
    balanced = True
    index = 0
    while index < len(string) and balanced:
        symbol = string[index]
        if symbol == '(':
            stack.push(symbol)
        else:
            if stack.isEmpty():
                balanced = False
            else:
                stack.pop()
        index = index + 1

    if balanced and stack.isEmpty():
        return True
    else:
        return False
Exemplo n.º 31
0
def HexToBinary(number):
    bin_holder = Stack()
    while number > 0:
        rem = number % 2
        bin_holder.push(rem)
        number = number // 2

    bin_string = ""
    while not bin_holder.isEmpty():
        bin_string = bin_string + str(bin_holder.pop())

    return bin_string
def check_balanced_symbols(symbols_string):
    """Checks if opening and closing symbols in a string are balanced"""

    open_symbols = Stack()

    for symbol in symbols_string:
        if symbol in "({[":
            open_symbols.push(symbol)
        elif symbol in ")}]":
            if open_symbols.is_empty():
                return False
            open_symbol = open_symbols.pop()
            if not is_matching_symbols(open_symbol, symbol):
                return False

    return open_symbols.is_empty()
Exemplo n.º 33
0
    def external_call(
            self,
            # account_number:int,
            exec_env: ExecutionEnvironment,
            condition=True
        #machine_state:MachineState=None
    ):
        # print('external call')
        # print('prev storage:')
        # print(self.get_processing_block().get_machine_state().get_storage().get_data())
        continuation_block = self.processing_block.inherit(
            len(self.basic_blocks), False)
        self.add_basic_block(continuation_block)
        # self.push_to_call_stack(continuation_block)

        new_block_number = len(self.basic_blocks)
        external_block = self.processing_block.duplicate(
            # account_number=account_number,
            new_block_number=new_block_number,
            exec_env=exec_env,
            # dfs_stack=[]
        )
        # print('external call')
        # print('prev call stack:')
        # print(id(self.processing_block.call_stack), self.processing_block.call_stack)
        # print('next call stack:')
        # print(id(external_block.call_stack), external_block.call_stack)
        external_block.set_pc(0)
        external_block.get_machine_state().set_stack(
            Stack(block_number=new_block_number))
        external_block.get_machine_state().set_memory(
            Memory(block_number=new_block_number))
        external_block.add_constraint_to_path_condition(condition)
        external_block.push_call_stack(continuation_block)

        # # TODO manage visited address
        # if not self.visited_address[exec_env.get_exec_env_id()][external_block.get_pc()]:

        self.basic_blocks.append(external_block)
        self.__edges[self.processing_block].append(external_block)

        self.processing_block = external_block
        # print('next storage:')
        # print(self.get_processing_block().get_machine_state().get_storage().get_data())
        return self.processing_block
Exemplo n.º 34
0
 def setUp(self):
     self.stack = Stack(range(1, 6))
     self.queue = Queue(range(1, 6))
     self.single = SinglyLinkedList()
     self.double = DoublyLinkedList()
     self.btree = BinaryTree()
Exemplo n.º 35
0
# -*- coding: utf-8 -*-
"""
Created on Fri Dec 05 17:18:10 2014

@author: ricmark
"""
import numpy as np
import time

# 3.4 Towers of Hanoi
from data_structures import Stack

S1 = Stack()
S2 = Stack()
S3 = Stack()

N = 5

for k in reversed(range(1,N+1)):
    S1.push(k)
  
  
def print_towers():
    l1, l2, l3 = len(S1.data), len(S2.data), len(S3.data)
    max_len = N # max(l1,l2,l3)    
    a = np.empty((max_len,3))
    a[:] = None
    if l1 > 0:
        a[max_len-l1:,0] = [x for x in reversed(S1.data)]
    if l2 > 0:
        a[max_len-l2:,1] = [x for x in reversed(S2.data)]
Exemplo n.º 36
0
    def setUp(self):
        self.emptyStack = Stack()
        self.Stack = Stack()

        for i in range(5):
            self.Stack.push(i)
Exemplo n.º 37
0
class TestStack(unittest.TestCase):  # LIFO

    def setUp(self):
        self.emptyStack = Stack()
        self.Stack = Stack()

        for i in range(5):
            self.Stack.push(i)

    def test_repr(self):
        '''Test returning the stack as a string literal.'''
        self.assertEqual(repr(self.emptyStack), str(()))
        tup = (1, 3.14, 'foo', True)

        for i in tup:
            self.emptyStack.push(i)

        self.assertEqual(repr(self.emptyStack), str((True, 'foo', 3.14, 1)))

    def test_len_size(self):
        '''Test returning the size of the stack.'''
        for i in range(100):
            self.emptyStack.push(i)

        self.assertEqual(len(self.emptyStack), 100)
        self.assertEqual(self.emptyStack.size(), 100)

        self.emptyStack.pop()
        self.assertEqual(len(self.emptyStack), 99)
        self.assertEqual(self.emptyStack.size(), 99)

    def test_tuple(self):
        '''Test returning the stack as a tuple literal.'''
        self.assertEqual(tuple(self.emptyStack), ())
        tup = (1, 3.14, 'foo', True)

        for i in tup:
            self.emptyStack.push(i)

        self.assertEqual(tuple(self.emptyStack), (True, 'foo', 3.14, 1))

    def test_list(self):
        '''Test returning the stack as a list literal.'''
        self.assertEqual(list(self.emptyStack), [])
        li = [1, 3.14, 'foo', True]

        for i in li:
            self.emptyStack.push(i)

        self.assertEqual(list(self.emptyStack), [True, 'foo', 3.14, 1])

    def test_push(self):
        '''Test pushing items on top of the stack.'''
        self.Stack.push(True)
        self.assertEqual(tuple(self.Stack), (True, 4, 3, 2, 1, 0))

    def test_pop(self):
        '''Test popping off and returning the top of the stack.'''
        self.assertEqual(self.Stack.pop(), 4)
        self.assertEqual(tuple(self.Stack), (3, 2, 1, 0))
        self.assertEqual(self.Stack.pop(), 3)
        self.assertEqual(self.Stack.pop(), 2)
        self.assertEqual(self.Stack.pop(), 1)
        self.assertEqual(self.Stack.pop(), 0)
        self.assertEqual(tuple(self.Stack), ())

        with self.assertRaises(ValueError):
            self.Stack.pop()

    def test_peek(self):
        '''Test peeking at the top of the stack w/o modifying the stack.'''
        self.assertEqual(self.Stack.peek(), 4)

        with self.assertRaises(ValueError):
            self.emptyStack.peek()
Exemplo n.º 38
0
class TestDataStructures(unittest.TestCase):

    def setUp(self):
        self.stack = Stack(range(1, 6))
        self.queue = Queue(range(1, 6))
        self.single = SinglyLinkedList()
        self.double = DoublyLinkedList()
        self.btree = BinaryTree()

    # STACK
    def test_stack_push(self):
        self.stack.push(6)
        self.assertEqual(self.stack.stack, range(1, 7)) 

    def test_stack_pop(self):
        self.assertEqual(self.stack.pop(), 5)
        self.assertEqual(self.stack.pop(), 4)

    def test_stack_peek(self):
        self.assertEqual(self.stack.peek(), 5)

    # QUEUE
    def test_queue_push(self):
        self.queue.push(6)
        self.assertEqual(self.queue.queue, range(1, 7))

    def test_queue_pop(self):
        self.assertEqual(self.queue.pop(), 1)
        self.assertEqual(self.queue.pop(), 2)

    def test_queue_peek(self):
        self.assertEqual(self.queue.peek(), 1)
        self.queue.pop()
        self.assertEqual(self.queue.peek(), 2)

    # SINGLY-LINKED LIST
    def test_add_nodes_to_single(self):
        node1, node2, node3 = Node(1), Node(2), Node(3)
        self.single._insert(node1)
        self.single._insert(node2, node1)
        self.assertEqual(self.single.head.value, 1)
        next = self.single.head.next
        self.assertEqual(next, node2)
        self.assertEqual(next.value, 2)
        self.single._insert(node3, node2)
        nextnext = self.single.head.next.next
        self.assertEqual(nextnext, node3)

    def test_add_node_to_beginning_of_single(self):
        node0, node1 = Node(0), Node(1)
        self.single._insert(node1)
        self.single._insert(node0)
        self.assertEqual(self.single.head.value, 0)
        self.assertEqual(self.single.head.next.value, 1)

    def test_remove_nodes_single(self):
        node1, node2, node3, node4 = Node(1), Node(2), Node(3), Node(4)
        self.single._insert(node1)
        self.single._insert(node2, node1)
        self.single._insert(node3, node2)
        self.single._insert(node4, node3)
        self.single._remove(node2)
        self.assertEqual(node2.next, node4)

    def test_remove_node_from_beginning_single(self):
        node1, node2, node3 = Node(1), Node(2), Node(3)
        self.single._insert(node1)
        self.single._insert(node2, node1)
        self.single._insert(node3, node2)
        self.single._remove()
        self.assertEqual(self.single.head, node2)

    def test_single_iteration(self):
        node1, node2, node3, node4 = Node(1), Node(2), Node(3), Node(4)
        self.single._insert(node1)
        self.single._insert(node2, node1)
        self.single._insert(node3, node2)
        self.single._insert(node4, node3)
        self.assertEqual([node for node in self.single], [node1, node2, node3, node4])

    def test_add_node_to_single_for_real(self):
        self.single.insert(2, 0)
        self.assertEqual(self.single[0].value, 2)
        self.single.insert(1, 0)
        self.assertEqual(self.single[0].value, 1)
        self.single.insert(3, 2)
        self.assertEqual(self.single[2].value, 3)
        self.single.insert(4, 100)
        self.assertEqual(self.single[3].value, 4)

    def test_remove_node_from_single_for_real(self):
        for i in range(4, 0, -1):
            self.single.insert(i, 0)
        # [1, 2, 3, 4]
        self.single.remove(1)
        # [1, 3, 4]
        self.assertEqual(self.single[1].value, 3)
        self.single.remove(2)
        # [1, 3]
        self.assertEqual(self.single[0].value, 1)
        self.assertEqual(self.single[1].value, 3)

   # DOUBLE-LINKED LIST
    def test_iteration_double(self):
        node1, node2, node3 = Node(1), Node(2), Node(3)
        node1.next, node2.next, node3.next = node2, node3, None
        node1.prev, node2.prev, node3.prev = None, node1, node2
        self.double.head = node1
        self.double.tail = node3
        # test __iter__
        self.assertEqual([str(i) for i in self.double], [str(i) for i in range(1, 4)])
        # test iterating over reversed
        self.assertEqual([str(i) for i in reversed(self.double)], [str(i) for i in range(3, 0, -1)])

    def test_double_slicing(self):
        node1, node2, node3 = Node(1), Node(2), Node(3)
        node1.next, node2.next, node3.next = node2, node3, None
        node1.prev, node2.prev, node3.prev = None, node1, node2
        self.double.head = node1
        self.double.tail = node3
        self.assertEqual(self.double[0].value, 1)
        self.assertEqual(self.double[1].value, 2)
        self.assertEqual(self.double[2].value, 3)
        self.assertRaises(IndexError, lambda val: self.double[val], 3)

    def test_base_insert_moving_forwards_with_double(self):
        node1, node2, node3 = Node(1), Node(2), Node(3)
        self.double._insert(node1)
        self.assertTrue(test_node(self.double[0], 1, None, None))
        self.assertTrue(test_linked_list(self.double, self.double[0], self.double[0]))

        self.double._insert(node3, node1)
        self.assertTrue(test_node(self.double[0], 1, 3, None))
        self.assertTrue(test_node(self.double[1], 3, None, 1))
        self.assertTrue(test_linked_list(self.double, self.double[0], self.double[1]))

        self.double._insert(node2, node1)
        self.assertTrue(test_node(self.double[0], 1, 2, None))
        self.assertTrue(test_node(self.double[1], 2, 3, 1))
        self.assertTrue(test_node(self.double[2], 3, None, 2))
        self.assertTrue(test_linked_list(self.double, self.double[0], self.double[2]))

        self.assertEqual(str(self.double), str([str(i) for i in range(1, 4)]))

    def test_base_insert_moving_backwards_with_double(self):
        node1, node2, node3 = Node(1), Node(2), Node(3)
        # insert node3 at the beginning/end of the list
        self.double._rev_insert(node3)
        self.assertTrue(test_node(self.double[0], 3, None, None))
        self.assertTrue(test_linked_list(self.double, self.double[0], self.double[0]))
        # insert node one before node 3 ([node1, node3])
        self.double._rev_insert(node1, node3)
        self.assertTrue(test_node(self.double[0], 1, 3, None))
        self.assertTrue(test_node(self.double[1], 3, None, 1))
        self.assertTrue(test_linked_list(self.double, self.double[0], self.double[1]))
        # insert node2 before node3 ([node1, node2, node3])
        self.double._rev_insert(node2, node3)
        self.assertTrue(test_node(self.double[0], 1, 2, None))
        self.assertTrue(test_node(self.double[1], 2, 3, 1))
        self.assertTrue(test_node(self.double[2], 3, None, 2))
        self.assertTrue(test_linked_list(self.double, self.double[0], self.double[2]))
        # check that the array is [node1, node2, node3]
        self.assertEqual(str(self.double), str([str(i) for i in range(1, 4)]))

    def test_insert_at_beginning_of_double(self):
        self.double.insert(2, 0)
        self.assertTrue(test_node(self.double[0], 2, None, None))
        self.assertTrue(test_linked_list(self.double, self.double[0], self.double[0]))
        self.double.insert(1, 0)
        self.assertTrue(test_node(self.double[0], 1, 2, None))
        self.assertTrue(test_node(self.double[1], 2, None, 1))
        self.assertTrue(test_linked_list(self.double, self.double[0], self.double[1]))

    def test_insert_in_middle_and_end_of_double(self):
        self.double.insert(1, 0)
        self.double.insert(3, 1)
        self.assertTrue(test_node(self.double[0], 1, 3, None))
        self.assertTrue(test_node(self.double[1], 3, None, 1))
        self.assertTrue(test_linked_list(self.double, self.double[0], self.double[1]))
        self.double.insert(2, 1) 
        self.assertTrue(test_node(self.double[0], 1, 2, None))
        self.assertTrue(test_node(self.double[1], 2, 3, 1))
        self.assertTrue(test_node(self.double[2], 3, None, 2))
        self.assertTrue(test_linked_list(self.double, self.double[0], self.double[2]))
        self.double.insert(5, 3) 
        self.assertTrue(test_node(self.double[0], 1, 2, None))
        self.assertTrue(test_node(self.double[1], 2, 3, 1))
        self.assertTrue(test_node(self.double[2], 3, 5, 2))
        self.assertTrue(test_node(self.double[3], 5, None, 3))
        self.assertTrue(test_linked_list(self.double, self.double[0], self.double[3]))
        self.double.insert(4, 3) 
        self.assertTrue(test_node(self.double[0], 1, 2, None))
        self.assertTrue(test_node(self.double[1], 2, 3, 1))
        self.assertTrue(test_node(self.double[2], 3, 4, 2))
        self.assertTrue(test_node(self.double[3], 4, 5, 3))
        self.assertTrue(test_node(self.double[4], 5, None, 4))
        self.assertTrue(test_linked_list(self.double, self.double[0], self.double[4]))

    # Binary Tree
    def test_binary_node_equality(self):
        one = BinaryNode(1)
        one2 = BinaryNode(1)
        self.assertTrue(one == one2)
        two = BinaryNode(2)
        self.assertFalse(one == two)

    def test_add_internal_child_to_binary_node(self):
        one = BinaryNode(1)
        two = BinaryNode(2)
        three = BinaryNode(3)
        one.left = three
        # one = {left: 3, right: None}
        one.insert(two, three)
        self.assertTrue(test_binary_node(one, 1, 2, None, None))
        self.assertTrue(test_binary_node(two, 2, 3, None, 1))
        self.assertTrue(test_binary_node(three, 3, None, None, 2))

    def test_add_external_child_to_binary_node(self):
        one = BinaryNode(1)
        two = BinaryNode(2)
        one.insert(two)
        self.assertTrue(test_binary_node(one, 1, 2, None, None))
        self.assertTrue(test_binary_node(two, 2, None, None, 1))
        three = BinaryNode(3)
        one.insert(three)
        self.assertTrue(test_binary_node(one, 1, 2, 3, None))
        self.assertTrue(test_binary_node(two, 2, None, None, 1))
        self.assertTrue(test_binary_node(three, 3, None, None, 1))
        four = BinaryNode(4)
        two.insert(four)
        self.assertTrue(test_binary_node(two, 2, 4, None, 1))
        self.assertTrue(test_binary_node(four, 4, None, None, 2))

    def test_depth_first_generation(self):
        self.btree.root = deep_btree()
        self.assertEquals([int(str(n)) for n in self.btree.depth_gen(self.btree.root)], range(1, 9))

    def test_breadth_first_generation(self):
        self.btree.root = wide_btree()
        self.assertEqual([int(str(n)) for n in self.btree.breadth_gen([self.btree.root])], range(1, 9))

    def test_binary_tree_iteration(self):
        self.btree.root = deep_btree()
        self.assertEquals([int(str(n)) for n in self.btree], range(1, 9))

    def test_contains(self):
        self.btree.root = deep_btree()
        for i in range(1, 9):
            self.assertTrue(i in self.btree)
        self.assertFalse(0 in self.btree)
        self.assertFalse(9 in self.btree)

    def test_insert_into_binary_tree(self):
        ## note - indexing grabs the node with that VALUE, not the node that exists at that index
        #       1
        self.btree.insert(1)
        self.assertTrue(test_binary_node(self.btree[1], 1, None, None, None))
        self.btree.insert(4, 1)
        #       1
        #      /
        #     4
        self.assertTrue(test_binary_node(self.btree[1], 1, 4, None, None))
        self.assertTrue(test_binary_node(self.btree[4], 4, None, None, 1))
        self.btree.insert(3, 1)
        #       1
        #      / \
        #     4   3
        self.assertTrue(test_binary_node(self.btree[1], 1, 4, 3, None))
        self.assertTrue(test_binary_node(self.btree[4], 4, None, None, 1))
        self.assertTrue(test_binary_node(self.btree[3], 3, None, None, 1))
        self.btree.insert(2, 1, 4)
        #       1
        #      / \
        #     2   3
        #    /
        #   4
        self.assertTrue(test_binary_node(self.btree[1], 1, 2, 3, None))
        self.assertTrue(test_binary_node(self.btree[2], 2, 4, None, 1))
        self.assertTrue(test_binary_node(self.btree[3], 3, None, None, 1))
        self.assertTrue(test_binary_node(self.btree[4], 4, None, None, 2))


    # Binary Search Tree
    def test_binary_search_node(self):
        root = binary_search_tree()
        for i in range(1, 9):
            self.assertTrue(root.search(i))
        self.assertFalse(root.search(0))
        self.assertFalse(root.search(9))

    def test_binary_search_insert(self):
    #               5
    #             /    \
    #           3        8
    #         /  \     /
    #       2     4   6

        root = BinarySearchNode(5)
        self.assertTrue(test_binary_node(root, 5, None, None, None))
        root.insert(3)
        self.assertTrue(test_binary_node(root, 5, 3, None, None))
        self.assertTrue(test_binary_node(root[3], 3, None, None, 5))
        root.insert(8)
        self.assertTrue(test_binary_node(root, 5, 3, 8, None))
        self.assertTrue(test_binary_node(root[3], 3, None, None, 5))
        self.assertTrue(test_binary_node(root[8], 8, None, None, 5))
        root.insert(4)
        self.assertTrue(test_binary_node(root, 5, 3, 8, None))
        self.assertTrue(test_binary_node(root[3], 3, None, 4, 5))
        self.assertTrue(test_binary_node(root[8], 8, None, None, 5))
        self.assertTrue(test_binary_node(root[4], 4, None, None, 3))
        root.insert(2)
        self.assertTrue(test_binary_node(root, 5, 3, 8, None))
        self.assertTrue(test_binary_node(root[3], 3, 2, 4, 5))
        self.assertTrue(test_binary_node(root[8], 8, None, None, 5))
        self.assertTrue(test_binary_node(root[2], 2, None, None, 3))
        self.assertTrue(test_binary_node(root[4], 4, None, None, 3))
        root.insert(6)
        self.assertTrue(test_binary_node(root, 5, 3, 8, None))
        self.assertTrue(test_binary_node(root[3], 3, 2, 4, 5))
        self.assertTrue(test_binary_node(root[8], 8, 6, None, 5))
        self.assertTrue(test_binary_node(root[2], 2, None, None, 3))
        self.assertTrue(test_binary_node(root[4], 4, None, None, 3))
        self.assertTrue(test_binary_node(root[6], 6, None, None, 8))

    # def test_binary_search_remove_external_node(self):
    #     root = binary_search_tree()
    #     root.remove(1)
    #     self.assertTrue(test_binary_node(root, 5, 3, 8, None))
    #     self.assertTrue(test_binary_node(root[3], 3, 2, 4, 5))
    #     self.assertTrue(test_binary_node(root[8], 8, 6, None, 5))
    #     self.assertTrue(test_binary_node(root[2], 2, None, None, 3))
    #     self.assertTrue(test_binary_node(root[4], 4, None, None, 3))
    #     self.assertTrue(test_binary_node(root[6], 6, None, 7, 8))
    #     self.assertTrue(test_binary_node(root[7], 7, None, None, 6))
    #     self.assertFalse(1 in root)
    #     self.assertFalse(root.search(1))

    def test_binary_search_remove_internal_node_without_children(self):
        root = binary_search_tree()
        root.remove(3, root[4])
        self.assertTrue(test_binary_node(root, 5, 4, 8, None))
        self.assertTrue(test_binary_node(root[4], 4, 2, None, 5))
        self.assertTrue(test_binary_node(root[8], 8, 6, None, 5))
        self.assertTrue(test_binary_node(root[2], 2, 1, None, 4))
        self.assertTrue(test_binary_node(root[6], 6, None, 7, 8))
        self.assertTrue(test_binary_node(root[7], 7, None, None, 6))
        self.assertFalse(3 in root)

    def test_binary_search_remove_internal_node_with_children1(self):
        root = binary_search_tree()
        root.insert(3.5)
        root.insert(4.5)
        root.remove(3, root[4])

        self.assertTrue(test_binary_node(root, 5, 4, 8, None))
        self.assertTrue(test_binary_node(root[4], 4, 3.5, 4.5, 5))
        self.assertTrue(test_binary_node(root[8], 8, 6, None, 5))
        self.assertTrue(test_binary_node(root[2], 2, 1, None, 3.5))
        self.assertTrue(test_binary_node(root[6], 6, None, 7, 8))
        self.assertTrue(test_binary_node(root[1], 1, None, None, 2))
        self.assertTrue(test_binary_node(root[3.5], 3.5, 2, None, 4))
        self.assertTrue(test_binary_node(root[4.5], 4.5, None, None, 4))
        self.assertTrue(test_binary_node(root[7], 7, None, None, 6))
        self.assertFalse(3 in root)

    def test_binary_search_remove_internal_node_with_children2(self):
        root = binary_search_tree()
        root.insert(3.5)
        root.insert(4.5)
        root.remove(3, root[2])

        self.assertTrue(test_binary_node(root, 5, 2, 8, None))
        self.assertTrue(test_binary_node(root[2], 2, 1, 4, 5))
        self.assertTrue(test_binary_node(root[8], 8, 6, None, 5))
        self.assertTrue(test_binary_node(root[6], 6, None, 7, 8))
        self.assertTrue(test_binary_node(root[1], 1, None, None, 2))
        self.assertTrue(test_binary_node(root[4], 4, 3.5, 4.5, 2))
        self.assertTrue(test_binary_node(root[3.5], 3.5, None, None, 4))
        self.assertTrue(test_binary_node(root[4.5], 4.5, None, None, 4))
        self.assertTrue(test_binary_node(root[7], 7, None, None, 6))
        self.assertFalse(3 in root)

    # HEAP
    def test_heap_iteration(self):
        heap = Heap(max_heap())
        self.assertEqual([int(str(n)) for n in heap.breadth()], [17, 15, 10, 6, 10, 7])
        self.assertEqual([int(str(n)) for n in heap], [17, 15, 10, 6, 10, 7])
        self.assertEqual(heap.flatten(), [17, 15, 10, 6, 10, 7])

    def test_find_open_with_empty_aunt(self):
        node17 = HeapNode(17)
        node15 = HeapNode(15)
        node11 = HeapNode(11)
        node6 = HeapNode(6)
        node10 = HeapNode(10)
        node17.left = node15
        node17.right = node11
        node15.left = node6
        node15.right = HeapNode(10)

        heap = Heap(node17)
        self.assertEqual(heap[-1].value, 10)
        self.assertEqual(heap.find_open(), (node11, 'left'))

    def test_find_open_with_single_child_aunt(self):
        node17 = HeapNode(17)
        node15 = HeapNode(15)
        node11 = HeapNode(11)
        node6 = HeapNode(6)
        node10 = HeapNode(10)
        node7 = HeapNode(7)
        node17.left = node15
        node17.right = node11
        node15.left = node6
        node15.right = HeapNode(10)
        node11.left = node7

        heap = Heap(node17)
        self.assertEqual(heap[-1].value, 7)
        self.assertEqual(heap.find_open(), (node11, 'right'))

    def test_find_open_with_non_empty_aunt(self):
        node17 = HeapNode(17)
        node15 = HeapNode(15)
        node11 = HeapNode(11)
        node6 = HeapNode(6)
        node10 = HeapNode(10)
        node7 = HeapNode(7)
        node5 = HeapNode(5)
        node17.left = node15
        node17.right = node11
        node15.left = node6
        node15.right = HeapNode(10)
        node11.left = node7
        node11.right = node5
        
        heap = Heap(node17)
        self.assertEqual(heap[-1].value, 5)
        self.assertEqual(heap.find_open(), (node6, 'left'))

    def test_insert(self):
        node17 = HeapNode(17)
        heap = Heap(node17)
        heap.insert(15)
        self.assertTrue(test_binary_node(heap.root, 17, 15, None, None))
        self.assertTrue(test_binary_node(heap.root.left, 15, None, None, 17))
        heap.insert(10)
        self.assertTrue(test_binary_node(heap.root, 17, 15, 10, None))
        self.assertTrue(test_binary_node(heap.root.left, 15, None, None, 17))        
        self.assertTrue(test_binary_node(heap.root.right, 10, None, None, 17))
        heap.insert(6)
        self.assertTrue(test_binary_node(heap.root, 17, 15, 10, None))
        self.assertTrue(test_binary_node(heap.root.left, 15, 6, None, 17))        
        self.assertTrue(test_binary_node(heap.root.right, 10, None, None, 17))
        self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 15))
        heap.insert(10)
        self.assertTrue(test_binary_node(heap.root, 17, 15, 10, None))
        self.assertTrue(test_binary_node(heap.root.left, 15, 6, 10, 17))        
        self.assertTrue(test_binary_node(heap.root.right, 10, None, None, 17))
        self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 15))
        self.assertTrue(test_binary_node(heap.root.left.right, 10, None, None, 15))
        heap.insert(7)
        self.assertTrue(test_binary_node(heap.root, 17, 15, 10, None))
        self.assertTrue(test_binary_node(heap.root.left, 15, 6, 10, 17))        
        self.assertTrue(test_binary_node(heap.root.right, 10, 7, None, 17))
        self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 15))
        self.assertTrue(test_binary_node(heap.root.left.right, 10, None, None, 15))
        self.assertTrue(test_binary_node(heap.root.right.left, 7, None, None, 10))

    def test_bubble(self):

        #               17                      17                  100
        #             /    \                  /    \               /    \
        #          15        10    -->     15       100    -->   15       17
        #         /  \      /  \          /  \      /  \        /  \     /  \
        #       6     10   7   100      6     10   7   10     6     10  7   10

        heap = Heap(max_heap())
        parent = heap.root.right
        last = HeapNode(100)
        parent.right = last
        last.parent = parent
        heap.bubble(last)

        self.assertTrue(test_binary_node(heap.root, 100, 15, 17, None))
        self.assertTrue(test_binary_node(heap.root.right, 17, 7, 10, 100))
        self.assertTrue(test_binary_node(heap.root.right.left, 7, None, None, 17))
        self.assertTrue(test_binary_node(heap.root.right.right, 10, None, None, 17))

        #             100                  100                  100
        #            /    \               /    \               /    \
        #          15       17   -->    15       17    -->  99       17
        #         /  \     /  \        /  \     /  \        /  \     /  \
        #       6     10  7   10     99   10  7   10     15     10  7   10
        #      /                     /                   /
        #     99                   6                   6

        parent = heap.root.left.left
        last = HeapNode(99)
        last.parent = parent
        parent.left = last
        heap.bubble(last)
        self.assertTrue(test_binary_node(heap.root, 100, 99, 17, None))
        self.assertTrue(test_binary_node(heap.root.left, 99, 15, 10, 100))
        self.assertTrue(test_binary_node(heap.root.left.left, 15, 6, None, 99))
        self.assertTrue(test_binary_node(heap.root.left.right, 10, None, None, 99))
        self.assertTrue(test_binary_node(heap.root.left.left.left, 6, None, None, 15))

        #             100                  100                  100
        #            /    \               /    \               /    \
        #          99       17   -->    99       17    -->  100       17
        #         /  \     /  \        /  \     /  \        /  \      /  \
        #       15    10  7   10     15  100  7   10     15    99   7   10
        #      /  \   /             / \   /              /  \   /
        #     6   12 100          6  12 10             6   12 10

        fifteen = heap.root.left.left
        twelve = HeapNode(12)
        twelve.parent = fifteen
        fifteen.right = twelve

        ten = heap.root.left.right
        last = HeapNode(100)
        ten.left = last
        last.parent = ten
        heap.bubble(last)
        self.assertTrue(test_binary_node(heap.root, 100, 100, 17, None))
        self.assertTrue(test_binary_node(heap.root.left, 100, 15, 99, 100))
        self.assertTrue(test_binary_node(heap.root.left.left, 15, 6, 12, 100))
        self.assertTrue(test_binary_node(heap.root.left.right, 99, 10, None, 100))


    def test_insertion_with_percolation(self):
        #               17
        #             /    \
        #          15        10
        #         /  \      /
        #       6     10   7

        #     6
        six = HeapNode(6)
        heap = Heap(six)
        self.assertTrue(test_binary_node(heap.root, 6, None, None, None))

        #     6             10
        #    /    -->     /
        #  10           6
        heap.insert(10)
        self.assertTrue(test_binary_node(heap.root, 10, 6, None, None))
        self.assertTrue(test_binary_node(heap.root.left, 6, None, None, 10))          
        #     10             10
        #    /  \  -->     /   \
        #  6     7       6      7
        heap.insert(7)
        self.assertTrue(test_binary_node(heap.root, 10, 6, 7, None))
        self.assertTrue(test_binary_node(heap.root.left, 6, None, None, 10)) 
        self.assertTrue(test_binary_node(heap.root.right, 7, None, None, 10))
        #      10            15
        #     /  \  -->     /   \
        #   6     7       10      7
        #  /              / 
        # 15             6
        heap.insert(15)
        self.assertTrue(test_binary_node(heap.root, 15, 10, 7, None))
        self.assertTrue(test_binary_node(heap.root.left, 10, 6, None, 15)) 
        self.assertTrue(test_binary_node(heap.root.right, 7, None, None, 15))
        self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 10))
        #      15            17
        #     /  \  -->     /   \
        #   10    7       15      7
        #  /  \          /  \
        # 6    17       6    10
        heap.insert(17)
        self.assertTrue(test_binary_node(heap.root, 17, 15, 7, None))
        self.assertTrue(test_binary_node(heap.root.left, 15, 6, 10, 17)) 
        self.assertTrue(test_binary_node(heap.root.right, 7, None, None, 17))
        self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 15))
        self.assertTrue(test_binary_node(heap.root.left.right, 10, None, None, 15))
        #       17             17    
        #      /   \  -->     /   \   
        #    15     7       15     11
        #   /  \   /       /  \   /  
        #  6   10 11      6   10 7  
        heap.insert(11)
        self.assertTrue(test_binary_node(heap.root, 17, 15, 11, None))
        self.assertTrue(test_binary_node(heap.root.left, 15, 6, 10, 17)) 
        self.assertTrue(test_binary_node(heap.root.right, 11, 7, None, 17))
        self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 15))
        self.assertTrue(test_binary_node(heap.root.left.right, 10, None, None, 15))
        self.assertTrue(test_binary_node(heap.root.right.left, 7, None, None, 11))

    def test_build_from_array(self):
        heap1 = [17, 15, 11, 6, 10, 7]
        heap2 = [6, 10, 7, 15, 17, 11]
        heap = Heap(array=heap1)
        self.assertTrue(test_binary_node(heap.root, 17, 15, 11, None))
        self.assertTrue(test_binary_node(heap.root.left, 15, 6, 10, 17)) 
        self.assertTrue(test_binary_node(heap.root.right, 11, 7, None, 17))
        self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 15))
        self.assertTrue(test_binary_node(heap.root.left.right, 10, None, None, 15))
        self.assertTrue(test_binary_node(heap.root.right.left, 7, None, None, 11)) 
        heap = Heap(array=heap2)
        self.assertTrue(test_binary_node(heap.root, 17, 15, 11, None))
        self.assertTrue(test_binary_node(heap.root.left, 15, 6, 10, 17)) 
        self.assertTrue(test_binary_node(heap.root.right, 11, 7, None, 17))
        self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 15))
        self.assertTrue(test_binary_node(heap.root.left.right, 10, None, None, 15))
        self.assertTrue(test_binary_node(heap.root.right.left, 7, None, None, 11)) 

    def test_delete(self):

        #          17                  7                  15                  15          
        #        /    \              /    \              /    \              /    \    
        #     15        11  -->   15        11  -->   7        11   -->   10        11
        #    /  \      /         /  \                /  \                /  \        
        #  6     10   7        6     10            6     10            6     7       
        heap = Heap(max_heap())
        heap[2].value = 11
        heap.delete_root()
        self.assertTrue(test_binary_node(heap.root, 15, 10, 11, None))
        self.assertTrue(test_binary_node(heap.root.left, 10, 6, 7, 15)) 
        self.assertTrue(test_binary_node(heap.root.right, 11, None, None, 15))
        self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 10))
        self.assertTrue(test_binary_node(heap.root.left.right, 7, None, None, 10))
        #         15                  7                  11    
        #       /    \              /    \             /    \  
        #     10      11  -->    10       11  -->   10       7
        #    /  \               /                  /           
        #  6     7            6                  6             
        heap.delete_root()
        self.assertTrue(test_binary_node(heap.root, 11, 10, 7, None))
        self.assertTrue(test_binary_node(heap.root.left, 10, 6, None, 11)) 
        self.assertTrue(test_binary_node(heap.root.right, 7, None, None, 11))
        self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 10))
        #          11               6                 10           
        #        /    \           /    \            /    \        
        #     10       7  -->   10      7   -->   6       7
        #    /                                                      
        #  6                                                       
        heap.delete_root()
        self.assertTrue(test_binary_node(heap.root, 10, 6, 7, None))
        self.assertTrue(test_binary_node(heap.root.left, 6, None, None, 10)) 
        self.assertTrue(test_binary_node(heap.root.right, 7, None, None, 10))
        #      10             7        
        #    /    \  -->    /       
        #  6       7      6     
        heap.delete_root()
        self.assertTrue(test_binary_node(heap.root, 7, 6, None, None))
        self.assertTrue(test_binary_node(heap.root.left, 6, None, None, 7)) 
        #      7                
        #    /   -->   6
        #  6             
        heap.delete_root()
        self.assertTrue(test_binary_node(heap.root, 6, None, None, None))
        #   6   -->  None
        heap.delete_root()
        self.assertFalse(heap.root)