From f9b30cecb4987a24acfd4e7bd1fc730618d29261 Mon Sep 17 00:00:00 2001 From: bonanashelby Date: Thu, 8 Jun 2017 17:56:17 -0700 Subject: [PATCH 01/14] initial commit --- src/dijkstra.py | 5 +++++ src/test_dijkstra.py | 0 2 files changed, 5 insertions(+) create mode 100644 src/dijkstra.py create mode 100644 src/test_dijkstra.py diff --git a/src/dijkstra.py b/src/dijkstra.py new file mode 100644 index 0000000..d194f6f --- /dev/null +++ b/src/dijkstra.py @@ -0,0 +1,5 @@ +"""Dijkstra algorithm for our shortest path graph.""" +from weighted_graph import Weighted + + +def dijkstra(): diff --git a/src/test_dijkstra.py b/src/test_dijkstra.py new file mode 100644 index 0000000..e69de29 From d38a27ac12e3492f9a1e97db9d3997e691fa324a Mon Sep 17 00:00:00 2001 From: kurtrm Date: Thu, 8 Jun 2017 18:27:40 -0700 Subject: [PATCH 02/14] Studied, meditated, groked, pseudocoded dijkstra. --- src/dijkstra.py | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/dijkstra.py b/src/dijkstra.py index d194f6f..e2fbb61 100644 --- a/src/dijkstra.py +++ b/src/dijkstra.py @@ -1,5 +1,30 @@ """Dijkstra algorithm for our shortest path graph.""" from weighted_graph import Weighted +from priorityq import PriorityQueue -def dijkstra(): +def dijkstra(weighted_graph, start_node): + """Find the shortest path to nodes from starting node.""" + if not weighted_graph.has_node(start_node): + raise IndexError('Node not in this weighted graph.') + current_node = {start_node: 0} + peeped = [] # list of dictionaries + priorityq = PriorityQueue() + priorityq.insert(start_node.key, start_node.value) + while len(priorityq) > 0: + # current_node = priorityq.pop() + # look at that nodes neighbors + + # insert neighbors into the queue with priority of + # edge weight plus current node weight. + + # The priority queue automatically organizes them + # by the minimum value, so we're good there. + + # We've looked at both of the current nodes neighbors, + # so we're good to move on to the next node. + + # If the current node's weight is less than the one + # in the peeped list, swap them out. + + # continue From 958dd17fdf8c611d7f4bf3dc0df7aa6f8b07a565 Mon Sep 17 00:00:00 2001 From: kurtrm Date: Fri, 9 Jun 2017 18:03:21 -0700 Subject: [PATCH 03/14] Got the logic down but ran into an issue with our implementation of the priority queue. --- src/dijkstra.py | 33 +++++++++++++++------------------ src/priorityq.py | 19 +++++++++++++++++++ 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/dijkstra.py b/src/dijkstra.py index e2fbb61..5aa6997 100644 --- a/src/dijkstra.py +++ b/src/dijkstra.py @@ -2,29 +2,26 @@ from weighted_graph import Weighted from priorityq import PriorityQueue +# {'A':{'B': 7, 'C': 9}, 'B': {'D': 2, 'E': 4}, 'C': {'F': 6}, 'D':{}, 'E': {}, 'F': {}} + def dijkstra(weighted_graph, start_node): """Find the shortest path to nodes from starting node.""" if not weighted_graph.has_node(start_node): raise IndexError('Node not in this weighted graph.') current_node = {start_node: 0} - peeped = [] # list of dictionaries + visited = {} priorityq = PriorityQueue() - priorityq.insert(start_node.key, start_node.value) + priorityq.insert(current_node, 0) while len(priorityq) > 0: - # current_node = priorityq.pop() - # look at that nodes neighbors - - # insert neighbors into the queue with priority of - # edge weight plus current node weight. - - # The priority queue automatically organizes them - # by the minimum value, so we're good there. - - # We've looked at both of the current nodes neighbors, - # so we're good to move on to the next node. - - # If the current node's weight is less than the one - # in the peeped list, swap them out. - - # continue + current_node = priorityq.pop() + next_nodes = weighted_graph[list(current_node.keys())[0]] + for key, value in next_nodes.items(): + distance_from_start_node = value + list(current_node.values())[0] + priorityq.insert( + {key: distance_from_start_node}, distance_from_start_node + ) + if key in visited and distance_from_start_node > visited[key]: + continue + visited.update({key: distance_from_start_node}) + return visited diff --git a/src/priorityq.py b/src/priorityq.py index 3ae9ec8..ff2d9ce 100644 --- a/src/priorityq.py +++ b/src/priorityq.py @@ -3,6 +3,25 @@ # [{1: 0}, {100: 1}, {33: 2}, {44: 3}, {2: 0}] + # def heapify(self, iterable): + # """Function that will be used in init and other methods.""" + # heap_list = iterable + # for item in heap_list[::-1]: + # item_index = heap_list.index(item) + # parent = (item_index - 1) // 2 + # while item_index > 0: + + # if list(heap_list[parent].values())[0] < list(heap_list[parent].values())[0]: + # curr_val = heap_list[parent] + # heap_list[parent] = heap_list[item_index] + # heap_list[item_index] = curr_val + # item_index = parent + # parent = (item_index - 1) // 2 + # else: + # break + # return heap_list + + class PriorityQueue(object): """Implement a priority queue.""" From e805a650112a0d57ee295edf3303317b21904ee7 Mon Sep 17 00:00:00 2001 From: Kurt Date: Wed, 28 Jun 2017 13:39:32 -0700 Subject: [PATCH 04/14] Worked on Nick's comments. Also worked on refactoring tests. --- setup.py | 2 +- src/dll.py | 31 +++++++++++-------------------- src/priorityq.py | 15 ++++----------- src/test_dll.py | 48 +++++++++--------------------------------------- 4 files changed, 25 insertions(+), 71 deletions(-) diff --git a/setup.py b/setup.py index 97eb6a0..9a14157 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ extra_packages = { - 'testing': ['pytest', 'pytest-watch', 'pytest-cov', 'tox'] + 'testing': ['pytest-cov', 'tox'] } diff --git a/src/dll.py b/src/dll.py index 19c48b1..c67ed34 100644 --- a/src/dll.py +++ b/src/dll.py @@ -24,29 +24,27 @@ def push(self, val): """Push a value to the head of the list.""" if not val: raise TypeError('Please provide a not null value.') - self._length += 1 if self.tail is None and self.head is None: new_node = Node(val) - self.tail = new_node - self.head = new_node + self.tail = self.head = new_node else: new_node = Node(val, None, self.head) self.head.next_node = new_node self.head = new_node + self._length += 1 def append(self, val): """Append a val to the tail of a list.""" if not val: raise TypeError('Please provide a not null value.') - self._length += 1 if self.tail is None and self.head is None: new_node = Node(val) - self.tail = new_node - self.head = new_node + self.tail = self.head = new_node else: new_node = Node(val, self.tail, None) self.tail.prior_node = new_node self.tail = new_node + self._length += 1 def pop(self): """Pop pops from the head of the list.""" @@ -56,29 +54,25 @@ def pop(self): self._length -= 1 if self.head == self.tail: last_pop = self.head - self.head = None - self.tail = None + self.tail = self.head = None return last_pop.data popped = self.head self.head = self.head.prior_node - popped.prior_node = None self.head.next_node = None return popped.data def shift(self): """Remove the node from the tail of the list.""" - if not self.head: + if not self.tail: raise IndexError( 'There\'s nothing to remove from the linked list.') self._length -= 1 if self.head == self.tail: last_pop = self.head - self.head = None - self.tail = None + self.tail = self.head = None return last_pop.data shifted = self.tail self.tail = self.tail.next_node - shifted.next_node = None self.tail.prior_node = None return shifted.data @@ -88,13 +82,12 @@ def __len__(self): def remove(self, val): """Remove a node with the value provided.""" - if val is None: - raise TypeError( - 'That value is not in this particular linked list.') if self.head.data == val: self.pop() + return elif self.tail.data == val: self.shift() + return current_node = self.head while current_node is not None: if current_node.data != val: @@ -102,9 +95,7 @@ def remove(self, val): else: new_next_node = current_node.next_node new_prior_node = current_node.prior_node - current_node.next_node.prior_node = new_prior_node - current_node.prior_node.next_node = new_next_node - current_node.next_node = None - current_node.prior_node = None + new_next_node.next_node.prior_node = new_prior_node + new_prior_node.prior_node.next_node = new_next_node self._length -= 1 break diff --git a/src/priorityq.py b/src/priorityq.py index ff2d9ce..b7459a5 100644 --- a/src/priorityq.py +++ b/src/priorityq.py @@ -37,15 +37,8 @@ def heapify(self, iterable): parent = (item_index - 1) // 2 while item_index > 0: if list(heap_list[parent].values())[0] is 0 and list(heap_list[item_index].values())[0] is 0: - if list(heap_list[item_index].keys())[0] < list(heap_list[parent].keys())[0]: - curr_val = heap_list[parent] - heap_list[parent] = heap_list[item_index] - heap_list[item_index] = curr_val - item_index = parent - parent = (item_index - 1) // 2 - else: - item_index = parent - parent = (item_index - 1) // 2 + item_index = parent + parent = (item_index - 1) // 2 elif list(heap_list[parent].values())[0] > 0 and list(heap_list[item_index].values())[0] is 0: item_index = parent parent = (item_index - 1) // 2 @@ -71,8 +64,8 @@ def heapify(self, iterable): def insert(self, value, priority=0): """Insert a value into the priority queue with an optional priority.""" - if not isinstance(value, int) or not isinstance(priority, int): - raise TypeError("Must provide an integer for value and priority.") + if not isinstance(priority, int): + raise TypeError("Must provide an integer for priority.") if priority < 0: raise ValueError("You may not use a negative priority. Priority must be 0 or greater.") self._heap.append({value: priority}) diff --git a/src/test_dll.py b/src/test_dll.py index 36f412f..339804d 100644 --- a/src/test_dll.py +++ b/src/test_dll.py @@ -16,12 +16,6 @@ def test_dll_initialization(dll): assert dll.head is None -def test_dll_push_raises_type_error(dll): - """Test that the value error is raised.""" - with pytest.raises(TypeError): - dll.push() - - def test_dll_push_pushes_value(dll): """Test that the push pushes a value to head of list.""" dll.push(1) @@ -69,17 +63,10 @@ def test_dll_pop_only_has_one_item(dll): assert dll.tail is None -def test_dll_append_raises_type_error(dll): - """Test that we get a type error.""" - with pytest.raises(TypeError): - dll.append() - - def test_dll_appends_a_value(dll): """Ensure tail and head are the same.""" dll.append(1) - assert dll.tail.data == 1 - assert dll.head.data == 1 + assert dll.tail.data == dll.head.data == 1 def test_dll_appends_3_values(dll): @@ -113,17 +100,7 @@ def test_dll_shift_only_has_one_item(dll): assert dll.head.next_node is None assert dll.tail.prior_node is None assert dll.shift() == 2 - assert dll.head is None - assert dll.tail is None - - -def test_dll_remove_index_error(dll): - """Testing that the Index Error is raised if no val is passed.""" - dll.push(1) - dll.push(2) - dll.push(3) - with pytest.raises(TypeError): - dll.remove() + assert dll.head is dll.tail is None def test_dll_remove(dll): @@ -133,35 +110,28 @@ def test_dll_remove(dll): dll.push(3) dll.push(4) dll.remove(3) - assert dll.head.prior_node.data == 2 - assert dll.head.prior_node.next_node.data == 4 + assert (dll.head.prior_node.data, + dll.head.prior_node.next_node.data) == (2, 4) dll.remove(1) assert dll.tail.data == 2 assert dll.tail.next_node.data == 4 dll.remove(4) - assert dll.head.data == 2 - assert dll.tail.data == 2 + assert dll.head.data == dll.tail.data == 2 def test_dll_len(dll): """Test to make sure we get the right number of nodes.""" - assert len(dll) == 0 + dll_lengths = [] dll.push(1) - assert len(dll) == 1 dll.push(2) - assert len(dll) == 2 dll.append(3) - assert len(dll) == 3 dll.push(4) - assert len(dll) == 4 dll.push(5) - assert len(dll) == 5 dll.push(6) + dll_lengths.append(len(dll)) dll.remove(4) - assert len(dll) == 5 dll.pop() - assert len(dll) == 4 dll.shift() - assert len(dll) == 3 dll.pop() - assert len(dll) == 2 + dll_lengths.append(len(dll)) + assert dll_lengths == [5, 2] From 83fd1c0ccc34c1efedc0d148c45b6711d8ad4e6d Mon Sep 17 00:00:00 2001 From: Kurt Date: Wed, 28 Jun 2017 17:31:18 -0700 Subject: [PATCH 05/14] got tox working, with coverage. --- .coveragerc | 31 +++++++++++++++ src/dll.py | 4 +- src/test_dll.py | 103 +++++++++++++++++++++++++++--------------------- tox.ini | 2 +- 4 files changed, 91 insertions(+), 49 deletions(-) create mode 100644 .coveragerc diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..2021d2b --- /dev/null +++ b/.coveragerc @@ -0,0 +1,31 @@ +[run] +source = + src/dll.py +omit = + src/binheap.py + src/deque.py + src/dijkstra.py + src/graph_1.py + src/graph_2.py + src/linked_list.py + src/priorityq.py + src/que_.py + src/reverse_linked_list.py + src/stack.py + src/test_dll.py + src/test_binheap.py + src/test_deque.py + src/test_dijkstra.py + src/test_graph.py + src/test_graph_2.py + src/test_linked_list.py + src/test_priority_que.py + src/test_que_.py + src/test_reverse_linked_list.py + src/test_stack.py + src/test_weighted_graph.py + src/test_weighted_traversal.py + src/weighted_graph.py + src/weighted_traversal.py +[report] +show_missing = True \ No newline at end of file diff --git a/src/dll.py b/src/dll.py index c67ed34..a148766 100644 --- a/src/dll.py +++ b/src/dll.py @@ -95,7 +95,7 @@ def remove(self, val): else: new_next_node = current_node.next_node new_prior_node = current_node.prior_node - new_next_node.next_node.prior_node = new_prior_node - new_prior_node.prior_node.next_node = new_next_node + new_next_node.prior_node = new_prior_node + new_prior_node.next_node = new_next_node self._length -= 1 break diff --git a/src/test_dll.py b/src/test_dll.py index 339804d..2b50ca7 100644 --- a/src/test_dll.py +++ b/src/test_dll.py @@ -12,23 +12,20 @@ def dll(): def test_dll_initialization(dll): """Test that there's nothing initialized.""" - assert dll.tail is None - assert dll.head is None + assert dll.tail is dll.head is None def test_dll_push_pushes_value(dll): """Test that the push pushes a value to head of list.""" dll.push(1) - assert dll.tail.data == 1 - assert dll.head.data == 1 + assert dll.tail.data == dll.head.data == 1 def test_dll_push_head_and_tail_change(dll): """Test if second item is pushed in. Head and tail are seperate values.""" dll.push(1) dll.push(2) - assert dll.tail.data == 1 - assert dll.head.data == 2 + assert (dll.tail.data, dll.head.data) == (1, 2) def test_dll_push_3(dll): @@ -36,12 +33,9 @@ def test_dll_push_3(dll): dll.push(1) dll.push(2) dll.push(3) - assert dll.tail.data == 1 - assert dll.head.prior_node.prior_node.data == 1 - assert dll.head != dll.head.prior_node - assert dll.head.data == 3 - assert dll.head.prior_node.next_node.data == 3 - assert dll.tail.next_node.data == 2 + assert (dll.tail.data, dll.head.prior_node.prior_node.data, + dll.head != dll.head.prior_node, dll.head.data, dll.head.prior_node.next_node.data, + dll.tail.next_node.data) == (1, 1, True, 3, 3, 2) def test_dll_pop_index_error(dll): @@ -50,17 +44,20 @@ def test_dll_pop_index_error(dll): dll.pop() -def test_dll_pop_only_has_one_item(dll): +def test_dll_pop_only_has_one_item_phase_one(dll): + """Test that pop only has one item and both are head and tail none vals.""" + dll.push(1) + dll.push(2) + assert (dll.pop(), dll.head.data, dll.tail.data, + dll.head.next_node) == (2, 1, 1, None) + + +def test_dll_pop_only_has_one_item_phase_two(dll): """Test that pop only has one item and both are head and tail none vals.""" dll.push(1) dll.push(2) - assert dll.pop() == 2 - assert dll.head.data == 1 - assert dll.tail.data == 1 - assert dll.head.next_node is None - assert dll.pop() == 1 - assert dll.head is None - assert dll.tail is None + dll.pop() + assert (dll.pop(), dll.head, dll.tail) == (1, None, None) def test_dll_appends_a_value(dll): @@ -74,36 +71,31 @@ def test_dll_appends_3_values(dll): dll.append(1) dll.append(2) dll.append(3) - assert dll.tail.data == 3 - assert dll.head.data == 1 - assert dll.head.next_node is None - assert dll.tail.prior_node is None - assert dll.tail.next_node.data == 2 - assert dll.head.prior_node.data == 2 - assert dll.head.prior_node.next_node.data == 1 - assert dll.tail.next_node.prior_node.data == 3 - - -def test_dll_shift_index_error(dll): - """Test that the Index Error is raised if no val is shifted.""" - with pytest.raises(IndexError): - dll.shift() + assert (dll.tail.data, dll.head.data, dll.head.next_node, + dll.tail.prior_node, dll.tail.next_node.data, + dll.head.prior_node.data, dll.head.prior_node.next_node.data, + dll.tail.next_node.prior_node.data) == (3, 1, None, + None, 2, 2, + 1, 3) -def test_dll_shift_only_has_one_item(dll): +def test_dll_shift_only_has_one_item_phase_one(dll): """Test that node connections after shifting.""" dll.push(1) dll.push(2) - assert dll.shift() == 1 - assert dll.head.data == 2 - assert dll.tail.data == 2 - assert dll.head.next_node is None - assert dll.tail.prior_node is None - assert dll.shift() == 2 - assert dll.head is dll.tail is None + assert (dll.shift(), dll.head.data, dll.tail.data, + dll.head.next_node, dll.tail.prior_node) == (1, 2, 2, None, None) -def test_dll_remove(dll): +def test_dll_shift_only_has_one_item_phase_two(dll): + """Test that node connections after shifting.""" + dll.push(1) + dll.push(2) + dll.shift() + assert (dll.shift(), dll.head, dll.tail) == (2, None, None) + + +def test_dll_remove_phase_one(dll): """Testing the dll remove function.""" dll.push(1) dll.push(2) @@ -112,9 +104,28 @@ def test_dll_remove(dll): dll.remove(3) assert (dll.head.prior_node.data, dll.head.prior_node.next_node.data) == (2, 4) + + +def test_dll_remove_phase_two(dll): + """Testing the dll remove function.""" + dll.push(1) + dll.push(2) + dll.push(3) + dll.push(4) + dll.remove(3) + dll.remove(1) + assert (dll.tail.data, + dll.tail.next_node.data) == (2, 4) + + +def test_dll_remove_phase_three(dll): + """Testing the dll remove function.""" + dll.push(1) + dll.push(2) + dll.push(3) + dll.push(4) + dll.remove(3) dll.remove(1) - assert dll.tail.data == 2 - assert dll.tail.next_node.data == 4 dll.remove(4) assert dll.head.data == dll.tail.data == 2 @@ -134,4 +145,4 @@ def test_dll_len(dll): dll.shift() dll.pop() dll_lengths.append(len(dll)) - assert dll_lengths == [5, 2] + assert dll_lengths == [6, 2] diff --git a/tox.ini b/tox.ini index 036b313..fa04b32 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,7 @@ envlist = py27, py36 [testenv] -commands = py.test src --cov=src --cov-report term-missing +commands = pytest src/test_dll.py --cov=src --cov-report term-missing deps = pytest pytest-cov From 2fd240101672811d3fc03cef4c9edbd928182a37 Mon Sep 17 00:00:00 2001 From: Kurt Date: Wed, 28 Jun 2017 18:00:20 -0700 Subject: [PATCH 06/14] Made some changes, refactored tests. --- .coveragerc | 4 ++-- src/dll.py | 2 +- src/que_.py | 4 ++-- src/test_dll.py | 6 +++--- src/test_que_.py | 46 ++++++++++++++++++++++------------------------ tox.ini | 2 +- 6 files changed, 31 insertions(+), 33 deletions(-) diff --git a/.coveragerc b/.coveragerc index 2021d2b..893ea00 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,6 +1,6 @@ [run] source = - src/dll.py + src/que_.py omit = src/binheap.py src/deque.py @@ -9,7 +9,7 @@ omit = src/graph_2.py src/linked_list.py src/priorityq.py - src/que_.py + src/dll.py src/reverse_linked_list.py src/stack.py src/test_dll.py diff --git a/src/dll.py b/src/dll.py index a148766..8716d3f 100644 --- a/src/dll.py +++ b/src/dll.py @@ -76,7 +76,7 @@ def shift(self): self.tail.prior_node = None return shifted.data - def __len__(self): + def size(self): """Return the length of the double linked list.""" return self._length diff --git a/src/que_.py b/src/que_.py index b1aafd8..08fce44 100644 --- a/src/que_.py +++ b/src/que_.py @@ -23,6 +23,6 @@ def peek(self): """Return a new value without dequeuing it.""" print(self._new_dll.tail.data) - def __len__(self): + def size(self): """Length function for the queue.""" - return len(self._new_dll) + return self._new_dll.size() diff --git a/src/test_dll.py b/src/test_dll.py index 2b50ca7..c1e0a59 100644 --- a/src/test_dll.py +++ b/src/test_dll.py @@ -130,7 +130,7 @@ def test_dll_remove_phase_three(dll): assert dll.head.data == dll.tail.data == 2 -def test_dll_len(dll): +def test_dll_size(dll): """Test to make sure we get the right number of nodes.""" dll_lengths = [] dll.push(1) @@ -139,10 +139,10 @@ def test_dll_len(dll): dll.push(4) dll.push(5) dll.push(6) - dll_lengths.append(len(dll)) + dll_lengths.append(dll.size()) dll.remove(4) dll.pop() dll.shift() dll.pop() - dll_lengths.append(len(dll)) + dll_lengths.append(dll.size()) assert dll_lengths == [6, 2] diff --git a/src/test_que_.py b/src/test_que_.py index 1227cfe..7f73761 100644 --- a/src/test_que_.py +++ b/src/test_que_.py @@ -13,8 +13,7 @@ def the_queue(): def test_the_queue_enqueue(the_queue): """Test for enqueuing to the queue.""" the_queue.enqueue(2) - assert the_queue._new_dll.head.data == 2 - assert the_queue._new_dll.tail.data == 2 + assert the_queue._new_dll.head.data == the_queue._new_dll.tail.data == 2 def test_the_queue_enqueue_multi_values(the_queue): @@ -23,10 +22,10 @@ def test_the_queue_enqueue_multi_values(the_queue): the_queue.enqueue(3) the_queue.enqueue(4) the_queue.enqueue(5) - assert the_queue._new_dll.head.data == 5 - assert the_queue._new_dll.tail.data == 2 - assert the_queue._new_dll.head.prior_node.data == 4 - assert the_queue._new_dll.tail.next_node.data == 3 + assert (the_queue._new_dll.head.data, + the_queue._new_dll.tail.data, + the_queue._new_dll.head.prior_node.data, + the_queue._new_dll.tail.next_node.data) == (5, 2, 4, 3) def test_the_queue_dequeue(the_queue): @@ -41,19 +40,25 @@ def test_the_queue_dequeue_raises_exception(the_queue): the_queue.dequeue() -def test_the_queue_dequeue_multi_values(the_queue): +def test_the_queue_dequeue_multi_values_phase_one(the_queue): """Test for dequeue on mulitple values.""" the_queue.enqueue(2) - assert the_queue._new_dll.tail.data == 2 the_queue.enqueue(3) - assert the_queue._new_dll.tail.next_node.data == 3 the_queue.enqueue(4) the_queue.enqueue(5) - assert the_queue._new_dll.head.data == 5 the_queue.dequeue() assert the_queue._new_dll.tail.data == 3 - assert the_queue.dequeue() == 3 - assert the_queue._new_dll.tail.data == 4 + + +def test_the_queue_dequeue_multi_values_phase_two(the_queue): + """Test for dequeue on mulitple values.""" + the_queue.enqueue(2) + the_queue.enqueue(3) + the_queue.enqueue(4) + the_queue.enqueue(5) + the_queue.dequeue() + assert (the_queue.dequeue(), + the_queue._new_dll.tail.data) == (3, 4) def test_the_peek(the_queue): @@ -61,25 +66,18 @@ def test_the_peek(the_queue): the_queue.enqueue(1) the_queue.enqueue(2) the_queue.enqueue(3) - assert the_queue._new_dll.tail.data == 1 the_queue.dequeue() assert the_queue._new_dll.tail.data == 2 -def test_the_queue_len(the_queue): +def test_the_queue_size(the_queue): """Test the length on the queue.""" the_queue.enqueue(1) the_queue.enqueue(2) the_queue.enqueue(3) - assert len(the_queue) == 3 - - - - - - - - - + assert the_queue.size() == 3 +def test_size_empty(the_queue): + """Test zero is returned if empty.""" + assert the_queue.size() == 0 diff --git a/tox.ini b/tox.ini index fa04b32..0c528e4 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,7 @@ envlist = py27, py36 [testenv] -commands = pytest src/test_dll.py --cov=src --cov-report term-missing +commands = pytest src/test_que_.py --cov=src --cov-report term-missing deps = pytest pytest-cov From 3e04fe53b973a97bd5e1e024cd890acce01e05d3 Mon Sep 17 00:00:00 2001 From: Kurt Date: Wed, 28 Jun 2017 21:39:40 -0700 Subject: [PATCH 07/14] Refactored tests, addresed comments. --- .coveragerc | 4 +- src/linked_list.py | 28 +++++++--- src/test_linked_list.py | 112 +++++++++++++++++++++++----------------- tox.ini | 2 +- 4 files changed, 89 insertions(+), 57 deletions(-) diff --git a/.coveragerc b/.coveragerc index 893ea00..37cb82c 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,13 +1,13 @@ [run] source = - src/que_.py + src/linked_list.py omit = + src/que_.py src/binheap.py src/deque.py src/dijkstra.py src/graph_1.py src/graph_2.py - src/linked_list.py src/priorityq.py src/dll.py src/reverse_linked_list.py diff --git a/src/linked_list.py b/src/linked_list.py index 8705d9a..4eff6e9 100644 --- a/src/linked_list.py +++ b/src/linked_list.py @@ -43,10 +43,14 @@ def pop(self): self._length -= 1 return popped.data - def __len__(self): + def size(self): """Return the length of the linked list.""" return self._length + def __len__(self): + """Interact with built-in len() function.""" + return self.size() + def search(self, val): """Search the nodes for the value provided.""" current_node = self.head @@ -56,7 +60,7 @@ def search(self, val): else: return current_node.data else: - return None + return def remove(self, val): """Removenode from anywhere in the linked list with the given value.""" @@ -65,18 +69,20 @@ def remove(self, val): 'That value is not in this particular linked list.') if self.head.data == val: self.pop() - return None + return current_node = self.head + previous_node = self.head while current_node is not None: - if current_node.next_node.data != val: + if current_node.data != val: + previous_node = current_node current_node = current_node.next_node + continue else: - removed_node = current_node.next_node - current_node.next_node = current_node.next_node.next_node + previous_node.next_node = current_node.next_node self._length -= 1 - if removed_node.next_node is not None: - removed_node.next_node = None break + else: + raise ValueError('Value not found.') def display(self): """Present a visual representation of the linked list.""" @@ -84,7 +90,13 @@ def display(self): display_str = ' ' while node is not None: display_str += ' ' + display_str += '\'' display_str += str(node.data) + display_str += '\'' node = node.next_node display_str = ', '.join(display_str.split()) return '{}{}{}'.format('(', display_str, ')') + + def __str__(self): + """Interact with built-in print function.""" + return self.display() diff --git a/src/test_linked_list.py b/src/test_linked_list.py index 1e41504..ac14d8f 100644 --- a/src/test_linked_list.py +++ b/src/test_linked_list.py @@ -12,6 +12,32 @@ def linked_list(): return linked_list +def test_size(linked_list): + """Verify size works.""" + linked_list.push('True') + linked_list.push(12) + linked_list.push(True) + assert linked_list.size() == 3 + + +def test_size_pop(linked_list): + """Verify size works.""" + linked_list.push('True') + linked_list.push(12) + linked_list.push(True) + linked_list.pop() + assert linked_list.size() == 2 + + +def test_linked_list_length(linked_list): + """Verify we can return the length of the linked list.""" + linked_list.push(3) + linked_list.push(4) + linked_list.push(5) + linked_list.pop() + assert len(linked_list) == 2 + + def test_linked_list_head(linked_list): """Test our linked_list class.""" assert hasattr(linked_list, 'head') @@ -20,17 +46,10 @@ def test_linked_list_head(linked_list): def test_iterable_linked_list(): """Test values of initialized linked list.""" from linked_list import LinkedList - linked_list = LinkedList([1, 2, 3]) - assert len(linked_list) == 3 - assert linked_list.head.data == 3 + assert (len(linked_list), linked_list.head.data) == (3, 3) - linked_list = LinkedList([1, 2, 3]) - assert len(linked_list) == 3 - assert linked_list.head.data == 3 - - def test_iterable_linked_list_exception(): """Ensure exception raised if a non-iterable is passed as argument.""" from linked_list import LinkedList @@ -49,18 +68,18 @@ def test_linked_list_push_three(linked_list): linked_list.push(5) linked_list.push(3) linked_list.push(2) - assert linked_list.head.data == 2 - assert linked_list.head.next_node.data == 3 - assert linked_list.head.next_node.next_node.data == 5 + assert (linked_list.head.data, + linked_list.head.next_node.data, + linked_list.head.next_node.next_node.data) == (2, 3, 5) def test_linked_list_popped(linked_list): """Test pop method.""" linked_list.push(5) linked_list.push(2) - assert linked_list.pop() == 2 - assert linked_list.head.data == 5 - assert linked_list.pop() == 5 + assert (linked_list.pop(), + linked_list.head.data, + linked_list.pop()) == (2, 5, 5) def test_linked_list_popped_exception(linked_list): @@ -69,28 +88,6 @@ def test_linked_list_popped_exception(linked_list): linked_list.pop() -def test_linked_list_length(linked_list): - """Verify we can return the length of the linked list.""" - linked_list.push(3) - linked_list.push(4) - assert len(linked_list) == 2 - linked_list.push(5) - assert len(linked_list) == 3 - linked_list.pop() - assert len(linked_list) == 2 - - -def test_linked_list_length(linked_list): - """Verify we can return the length of the linked list.""" - linked_list.push(3) - linked_list.push(4) - assert len(linked_list) == 2 - linked_list.push(5) - assert len(linked_list) == 3 - linked_list.pop() - assert len(linked_list) == 2 - - def test_linked_list_search(linked_list): """Test the linked list search method.""" from linked_list import LinkedList @@ -98,29 +95,52 @@ def test_linked_list_search(linked_list): obj_2 = 45 obj_3 = ['stringy'] linked_list = LinkedList([obj_1, obj_2, obj_3]) - assert linked_list.search(45) == obj_2 - assert linked_list.search(['stringy']) == obj_3 - assert linked_list.search(obj_1) == 'apple' - assert linked_list.search(47) is None + assert (linked_list.search(45), + linked_list.search(['stringy']), + linked_list.search(obj_1), + linked_list.search(47)) == (obj_2, obj_3, 'apple', None) -def test_linked_list_remove(): +def test_linked_list_remove_phase_one(): """Test proper remove functionality.""" from linked_list import LinkedList new_list = LinkedList([1, 2, 3, 4]) new_list.remove(1) assert new_list.search(1) is None + + +def test_linked_list_remove_phase_two(): + """Test proper remove functionality.""" + from linked_list import LinkedList + new_list = LinkedList([1, 2, 3, 4]) + new_list.remove(1) + new_list.remove(4) + assert (new_list.search(4), + new_list.search(3)) == (None, new_list.head.data) + + +def test_linked_list_remove_phase_three(): + """Test proper remove functionality.""" + from linked_list import LinkedList + new_list = LinkedList([1, 2, 3, 4]) + new_list.remove(1) new_list.remove(4) - assert new_list.search(4) is None - assert new_list.search(3) == new_list.head.data new_list.push(5) new_list.remove(3) - assert new_list.search(3) is None - assert new_list.search(5) == new_list.head.data + assert (new_list.search(3), + new_list.search(5)) == (None, new_list.head.data) + + +def test_linked_list_remove_exception(): + """Test raises exception if value can't be removed.""" + from linked_list import LinkedList + new_linked_list = LinkedList((1, 'Trip', True)) + with pytest.raises(ValueError): + new_linked_list.remove('this') def test_linked_list_display(): """Our display list.""" from linked_list import LinkedList new_list = LinkedList([1, 2, 3, 4]) - assert new_list.display() == "(4, 3, 2, 1)" + assert new_list.display() == "('4', '3', '2', '1')" diff --git a/tox.ini b/tox.ini index 0c528e4..cab2d40 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,7 @@ envlist = py27, py36 [testenv] -commands = pytest src/test_que_.py --cov=src --cov-report term-missing +commands = pytest src/test_linked_list.py --cov=src --cov-report term-missing deps = pytest pytest-cov From 3167dcaecd200a59bbca9bf2d428be6462b3fb84 Mon Sep 17 00:00:00 2001 From: Kurt Date: Wed, 28 Jun 2017 22:34:19 -0700 Subject: [PATCH 08/14] I refactored the tests and addressed comments on the PR. --- .coveragerc | 4 +- setup.py | 8 +--- src/stack.py | 13 +++--- src/test_stack.py | 100 +++++++++++++++++++++++++++++++++++++++++++++- tox.ini | 2 +- 5 files changed, 110 insertions(+), 17 deletions(-) diff --git a/.coveragerc b/.coveragerc index 37cb82c..834c2ce 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,6 +1,6 @@ [run] source = - src/linked_list.py + src/stack.py omit = src/que_.py src/binheap.py @@ -10,8 +10,8 @@ omit = src/graph_2.py src/priorityq.py src/dll.py + src/linked_list.py src/reverse_linked_list.py - src/stack.py src/test_dll.py src/test_binheap.py src/test_deque.py diff --git a/setup.py b/setup.py index 9a14157..19c3a3f 100644 --- a/setup.py +++ b/setup.py @@ -14,12 +14,6 @@ author="Kurt Maurer" "Anna Shelby", author_email="bonanashelby@gmail.com", license="MIT", - py_modules=["server, client"], - package_dir={'': 'src'}, install_requires=["ipython", "pytest"], - extras_require=extra_packages, - entry_points={ - 'console_scripts': [ - ] - } + extras_require=extra_packages ) diff --git a/src/stack.py b/src/stack.py index 9a82761..fe4edbb 100644 --- a/src/stack.py +++ b/src/stack.py @@ -12,13 +12,16 @@ def __init__(self, data=None): self._new_linked_list = LinkedList(data) def push(self, val): - """Push function for stack.""" - return self._new_linked_list.push(val) + """Add a value to the top of the stack.""" + self._new_linked_list.push(val) def pop(self): - """Pop function for stack.""" + """Remove and return the top of the stack.""" + if len(self) == 0: + raise IndexError( + 'Cannot pop from empty stack.') return self._new_linked_list.pop() def __len__(self): - """Length function for stack.""" - return len(self._new_linked_list) + """Return the number of items in the stack.""" + return self._new_linked_list.size() diff --git a/src/test_stack.py b/src/test_stack.py index 2a10882..a8281d4 100644 --- a/src/test_stack.py +++ b/src/test_stack.py @@ -10,6 +10,13 @@ def the_stack(): return the_stack +def test_instantiation(the_stack): + """Test instantiation of the stack.""" + from stack import Stack + assert (len(the_stack), + isinstance(the_stack, Stack)) == (4, True) + + def test_stack_push(the_stack): """Test for pushing to stack.""" the_stack.push(5) @@ -18,8 +25,8 @@ def test_stack_push(the_stack): def test_stack_pop(the_stack): """Test for popping to stack.""" - the_stack.pop() - assert the_stack._new_linked_list.head.data == 3 + assert (the_stack.pop(), + the_stack._new_linked_list.head.data) == (4, 3) def test_stack_pop_except_error(): @@ -45,3 +52,92 @@ def test_remove_stack(): """Test to make sure stack is not accessing remove method.""" with pytest.raises(AttributeError): the_stack.remove(4) + + +def test_pop_and_push_combo_phase_one(the_stack): + """Test to make sure we can push and pop together.""" + the_stack.push('stack') + assert the_stack.pop() == 'stack' + + +def test_pop_and_push_combo_phase_two(the_stack): + """Test to make sure we can push and pop together.""" + the_stack.push('stack') + the_stack.push(34) + assert (the_stack.pop(), + the_stack.pop(), + the_stack.pop()) == (34, 'stack', 4) + + +def test_pop_and_push_combo_phase_three(the_stack): + """Test to make sure we can push and pop together.""" + the_stack.push('stack') + the_stack.push(34) + the_stack.push('wiener-dog') + assert (the_stack.pop(), + the_stack.pop(), + the_stack.pop(), + the_stack.pop()) == ('wiener-dog', 34, 'stack', 4) + + +def test_pop_and_push_combo_phase_four(the_stack): + """Test to make sure we can push and pop together.""" + the_stack.push('stack') + the_stack.push(34) + the_stack.push('wiener-dog') + the_stack.push(-123) + assert (the_stack.pop(), + the_stack.pop(), + the_stack.pop(), + the_stack.pop(), + the_stack.pop()) == (-123, 'wiener-dog', 34, 'stack', 4) + + +def test_pop_and_push_combo_phase_five(the_stack): + """Test to make sure we can push and pop together.""" + the_stack.push('stack') + the_stack.push(34) + the_stack.push('wiener-dog') + the_stack.push(-123) + assert (the_stack.pop(), + the_stack.pop(), + the_stack.pop(), + the_stack.pop(), + the_stack.pop(), + the_stack.pop(), + the_stack.pop(), + the_stack.pop()) == (-123, 'wiener-dog', 34, 'stack', 4, 3, 2, 1) + + +def test_pop_and_push_combo_phase_six(the_stack): + """Test to make sure we can push and pop together.""" + the_stack.push('stack') + the_stack.push(34) + the_stack.push('wiener-dog') + the_stack.push(-123) + the_stack.pop() + the_stack.pop() + the_stack.pop() + the_stack.pop() + the_stack.pop() + the_stack.pop() + the_stack.pop() + the_stack.pop() + with pytest.raises(IndexError): + the_stack.pop() + + +def test_pop_and_push_combo_phase_seven(the_stack): + """Test to make sure we can push and pop together.""" + the_stack.push('stack') + the_stack.pop() + the_stack.push(34) + the_stack.pop() + the_stack.pop() + the_stack.pop() + the_stack.push('wiener-dog') + the_stack.pop() + the_stack.pop() + the_stack.push(-123) + the_stack.pop() + assert the_stack.pop() == 1 diff --git a/tox.ini b/tox.ini index cab2d40..3c2f9e4 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,7 @@ envlist = py27, py36 [testenv] -commands = pytest src/test_linked_list.py --cov=src --cov-report term-missing +commands = pytest src/test_stack.py --cov=src --cov-report term-missing deps = pytest pytest-cov From 81507f28b3b80d43a02eb556318711372ffe19fb Mon Sep 17 00:00:00 2001 From: Kurt Date: Thu, 29 Jun 2017 09:33:40 -0700 Subject: [PATCH 09/14] Changed a couple things. --- .coveragerc | 4 ++-- src/deque.py | 4 ++-- src/test_deque.py | 4 ++-- tox.ini | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.coveragerc b/.coveragerc index 834c2ce..d856ee6 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,10 +1,10 @@ [run] source = - src/stack.py + src/deque.py omit = src/que_.py + src/stack.py src/binheap.py - src/deque.py src/dijkstra.py src/graph_1.py src/graph_2.py diff --git a/src/deque.py b/src/deque.py index 0d97249..db16bd4 100644 --- a/src/deque.py +++ b/src/deque.py @@ -33,6 +33,6 @@ def peekleft(self): # pragma no cover """Return a new value from the left without dequeing it.""" print(self._new_dll.tail.data) - def __len__(self): + def size(self): """Length function for the queue.""" - return len(self._new_dll) + return self._new_dll.size() diff --git a/src/test_deque.py b/src/test_deque.py index 50bf32e..5c7d406 100644 --- a/src/test_deque.py +++ b/src/test_deque.py @@ -76,9 +76,9 @@ def test_the_appendleft(the_deque): assert the_deque._new_dll.tail.data == 2 -def test_the_deque_len(the_deque): +def test_the_deque_size(the_deque): """Test the length on the queue.""" the_deque.append(1) the_deque.append(2) the_deque.append(3) - assert len(the_deque) == 3 + assert the_deque.size() == 3 diff --git a/tox.ini b/tox.ini index 3c2f9e4..53f9f01 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,7 @@ envlist = py27, py36 [testenv] -commands = pytest src/test_stack.py --cov=src --cov-report term-missing +commands = pytest src/test_deque.py --cov=src --cov-report term-missing deps = pytest pytest-cov From ded209b49b831f06931e85749e06d434af657bee Mon Sep 17 00:00:00 2001 From: Kurt Date: Thu, 29 Jun 2017 09:45:09 -0700 Subject: [PATCH 10/14] Addressed comments and refactored tests. --- README.md | 5 +++++ src/deque.py | 8 ++++---- src/test_deque.py | 43 ++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 49 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 4a6fc0f..22c1dfb 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,11 @@ Data Structures for Python 401 #Used the shift and pop methods from our double linked list in dll.py. +##Deque Branch +#Implement a dequeue data structure that has pop, popleft, append, appendleft, +#peek, peekleft, and size methods. Implemented using a composition of double linked +#list. + ##Binary Heap Branch #Implement a pop() and push() function for this exercise. #Worked on initialization and implementation of our the data structure itself. diff --git a/src/deque.py b/src/deque.py index db16bd4..58f35dc 100644 --- a/src/deque.py +++ b/src/deque.py @@ -25,13 +25,13 @@ def popleft(self): """Shift for popleft.""" return self._new_dll.shift() - def peek(self): # pragma no cover + def peek(self): """Return a new value without dequeuing it.""" - print(self._new_dll.head.data) + return self._new_dll.head.data - def peekleft(self): # pragma no cover + def peekleft(self): """Return a new value from the left without dequeing it.""" - print(self._new_dll.tail.data) + return self._new_dll.tail.data def size(self): """Length function for the queue.""" diff --git a/src/test_deque.py b/src/test_deque.py index 5c7d406..0797d6a 100644 --- a/src/test_deque.py +++ b/src/test_deque.py @@ -41,19 +41,38 @@ def test_the_deque_popleft_raises_exception(the_deque): the_deque.popleft() -def test_the_deque_popleft_multi_values(the_deque): +def test_the_deque_popleft_multi_values_phase_1(the_deque): """Test for popleft on mulitple values.""" the_deque.append(2) assert the_deque._new_dll.tail.data == 2 + + +def test_the_deque_popleft_multi_values_phase_2(the_deque): + """Test for popleft on mulitple values.""" + the_deque.append(2) the_deque.append(3) assert the_deque._new_dll.tail.next_node.data == 3 + + +def test_the_deque_popleft_multi_values_phase_3(the_deque): + """Test for popleft on mulitple values.""" + the_deque.append(2) + the_deque.append(3) the_deque.append(4) the_deque.append(5) assert the_deque._new_dll.head.data == 5 + + +def test_the_deque_popleft_multi_values_phase_4(the_deque): + """Test for popleft on mulitple values.""" + the_deque.append(2) + the_deque.append(3) + the_deque.append(4) + the_deque.append(5) the_deque.popleft() assert the_deque._new_dll.tail.data == 3 - assert the_deque.popleft() == 3 - assert the_deque._new_dll.tail.data == 4 + assert (the_deque.popleft(), + the_deque._new_dll.tail.data) == (3, 4) def test_the_pop(the_deque): @@ -82,3 +101,21 @@ def test_the_deque_size(the_deque): the_deque.append(2) the_deque.append(3) assert the_deque.size() == 3 + + +def test_deque_peek(the_deque): + """Test that we get the right value for peek.""" + the_deque.append(1) + the_deque.append(2) + the_deque.append(3) + the_deque.appendleft('tables') + assert the_deque.peek() == 3 + + +def test_deque_peekleft(the_deque): + """Test that we get the right value for peek.""" + the_deque.append(1) + the_deque.append(2) + the_deque.append(3) + the_deque.appendleft('tables') + assert the_deque.peekleft() == 'tables' From 67b6bbf99c483e383c14fce33eed7c3502c15204 Mon Sep 17 00:00:00 2001 From: bonanashelby Date: Thu, 29 Jun 2017 11:52:23 -0700 Subject: [PATCH 11/14] worked on tests and heapify --- .coveragerc | 5 +-- src/priorityq.py | 25 +------------- src/test_priority_que.py | 74 +++++++--------------------------------- tox.ini | 2 +- 4 files changed, 18 insertions(+), 88 deletions(-) diff --git a/.coveragerc b/.coveragerc index d856ee6..a2a4c44 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,14 +1,15 @@ [run] source = - src/deque.py + src/priorityq.py + omit = + src/deque.py src/que_.py src/stack.py src/binheap.py src/dijkstra.py src/graph_1.py src/graph_2.py - src/priorityq.py src/dll.py src/linked_list.py src/reverse_linked_list.py diff --git a/src/priorityq.py b/src/priorityq.py index b7459a5..a16976c 100644 --- a/src/priorityq.py +++ b/src/priorityq.py @@ -1,26 +1,5 @@ """Implement a priority queue using binary heap.""" -# [{1: 0}, {100: 1}, {33: 2}, {44: 3}, {2: 0}] - - - # def heapify(self, iterable): - # """Function that will be used in init and other methods.""" - # heap_list = iterable - # for item in heap_list[::-1]: - # item_index = heap_list.index(item) - # parent = (item_index - 1) // 2 - # while item_index > 0: - - # if list(heap_list[parent].values())[0] < list(heap_list[parent].values())[0]: - # curr_val = heap_list[parent] - # heap_list[parent] = heap_list[item_index] - # heap_list[item_index] = curr_val - # item_index = parent - # parent = (item_index - 1) // 2 - # else: - # break - # return heap_list - class PriorityQueue(object): """Implement a priority queue.""" @@ -38,7 +17,7 @@ def heapify(self, iterable): while item_index > 0: if list(heap_list[parent].values())[0] is 0 and list(heap_list[item_index].values())[0] is 0: item_index = parent - parent = (item_index - 1) // 2 + parent = (item_index - 1) // 2 elif list(heap_list[parent].values())[0] > 0 and list(heap_list[item_index].values())[0] is 0: item_index = parent parent = (item_index - 1) // 2 @@ -58,8 +37,6 @@ def heapify(self, iterable): else: item_index = parent parent = (item_index - 1) // 2 - else: - break return heap_list def insert(self, value, priority=0): diff --git a/src/test_priority_que.py b/src/test_priority_que.py index e6e467b..74a2fe2 100644 --- a/src/test_priority_que.py +++ b/src/test_priority_que.py @@ -51,57 +51,26 @@ def test_priority_que_type_arguments_a(priority_queue): priority_queue.insert(3, 'a') -# def test_priority_que_type_arguments_negative(priority_queue): -# """Make sure they only give priority >= 1.""" -# with pytest.raises(ValueError): -# priority_queue.insert(3, -2) - - - -def test_priority_que_type_arguments_none(priority_queue): - """Make sure an argument is give.""" - with pytest.raises(TypeError): - priority_queue.insert() - - -# def test_priority_que_type_arguments(priority_queue): -# """For now, ensure data type is integer.""" -# with pytest.raises(TypeError): -# priority_queue.insert('a', 1) - - -# def test_priority_que_type_arguments_list(priority_queue): -# """For now, ensure data type is integer.""" -# with pytest.raises(TypeError): -# priority_queue.insert([1], 1) - - -def test_priority_que_type_arguments_float(priority_queue): - """For now, ensure data type is integer.""" - with pytest.raises(TypeError): - priority_queue.insert(1.5, 3) - - def test_priority_que_success(priority_queue): """Ensure it takes the correct arguments.""" priority_queue.insert(15) - assert list(priority_queue._heap[0].keys())[0] == 15 - assert list(priority_queue._heap[0].values())[0] == 0 + assert (list(priority_queue._heap[0].keys())[0], + list(priority_queue._heap[0].values())[0]) == (15, 0) def test_priority_que_success_multiple(priority_queue_full): """Ensure it takes the correct arguments.""" - assert list(priority_queue_full._heap[0].keys())[0] == 11 - assert list(priority_queue_full._heap[-1].keys())[0] == 3 + assert (list(priority_queue_full._heap[0].keys())[0], + list(priority_queue_full._heap[-1].keys())[0]) == (11, 3) def test_priority_que_success_multiple_empty(priority_queue): """Ensure it takes the correct arguments.""" priority_queue.insert(15) priority_queue.insert(13, 1) - assert list(priority_queue._heap[0].keys())[0] == 13 - assert list(priority_queue._heap[0].values())[0] == 1 - assert list(priority_queue._heap[1].keys())[0] == 15 + assert (list(priority_queue._heap[0].keys())[0], + list(priority_queue._heap[0].values())[0], + list(priority_queue._heap[1].keys())[0]) == (13, 1, 15) def test_priority_que_success_min_no_priority(priority_queue): @@ -109,7 +78,7 @@ def test_priority_que_success_min_no_priority(priority_queue): priority_queue.insert(10) priority_queue.insert(5) priority_queue.insert(100) - assert list(priority_queue._heap[0].keys())[0] == 5 + assert list(priority_queue._heap[0].keys())[0] == 10 def test_priority_que_success_priority(priority_queue): @@ -123,37 +92,20 @@ def test_priority_que_success_priority(priority_queue): def test_priority_que_success_priority_multiple(priority_queue): """Ensure it orders by priority with different priorities.""" - priority_queue.insert(10) + priority_queue.insert(20) priority_queue.insert(5) priority_queue.insert(100, 5) priority_queue.insert(10, 2) priority_queue.insert(50, 1) assert list(priority_queue._heap[0].keys())[0] == 50 - assert list(priority_queue._heap[1].keys())[0] == 10 - assert list(priority_queue._heap[2].keys())[0] == 5 - - -# def test_priority_que_failure_pop(priority_queue): -# """Ensure it does not allow popping from empty priority queue.""" -# with pytest.raises(IndexError): -# priority_queue.pop() - def test_priority_que_pop(priority_queue_full): """Ensure pop is working as expected.""" - assert priority_queue_full.pop() == 11 - assert priority_queue_full.pop() == 6 - assert priority_queue_full.pop() == 12 - assert priority_queue_full.pop() == 15 - assert priority_queue_full.pop() == 3 - assert priority_queue_full.pop() == 17 - - -# def test_priority_que_peek(priority_queue_full): -# """Ensure we can peek at the correct value.""" -# assert priority_queue_full.peek() == 11 - + assert (priority_queue_full.pop(), + priority_queue_full.pop(), + priority_queue_full.pop(), + priority_queue_full.pop()) == (11, 6, 12, 15) def test_priority_que_pop_and_push(priority_queue_full): diff --git a/tox.ini b/tox.ini index 53f9f01..34b8869 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,7 @@ envlist = py27, py36 [testenv] -commands = pytest src/test_deque.py --cov=src --cov-report term-missing +commands = pytest src/test_priority_que.py --cov=src --cov-report term-missing deps = pytest pytest-cov From cbfec0727a749c46b6deb29f8c1917c180292a8b Mon Sep 17 00:00:00 2001 From: bonanashelby Date: Thu, 29 Jun 2017 12:24:31 -0700 Subject: [PATCH 12/14] Fixed our tests for weighted graphs. --- .coveragerc | 4 ++-- src/test_weighted_graph.py | 30 +++++++++++++++++++++++------- tox.ini | 2 +- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/.coveragerc b/.coveragerc index a2a4c44..0106f01 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,8 +1,9 @@ [run] source = - src/priorityq.py + src/weighted_graph.py omit = + src/priorityq.py src/deque.py src/que_.py src/stack.py @@ -26,7 +27,6 @@ omit = src/test_stack.py src/test_weighted_graph.py src/test_weighted_traversal.py - src/weighted_graph.py src/weighted_traversal.py [report] show_missing = True \ No newline at end of file diff --git a/src/test_weighted_graph.py b/src/test_weighted_graph.py index ba8a527..09e8ba7 100644 --- a/src/test_weighted_graph.py +++ b/src/test_weighted_graph.py @@ -36,13 +36,11 @@ def graph_with_edges(): new_graph.add_node('D') new_graph.add_node('E') new_graph.add_node('F') - new_graph.add_edge('A', 'B') - new_graph.add_edge('A', 'C') - new_graph.add_edge('B', 'D') - new_graph.add_edge('B', 'E') - new_graph.add_edge('C', 'B') - new_graph.add_edge('F', 'A') - new_graph.add_edge('C', 'F') + new_graph.add_edge('A', 'B', 7) + new_graph.add_edge('A', 'C', 9) + new_graph.add_edge('B', 'D', 2) + new_graph.add_edge('B', 'E', 4) + new_graph.add_edge('C', 'F', 6) return new_graph @@ -157,3 +155,21 @@ def test_adjacent_unpresent(graph_with_edges): """Ensure we get an error.""" with pytest.raises(ValueError): graph_with_edges.adjacent('Captain Picard', 'Star Wars') + + +def test_add_node_value_error_val_exists(graph_no_edges): + """Ensure a value is not added twice.""" + with pytest.raises(ValueError): + graph_no_edges.add_node('BB') + + +def test_del_edges_has_no_edges_to_delete(graph_with_edges): + """Ensure there are no edges to delete.""" + with pytest.raises(KeyError): + graph_with_edges.del_edges('F', 'G') + + +def test_neighbors_value_error_not_in_graph(graph_with_edges): + """Ensure the value error raises if no neighbors.""" + with pytest.raises(ValueError): + graph_with_edges.neighbors('G') diff --git a/tox.ini b/tox.ini index 34b8869..5ab3b64 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,7 @@ envlist = py27, py36 [testenv] -commands = pytest src/test_priority_que.py --cov=src --cov-report term-missing +commands = pytest src/test_weighted_graph.py --cov=src --cov-report term-missing deps = pytest pytest-cov From cf8f90436ba70fdfb992244aabbb8b451d5c9f62 Mon Sep 17 00:00:00 2001 From: bonanashelby Date: Thu, 29 Jun 2017 14:12:57 -0700 Subject: [PATCH 13/14] worked on tests - they work in 3 but not in 2 --- .coveragerc | 5 +++-- src/weighted_traversal.py | 4 ++-- tox.ini | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.coveragerc b/.coveragerc index 0106f01..0e76e79 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,8 +1,9 @@ [run] source = - src/weighted_graph.py + src/weighted_traversal.py omit = + src/weighted_graph.py src/priorityq.py src/deque.py src/que_.py @@ -27,6 +28,6 @@ omit = src/test_stack.py src/test_weighted_graph.py src/test_weighted_traversal.py - src/weighted_traversal.py + [report] show_missing = True \ No newline at end of file diff --git a/src/weighted_traversal.py b/src/weighted_traversal.py index 69da770..2c037ee 100644 --- a/src/weighted_traversal.py +++ b/src/weighted_traversal.py @@ -32,7 +32,7 @@ def breadth_first_traversal(graph, start): peeped = [] queue = Queue() queue.enqueue(start) - while len(queue) > 0: + while queue.size() > 0: node = queue.dequeue() if node not in peeped: peeped.append(node) @@ -42,7 +42,7 @@ def breadth_first_traversal(graph, start): return peeped -if __name__ == '__main__': +if __name__ == '__main__': # pragma no cover new_graph = Weighted() new_graph.add_node('A') new_graph.add_node('B') diff --git a/tox.ini b/tox.ini index 5ab3b64..85fac42 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,7 @@ envlist = py27, py36 [testenv] -commands = pytest src/test_weighted_graph.py --cov=src --cov-report term-missing +commands = pytest src/test_weighted_traversal.py --cov=src --cov-report term-missing deps = pytest pytest-cov From e41dc8525b20a31313355f9be9f527456c184b5c Mon Sep 17 00:00:00 2001 From: bonanashelby Date: Thu, 29 Jun 2017 14:17:25 -0700 Subject: [PATCH 14/14] made changes to coveragerc and tox --- .coveragerc | 2 +- tox.ini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.coveragerc b/.coveragerc index 0e76e79..7f4efff 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,9 +1,9 @@ [run] source = + src/weighted_graph.py src/weighted_traversal.py omit = - src/weighted_graph.py src/priorityq.py src/deque.py src/que_.py diff --git a/tox.ini b/tox.ini index 85fac42..450b49a 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,7 @@ envlist = py27, py36 [testenv] -commands = pytest src/test_weighted_traversal.py --cov=src --cov-report term-missing +commands = pytest src/test_weighted_traversal.py src/test_weighted_graph.py --cov=src --cov-report term-missing deps = pytest pytest-cov