From d44d98f32f2a49af0a2700adad46b5ff1f845ec0 Mon Sep 17 00:00:00 2001 From: jordan Date: Mon, 12 Dec 2016 13:22:43 -0800 Subject: [PATCH 01/38] creating first draft of linked list file. --- .gitignore | 1 + setup.py | 15 +++++++++++++++ src/linked_list.py | 24 ++++++++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 setup.py create mode 100644 src/linked_list.py diff --git a/.gitignore b/.gitignore index 72364f9..18d1c99 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ var/ *.egg-info/ .installed.cfg *.egg +data_structures_venv/ # PyInstaller # Usually these files are written by a python script from a template diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..f169825 --- /dev/null +++ b/setup.py @@ -0,0 +1,15 @@ +"""The setup for Mailroom distribution.""" + +from setuptools import setup + +setup( + name='linked_list', + description='Implementation of Linked List.', + version=0.1, + author='Jordan Schatzman, Julien Wilson', + author_email='j.schatzman@outlook.com, julienawilson@gmail.com', + license='MIT', + package_dir={'': 'src'}, + py_modules=['linked_list'], + extras_require={'test': ['pytest', 'pytest-watch', 'pytest-cov', 'tox']}, +) diff --git a/src/linked_list.py b/src/linked_list.py new file mode 100644 index 0000000..5c2d8ab --- /dev/null +++ b/src/linked_list.py @@ -0,0 +1,24 @@ +"""Implementation of Linked_List data type.""" + + +class LinkedList(object): + """Class representation of linked list.""" + + def __init__(self, head_node): + """Instantiate linked list.""" + self.head_node = head_node + self.length = 0 + + def add_node(self, contents): + """Add node to this linked list.""" + self.head_node = Node(contents, self.head_node) + self.length += 1 + + +class Node(object): + """Class representation of linked list node.""" + + def __init__(self, contents, next_node): + """Instantiate linked list node.""" + self.contents = contents + self.next_node = next_node From 34e4d4af9de8a31bf825ad29726ee07e14092d73 Mon Sep 17 00:00:00 2001 From: Julien Wilson Date: Mon, 12 Dec 2016 13:44:48 -0800 Subject: [PATCH 02/38] tests for node and linked_list class creation --- .gitignore | 4 ++++ src/linked_list.py | 4 ++-- src/test_linked_list.py | 16 ++++++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 src/test_linked_list.py diff --git a/.gitignore b/.gitignore index 18d1c99..9e65d1a 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,10 @@ var/ .installed.cfg *.egg data_structures_venv/ +bin/ +lib64 +pyvenv.cfg +share/ # PyInstaller # Usually these files are written by a python script from a template diff --git a/src/linked_list.py b/src/linked_list.py index 5c2d8ab..885ec6c 100644 --- a/src/linked_list.py +++ b/src/linked_list.py @@ -7,9 +7,9 @@ class LinkedList(object): def __init__(self, head_node): """Instantiate linked list.""" self.head_node = head_node - self.length = 0 + self.length = 1 - def add_node(self, contents): + def push(self, contents): """Add node to this linked list.""" self.head_node = Node(contents, self.head_node) self.length += 1 diff --git a/src/test_linked_list.py b/src/test_linked_list.py new file mode 100644 index 0000000..938b3dc --- /dev/null +++ b/src/test_linked_list.py @@ -0,0 +1,16 @@ +"""Tests for linked_list.py.""" + + +def test_node_init(): + """Test node class init.""" + from linked_list import Node + new_node = Node(1, None) + assert new_node.contents == 1 and new_node.next_node is None + + +def test_linkedlist_init(): + """Test for LinkedList init.""" + from linked_list import Node, LinkedList + new_node = Node(34, None) + new_llist = LinkedList(new_node) + assert new_llist.length == 1 From d144503fc3fb26472804d139746f76ee0b760dbd Mon Sep 17 00:00:00 2001 From: jordan Date: Mon, 12 Dec 2016 13:58:36 -0800 Subject: [PATCH 03/38] adding pop and push with testing --- src/linked_list.py | 7 +++++++ src/test_linked_list.py | 22 ++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/linked_list.py b/src/linked_list.py index 885ec6c..94574c8 100644 --- a/src/linked_list.py +++ b/src/linked_list.py @@ -14,6 +14,13 @@ def push(self, contents): self.head_node = Node(contents, self.head_node) self.length += 1 + def pop(self): + """Remove and return the current head node.""" + old_head_node = self.head_node + self.head_node = self.head_node.next_node + self.length -= 1 + return old_head_node + class Node(object): """Class representation of linked list node.""" diff --git a/src/test_linked_list.py b/src/test_linked_list.py index 938b3dc..da7e68b 100644 --- a/src/test_linked_list.py +++ b/src/test_linked_list.py @@ -14,3 +14,25 @@ def test_linkedlist_init(): new_node = Node(34, None) new_llist = LinkedList(new_node) assert new_llist.length == 1 + assert new_llist.head_node == new_node + + +def test_linkedlist_push(): + """Test for LinkedList push.""" + from linked_list import Node, LinkedList + new_node = Node(34, None) + new_llist = LinkedList(new_node) + new_llist.push(1) + assert new_llist.length == 2 + assert new_llist.head_node.contents == 1 + + +def test_linkedlist_pop(): + """Test for LinkedList pop.""" + from linked_list import Node, LinkedList + new_node = Node(34, None) + new_llist = LinkedList(new_node) + new_llist.push(1) + new_llist.pop() + assert new_llist.head_node.contents == 34 + assert new_llist.length == 1 From c306cb1ef6d1c06e192f3ed2cbf27d88839826db Mon Sep 17 00:00:00 2001 From: jordan Date: Mon, 12 Dec 2016 14:16:28 -0800 Subject: [PATCH 04/38] adding search with tests --- src/linked_list.py | 15 +++++++++++++++ src/test_linked_list.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/src/linked_list.py b/src/linked_list.py index 94574c8..59fc308 100644 --- a/src/linked_list.py +++ b/src/linked_list.py @@ -21,6 +21,21 @@ def pop(self): self.length -= 1 return old_head_node + def size(self): + """Return the current size of this linked list.""" + return self.length + + def search(self, search_value): + """Return the node with the searched contents if found.""" + if search_value == self.head_node.contents: + return self.head_node + current_node = self.head_node + while current_node.contents != search_value: + if current_node.next_node is None: + return None + current_node = current_node.next_node + return current_node + class Node(object): """Class representation of linked list node.""" diff --git a/src/test_linked_list.py b/src/test_linked_list.py index da7e68b..bae0404 100644 --- a/src/test_linked_list.py +++ b/src/test_linked_list.py @@ -36,3 +36,32 @@ def test_linkedlist_pop(): new_llist.pop() assert new_llist.head_node.contents == 34 assert new_llist.length == 1 + + +def test_linkedlist_size(): + """Test for LinkedList size.""" + from linked_list import Node, LinkedList + new_node = Node(34, None) + new_llist = LinkedList(new_node) + new_llist.push(1) + new_llist.pop() + new_llist.push('test1') + new_llist.push('test2') + new_llist.push('test3') + new_llist.push('test4') + assert new_llist.size() == 5 + + +def test_linkedlist_search(): + """Test for LinkedList search.""" + from linked_list import Node, LinkedList + new_node = Node(34, None) + new_llist = LinkedList(new_node) + new_llist.push(1) + new_llist.pop() + new_llist.push('test1') + new_llist.push('test2') + new_llist.push('test3') + new_llist.push('test4') + assert new_llist.search('test4').contents == 'test4' + assert new_llist.search('test100') is None From 319d906add0d9b01c8ee17d62fe35508930c81bb Mon Sep 17 00:00:00 2001 From: Julien Wilson Date: Mon, 12 Dec 2016 14:47:56 -0800 Subject: [PATCH 05/38] test for remove() --- src/linked_list.py | 12 ++++++++++++ src/test_linked_list.py | 14 ++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/linked_list.py b/src/linked_list.py index 59fc308..6ca120b 100644 --- a/src/linked_list.py +++ b/src/linked_list.py @@ -36,6 +36,18 @@ def search(self, search_value): current_node = current_node.next_node return current_node + def remove(self, remove_node): + """Remove a node from linked list.""" + if remove_node == self.head_node: + self.head_node = self.head_node.next_node + current_node = self.head_node + while current_node.next_node != remove_node: + if current_node.next_node is None: + raise ValueError("Provided value not in list.") + current_node = current_node.next_node + current_node.next_node = current_node.next_node.next_node + self.length -= 1 + class Node(object): """Class representation of linked list node.""" diff --git a/src/test_linked_list.py b/src/test_linked_list.py index bae0404..be0fa22 100644 --- a/src/test_linked_list.py +++ b/src/test_linked_list.py @@ -65,3 +65,17 @@ def test_linkedlist_search(): new_llist.push('test4') assert new_llist.search('test4').contents == 'test4' assert new_llist.search('test100') is None + + +def test_linkedlist_remove(): + """Test for LinkedList remove.""" + from linked_list import Node, LinkedList + new_node = Node('Test5', None) + new_llist = LinkedList(new_node) + new_llist.push('test4') + new_llist.push('test3') + new_llist.push('test2') + new_llist.push('test1') + new_llist.remove(new_llist.search('test2')) + assert new_llist.size() == 4 + assert new_llist.search('test1').next_node.contents == 'test3' From 3cf09b7412ed13bf626726d5294cea40f980b875 Mon Sep 17 00:00:00 2001 From: Julien Wilson Date: Mon, 12 Dec 2016 15:02:41 -0800 Subject: [PATCH 06/38] finished linked_list and testing with display() --- .gitignore | 2 ++ src/linked_list.py | 9 +++++++++ src/test_linked_list.py | 14 ++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/.gitignore b/.gitignore index 9e65d1a..05b9881 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,8 @@ bin/ lib64 pyvenv.cfg share/ +pip-selfcheck.json +tox.ini # PyInstaller # Usually these files are written by a python script from a template diff --git a/src/linked_list.py b/src/linked_list.py index 6ca120b..ce15be4 100644 --- a/src/linked_list.py +++ b/src/linked_list.py @@ -48,6 +48,15 @@ def remove(self, remove_node): current_node.next_node = current_node.next_node.next_node self.length -= 1 + def display(self): + """Return the tuple of all values in linked list.""" + new_list = [self.head_node.contents] + current_node = self.head_node + while current_node.next_node is not None: + current_node = current_node.next_node + new_list.append(current_node.contents) + return tuple(new_list) + class Node(object): """Class representation of linked list node.""" diff --git a/src/test_linked_list.py b/src/test_linked_list.py index be0fa22..eb91335 100644 --- a/src/test_linked_list.py +++ b/src/test_linked_list.py @@ -79,3 +79,17 @@ def test_linkedlist_remove(): new_llist.remove(new_llist.search('test2')) assert new_llist.size() == 4 assert new_llist.search('test1').next_node.contents == 'test3' + + +def test_linkedlist_display(): + """Test for LinkedList remove.""" + from linked_list import Node, LinkedList + new_node = Node('test5', None) + new_llist = LinkedList(new_node) + new_llist.push('test4') + new_llist.push('test3') + new_llist.push('test2') + new_llist.push('test1') + new_llist2 = LinkedList(new_node) + assert new_llist.display() == ('test1', 'test2', 'test3', 'test4', 'test5') + assert new_llist2.display() == ('test5',) From d8fe87398be81f439d66b86ce8e974ea13ca5314 Mon Sep 17 00:00:00 2001 From: jordan Date: Mon, 12 Dec 2016 16:04:44 -0800 Subject: [PATCH 07/38] adding final tests --- src/linked_list.py | 6 ++++-- src/test_linked_list.py | 13 +++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/linked_list.py b/src/linked_list.py index ce15be4..f0b66db 100644 --- a/src/linked_list.py +++ b/src/linked_list.py @@ -40,10 +40,12 @@ def remove(self, remove_node): """Remove a node from linked list.""" if remove_node == self.head_node: self.head_node = self.head_node.next_node + self.length -= 1 + return None + elif remove_node is None: + raise ValueError("Provided value not in list.") current_node = self.head_node while current_node.next_node != remove_node: - if current_node.next_node is None: - raise ValueError("Provided value not in list.") current_node = current_node.next_node current_node.next_node = current_node.next_node.next_node self.length -= 1 diff --git a/src/test_linked_list.py b/src/test_linked_list.py index eb91335..73089c0 100644 --- a/src/test_linked_list.py +++ b/src/test_linked_list.py @@ -64,6 +64,7 @@ def test_linkedlist_search(): new_llist.push('test3') new_llist.push('test4') assert new_llist.search('test4').contents == 'test4' + assert new_llist.search('test2').contents == 'test2' assert new_llist.search('test100') is None @@ -79,6 +80,18 @@ def test_linkedlist_remove(): new_llist.remove(new_llist.search('test2')) assert new_llist.size() == 4 assert new_llist.search('test1').next_node.contents == 'test3' + new_node2 = Node('Test5', None) + new_llist2 = LinkedList(new_node2) + new_llist2.push('test4') + new_llist2.push('test3') + new_llist2.push('test2') + new_llist2.push('test1') + new_llist2.remove(new_llist2.search('test1')) + assert new_llist2.head_node.contents == 'test2' + try: + new_llist.remove(new_llist.search('blah')) + except ValueError: + assert True def test_linkedlist_display(): From 9682aac563f8e58b37154f9f03f498e7de467cb9 Mon Sep 17 00:00:00 2001 From: Julien Wilson Date: Mon, 12 Dec 2016 16:13:16 -0800 Subject: [PATCH 08/38] gitignore fix --- .gitignore | 2 +- tox.ini | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 tox.ini diff --git a/.gitignore b/.gitignore index 05b9881..3c25e9a 100644 --- a/.gitignore +++ b/.gitignore @@ -29,7 +29,7 @@ lib64 pyvenv.cfg share/ pip-selfcheck.json -tox.ini + # PyInstaller # Usually these files are written by a python script from a template diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..936b849 --- /dev/null +++ b/tox.ini @@ -0,0 +1,7 @@ +[tox] +envlist = py27, py35 + +[testenv] +commands = py.test +deps = + pytest \ No newline at end of file From 3de31ae797fc6a9caa371d2a86c86e18e44a9077 Mon Sep 17 00:00:00 2001 From: jordan Date: Mon, 12 Dec 2016 21:30:13 -0800 Subject: [PATCH 09/38] adding content to r readme --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 46203ab..89d6031 100644 --- a/README.md +++ b/README.md @@ -1 +1,7 @@ -# data_structures \ No newline at end of file +# data_structures + +##### This repository contains python implementations of various +##### fundamental abstract data structures. These include. + + +##### 1. Linked List (src/linked_list.py) \ No newline at end of file From 62beee98befbca1df35c34db4cad81e91d52093f Mon Sep 17 00:00:00 2001 From: jordan Date: Mon, 12 Dec 2016 21:31:42 -0800 Subject: [PATCH 10/38] adding content to readme --- .gitignore | 2 +- tox.ini | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 tox.ini diff --git a/.gitignore b/.gitignore index 05b9881..3c25e9a 100644 --- a/.gitignore +++ b/.gitignore @@ -29,7 +29,7 @@ lib64 pyvenv.cfg share/ pip-selfcheck.json -tox.ini + # PyInstaller # Usually these files are written by a python script from a template diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..936b849 --- /dev/null +++ b/tox.ini @@ -0,0 +1,7 @@ +[tox] +envlist = py27, py35 + +[testenv] +commands = py.test +deps = + pytest \ No newline at end of file From eab105936e03f479ed6ef218420bd571dd0ed721 Mon Sep 17 00:00:00 2001 From: jordan Date: Mon, 12 Dec 2016 21:33:50 -0800 Subject: [PATCH 11/38] adding readme content --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 89d6031..3688940 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # data_structures ##### This repository contains python implementations of various -##### fundamental abstract data structures. These include. +##### fundamental abstract data structures. These include: ##### 1. Linked List (src/linked_list.py) \ No newline at end of file From c3eb6dd52b9eb46f590bc16b972e9a19851f1689 Mon Sep 17 00:00:00 2001 From: jordan Date: Mon, 12 Dec 2016 21:35:42 -0800 Subject: [PATCH 12/38] fixing readme --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 3688940..0ff01d5 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ # data_structures -##### This repository contains python implementations of various -##### fundamental abstract data structures. These include: +##### This repository contains python implementations of various fundamental abstract data structures. These include: ##### 1. Linked List (src/linked_list.py) \ No newline at end of file From c2f92afc094afa344e905d0461e8671413726449 Mon Sep 17 00:00:00 2001 From: Julien Wilson Date: Tue, 13 Dec 2016 13:14:06 -0800 Subject: [PATCH 13/38] updated setup file, testing for stack init and push --- setup.py | 6 +++--- src/stack.py | 37 +++++++++++++++++++++++++++++++++++++ src/test_stack.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 src/stack.py create mode 100644 src/test_stack.py diff --git a/setup.py b/setup.py index f169825..e4ca4e1 100644 --- a/setup.py +++ b/setup.py @@ -3,13 +3,13 @@ from setuptools import setup setup( - name='linked_list', - description='Implementation of Linked List.', + name='data_structures', + description='Implementation of Data Structures.', version=0.1, author='Jordan Schatzman, Julien Wilson', author_email='j.schatzman@outlook.com, julienawilson@gmail.com', license='MIT', package_dir={'': 'src'}, - py_modules=['linked_list'], + py_modules=['linked_list', 'stack'], extras_require={'test': ['pytest', 'pytest-watch', 'pytest-cov', 'tox']}, ) diff --git a/src/stack.py b/src/stack.py new file mode 100644 index 0000000..cfe643b --- /dev/null +++ b/src/stack.py @@ -0,0 +1,37 @@ +"""Implementation of Stack data type.""" + + +class Stack(object): + """Class representation of a stack.""" + + def __init__(self, iterable=None): + """Instantiate stack.""" + self.head_node = None + self.length = 0 + if iterable: + for item in iterable: + self.push(item) + + def push(self, contents): + """Add node to this stack.""" + if self.head_node: + self.head_node = Node(contents, self.head_node) + else: + self.head_node = Node(contents, None) + self.length += 1 + + # def pop(self): + # """Remove and return the current head node.""" + # old_head_node = self.head_node + # self.head_node = self.head_node.next_node + # self.length -= 1 + # return old_head_node + + +class Node(object): + """Class representation of linked list node.""" + + def __init__(self, contents, next_node): + """Instantiate linked list node.""" + self.contents = contents + self.next_node = next_node diff --git a/src/test_stack.py b/src/test_stack.py new file mode 100644 index 0000000..a97d714 --- /dev/null +++ b/src/test_stack.py @@ -0,0 +1,42 @@ +"""Tests for stack.py.""" + + +def test_node_init(): + """Test node class init.""" + from stack import Node + new_node = Node(1, None) + assert new_node.contents == 1 and new_node.next_node is None + + +def test_stack_init(): + """Test for Stack init.""" + from stack import Node, Stack + new_stack = Stack() + assert new_stack.length == 0 + assert new_stack.head_node is None + new_stack2 = Stack([1, 2, 3, 4, 5]) + assert new_stack2.head_node.contents == 5 + assert new_stack2.length == 5 + + +def test_stack_push(): + """Test for Stack push.""" + from stack import Node, Stack + new_stack = Stack() + new_stack.push(34) + assert new_stack.length == 1 + assert new_stack.head_node.contents == 34 + new_stack2 = Stack() + new_stack2.push(None) + assert new_stack2.head_node.contents is None + + +# def test_stack_pop(): +# """Test for Stack pop.""" +# from stack import Node, Stack +# new_node = Node(34, None) +# new_llist = Stack(new_node) +# new_llist.push(1) +# new_llist.pop() +# assert new_llist.head_node.contents == 34 +# assert new_llist.length == 1 \ No newline at end of file From f5783ff0e55787e04f1967388e112727a05a8969 Mon Sep 17 00:00:00 2001 From: jordan Date: Tue, 13 Dec 2016 13:32:29 -0800 Subject: [PATCH 14/38] commiting finals tests for stack --- src/stack.py | 15 +++++++++------ src/test_stack.py | 22 +++++++++++++--------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/stack.py b/src/stack.py index cfe643b..4170624 100644 --- a/src/stack.py +++ b/src/stack.py @@ -20,12 +20,15 @@ def push(self, contents): self.head_node = Node(contents, None) self.length += 1 - # def pop(self): - # """Remove and return the current head node.""" - # old_head_node = self.head_node - # self.head_node = self.head_node.next_node - # self.length -= 1 - # return old_head_node + + def pop(self): + """Remove and return the current head node.""" + if not self.head_node: + raise NameError('Stack is empty, cannot pop!') + old_head_node = self.head_node + self.head_node = self.head_node.next_node + self.length -= 1 + return old_head_node class Node(object): diff --git a/src/test_stack.py b/src/test_stack.py index a97d714..fecf8a3 100644 --- a/src/test_stack.py +++ b/src/test_stack.py @@ -31,12 +31,16 @@ def test_stack_push(): assert new_stack2.head_node.contents is None -# def test_stack_pop(): -# """Test for Stack pop.""" -# from stack import Node, Stack -# new_node = Node(34, None) -# new_llist = Stack(new_node) -# new_llist.push(1) -# new_llist.pop() -# assert new_llist.head_node.contents == 34 -# assert new_llist.length == 1 \ No newline at end of file +def test_stack_pop(): + """Test for Stack pop.""" + from stack import Node, Stack + empty = Stack() + try: + empty.pop() + except NameError: + assert True + new_stack = Stack(('a', 'b', 'c', 'd', 'e')) + assert new_stack.pop().contents == 'e' + assert new_stack.head_node.contents == 'd' + assert new_stack.length == 4 + From 5742fe7a6367214fa235102f63852fd2728ecdc8 Mon Sep 17 00:00:00 2001 From: Julien Wilson Date: Tue, 13 Dec 2016 13:34:08 -0800 Subject: [PATCH 15/38] small linter fix --- src/test_stack.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/test_stack.py b/src/test_stack.py index fecf8a3..3decf09 100644 --- a/src/test_stack.py +++ b/src/test_stack.py @@ -34,13 +34,9 @@ def test_stack_push(): def test_stack_pop(): """Test for Stack pop.""" from stack import Node, Stack - empty = Stack() - try: - empty.pop() - except NameError: - assert True - new_stack = Stack(('a', 'b', 'c', 'd', 'e')) - assert new_stack.pop().contents == 'e' - assert new_stack.head_node.contents == 'd' - assert new_stack.length == 4 - + new_node = Node(34, None) + new_llist = Stack(new_node) + new_llist.push(1) + new_llist.pop() + assert new_llist.head_node.contents == 34 + assert new_llist.length == 1 From ef25a88568ab85444fce92bd65464a75e202a356 Mon Sep 17 00:00:00 2001 From: Julien Wilson Date: Tue, 13 Dec 2016 13:36:27 -0800 Subject: [PATCH 16/38] Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0ff01d5..444adae 100644 --- a/README.md +++ b/README.md @@ -3,4 +3,7 @@ ##### This repository contains python implementations of various fundamental abstract data structures. These include: -##### 1. Linked List (src/linked_list.py) \ No newline at end of file +##### 1. Linked List (src/linked_list.py) + +##### 2. Stack (src/stack.py) + From f816975086e443297b2f7f74b15dca61bfc0327c Mon Sep 17 00:00:00 2001 From: Julien Wilson Date: Wed, 14 Dec 2016 11:58:47 -0800 Subject: [PATCH 17/38] updated linked list and test to allow empty --- src/linked_list.py | 15 +++++-- src/test_linked_list.py | 91 +++++++++++++++-------------------------- 2 files changed, 45 insertions(+), 61 deletions(-) diff --git a/src/linked_list.py b/src/linked_list.py index f0b66db..f21d208 100644 --- a/src/linked_list.py +++ b/src/linked_list.py @@ -4,10 +4,16 @@ class LinkedList(object): """Class representation of linked list.""" - def __init__(self, head_node): + def __init__(self, iterable=None): """Instantiate linked list.""" - self.head_node = head_node - self.length = 1 + self.head_node = None + self.length = 0 + try: + for item in iterable: + self.push(item) + except TypeError: + if iterable: + print("Please only enter iterable values") def push(self, contents): """Add node to this linked list.""" @@ -16,6 +22,9 @@ def push(self, contents): def pop(self): """Remove and return the current head node.""" + if not self.head_node: + print("Linked list is already empty") + return old_head_node = self.head_node self.head_node = self.head_node.next_node self.length -= 1 diff --git a/src/test_linked_list.py b/src/test_linked_list.py index 73089c0..11d1164 100644 --- a/src/test_linked_list.py +++ b/src/test_linked_list.py @@ -4,61 +4,51 @@ def test_node_init(): """Test node class init.""" from linked_list import Node - new_node = Node(1, None) - assert new_node.contents == 1 and new_node.next_node is None + new_node = Node(0, None) + assert new_node.contents == 0 and new_node.next_node is None def test_linkedlist_init(): """Test for LinkedList init.""" - from linked_list import Node, LinkedList - new_node = Node(34, None) - new_llist = LinkedList(new_node) - assert new_llist.length == 1 - assert new_llist.head_node == new_node + from linked_list import LinkedList + new_llist = LinkedList() + assert new_llist.length == 0 + assert new_llist.head_node is None def test_linkedlist_push(): """Test for LinkedList push.""" - from linked_list import Node, LinkedList - new_node = Node(34, None) - new_llist = LinkedList(new_node) - new_llist.push(1) - assert new_llist.length == 2 - assert new_llist.head_node.contents == 1 + from linked_list import LinkedList + new_llist = LinkedList() + new_llist.push("new") + assert new_llist.length == 1 + assert new_llist.head_node.contents == "new" def test_linkedlist_pop(): """Test for LinkedList pop.""" - from linked_list import Node, LinkedList - new_node = Node(34, None) - new_llist = LinkedList(new_node) + from linked_list import LinkedList + new_llist = LinkedList() + new_llist.push(34) new_llist.push(1) - new_llist.pop() + assert new_llist.pop().contents == 1 assert new_llist.head_node.contents == 34 assert new_llist.length == 1 + assert new_llist.pop().contents == 34 + assert new_llist.pop() is None def test_linkedlist_size(): """Test for LinkedList size.""" - from linked_list import Node, LinkedList - new_node = Node(34, None) - new_llist = LinkedList(new_node) - new_llist.push(1) - new_llist.pop() - new_llist.push('test1') - new_llist.push('test2') - new_llist.push('test3') - new_llist.push('test4') - assert new_llist.size() == 5 + from linked_list import LinkedList + new_llist = LinkedList(('test1', 'test2', 'test3', 'test4')) + assert new_llist.size() == 4 def test_linkedlist_search(): """Test for LinkedList search.""" - from linked_list import Node, LinkedList - new_node = Node(34, None) - new_llist = LinkedList(new_node) - new_llist.push(1) - new_llist.pop() + from linked_list import LinkedList + new_llist = LinkedList() new_llist.push('test1') new_llist.push('test2') new_llist.push('test3') @@ -70,24 +60,14 @@ def test_linkedlist_search(): def test_linkedlist_remove(): """Test for LinkedList remove.""" - from linked_list import Node, LinkedList - new_node = Node('Test5', None) - new_llist = LinkedList(new_node) - new_llist.push('test4') - new_llist.push('test3') - new_llist.push('test2') - new_llist.push('test1') + from linked_list import LinkedList + new_llist = LinkedList(('test1', 'test2', 'test3', 'test4')) new_llist.remove(new_llist.search('test2')) - assert new_llist.size() == 4 - assert new_llist.search('test1').next_node.contents == 'test3' - new_node2 = Node('Test5', None) - new_llist2 = LinkedList(new_node2) - new_llist2.push('test4') - new_llist2.push('test3') - new_llist2.push('test2') - new_llist2.push('test1') - new_llist2.remove(new_llist2.search('test1')) - assert new_llist2.head_node.contents == 'test2' + assert new_llist.size() == 3 + assert new_llist.search('test3').next_node.contents == 'test1' + new_llist2 = LinkedList(('test1', 'test2', 'test3', 'test4')) + new_llist2.remove(new_llist2.search('test4')) + assert new_llist2.head_node.contents == 'test3' try: new_llist.remove(new_llist.search('blah')) except ValueError: @@ -96,13 +76,8 @@ def test_linkedlist_remove(): def test_linkedlist_display(): """Test for LinkedList remove.""" - from linked_list import Node, LinkedList - new_node = Node('test5', None) - new_llist = LinkedList(new_node) - new_llist.push('test4') - new_llist.push('test3') - new_llist.push('test2') - new_llist.push('test1') - new_llist2 = LinkedList(new_node) - assert new_llist.display() == ('test1', 'test2', 'test3', 'test4', 'test5') + from linked_list import LinkedList + new_llist = LinkedList(('test1', 'test2', 'test3', 'test4')) + new_llist2 = LinkedList(('test5',)) + assert new_llist.display() == ('test4', 'test3', 'test2', 'test1') assert new_llist2.display() == ('test5',) From 127fd29cc9d67ad7ece0c978a84221af30d514d4 Mon Sep 17 00:00:00 2001 From: Julien Wilson Date: Wed, 14 Dec 2016 12:06:04 -0800 Subject: [PATCH 18/38] test removing tail node --- src/test_linked_list.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test_linked_list.py b/src/test_linked_list.py index 11d1164..9c57c05 100644 --- a/src/test_linked_list.py +++ b/src/test_linked_list.py @@ -68,6 +68,8 @@ def test_linkedlist_remove(): new_llist2 = LinkedList(('test1', 'test2', 'test3', 'test4')) new_llist2.remove(new_llist2.search('test4')) assert new_llist2.head_node.contents == 'test3' + new_llist2.remove(new_llist2.search('test1')) + assert new_llist2.search('test2').next_node is None try: new_llist.remove(new_llist.search('blah')) except ValueError: From ea3d7594d30d0d69586605cc2f62cc80306b9fbb Mon Sep 17 00:00:00 2001 From: jordan Date: Wed, 14 Dec 2016 13:04:10 -0800 Subject: [PATCH 19/38] change stack to use composition --- src/stack.py | 34 +++++++++------------------------- src/test_stack.py | 35 +++++++++++++++++------------------ 2 files changed, 26 insertions(+), 43 deletions(-) diff --git a/src/stack.py b/src/stack.py index 4170624..8b178cf 100644 --- a/src/stack.py +++ b/src/stack.py @@ -1,40 +1,24 @@ """Implementation of Stack data type.""" +from linked_list import LinkedList + class Stack(object): """Class representation of a stack.""" def __init__(self, iterable=None): """Instantiate stack.""" - self.head_node = None - self.length = 0 - if iterable: - for item in iterable: - self.push(item) + self.linked_list = LinkedList(iterable) + self.length = self.linked_list.length + self.head_node = self.linked_list.head_node def push(self, contents): """Add node to this stack.""" - if self.head_node: - self.head_node = Node(contents, self.head_node) - else: - self.head_node = Node(contents, None) - self.length += 1 - + self.linked_list.push(contents) + self.head_node = self.linked_list.head_node def pop(self): """Remove and return the current head node.""" - if not self.head_node: - raise NameError('Stack is empty, cannot pop!') - old_head_node = self.head_node - self.head_node = self.head_node.next_node - self.length -= 1 + old_head_node = self.linked_list.pop() + self.head_node = self.linked_list.head_node return old_head_node - - -class Node(object): - """Class representation of linked list node.""" - - def __init__(self, contents, next_node): - """Instantiate linked list node.""" - self.contents = contents - self.next_node = next_node diff --git a/src/test_stack.py b/src/test_stack.py index 3decf09..8c47874 100644 --- a/src/test_stack.py +++ b/src/test_stack.py @@ -1,30 +1,21 @@ """Tests for stack.py.""" -def test_node_init(): - """Test node class init.""" - from stack import Node - new_node = Node(1, None) - assert new_node.contents == 1 and new_node.next_node is None - - def test_stack_init(): """Test for Stack init.""" - from stack import Node, Stack + from stack import Stack new_stack = Stack() assert new_stack.length == 0 assert new_stack.head_node is None new_stack2 = Stack([1, 2, 3, 4, 5]) assert new_stack2.head_node.contents == 5 - assert new_stack2.length == 5 def test_stack_push(): """Test for Stack push.""" - from stack import Node, Stack + from stack import Stack new_stack = Stack() new_stack.push(34) - assert new_stack.length == 1 assert new_stack.head_node.contents == 34 new_stack2 = Stack() new_stack2.push(None) @@ -33,10 +24,18 @@ def test_stack_push(): def test_stack_pop(): """Test for Stack pop.""" - from stack import Node, Stack - new_node = Node(34, None) - new_llist = Stack(new_node) - new_llist.push(1) - new_llist.pop() - assert new_llist.head_node.contents == 34 - assert new_llist.length == 1 + from stack import Stack + new_stack = Stack(['a', 'b', 'c', 'd']) + assert new_stack.length == 4 + assert new_stack.head_node + assert new_stack.pop() + assert new_stack.head_node.contents == 'c' + empty_stack = Stack() + try: + empty_stack.pop() + except TypeError: + assert True + one_stack = Stack([1]) + assert one_stack.head_node.next_node is None + one_stack.pop() + assert one_stack.head_node is None From 1e1b7110ca1921457befa50f322b63e2ae0bfee2 Mon Sep 17 00:00:00 2001 From: Julien Wilson Date: Wed, 14 Dec 2016 13:44:24 -0800 Subject: [PATCH 20/38] dll init, push and append with tests --- src/dll.py | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ src/test_dll.py | 43 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 src/dll.py create mode 100644 src/test_dll.py diff --git a/src/dll.py b/src/dll.py new file mode 100644 index 0000000..b49d5e1 --- /dev/null +++ b/src/dll.py @@ -0,0 +1,50 @@ +"""Implementation of Doubly Linked List data type.""" + + +class DoublyLinkedList(object): + """Class representation of doubly linked list.""" + + def __init__(self, iterable=None): + """Instantiate linked list.""" + self.head_node = None + self.tail_node = None + self.length = 0 + try: + for item in iterable: + self.push(item) + except TypeError: + if iterable: + print("Please only enter iterable values") + + def push(self, contents): + """Add node to this dll.""" + if self.length == 0: + self.head_node = Node(contents, None, None) + self.tail_node = self.head_node + else: + self.head_node = Node(contents, self.head_node, None) + self.length += 1 + + def append(self, contents): + """Add node to this dll.""" + if self.length == 0: + self.tail_node = Node(contents, None, None) + self.head_node = self.tail_node + else: + self.tail_node = Node(contents, None, self.tail_node) + self.length += 1 + + def pop(self): + """Remove and return the current head node.""" + + + +class Node(object): + """Class representation of doubly linked list node.""" + + def __init__(self, contents, next_node, previous_node): + """Instantiate doubly linked list node.""" + self.contents = contents + self.next_node = next_node + self.previous_node = previous_node + diff --git a/src/test_dll.py b/src/test_dll.py new file mode 100644 index 0000000..b428d99 --- /dev/null +++ b/src/test_dll.py @@ -0,0 +1,43 @@ +"""Tests for dll.py.""" + + +def test_node_init(): + """Test node class init.""" + from dll import Node + new_node = Node(0, None, None) + assert new_node.contents == 0 + assert new_node.next_node is None + assert new_node.previous_node is None + + +def test_dll_init(): + """Test for LinkedList init.""" + from dll import DoublyLinkedList + new_dll = DoublyLinkedList() + assert new_dll.length == 0 + assert new_dll.head_node is None + assert new_dll.tail_node is None + + +def test_linkedlist_push(): + """Test for LinkedList push.""" + from dll import DoublyLinkedList + new_dll = DoublyLinkedList() + new_dll.push("new") + assert new_dll.length == 1 + assert new_dll.head_node.contents == "new" + new_dll.push("second") + assert new_dll.length == 2 + assert new_dll.head_node.contents == "second" + + +def test_linkedlist_append(): + """Test for LinkedList push.""" + from dll import DoublyLinkedList + new_dll = DoublyLinkedList() + new_dll.append("new") + assert new_dll.length == 1 + assert new_dll.tail_node.contents == "new" + new_dll.append("second") + assert new_dll.length == 2 + assert new_dll.tail_node.contents == "second" From 4278df656b6504e88bb51aa92715207ff9c5a1fc Mon Sep 17 00:00:00 2001 From: Julien Wilson Date: Wed, 14 Dec 2016 13:54:22 -0800 Subject: [PATCH 21/38] dll pop with test --- src/dll.py | 10 +++++++--- src/test_dll.py | 7 +++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/dll.py b/src/dll.py index b49d5e1..1cf609c 100644 --- a/src/dll.py +++ b/src/dll.py @@ -36,8 +36,13 @@ def append(self, contents): def pop(self): """Remove and return the current head node.""" - - + if not self.head_node: + print("Linked list is already empty") + return + old_head_node = self.head_node + self.head_node = self.head_node.next_node + self.length -= 1 + return old_head_node class Node(object): """Class representation of doubly linked list node.""" @@ -47,4 +52,3 @@ def __init__(self, contents, next_node, previous_node): self.contents = contents self.next_node = next_node self.previous_node = previous_node - diff --git a/src/test_dll.py b/src/test_dll.py index b428d99..72c9c05 100644 --- a/src/test_dll.py +++ b/src/test_dll.py @@ -41,3 +41,10 @@ def test_linkedlist_append(): new_dll.append("second") assert new_dll.length == 2 assert new_dll.tail_node.contents == "second" + + +def test_linkedlist_pop(): + """Test for LinkedList pop.""" + from dll import DoublyLinkedList + new_dll = DoublyLinkedList([1, 2, 3, 4, 5]) + assert new_dll.pop().contents == 5 From 98b492e4f633e552358e016d04b63fad629e27da Mon Sep 17 00:00:00 2001 From: jordan Date: Wed, 14 Dec 2016 15:07:55 -0800 Subject: [PATCH 22/38] adding dll with tests --- src/dll.py | 40 +++++++++++++++++++ src/test_dll.py | 102 +++++++++++++++++++++++++++++++++++++----------- 2 files changed, 120 insertions(+), 22 deletions(-) diff --git a/src/dll.py b/src/dll.py index 1cf609c..b5532a3 100644 --- a/src/dll.py +++ b/src/dll.py @@ -44,6 +44,46 @@ def pop(self): self.length -= 1 return old_head_node + def shift(self): + """Remove the end of the dll.""" + if not self.tail_node: + print("Linked list is already empty") + return + old_tail_node = self.tail_node + self.tail_node = self.tail_node.previous_node + self.length -= 1 + return old_tail_node + + def remove(self, contents): + """Remove the first node with input contents if it exists.""" + if not self.length: + raise NameError('This dll is empty.') + if self.head_node.contents == contents: + if self.length == 1: + self.head_node = None + self.tail_node = None + else: + self.head_node = self.head_node.next_node + self.head_node.previous_node = None + self.length -= 1 + return + test_node = self.head_node + while test_node.contents != contents and test_node.next_node: + last_node = test_node + test_node = test_node.next_node + if test_node.contents == contents and not test_node.next_node: + last_node.next_node = None + self.tail_node = last_node + self.length -= 1 + return + elif test_node.contents == contents: + last_node.next_node = test_node.next_node + test_node.next_node.previous_node = last_node + self.length -= 1 + return + raise NameError('{0} is not in the dll'.format(contents)) + + class Node(object): """Class representation of doubly linked list node.""" diff --git a/src/test_dll.py b/src/test_dll.py index 72c9c05..c3ba5d5 100644 --- a/src/test_dll.py +++ b/src/test_dll.py @@ -1,5 +1,17 @@ """Tests for dll.py.""" +import pytest + + +@pytest.fixture +def sample_dll(): + """Create testing dlls.""" + from dll import DoublyLinkedList + one_dll = DoublyLinkedList([1]) + empty_dll = DoublyLinkedList() + new_dll = DoublyLinkedList([1, 2, 3, 4, 5]) + return one_dll, empty_dll, new_dll + def test_node_init(): """Test node class init.""" @@ -11,40 +23,86 @@ def test_node_init(): def test_dll_init(): - """Test for LinkedList init.""" + """Test for dll init.""" from dll import DoublyLinkedList - new_dll = DoublyLinkedList() - assert new_dll.length == 0 - assert new_dll.head_node is None - assert new_dll.tail_node is None + one_dll, empty_dll, new_dll = sample_dll() + assert empty_dll.length == 0 + assert empty_dll.head_node is None + assert empty_dll.tail_node is None -def test_linkedlist_push(): - """Test for LinkedList push.""" +def test_dll_push(): + """Test for dll push.""" from dll import DoublyLinkedList - new_dll = DoublyLinkedList() + one_dll, empty_dll, new_dll = sample_dll() new_dll.push("new") - assert new_dll.length == 1 + assert new_dll.length == 6 assert new_dll.head_node.contents == "new" - new_dll.push("second") - assert new_dll.length == 2 - assert new_dll.head_node.contents == "second" + empty_dll.push("second") + assert empty_dll.length == 1 + assert empty_dll.head_node.contents == "second" -def test_linkedlist_append(): - """Test for LinkedList push.""" +def test_dll_append(): + """Test for dll push.""" from dll import DoublyLinkedList - new_dll = DoublyLinkedList() - new_dll.append("new") - assert new_dll.length == 1 - assert new_dll.tail_node.contents == "new" + one_dll, empty_dll, new_dll = sample_dll() + empty_dll.append("new") + assert empty_dll.length == 1 + assert empty_dll.tail_node.contents == "new" + assert empty_dll.head_node.contents == "new" new_dll.append("second") - assert new_dll.length == 2 + assert new_dll.length == 6 assert new_dll.tail_node.contents == "second" + one_dll.append('2') + assert one_dll.length == 2 + assert one_dll.tail_node.contents == '2' + assert one_dll.head_node.contents == 1 -def test_linkedlist_pop(): - """Test for LinkedList pop.""" +def test_dll_pop(): + """Test for dll pop.""" from dll import DoublyLinkedList - new_dll = DoublyLinkedList([1, 2, 3, 4, 5]) + one_dll, empty_dll, new_dll = sample_dll() assert new_dll.pop().contents == 5 + assert new_dll.length == 4 + assert one_dll.pop().contents == 1 + assert one_dll.length == 0 + + +def test_dll_shift(): + """Test for dll shift.""" + from dll import DoublyLinkedList + one_dll, empty_dll, new_dll = sample_dll() + assert new_dll.shift().contents == 1 + assert empty_dll.shift() is None + assert one_dll.shift().contents == 1 + assert one_dll.length == 0 + + +def test_dll_remove(): + """Test for dll remove.""" + from dll import DoublyLinkedList + one_dll, empty_dll, new_dll = sample_dll() + new_dll.remove(3) + assert new_dll.length == 4 + assert new_dll.head_node.next_node.next_node.contents == 2 + assert new_dll.head_node.next_node.next_node.previous_node.contents == 4 + try: + new_dll.remove(10) + except NameError: + assert True + new_dll.remove(5) + assert new_dll.head_node.contents == 4 + new_dll.remove(1) + assert new_dll.tail_node.contents == 2 + empty_dll = DoublyLinkedList() + try: + empty_dll.remove(100) + except NameError: + assert True + one_dll = DoublyLinkedList([1]) + one_dll.remove(1) + assert one_dll.head_node is None + assert one_dll.tail_node is None + assert one_dll.length == 0 From 5e5f97bcef4f7ea9ab672e7bc080134b746ce8ec Mon Sep 17 00:00:00 2001 From: Julien Wilson Date: Thu, 15 Dec 2016 17:44:59 -0800 Subject: [PATCH 23/38] used fixtures in testing --- src/linked_list.py | 36 +++++---- src/test_linked_list.py | 170 ++++++++++++++++++++++++++++------------ 2 files changed, 143 insertions(+), 63 deletions(-) diff --git a/src/linked_list.py b/src/linked_list.py index f21d208..5e7e1c8 100644 --- a/src/linked_list.py +++ b/src/linked_list.py @@ -28,7 +28,7 @@ def pop(self): old_head_node = self.head_node self.head_node = self.head_node.next_node self.length -= 1 - return old_head_node + return old_head_node.contents def size(self): """Return the current size of this linked list.""" @@ -36,14 +36,17 @@ def size(self): def search(self, search_value): """Return the node with the searched contents if found.""" - if search_value == self.head_node.contents: - return self.head_node - current_node = self.head_node - while current_node.contents != search_value: - if current_node.next_node is None: - return None - current_node = current_node.next_node - return current_node + if self.length: + if search_value == self.head_node.contents: + return self.head_node + current_node = self.head_node + while current_node.contents != search_value: + if current_node.next_node is None: + return None + current_node = current_node.next_node + return current_node + else: + return None def remove(self, remove_node): """Remove a node from linked list.""" @@ -61,12 +64,15 @@ def remove(self, remove_node): def display(self): """Return the tuple of all values in linked list.""" - new_list = [self.head_node.contents] - current_node = self.head_node - while current_node.next_node is not None: - current_node = current_node.next_node - new_list.append(current_node.contents) - return tuple(new_list) + if self.length == 0: + return None + else: + new_list = [self.head_node.contents] + current_node = self.head_node + while current_node.next_node is not None: + current_node = current_node.next_node + new_list.append(current_node.contents) + return tuple(new_list) class Node(object): diff --git a/src/test_linked_list.py b/src/test_linked_list.py index 9c57c05..7e57030 100644 --- a/src/test_linked_list.py +++ b/src/test_linked_list.py @@ -1,5 +1,17 @@ """Tests for linked_list.py.""" +import pytest + + +@pytest.fixture +def sample_linked_list(): + """Create testing linked list.""" + from linked_list import LinkedList + one_llist = LinkedList([1]) + empty_llist = LinkedList() + new_llist = LinkedList([1, 2, 3, 4, 5]) + return (one_llist, empty_llist, new_llist) + def test_node_init(): """Test node class init.""" @@ -8,41 +20,72 @@ def test_node_init(): assert new_node.contents == 0 and new_node.next_node is None -def test_linkedlist_init(): - """Test for LinkedList init.""" - from linked_list import LinkedList - new_llist = LinkedList() - assert new_llist.length == 0 - assert new_llist.head_node is None +def test_linkedlist_init_empty_size(): + """Test for empty LinkedList init.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert empty_llist.length == 0 -def test_linkedlist_push(): - """Test for LinkedList push.""" - from linked_list import LinkedList - new_llist = LinkedList() +def test_linkedlist_init_empty_head(): + """Test head in empty LinkedList init.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert empty_llist.head_node is None + + +def test_linkedlist_init_one_size(): + """Test for LinkedList init single item.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert one_llist.length == 1 + + +def test_linkedlist_init_one_head(): + """Test head in LinkedList init single item.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert one_llist.head_node.contents == 1 + + +def test_linkedlist_init_list_size(): + """Test for LinkedList init with list.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert new_llist.length == 5 + + +def test_linkedlist_init_list_head(): + """Test head in LinkedList init with list.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert new_llist.head_node.contents == 5 + + +def test_linkedlist_push_size(): + """Test for LinkedList size after push.""" + one_llist, empty_llist, new_llist = sample_linked_list() + new_llist.push("new") + assert new_llist.length == 6 + + +def test_linkedlist_push_val(): + """Test for LinkedList head value after push.""" + one_llist, empty_llist, new_llist = sample_linked_list() new_llist.push("new") - assert new_llist.length == 1 assert new_llist.head_node.contents == "new" -def test_linkedlist_pop(): - """Test for LinkedList pop.""" - from linked_list import LinkedList - new_llist = LinkedList() - new_llist.push(34) - new_llist.push(1) - assert new_llist.pop().contents == 1 - assert new_llist.head_node.contents == 34 - assert new_llist.length == 1 - assert new_llist.pop().contents == 34 - assert new_llist.pop() is None +def test_linkedlist_pop_empty(): + """Test for Linked List pop on empty.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert empty_llist.pop() is None -def test_linkedlist_size(): - """Test for LinkedList size.""" - from linked_list import LinkedList - new_llist = LinkedList(('test1', 'test2', 'test3', 'test4')) - assert new_llist.size() == 4 +def test_linkedlist_pop_one(): + """Test for Linked List pop on list with one item.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert one_llist.pop() == 1 + + +def test_linkedlist_pop_list(): + """Test for Linked List pop on multi-item list.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert new_llist.pop() == 5 def test_linkedlist_search(): @@ -58,28 +101,59 @@ def test_linkedlist_search(): assert new_llist.search('test100') is None +def test_linkedlist_search_list(): + """Test for LinkedList search list.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert new_llist.search(2).contents == 2 + + +def test_linkedlist_search_empty(): + """Test for LinkedList search empty list.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert empty_llist.search(2) is None + + +def test_linkedlist_search_list_false(): + """Test for LinkedList search list when search value is not in list.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert new_llist.search(100) is None + + def test_linkedlist_remove(): - """Test for LinkedList remove.""" - from linked_list import LinkedList - new_llist = LinkedList(('test1', 'test2', 'test3', 'test4')) - new_llist.remove(new_llist.search('test2')) - assert new_llist.size() == 3 - assert new_llist.search('test3').next_node.contents == 'test1' - new_llist2 = LinkedList(('test1', 'test2', 'test3', 'test4')) - new_llist2.remove(new_llist2.search('test4')) - assert new_llist2.head_node.contents == 'test3' - new_llist2.remove(new_llist2.search('test1')) - assert new_llist2.search('test2').next_node is None - try: - new_llist.remove(new_llist.search('blah')) - except ValueError: - assert True + """Test LinkedList remove() on a list.""" + one_llist, empty_llist, new_llist = sample_linked_list() + new_llist.remove(new_llist.search(3)) + assert new_llist.search(3) is None + assert new_llist.search(4).next_node.contents == 2 + + +def test_linkedlist_remove_head(): + """Test LinkedList remove() the head on a list.""" + one_llist, empty_llist, new_llist = sample_linked_list() + new_llist.remove(new_llist.search(5)) + assert new_llist.head_node.contents == 4 + + +def test_linkedlist_remove_empty(): + """Test LinkedList remove() on a list list.""" + one_llist, empty_llist, new_llist = sample_linked_list() + with pytest.raises(ValueError): + new_llist.remove(new_llist.search(100)) def test_linkedlist_display(): - """Test for LinkedList remove.""" - from linked_list import LinkedList - new_llist = LinkedList(('test1', 'test2', 'test3', 'test4')) - new_llist2 = LinkedList(('test5',)) - assert new_llist.display() == ('test4', 'test3', 'test2', 'test1') - assert new_llist2.display() == ('test5',) + """Test for LinkedList display.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert new_llist.display() == (5, 4, 3, 2, 1) + + +def test_linkedlist_display_one(): + """Test for LinkedList display on single item list.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert one_llist.display() == (1,) + + +def test_linkedlist_display_empty(): + """Test for LinkedList display on empty list.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert empty_llist.display() is None From 35ca79d2a8a064fa5008cab215fc2e5e499e5c0e Mon Sep 17 00:00:00 2001 From: Julien Wilson Date: Thu, 15 Dec 2016 17:57:34 -0800 Subject: [PATCH 24/38] changed error messages to actual error raising --- src/linked_list.py | 5 ++--- src/test_linked_list.py | 16 ++-------------- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/src/linked_list.py b/src/linked_list.py index 5e7e1c8..d83b18b 100644 --- a/src/linked_list.py +++ b/src/linked_list.py @@ -13,7 +13,7 @@ def __init__(self, iterable=None): self.push(item) except TypeError: if iterable: - print("Please only enter iterable values") + raise TypeError("Please only enter iterable values") def push(self, contents): """Add node to this linked list.""" @@ -23,8 +23,7 @@ def push(self, contents): def pop(self): """Remove and return the current head node.""" if not self.head_node: - print("Linked list is already empty") - return + raise AttributeError("List is empty") old_head_node = self.head_node self.head_node = self.head_node.next_node self.length -= 1 diff --git a/src/test_linked_list.py b/src/test_linked_list.py index 7e57030..9ca019d 100644 --- a/src/test_linked_list.py +++ b/src/test_linked_list.py @@ -73,7 +73,8 @@ def test_linkedlist_push_val(): def test_linkedlist_pop_empty(): """Test for Linked List pop on empty.""" one_llist, empty_llist, new_llist = sample_linked_list() - assert empty_llist.pop() is None + with pytest.raises(AttributeError): + empty_llist.pop() def test_linkedlist_pop_one(): @@ -88,19 +89,6 @@ def test_linkedlist_pop_list(): assert new_llist.pop() == 5 -def test_linkedlist_search(): - """Test for LinkedList search.""" - from linked_list import LinkedList - new_llist = LinkedList() - new_llist.push('test1') - new_llist.push('test2') - new_llist.push('test3') - new_llist.push('test4') - assert new_llist.search('test4').contents == 'test4' - assert new_llist.search('test2').contents == 'test2' - assert new_llist.search('test100') is None - - def test_linkedlist_search_list(): """Test for LinkedList search list.""" one_llist, empty_llist, new_llist = sample_linked_list() From d52fc51575914658830ec4ae28247456350f78d5 Mon Sep 17 00:00:00 2001 From: jordan Date: Thu, 15 Dec 2016 18:03:48 -0800 Subject: [PATCH 25/38] redoing tests --- src/linked_list.py | 41 ++++++---- src/test_linked_list.py | 177 ++++++++++++++++++++++++++-------------- src/test_stack.py | 107 +++++++++++++++++------- 3 files changed, 217 insertions(+), 108 deletions(-) diff --git a/src/linked_list.py b/src/linked_list.py index f21d208..af36cc5 100644 --- a/src/linked_list.py +++ b/src/linked_list.py @@ -13,7 +13,7 @@ def __init__(self, iterable=None): self.push(item) except TypeError: if iterable: - print("Please only enter iterable values") + return "Please only enter iterable values" def push(self, contents): """Add node to this linked list.""" @@ -23,12 +23,11 @@ def push(self, contents): def pop(self): """Remove and return the current head node.""" if not self.head_node: - print("Linked list is already empty") - return + return "Linked list is already empty" old_head_node = self.head_node self.head_node = self.head_node.next_node self.length -= 1 - return old_head_node + return old_head_node.contents def size(self): """Return the current size of this linked list.""" @@ -36,14 +35,17 @@ def size(self): def search(self, search_value): """Return the node with the searched contents if found.""" - if search_value == self.head_node.contents: - return self.head_node - current_node = self.head_node - while current_node.contents != search_value: - if current_node.next_node is None: - return None - current_node = current_node.next_node - return current_node + if self.length: + if search_value == self.head_node.contents: + return self.head_node + current_node = self.head_node + while current_node.contents != search_value: + if current_node.next_node is None: + return None + current_node = current_node.next_node + return current_node + else: + return None def remove(self, remove_node): """Remove a node from linked list.""" @@ -61,12 +63,15 @@ def remove(self, remove_node): def display(self): """Return the tuple of all values in linked list.""" - new_list = [self.head_node.contents] - current_node = self.head_node - while current_node.next_node is not None: - current_node = current_node.next_node - new_list.append(current_node.contents) - return tuple(new_list) + if self.length == 0: + return None + else: + new_list = [self.head_node.contents] + current_node = self.head_node + while current_node.next_node is not None: + current_node = current_node.next_node + new_list.append(current_node.contents) + return tuple(new_list) class Node(object): diff --git a/src/test_linked_list.py b/src/test_linked_list.py index 9c57c05..4f678c9 100644 --- a/src/test_linked_list.py +++ b/src/test_linked_list.py @@ -1,5 +1,17 @@ """Tests for linked_list.py.""" +import pytest + + +@pytest.fixture +def sample_linked_list(): + """Create testing linked list.""" + from linked_list import LinkedList + one_llist = LinkedList([1]) + empty_llist = LinkedList() + new_llist = LinkedList([1, 2, 3, 4, 5]) + return (one_llist, empty_llist, new_llist) + def test_node_init(): """Test node class init.""" @@ -8,78 +20,121 @@ def test_node_init(): assert new_node.contents == 0 and new_node.next_node is None -def test_linkedlist_init(): - """Test for LinkedList init.""" - from linked_list import LinkedList - new_llist = LinkedList() - assert new_llist.length == 0 - assert new_llist.head_node is None +def test_linkedlist_init_empty_size(): + """Test for empty LinkedList init.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert empty_llist.length == 0 -def test_linkedlist_push(): - """Test for LinkedList push.""" - from linked_list import LinkedList - new_llist = LinkedList() +def test_linkedlist_init_empty_head(): + """Test head in empty LinkedList init.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert empty_llist.head_node is None + + +def test_linkedlist_init_one_size(): + """Test for LinkedList init single item.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert one_llist.length == 1 + + +def test_linkedlist_init_one_head(): + """Test head in LinkedList init single item.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert one_llist.head_node.contents == 1 + + +def test_linkedlist_init_list_size(): + """Test for LinkedList init with list.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert new_llist.length == 5 + + +def test_linkedlist_init_list_head(): + """Test head in LinkedList init with list.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert new_llist.head_node.contents == 5 + + +def test_linkedlist_push_size(): + """Test for LinkedList size after push.""" + one_llist, empty_llist, new_llist = sample_linked_list() + new_llist.push("new") + assert new_llist.length == 6 + + +def test_linkedlist_push_val(): + """Test for LinkedList head value after push.""" + one_llist, empty_llist, new_llist = sample_linked_list() new_llist.push("new") - assert new_llist.length == 1 assert new_llist.head_node.contents == "new" -def test_linkedlist_pop(): - """Test for LinkedList pop.""" - from linked_list import LinkedList - new_llist = LinkedList() - new_llist.push(34) - new_llist.push(1) - assert new_llist.pop().contents == 1 - assert new_llist.head_node.contents == 34 - assert new_llist.length == 1 - assert new_llist.pop().contents == 34 - assert new_llist.pop() is None - - -def test_linkedlist_size(): - """Test for LinkedList size.""" - from linked_list import LinkedList - new_llist = LinkedList(('test1', 'test2', 'test3', 'test4')) - assert new_llist.size() == 4 +def test_linkedlist_pop_one(): + """Test for Linked List pop on list with one item.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert one_llist.pop() == 1 -def test_linkedlist_search(): - """Test for LinkedList search.""" - from linked_list import LinkedList - new_llist = LinkedList() - new_llist.push('test1') - new_llist.push('test2') - new_llist.push('test3') - new_llist.push('test4') - assert new_llist.search('test4').contents == 'test4' - assert new_llist.search('test2').contents == 'test2' - assert new_llist.search('test100') is None +def test_linkedlist_pop_list(): + """Test for Linked List pop on multi-item list.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert new_llist.pop() == 5 + + +def test_linkedlist_search_list(): + """Test for LinkedList search list.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert new_llist.search(2).contents == 2 + + +def test_linkedlist_search_empty(): + """Test for LinkedList search empty list.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert empty_llist.search(2) is None + + +def test_linkedlist_search_list_false(): + """Test for LinkedList search list when search value is not in list.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert new_llist.search(100) is None def test_linkedlist_remove(): - """Test for LinkedList remove.""" - from linked_list import LinkedList - new_llist = LinkedList(('test1', 'test2', 'test3', 'test4')) - new_llist.remove(new_llist.search('test2')) - assert new_llist.size() == 3 - assert new_llist.search('test3').next_node.contents == 'test1' - new_llist2 = LinkedList(('test1', 'test2', 'test3', 'test4')) - new_llist2.remove(new_llist2.search('test4')) - assert new_llist2.head_node.contents == 'test3' - new_llist2.remove(new_llist2.search('test1')) - assert new_llist2.search('test2').next_node is None - try: - new_llist.remove(new_llist.search('blah')) - except ValueError: - assert True + """Test LinkedList remove() on a list.""" + one_llist, empty_llist, new_llist = sample_linked_list() + new_llist.remove(new_llist.search(3)) + assert new_llist.search(3) is None + assert new_llist.search(4).next_node.contents == 2 + + +def test_linkedlist_remove_head(): + """Test LinkedList remove() the head on a list.""" + one_llist, empty_llist, new_llist = sample_linked_list() + new_llist.remove(new_llist.search(5)) + assert new_llist.head_node.contents == 4 + + +def test_linkedlist_remove_empty(): + """Test LinkedList remove() on a list list.""" + one_llist, empty_llist, new_llist = sample_linked_list() + with pytest.raises(ValueError): + new_llist.remove(new_llist.search(100)) def test_linkedlist_display(): - """Test for LinkedList remove.""" - from linked_list import LinkedList - new_llist = LinkedList(('test1', 'test2', 'test3', 'test4')) - new_llist2 = LinkedList(('test5',)) - assert new_llist.display() == ('test4', 'test3', 'test2', 'test1') - assert new_llist2.display() == ('test5',) + """Test for LinkedList display.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert new_llist.display() == (5, 4, 3, 2, 1) + + +def test_linkedlist_display_one(): + """Test for LinkedList display on single item list.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert one_llist.display() == (1,) + + +def test_linkedlist_display_empty(): + """Test for LinkedList display on empty list.""" + one_llist, empty_llist, new_llist = sample_linked_list() + assert empty_llist.display() is None diff --git a/src/test_stack.py b/src/test_stack.py index 8c47874..d13615f 100644 --- a/src/test_stack.py +++ b/src/test_stack.py @@ -1,41 +1,90 @@ """Tests for stack.py.""" +import pytest -def test_stack_init(): - """Test for Stack init.""" + +@pytest.fixture +def sample_stack(): + """Create testing dlls.""" from stack import Stack - new_stack = Stack() - assert new_stack.length == 0 - assert new_stack.head_node is None - new_stack2 = Stack([1, 2, 3, 4, 5]) - assert new_stack2.head_node.contents == 5 + one_stack = Stack([1]) + empty_stack = Stack() + new_stack = Stack([1, 2, 3, 4, 5]) + return one_stack, empty_stack, new_stack -def test_stack_push(): - """Test for Stack push.""" - from stack import Stack - new_stack = Stack() +def test_stack_empty_length(): + """Test for empty stack length.""" + one_stack, empty_stack, new_stack = sample_stack() + assert empty_stack.length == 0 + + +def test_stack_init_length_head_node(): + """Test for empty Stack head node.""" + one_stack, empty_stack, new_stack = sample_stack() + assert empty_stack.head_node is None + + +def test_stack_new_length(): + """Test for new Stack length.""" + one_stack, empty_stack, new_stack = sample_stack() + assert new_stack.length == 5 + + +def test_stack_new_contents(): + """Test for new stack head node contents.""" + one_stack, empty_stack, new_stack = sample_stack() + assert new_stack.head_node.contents == 5 + + +def test_stack_new_push(): + """Test for new stack head node contents.""" + one_stack, empty_stack, new_stack = sample_stack() new_stack.push(34) assert new_stack.head_node.contents == 34 - new_stack2 = Stack() - new_stack2.push(None) - assert new_stack2.head_node.contents is None -def test_stack_pop(): - """Test for Stack pop.""" - from stack import Stack - new_stack = Stack(['a', 'b', 'c', 'd']) - assert new_stack.length == 4 - assert new_stack.head_node - assert new_stack.pop() - assert new_stack.head_node.contents == 'c' - empty_stack = Stack() - try: - empty_stack.pop() - except TypeError: - assert True - one_stack = Stack([1]) - assert one_stack.head_node.next_node is None +def test_stack_one_push(): + """Test for new stack head node contents.""" + one_stack, empty_stack, new_stack = sample_stack() + one_stack.push(34) + assert one_stack.head_node.contents == 34 + + +def test_stack_empty_push(): + """Test for empty stack head node contents.""" + one_stack, empty_stack, new_stack = sample_stack() + empty_stack.push(34) + assert empty_stack.head_node.contents == 34 + + +def test_stack_new_pop(): + """Test that pop the new stack returns 5.""" + one_stack, empty_stack, new_stack = sample_stack() + assert new_stack.pop() == 5 + + +def test_stack_new_pop_length(): + """Test that pop the new stack decreases length.""" + one_stack, empty_stack, new_stack = sample_stack() + assert new_stack.pop() == 5 + + +def test_stack_one_pop(): + """Test that pop of one stack returns 1.""" + one_stack, empty_stack, new_stack = sample_stack() + assert one_stack.pop() == 1 + + +def test_stack_one_pop_contents(): + """Test that pop of one stack behaves as expeted.""" + one_stack, empty_stack, new_stack = sample_stack() one_stack.pop() assert one_stack.head_node is None + + +def tst_stack_empty_pop(): + """Test that pop empty stack throws correct error.""" + one_stack, empty_stack, new_stack = sample_stack() + with pytest.raises(TypeError): + empty_stack.pop() From abd7ea5bae8c97ef77cf0daf56eed0df3de88b5c Mon Sep 17 00:00:00 2001 From: Julien Wilson Date: Thu, 15 Dec 2016 18:30:57 -0800 Subject: [PATCH 26/38] update terminology on stack pop --- src/stack.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stack.py b/src/stack.py index 8b178cf..7c6e988 100644 --- a/src/stack.py +++ b/src/stack.py @@ -19,6 +19,6 @@ def push(self, contents): def pop(self): """Remove and return the current head node.""" - old_head_node = self.linked_list.pop() + old_head_node_value = self.linked_list.pop() self.head_node = self.linked_list.head_node - return old_head_node + return old_head_node_value From 50a6f3015a0a3ed461f560a87fb92047c45fff73 Mon Sep 17 00:00:00 2001 From: jordan Date: Thu, 15 Dec 2016 19:21:01 -0800 Subject: [PATCH 27/38] improving test file format --- src/test_stack.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test_stack.py b/src/test_stack.py index d13615f..47fd7a2 100644 --- a/src/test_stack.py +++ b/src/test_stack.py @@ -5,7 +5,7 @@ @pytest.fixture def sample_stack(): - """Create testing dlls.""" + """Create testing stacks.""" from stack import Stack one_stack = Stack([1]) empty_stack = Stack() @@ -19,14 +19,14 @@ def test_stack_empty_length(): assert empty_stack.length == 0 -def test_stack_init_length_head_node(): - """Test for empty Stack head node.""" +def test_stack_empty_head_node(): + """Test for empty stack head node.""" one_stack, empty_stack, new_stack = sample_stack() assert empty_stack.head_node is None def test_stack_new_length(): - """Test for new Stack length.""" + """Test for new stack length.""" one_stack, empty_stack, new_stack = sample_stack() assert new_stack.length == 5 From 6ed3652b1aa279cc6eed979e3d82c52801010bd9 Mon Sep 17 00:00:00 2001 From: Julien Wilson Date: Tue, 27 Dec 2016 13:41:14 -0800 Subject: [PATCH 28/38] llist updates --- src/linked_list.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/linked_list.py b/src/linked_list.py index d83b18b..230c1bc 100644 --- a/src/linked_list.py +++ b/src/linked_list.py @@ -23,7 +23,7 @@ def push(self, contents): def pop(self): """Remove and return the current head node.""" if not self.head_node: - raise AttributeError("List is empty") + raise IndexError("List is empty") old_head_node = self.head_node self.head_node = self.head_node.next_node self.length -= 1 @@ -71,7 +71,7 @@ def display(self): while current_node.next_node is not None: current_node = current_node.next_node new_list.append(current_node.contents) - return tuple(new_list) + return str(tuple(new_list)) class Node(object): From e085be0e43dd48997c2304c7d2fc9a6cd132bfd6 Mon Sep 17 00:00:00 2001 From: Julien Wilson Date: Tue, 27 Dec 2016 13:46:57 -0800 Subject: [PATCH 29/38] remove() edits --- src/linked_list.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/linked_list.py b/src/linked_list.py index 230c1bc..1b2bb8d 100644 --- a/src/linked_list.py +++ b/src/linked_list.py @@ -23,7 +23,7 @@ def push(self, contents): def pop(self): """Remove and return the current head node.""" if not self.head_node: - raise IndexError("List is empty") + raise IndexError("List is already empty") old_head_node = self.head_node self.head_node = self.head_node.next_node self.length -= 1 @@ -53,8 +53,8 @@ def remove(self, remove_node): self.head_node = self.head_node.next_node self.length -= 1 return None - elif remove_node is None: - raise ValueError("Provided value not in list.") + elif self.lenth == 0: + raise IndexError("The list is already empty.") current_node = self.head_node while current_node.next_node != remove_node: current_node = current_node.next_node From 68e2840b4f526e3625bae8e710766eca6da7c51d Mon Sep 17 00:00:00 2001 From: jordan Date: Tue, 27 Dec 2016 13:49:43 -0800 Subject: [PATCH 30/38] fix typo --- src/linked_list.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/linked_list.py b/src/linked_list.py index 1b2bb8d..9dc68ca 100644 --- a/src/linked_list.py +++ b/src/linked_list.py @@ -53,7 +53,7 @@ def remove(self, remove_node): self.head_node = self.head_node.next_node self.length -= 1 return None - elif self.lenth == 0: + elif self.length == 0: raise IndexError("The list is already empty.") current_node = self.head_node while current_node.next_node != remove_node: From fdf4a2c055e1697a1abccf382709c54aeef6ae6d Mon Sep 17 00:00:00 2001 From: jordan Date: Tue, 27 Dec 2016 15:31:41 -0800 Subject: [PATCH 31/38] fix remove --- src/linked_list.py | 26 ++++++++----- src/test_linked_list.py | 86 ++++++++++++++++++----------------------- 2 files changed, 54 insertions(+), 58 deletions(-) diff --git a/src/linked_list.py b/src/linked_list.py index 9dc68ca..566d970 100644 --- a/src/linked_list.py +++ b/src/linked_list.py @@ -47,19 +47,20 @@ def search(self, search_value): else: return None - def remove(self, remove_node): + def remove(self, remove_value): """Remove a node from linked list.""" - if remove_node == self.head_node: - self.head_node = self.head_node.next_node - self.length -= 1 - return None - elif self.length == 0: - raise IndexError("The list is already empty.") + last_node = None current_node = self.head_node - while current_node.next_node != remove_node: + while current_node: + if current_node.contents == remove_value: + if last_node: + last_node.next_node = current_node.next_node + else: + self.head_node = current_node.next_node + self.length -= 1 + return + last_node = current_node current_node = current_node.next_node - current_node.next_node = current_node.next_node.next_node - self.length -= 1 def display(self): """Return the tuple of all values in linked list.""" @@ -81,3 +82,8 @@ def __init__(self, contents, next_node): """Instantiate linked list node.""" self.contents = contents self.next_node = next_node + + +test = LinkedList([4,3,'blah',1]) +test.remove(1) +print (test.display()) \ No newline at end of file diff --git a/src/test_linked_list.py b/src/test_linked_list.py index 9ca019d..27804f1 100644 --- a/src/test_linked_list.py +++ b/src/test_linked_list.py @@ -10,7 +10,7 @@ def sample_linked_list(): one_llist = LinkedList([1]) empty_llist = LinkedList() new_llist = LinkedList([1, 2, 3, 4, 5]) - return (one_llist, empty_llist, new_llist) + return (empty_llist, one_llist, new_llist) def test_node_init(): @@ -20,94 +20,84 @@ def test_node_init(): assert new_node.contents == 0 and new_node.next_node is None -def test_linkedlist_init_empty_size(): +def test_linkedlist_init_empty_size(sample_linked_list): """Test for empty LinkedList init.""" - one_llist, empty_llist, new_llist = sample_linked_list() - assert empty_llist.length == 0 + assert sample_linked_list[0].length == 0 -def test_linkedlist_init_empty_head(): +def test_linkedlist_init_empty_head(sample_linked_list): """Test head in empty LinkedList init.""" - one_llist, empty_llist, new_llist = sample_linked_list() - assert empty_llist.head_node is None + assert sample_linked_list[0].head_node is None -def test_linkedlist_init_one_size(): +def test_linkedlist_init_one_size(sample_linked_list): """Test for LinkedList init single item.""" - one_llist, empty_llist, new_llist = sample_linked_list() - assert one_llist.length == 1 + assert sample_linked_list[1].length == 1 -def test_linkedlist_init_one_head(): +def test_linkedlist_init_one_head(sample_linked_list): """Test head in LinkedList init single item.""" - one_llist, empty_llist, new_llist = sample_linked_list() - assert one_llist.head_node.contents == 1 + assert sample_linked_list[1].head_node.contents == 1 -def test_linkedlist_init_list_size(): +def test_linkedlist_init_list_size(sample_linked_list): """Test for LinkedList init with list.""" - one_llist, empty_llist, new_llist = sample_linked_list() - assert new_llist.length == 5 + assert sample_linked_list[2].length == 5 -def test_linkedlist_init_list_head(): +def test_linkedlist_init_list_head(sample_linked_list): """Test head in LinkedList init with list.""" - one_llist, empty_llist, new_llist = sample_linked_list() - assert new_llist.head_node.contents == 5 + assert sample_linked_list[2].head_node.contents == 5 -def test_linkedlist_push_size(): +def test_linkedlist_push_size(sample_linked_list): """Test for LinkedList size after push.""" - one_llist, empty_llist, new_llist = sample_linked_list() - new_llist.push("new") - assert new_llist.length == 6 + test_linkedlist = sample_linked_list[2] + test_linkedlist.push("new") + assert test_linkedlist.length == 6 -def test_linkedlist_push_val(): +def test_linkedlist_push_val(sample_linked_list): """Test for LinkedList head value after push.""" - one_llist, empty_llist, new_llist = sample_linked_list() - new_llist.push("new") - assert new_llist.head_node.contents == "new" + test_linkedlist = sample_linked_list[2] + test_linkedlist.push("new") + assert test_linkedlist.head_node.contents == 'new' -def test_linkedlist_pop_empty(): +def test_linkedlist_pop_empty(sample_linked_list): """Test for Linked List pop on empty.""" - one_llist, empty_llist, new_llist = sample_linked_list() - with pytest.raises(AttributeError): - empty_llist.pop() + with pytest.raises(IndexError): + sample_linked_list[0].pop() -def test_linkedlist_pop_one(): +def tesst_linkedlist_pop_one(sample_linked_list): """Test for Linked List pop on list with one item.""" - one_llist, empty_llist, new_llist = sample_linked_list() - assert one_llist.pop() == 1 + assert sample_linked_list[1].pop() == 1 -def test_linkedlist_pop_list(): +def test_linkedlist_pop_list(sample_linked_list): """Test for Linked List pop on multi-item list.""" - one_llist, empty_llist, new_llist = sample_linked_list() - assert new_llist.pop() == 5 + assert sample_linked_list[2].pop() == 5 -def test_linkedlist_search_list(): +def test_linkedlist_search_list(sample_linked_list): """Test for LinkedList search list.""" - one_llist, empty_llist, new_llist = sample_linked_list() - assert new_llist.search(2).contents == 2 + assert sample_linked_list[2].search(2).contents == 2 -def test_linkedlist_search_empty(): +def tst_linkedlist_search_empty(): """Test for LinkedList search empty list.""" one_llist, empty_llist, new_llist = sample_linked_list() assert empty_llist.search(2) is None -def test_linkedlist_search_list_false(): +def tst_linkedlist_search_list_false(): """Test for LinkedList search list when search value is not in list.""" one_llist, empty_llist, new_llist = sample_linked_list() assert new_llist.search(100) is None -def test_linkedlist_remove(): +def tst_linkedlist_remove(): """Test LinkedList remove() on a list.""" one_llist, empty_llist, new_llist = sample_linked_list() new_llist.remove(new_llist.search(3)) @@ -115,33 +105,33 @@ def test_linkedlist_remove(): assert new_llist.search(4).next_node.contents == 2 -def test_linkedlist_remove_head(): +def tst_linkedlist_remove_head(): """Test LinkedList remove() the head on a list.""" one_llist, empty_llist, new_llist = sample_linked_list() new_llist.remove(new_llist.search(5)) assert new_llist.head_node.contents == 4 -def test_linkedlist_remove_empty(): +def tst_linkedlist_remove_empty(): """Test LinkedList remove() on a list list.""" one_llist, empty_llist, new_llist = sample_linked_list() with pytest.raises(ValueError): new_llist.remove(new_llist.search(100)) -def test_linkedlist_display(): +def tst_linkedlist_display(): """Test for LinkedList display.""" one_llist, empty_llist, new_llist = sample_linked_list() assert new_llist.display() == (5, 4, 3, 2, 1) -def test_linkedlist_display_one(): +def tst_linkedlist_display_one(): """Test for LinkedList display on single item list.""" one_llist, empty_llist, new_llist = sample_linked_list() assert one_llist.display() == (1,) -def test_linkedlist_display_empty(): +def est_linkedlist_display_empty(): """Test for LinkedList display on empty list.""" one_llist, empty_llist, new_llist = sample_linked_list() assert empty_llist.display() is None From 54961fb7ae33f69fb63cd0c14807002e8ab67b90 Mon Sep 17 00:00:00 2001 From: jordan Date: Tue, 27 Dec 2016 15:34:35 -0800 Subject: [PATCH 32/38] adding more tests --- src/test_linked_list.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test_linked_list.py b/src/test_linked_list.py index 27804f1..994884b 100644 --- a/src/test_linked_list.py +++ b/src/test_linked_list.py @@ -85,7 +85,7 @@ def test_linkedlist_search_list(sample_linked_list): assert sample_linked_list[2].search(2).contents == 2 -def tst_linkedlist_search_empty(): +def test_linkedlist_search_empty(): """Test for LinkedList search empty list.""" one_llist, empty_llist, new_llist = sample_linked_list() assert empty_llist.search(2) is None From 7f6b8169c7be781ae6e455cb24d78f52b4ace8ad Mon Sep 17 00:00:00 2001 From: Julien Wilson Date: Tue, 27 Dec 2016 16:04:20 -0800 Subject: [PATCH 33/38] changed tests to use fixtures --- src/test_linked_list.py | 58 +++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/src/test_linked_list.py b/src/test_linked_list.py index 994884b..085a8b8 100644 --- a/src/test_linked_list.py +++ b/src/test_linked_list.py @@ -70,7 +70,7 @@ def test_linkedlist_pop_empty(sample_linked_list): sample_linked_list[0].pop() -def tesst_linkedlist_pop_one(sample_linked_list): +def test_linkedlist_pop_one(sample_linked_list): """Test for Linked List pop on list with one item.""" assert sample_linked_list[1].pop() == 1 @@ -85,53 +85,49 @@ def test_linkedlist_search_list(sample_linked_list): assert sample_linked_list[2].search(2).contents == 2 -def test_linkedlist_search_empty(): +def test_linkedlist_search_empty(sample_linked_list): """Test for LinkedList search empty list.""" - one_llist, empty_llist, new_llist = sample_linked_list() - assert empty_llist.search(2) is None + assert sample_linked_list[1].search(2) is None -def tst_linkedlist_search_list_false(): +def test_linkedlist_search_list_false(sample_linked_list): """Test for LinkedList search list when search value is not in list.""" - one_llist, empty_llist, new_llist = sample_linked_list() - assert new_llist.search(100) is None + assert sample_linked_list[2].search(100) is None -def tst_linkedlist_remove(): - """Test LinkedList remove() on a list.""" - one_llist, empty_llist, new_llist = sample_linked_list() - new_llist.remove(new_llist.search(3)) - assert new_llist.search(3) is None - assert new_llist.search(4).next_node.contents == 2 +def test_linkedlist_remove(sample_linked_list): + """Test that removed value is gone after remove().""" + sample_linked_list[2].remove(3) + assert sample_linked_list[2].search(3) is None -def tst_linkedlist_remove_head(): +def test_linkedlist_remove_pointers(sample_linked_list): + """Test that previous node points to correct node after remove().""" + sample_linked_list[2].remove(3) + assert sample_linked_list[2].search(4).next_node.contents == 2 + + +def test_linkedlist_remove_head(sample_linked_list): """Test LinkedList remove() the head on a list.""" - one_llist, empty_llist, new_llist = sample_linked_list() - new_llist.remove(new_llist.search(5)) - assert new_llist.head_node.contents == 4 + sample_linked_list[2].remove(5) + assert sample_linked_list[2].head_node.contents == 4 -def tst_linkedlist_remove_empty(): - """Test LinkedList remove() on a list list.""" - one_llist, empty_llist, new_llist = sample_linked_list() - with pytest.raises(ValueError): - new_llist.remove(new_llist.search(100)) +def test_linkedlist_remove_empty(sample_linked_list): + """Test LinkedList remove() on an empty linked list.""" + sample_linked_list[1].remove(5) is None -def tst_linkedlist_display(): +def test_linkedlist_display(sample_linked_list): """Test for LinkedList display.""" - one_llist, empty_llist, new_llist = sample_linked_list() - assert new_llist.display() == (5, 4, 3, 2, 1) + assert sample_linked_list[2].display() == '(5, 4, 3, 2, 1)' -def tst_linkedlist_display_one(): +def test_linkedlist_display_one(sample_linked_list): """Test for LinkedList display on single item list.""" - one_llist, empty_llist, new_llist = sample_linked_list() - assert one_llist.display() == (1,) + assert sample_linked_list[1].display() == '(1,)' -def est_linkedlist_display_empty(): +def test_linkedlist_display_empty(sample_linked_list): """Test for LinkedList display on empty list.""" - one_llist, empty_llist, new_llist = sample_linked_list() - assert empty_llist.display() is None + assert sample_linked_list[0].display() is None From dc108d412a8573f34ccce20cb471d8f2ed2f1fcd Mon Sep 17 00:00:00 2001 From: jordan Date: Tue, 27 Dec 2016 16:07:50 -0800 Subject: [PATCH 34/38] clean up ll.py --- src/linked_list.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/linked_list.py b/src/linked_list.py index 566d970..f1b91db 100644 --- a/src/linked_list.py +++ b/src/linked_list.py @@ -82,8 +82,3 @@ def __init__(self, contents, next_node): """Instantiate linked list node.""" self.contents = contents self.next_node = next_node - - -test = LinkedList([4,3,'blah',1]) -test.remove(1) -print (test.display()) \ No newline at end of file From 864cf8eb782b8a34e202fa9ed3e73fef0601c841 Mon Sep 17 00:00:00 2001 From: Julien Wilson Date: Tue, 27 Dec 2016 16:12:30 -0800 Subject: [PATCH 35/38] made tests fixtures --- src/test_stack.py | 72 ++++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 42 deletions(-) diff --git a/src/test_stack.py b/src/test_stack.py index 47fd7a2..5a017c7 100644 --- a/src/test_stack.py +++ b/src/test_stack.py @@ -7,84 +7,72 @@ def sample_stack(): """Create testing stacks.""" from stack import Stack - one_stack = Stack([1]) empty_stack = Stack() + one_stack = Stack([1]) new_stack = Stack([1, 2, 3, 4, 5]) - return one_stack, empty_stack, new_stack + return (empty_stack, one_stack, new_stack) -def test_stack_empty_length(): +def test_stack_empty_length(sample_stack): """Test for empty stack length.""" - one_stack, empty_stack, new_stack = sample_stack() - assert empty_stack.length == 0 + assert sample_stack[0].length == 0 -def test_stack_empty_head_node(): +def test_stack_empty_head_node(sample_stack): """Test for empty stack head node.""" - one_stack, empty_stack, new_stack = sample_stack() - assert empty_stack.head_node is None + assert sample_stack[0].head_node is None -def test_stack_new_length(): +def test_stack_new_length(sample_stack): """Test for new stack length.""" - one_stack, empty_stack, new_stack = sample_stack() - assert new_stack.length == 5 + assert sample_stack[2].length == 5 -def test_stack_new_contents(): +def test_stack_new_contents(sample_stack): """Test for new stack head node contents.""" - one_stack, empty_stack, new_stack = sample_stack() - assert new_stack.head_node.contents == 5 + assert sample_stack[2].head_node.contents == 5 -def test_stack_new_push(): +def test_stack_new_push(sample_stack): """Test for new stack head node contents.""" - one_stack, empty_stack, new_stack = sample_stack() - new_stack.push(34) - assert new_stack.head_node.contents == 34 + sample_stack[2].push(34) + assert sample_stack[2].head_node.contents == 34 -def test_stack_one_push(): +def test_stack_one_push(sample_stack): """Test for new stack head node contents.""" - one_stack, empty_stack, new_stack = sample_stack() - one_stack.push(34) - assert one_stack.head_node.contents == 34 + sample_stack[1].push(34) + assert sample_stack[1].head_node.contents == 34 -def test_stack_empty_push(): +def test_stack_empty_push(sample_stack): """Test for empty stack head node contents.""" - one_stack, empty_stack, new_stack = sample_stack() - empty_stack.push(34) - assert empty_stack.head_node.contents == 34 + sample_stack[0].push(34) + assert sample_stack[0].head_node.contents == 34 -def test_stack_new_pop(): +def test_stack_new_pop(sample_stack): """Test that pop the new stack returns 5.""" - one_stack, empty_stack, new_stack = sample_stack() - assert new_stack.pop() == 5 + assert sample_stack[2].pop() == 5 -def test_stack_new_pop_length(): +def test_stack_new_pop_length(sample_stack): """Test that pop the new stack decreases length.""" - one_stack, empty_stack, new_stack = sample_stack() - assert new_stack.pop() == 5 + assert sample_stack[2].pop() == 5 -def test_stack_one_pop(): +def test_stack_one_pop(sample_stack): """Test that pop of one stack returns 1.""" - one_stack, empty_stack, new_stack = sample_stack() - assert one_stack.pop() == 1 + assert sample_stack[1].pop() == 1 -def test_stack_one_pop_contents(): +def test_stack_one_pop_contents(sample_stack): """Test that pop of one stack behaves as expeted.""" - one_stack, empty_stack, new_stack = sample_stack() - one_stack.pop() - assert one_stack.head_node is None + sample_stack[1].pop() + assert sample_stack[1].head_node is None -def tst_stack_empty_pop(): +def tst_stack_empty_pop(sample_stack): """Test that pop empty stack throws correct error.""" - one_stack, empty_stack, new_stack = sample_stack() with pytest.raises(TypeError): - empty_stack.pop() + sample_stack[0].pop() From 8d9aa056374a264518c44c478b1b0da77870085c Mon Sep 17 00:00:00 2001 From: jordan Date: Tue, 27 Dec 2016 16:18:22 -0800 Subject: [PATCH 36/38] fix another conflict --- src/linked_list.py | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/linked_list.py b/src/linked_list.py index fc8a16d..43926d0 100644 --- a/src/linked_list.py +++ b/src/linked_list.py @@ -13,11 +13,7 @@ def __init__(self, iterable=None): self.push(item) except TypeError: if iterable: -<<<<<<< HEAD - return "Please only enter iterable values" -======= raise TypeError("Please only enter iterable values") ->>>>>>> dc108d412a8573f34ccce20cb471d8f2ed2f1fcd def push(self, contents): """Add node to this linked list.""" @@ -27,11 +23,7 @@ def push(self, contents): def pop(self): """Remove and return the current head node.""" if not self.head_node: -<<<<<<< HEAD - return "Linked list is already empty" -======= raise IndexError("List is already empty") ->>>>>>> dc108d412a8573f34ccce20cb471d8f2ed2f1fcd old_head_node = self.head_node self.head_node = self.head_node.next_node self.length -= 1 @@ -80,11 +72,7 @@ def display(self): while current_node.next_node is not None: current_node = current_node.next_node new_list.append(current_node.contents) -<<<<<<< HEAD - return tuple(new_list) -======= return str(tuple(new_list)) ->>>>>>> dc108d412a8573f34ccce20cb471d8f2ed2f1fcd class Node(object): @@ -93,4 +81,4 @@ class Node(object): def __init__(self, contents, next_node): """Instantiate linked list node.""" self.contents = contents - self.next_node = next_node +self.next_node = next_node \ No newline at end of file From 2eccafd95a7b2bfcc349576df097878493b90de0 Mon Sep 17 00:00:00 2001 From: jordan Date: Tue, 27 Dec 2016 16:20:36 -0800 Subject: [PATCH 37/38] new linked list for stack --- src/linked_list.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/linked_list.py b/src/linked_list.py index 43926d0..f1b91db 100644 --- a/src/linked_list.py +++ b/src/linked_list.py @@ -81,4 +81,4 @@ class Node(object): def __init__(self, contents, next_node): """Instantiate linked list node.""" self.contents = contents -self.next_node = next_node \ No newline at end of file + self.next_node = next_node From de9835c7e178524447f11695401634729e6953fd Mon Sep 17 00:00:00 2001 From: Julien Wilson Date: Tue, 27 Dec 2016 16:27:58 -0800 Subject: [PATCH 38/38] use fixtures in testing --- src/stack.py | 6 ------ src/test_stack.py | 4 ++-- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/stack.py b/src/stack.py index fb14575..7c6e988 100644 --- a/src/stack.py +++ b/src/stack.py @@ -22,9 +22,3 @@ def pop(self): old_head_node_value = self.linked_list.pop() self.head_node = self.linked_list.head_node return old_head_node_value - -test = Stack([1,2,3]) -print (test.pop()) -print (test.pop()) -print (test.pop()) -print (test.pop()) diff --git a/src/test_stack.py b/src/test_stack.py index 5a017c7..c690dfa 100644 --- a/src/test_stack.py +++ b/src/test_stack.py @@ -72,7 +72,7 @@ def test_stack_one_pop_contents(sample_stack): assert sample_stack[1].head_node is None -def tst_stack_empty_pop(sample_stack): +def test_stack_empty_pop(sample_stack): """Test that pop empty stack throws correct error.""" - with pytest.raises(TypeError): + with pytest.raises(IndexError): sample_stack[0].pop()