def test_push(): queue = Queue() assert (queue.is_empty()) for i in range(ITERS): queue.push(i) assert (len(queue) == i + 1) assert (queue.peek() == 0) assert (not queue.is_empty())
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
def bfs(grid:np.array,start:tuple,end:tuple) -> Tuple[list,list]: """ A function that searches for the shortest path in a grid using the Breadth-first-search algorithm This function searches through a grid searching for the shortest path using the Breadth-first-search algorithm. First a Queue (queue) object is created and the first node is pushed into it. A VisitedNodes (visited) object is created after. While there are objects in queue, the first object in the queue is removed and placed in visited. If the node's position is equal to the end, then a visited list and a path list is returned. Otherwise, each child of the node is iterated upon and checked to see if they are in visited or the queue, and if that child is accessible. If true, then that child node is pushed into the queue and the process repeats. Parameters ---------- grid : np.array a numpy array detailing the grid start : tuple a tuple detailing the starting node's position end : tuple a tuple detailing the ending node's position Returns ------- Tuple[list,list] A list of visited nodes and a list of nodes that are included in the path """ if grid[start[0]][start[1]] == 1 or grid[end[0]][end[1]] == 1: return [None],[None] queue = Queue() queue.push(Node(grid,start)) visited= VisitedNodes() while len(queue) > 0: node = queue.pop() visited._store_node(node) if node.pos == end: visited_list, path_list = visited.create_path(node.pos, start) return visited_list, path_list else: for child in node.children: if child["node"] not in visited.visited_nodes and child["node"] not in queue.queue_list and child["accessibility"]: queue.push(Node(grid, child["node"], parent=node.pos)) return [None],[None]
def test_pop(): queue, arr = Queue(), [] assert (queue.is_empty()) with pytest.raises(AssertionError): queue.pop() for _ in range(ITERS): value = random.randrange(MAX_VAL) queue.push(value) arr.append(value) assert (len(queue) == len(arr)) for _ in range(ITERS): assert (not queue.is_empty()) expected, arr = arr[0], arr[1:] actual = queue.peek() assert (actual == expected) actual = queue.pop() assert (actual == expected) assert (len(queue) == len(arr)) assert (queue.is_empty()) with pytest.raises(AssertionError): queue.pop()
class PathfindingTests(unittest.TestCase): ############################ #### setup and teardown #### ############################ 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() def tearDown(self): self.priority_queue = PriorityQueue() self.stack = Stack() self.queue = Queue() self.visited = VisitedNodes() ############### #### tests #### ############### #### Algorithm Testing #### # settings decorator with verbosity to show inputs and errors in terminal #@settings(verbosity=Verbosity.verbose) # given decorater to set up the inputs, we use hypo array (imported above) to create a mock numpy array for the grid # st.tuples(st.integer(),st.integer()) is creating a tuple with two integers set between 0 to 4 @given(hypo_array(dtype=np.int, shape=(5, 5), elements=st.integers(0, 1)), st.tuples(st.integers(0, 4), st.integers(0, 4)), st.tuples(st.integers(0, 4), st.integers(0, 4))) # the above will paramaterize the function and for this particular test we assert that the function will return # two lists. def test_dfs_assert_return_lists(self, grid, start, end): visited_list, path_list = dfs(grid, start, end, _stack=Stack()) assert visited_list assert path_list 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") @given(hypo_array(dtype=np.int, shape=(5, 5), elements=st.integers(0, 1)), st.tuples(st.integers(0, 4), st.integers(0, 4)), st.tuples(st.integers(0, 4), st.integers(0, 4))) def test_bfs_assert_return_lists(self, grid, start, end): visited_list, path_list = bfs(grid, start, end) assert visited_list assert path_list def test_bfs_assert_equal_return_lists(self): visited_list, path_list = bfs(self.grid, self.start, self.end) self.assertEqual( visited_list, self.bfs_correct_returns["visited_list"], "tested visited_list is not equal to correct visited list") self.assertEqual(path_list, self.bfs_correct_returns["path_list"], "tested path_list is not equal to correct path list") @given(hypo_array(dtype=np.int, shape=(5, 5), elements=st.integers(0, 1)), st.tuples(st.integers(0, 4), st.integers(0, 4)), st.tuples(st.integers(0, 4), st.integers(0, 4))) def test_a_star_assert_return_lists(self, grid, start, end): visited_list, path_list = a_star(grid, start, end) assert visited_list assert path_list def test_a_star_assert_equal_return_lists(self): visited_list, path_list = a_star(self.grid, self.start, self.end) self.assertEqual( visited_list, self.a_star_correct_returns["visited_list"], "tested visited_list is not equal to correct visited list") self.assertEqual(path_list, self.a_star_correct_returns["path_list"], "tested path_list is not equal to correct path list") #### Class Testing #### def test_stack_push_assert_in(self): self.stack.push(self.test_nodes[0]) self.assertIn(self.test_nodes[0], self.stack.stacked_nodes, "Was not able to push node into stack") def test_stack_pop_assert_sequence_equal(self): for test_node in self.test_nodes: self.stack.push(test_node) self.assertEqual(self.stack.pop(), self.test_nodes.pop(-1), "Popped value incorrect.") def test_queue_push_assert_in(self): self.queue.push(self.test_nodes[0]) self.assertIn(self.test_nodes[0], self.queue.queued_nodes, "Test node not in queue") def test_queue_pop_assert_sequence_equal(self): for test_node in self.test_nodes: self.queue.push(test_node) self.assertEqual(self.queue.pop(), self.test_nodes.pop(0), "Popped value incorrect") def test_priority_queue_push(self): self.priority_queue.push(self.test_nodes[0]) self.assertIn(self.test_nodes[0], self.priority_queue.queued_nodes, "Was not able to push Node into priority queue.") def test_priority_queue_prioritize(self): for node in self.test_nodes[1:]: self.priority_queue.push(node) self.assertEqual(self.priority_queue.queued_nodes[0], self.test_nodes[2], "prioritize failed with test nodes.") def test_priority_queue_pop(self): for node in self.test_nodes: self.priority_queue.push(node) self.priority_queue.pop() self.assertSequenceEqual(self.priority_queue.queued_nodes, [self.test_nodes[1], self.test_nodes[2]], "pop failed with test nodes.") def test_visited_nodes_store_node(self): pass def test_visited_nodes_create_path(self): pass
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)