-
Notifications
You must be signed in to change notification settings - Fork 0
Linked list #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
julienawilson
wants to merge
11
commits into
master
Choose a base branch
from
linked_list
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Linked list #3
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
f816975
updated linked list and test to allow empty
julienawilson 127fd29
test removing tail node
julienawilson 5e5f97b
used fixtures in testing
julienawilson 35ca79d
changed error messages to actual error raising
julienawilson 6ed3652
llist updates
julienawilson e085be0
remove() edits
julienawilson 68e2840
fix typo
JSchatzman fdf4a2c
fix remove
JSchatzman 54961fb
adding more tests
JSchatzman 7f6b816
changed tests to use fixtures
julienawilson dc108d4
clean up ll.py
JSchatzman File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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: | ||
| raise TypeError("Please only enter iterable values") | ||
|
|
||
| def push(self, contents): | ||
| """Add node to this linked list.""" | ||
|
|
@@ -16,48 +22,57 @@ def push(self, contents): | |
|
|
||
| def pop(self): | ||
| """Remove and return the current head node.""" | ||
| if not self.head_node: | ||
| raise IndexError("List is already empty") | ||
| old_head_node = self.head_node | ||
| self.head_node = self.head_node.next_node | ||
| self.length -= 1 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pop should return the value/contents, not the node itself! |
||
| return old_head_node | ||
| return old_head_node.contents | ||
|
|
||
| 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 | ||
| 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): | ||
| def remove(self, remove_value): | ||
| """Remove a node from linked list.""" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| 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.") | ||
| 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.""" | ||
| 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 str(tuple(new_list)) | ||
|
|
||
|
|
||
| class Node(object): | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,108 +1,133 @@ | ||
| """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 (empty_llist, one_llist, new_llist) | ||
|
|
||
|
|
||
| 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 | ||
| 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 | ||
|
|
||
|
|
||
| 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('test2').contents == 'test2' | ||
| 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' | ||
| 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(): | ||
| """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',) | ||
| new_node = Node(0, None) | ||
| assert new_node.contents == 0 and new_node.next_node is None | ||
|
|
||
|
|
||
| def test_linkedlist_init_empty_size(sample_linked_list): | ||
| """Test for empty LinkedList init.""" | ||
| assert sample_linked_list[0].length == 0 | ||
|
|
||
|
|
||
| def test_linkedlist_init_empty_head(sample_linked_list): | ||
| """Test head in empty LinkedList init.""" | ||
| assert sample_linked_list[0].head_node is None | ||
|
|
||
|
|
||
| def test_linkedlist_init_one_size(sample_linked_list): | ||
| """Test for LinkedList init single item.""" | ||
| assert sample_linked_list[1].length == 1 | ||
|
|
||
|
|
||
| def test_linkedlist_init_one_head(sample_linked_list): | ||
| """Test head in LinkedList init single item.""" | ||
| assert sample_linked_list[1].head_node.contents == 1 | ||
|
|
||
|
|
||
| def test_linkedlist_init_list_size(sample_linked_list): | ||
| """Test for LinkedList init with list.""" | ||
| assert sample_linked_list[2].length == 5 | ||
|
|
||
|
|
||
| def test_linkedlist_init_list_head(sample_linked_list): | ||
| """Test head in LinkedList init with list.""" | ||
| assert sample_linked_list[2].head_node.contents == 5 | ||
|
|
||
|
|
||
| def test_linkedlist_push_size(sample_linked_list): | ||
| """Test for LinkedList size after push.""" | ||
| test_linkedlist = sample_linked_list[2] | ||
| test_linkedlist.push("new") | ||
| assert test_linkedlist.length == 6 | ||
|
|
||
|
|
||
| def test_linkedlist_push_val(sample_linked_list): | ||
| """Test for LinkedList head value after push.""" | ||
| test_linkedlist = sample_linked_list[2] | ||
| test_linkedlist.push("new") | ||
| assert test_linkedlist.head_node.contents == 'new' | ||
|
|
||
|
|
||
| def test_linkedlist_pop_empty(sample_linked_list): | ||
| """Test for Linked List pop on empty.""" | ||
| with pytest.raises(IndexError): | ||
| sample_linked_list[0].pop() | ||
|
|
||
|
|
||
| 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 | ||
|
|
||
|
|
||
| def test_linkedlist_pop_list(sample_linked_list): | ||
| """Test for Linked List pop on multi-item list.""" | ||
| assert sample_linked_list[2].pop() == 5 | ||
|
|
||
|
|
||
| def test_linkedlist_search_list(sample_linked_list): | ||
| """Test for LinkedList search list.""" | ||
| assert sample_linked_list[2].search(2).contents == 2 | ||
|
|
||
|
|
||
| def test_linkedlist_search_empty(sample_linked_list): | ||
| """Test for LinkedList search empty list.""" | ||
| assert sample_linked_list[1].search(2) is None | ||
|
|
||
|
|
||
| def test_linkedlist_search_list_false(sample_linked_list): | ||
| """Test for LinkedList search list when search value is not in list.""" | ||
| assert sample_linked_list[2].search(100) is None | ||
|
|
||
|
|
||
| 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 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.""" | ||
| sample_linked_list[2].remove(5) | ||
| assert sample_linked_list[2].head_node.contents == 4 | ||
|
|
||
|
|
||
| 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 test_linkedlist_display(sample_linked_list): | ||
| """Test for LinkedList display.""" | ||
| assert sample_linked_list[2].display() == '(5, 4, 3, 2, 1)' | ||
|
|
||
|
|
||
| def test_linkedlist_display_one(sample_linked_list): | ||
| """Test for LinkedList display on single item list.""" | ||
| assert sample_linked_list[1].display() == '(1,)' | ||
|
|
||
|
|
||
| def test_linkedlist_display_empty(sample_linked_list): | ||
| """Test for LinkedList display on empty list.""" | ||
| assert sample_linked_list[0].display() is None |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very good! You probably want to go ahead and raise an exception instead of just printing a message. Raising an exception is the best way to let users know that they done fucked up.