Skip to content
74 changes: 74 additions & 0 deletions Sprint-2/implement_linked_list/linked_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
class Node:
def __init__(self, data):
self.data = data
self.previous = None
self.next = None

class LinkedList:
def __init__(self):
self.head = None
self.tail = None

def push_head(self, data):
new_head_node = Node(data)
if self.head is not None:
new_head_node.next = self.head
self.head.previous = new_head_node

self.head = new_head_node
if self.tail is None:
self.tail = new_head_node

return new_head_node



def pop_tail(self):
if self.tail is None:
raise IndexError("Unable to remove from empty linked list")

tail_node = self.tail
previous = self.tail.previous

self.tail = previous
if self.tail is not None:
self.tail.next = None
else:
self.head = None

tail_node.previous = None
tail_node.next = None

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Could consider delegating the node removing task to remove() -- less code to maintain.

  • Could also consider this style of code writing:

        # Handle all errors and special cases first
        if self.tail is None:
            raise IndexError("Unable to remove from empty linked list")

        # From this point onward, we don't have to worry about special cases.

        # No else needed; one less indentation level.
        tail_node = self.tail
        previous = self.tail.previous
        self.tail = previous
        if self.tail is not None:
            self.tail.next = None
        else:
            self.head = None

return tail_node.data



def remove(self, node):
previous_node = node.previous
next_node = node.next

if node.previous is not None:
previous_node.next = next_node
else:
self.head = next_node

if node.next is not None:
next_node.previous = previous_node
else:
self.tail = previous_node

node.previous = None
node.next = None













14 changes: 14 additions & 0 deletions Sprint-2/implement_linked_list/linked_list_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,20 @@ def test_remove_tail(self):
self.assertIsNone(b.next)
self.assertIsNone(b.previous)

def test_remove_middle(self):
l = LinkedList()
l.push_head("a")
b = l.push_head("b")
l.push_head("c")

l.remove(b)

self.assertIsNone(b.next)
self.assertIsNone(b.previous)

self.assertEqual(l.pop_tail(), "a")
self.assertEqual(l.pop_tail(), "c")


if __name__ == "__main__":
unittest.main()