From ab515eb2bb0cf529f5f5d71512299c4e0ff63d66 Mon Sep 17 00:00:00 2001 From: FabiolaSaga Date: Sun, 20 Sep 2020 21:22:24 -0500 Subject: [PATCH 1/6] Finished Day 1 --- queue/queue.py | 19 ++- queue/singly_linked_list.py | 107 +++++++++++++++++ ..._linked_list.py => singly_linked_list1.py} | 0 stack/singly_linked_list.py | 113 ++++++++++++++++++ stack/stack.py | 16 ++- 5 files changed, 247 insertions(+), 8 deletions(-) create mode 100644 queue/singly_linked_list.py rename singly_linked_list/{singly_linked_list.py => singly_linked_list1.py} (100%) create mode 100644 stack/singly_linked_list.py diff --git a/queue/queue.py b/queue/queue.py index 0d2599ded7..c782612c02 100644 --- a/queue/queue.py +++ b/queue/queue.py @@ -13,16 +13,27 @@ Stretch: What if you could only use instances of your Stack class to implement the Queue? What would that look like? How many Stacks would you need? Try it! """ +from singly_linked_list import LinkedList + class Queue: def __init__(self): self.size = 0 - # self.storage = ? + self.storage = LinkedList() def __len__(self): - pass + return self.size def enqueue(self, value): - pass + self.storage.add_to_tail(value) + self.size += 1 + return self.storage def dequeue(self): - pass + if self.size >= 1: + value = self.storage.remove_head() + self.size -= 1 + return value + return None + +new_queue = Queue() +print(f"{new_queue.enqueue(13)}") \ No newline at end of file diff --git a/queue/singly_linked_list.py b/queue/singly_linked_list.py new file mode 100644 index 0000000000..979870c423 --- /dev/null +++ b/queue/singly_linked_list.py @@ -0,0 +1,107 @@ +class Node: + def __init__(self, value, next_node = None): + # value that the node is holding + self.value = value + # ref to the next node in the chain + self.next_node = next_node + + + def get_value(self): + """ + Method to get the value of a node + """ + return self.value + + def get_next(self): + """ + Method to get the node's "next_node" + """ + return self.next_node + + def set_next(self, new_next): + """ + Method to update the node's "next_node" to the new_next + """ + self.next_node = new_next + +class LinkedList: + def __init__(self): + self.head = None + self.tail = None + + def add_to_tail(self, value): + # wrap the value in a new Node + new_node = Node(value) + # check if the linked list is empty + if self.head is None and self.tail is None: + # set the head and tail to the new node + self.head = new_node + self.tail = new_node + # otherwise the list must have at least one item in there + else: + # update the last node's "next_node" to the new node + self.tail.set_next(new_node) # (last node in chain).next_node = new_node + # update the "self.tail" to point to the new node that we just added + self.tail = new_node + + def remove_tail(self): + """ + remove the last node in the chain and return its value + """ + # check for empty list + if self.head is None and self.tail is None: + # return None + return None + # check if there is only one node + if self.head == self.tail: + # store the value of the node that we are going to remove + value = self.tail.get_value() + # remove the node + # set head and the tail to None + self.head = None + self.tail = None + # return the stored value + return value + # otherwise + else: + # store the value of the node that we are going to remove + value = self.tail.get_value() + # we need to set the "self.tail" to the second to last node + # we can only do this by traversing the whole list from beginning to end + + # starting from the head + current_node = self.head + + # keep iterating until the node after "current_node" is the tail + while current_node.get_next() != self.tail: + # keep looping + current_node = current_node.get_next() + + # at the end of the iteration set "self.tail" to the current_node + self.tail = current_node + # set the new tail's "next_node" to None + self.tail.set_next(None) + # return Value + return value + + def remove_head(self): + # check for empty list + if self.head is None and self.tail is None: + # return None + return None + if self.head == self.tail: + # store the value of the node that we are going to remove + value = self.head.get_value() + # remove the node + # set head and the tail to None + self.head = None + self.tail = None + # return the stored value + return value + else: + # store the old head's value + value = self.head.get_value() + # set self.head to old head's next + self.head = self.head.get_next() + # return the value + return value \ No newline at end of file diff --git a/singly_linked_list/singly_linked_list.py b/singly_linked_list/singly_linked_list1.py similarity index 100% rename from singly_linked_list/singly_linked_list.py rename to singly_linked_list/singly_linked_list1.py diff --git a/stack/singly_linked_list.py b/stack/singly_linked_list.py new file mode 100644 index 0000000000..17b77a596b --- /dev/null +++ b/stack/singly_linked_list.py @@ -0,0 +1,113 @@ +class Node: + def __init__(self, value, next_node = None): + # value that the node is holding + self.value = value + # ref to the next node in the chain + self.next_node = next_node + + + def get_value(self): + """ + Method to get the value of a node + """ + return self.value + + def get_next(self): + """ + Method to get the node's "next_node" + """ + return self.next_node + + def set_next(self, new_next): + """ + Method to update the node's "next_node" to the new_next + """ + self.next_node = new_next + +class LinkedList: + def __init__(self): + self.head = None + self.tail = None + + def add_to_tail(self, value): + # wrap the value in a new Node + new_node = Node(value) + # check if the linked list is empty + if self.head is None and self.tail is None: + # set the head and tail to the new node + self.head = new_node + self.tail = new_node + # otherwise the list must have at least one item in there + else: + # update the last node's "next_node" to the new node + self.tail.set_next(new_node) # (last node in chain).next_node = new_node + # update the "self.tail" to point to the new node that we just added + self.tail = new_node + + def add_to_head(self, value): + new_node = Node(value, self.head) + self.head = new_node + if self.head is None: + self.tail = new_node + + def remove_tail(self): + """ + remove the last node in the chain and return its value + """ + # check for empty list + if self.head is None and self.tail is None: + # return None + return None + # check if there is only one node + if self.head == self.tail: + # store the value of the node that we are going to remove + value = self.tail.get_value() + # remove the node + # set head and the tail to None + self.head = None + self.tail = None + # return the stored value + return value + # otherwise + else: + # store the value of the node that we are going to remove + value = self.tail.get_value() + # we need to set the "self.tail" to the second to last node + # we can only do this by traversing the whole list from beginning to end + + # starting from the head + current_node = self.head + + # keep iterating until the node after "current_node" is the tail + while current_node.get_next() != self.tail: + # keep looping + current_node = current_node.get_next() + + # at the end of the iteration set "self.tail" to the current_node + self.tail = current_node + # set the new tail's "next_node" to None + self.tail.set_next(None) + # return Value + return value + + def remove_head(self): + # check for empty list + if self.head is None and self.tail is None: + # return None + return None + if self.head == self.tail: + # store the value of the node that we are going to remove + value = self.head.get_value() + # remove the node + # set head and the tail to None + self.head = None + self.tail = None + # return the stored value + return value + else: + # store the old head's value + value = self.head.get_value() + # set self.head to old head's next + self.head = self.head.get_next() + # return the value + return value \ No newline at end of file diff --git a/stack/stack.py b/stack/stack.py index 6e6d660ac7..c245ebbd0e 100644 --- a/stack/stack.py +++ b/stack/stack.py @@ -10,16 +10,24 @@ 3. What is the difference between using an array vs. a linked list when implementing a Stack? """ +from singly_linked_list import LinkedList + class Stack: def __init__(self): self.size = 0 - # self.storage = ? + self.storage = LinkedList() def __len__(self): - pass + return self.size def push(self, value): - pass + self.storage.add_to_head(value) + self.size += 1 + return self.storage def pop(self): - pass + if self.size > 0: + value = self.storage.remove_head() + self.size -= 1 + return value + return None \ No newline at end of file From e967fd934a2a92daff24f7f64c028ece6df664ad Mon Sep 17 00:00:00 2001 From: FabiolaSaga Date: Tue, 22 Sep 2020 19:06:19 -0500 Subject: [PATCH 2/6] DLL --- binary_search_tree/binary_search_tree.py | 25 ++++++++++++++++++++++-- queue/queue.py | 2 -- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/binary_search_tree/binary_search_tree.py b/binary_search_tree/binary_search_tree.py index d80d9f6282..61b85bdb77 100644 --- a/binary_search_tree/binary_search_tree.py +++ b/binary_search_tree/binary_search_tree.py @@ -17,12 +17,33 @@ def __init__(self, value): # Insert the given value into the tree def insert(self, value): - pass + if value < self.value: + if self.left == None: + self.left = BSTNode(value) + else: + self.left.insert(value) + elif value >= value: + if self.right == None: + self.right = BSTNode(value) + else: + self.right.insert(value) + # Return True if the tree contains the value # False if it does not def contains(self, target): - pass + if self.value == target: + return True + if target < self.value: + if self.left == None: + return False + else: + self.left.contains(target) + elif target > self.value: + if self.right == None: + return False + else: + self.right.contains(target) # Return the maximum value found in the tree def get_max(self): diff --git a/queue/queue.py b/queue/queue.py index c782612c02..5bafaeddd1 100644 --- a/queue/queue.py +++ b/queue/queue.py @@ -35,5 +35,3 @@ def dequeue(self): return value return None -new_queue = Queue() -print(f"{new_queue.enqueue(13)}") \ No newline at end of file From d4d13b4563357eb6f0f9120fe143cb05666c0603 Mon Sep 17 00:00:00 2001 From: FabiolaSaga Date: Tue, 22 Sep 2020 19:24:07 -0500 Subject: [PATCH 3/6] Dll --- doubly_linked_list/doubly_linked_list.py | 94 +++++++++++++++++++++--- 1 file changed, 85 insertions(+), 9 deletions(-) diff --git a/doubly_linked_list/doubly_linked_list.py b/doubly_linked_list/doubly_linked_list.py index 6f91b43a9b..1213ea1112 100644 --- a/doubly_linked_list/doubly_linked_list.py +++ b/doubly_linked_list/doubly_linked_list.py @@ -7,7 +7,14 @@ def __init__(self, value, prev=None, next=None): self.prev = prev self.value = value self.next = next - + + def delete(self): + if self.prev: + self.prev.next = self.next + + if self.next: + self.next.prev = self.prev + """ Our doubly-linked list class. It holds references to the list's head and tail nodes. @@ -27,7 +34,17 @@ def __len__(self): the old head node's previous pointer accordingly. """ def add_to_head(self, value): - pass + self.length += 1 + new_node = ListNode(value) + + if not self.head and not self.tail: + self.head = new_node + self.tail = new_node + else: + new_node.next = self.head + self.head.prev = new_node + self.head = new_node + """ Removes the List's current head node, making the @@ -35,7 +52,12 @@ def add_to_head(self, value): Returns the value of the removed Node. """ def remove_from_head(self): - pass + if self.head is None and self.tail is None: + return None + self.length -= 1 + value = self.head.value + self.delete(self.head) + return value """ Wraps the given value in a ListNode and inserts it @@ -43,7 +65,17 @@ def remove_from_head(self): the old tail node's next pointer accordingly. """ def add_to_tail(self, value): - pass + self.length += 1 + new_node = ListNode(value, None, None) + + if not self.head and not self.tail: + self.head = new_node + self.tail = new_node + else : + new_node.prev = self.tail + self.tail.next = new_node + self.tail = new_node + """ Removes the List's current tail node, making the @@ -51,32 +83,76 @@ def add_to_tail(self, value): Returns the value of the removed Node. """ def remove_from_tail(self): - pass + if self.head is None and self.tail is None: + return None + self.length -= 1 + value = self.tail.value + self.delete(self.tail) + return value """ Removes the input node from its current spot in the List and inserts it as the new head node of the List. """ def move_to_front(self, node): - pass + if node is self.head: + return + value = node.value + if node is self.tail: + self.remove_from_tail() + else: + node.delete() + + self.length -= 1 + self.add_to_head(value) """ Removes the input node from its current spot in the List and inserts it as the new tail node of the List. """ def move_to_end(self, node): - pass + if node is self.tail: + return + if node is self.head: + self.remove_from_head() + else: + node.delete() + + self.length -= 1 + self.add_to_tail(node.value) + """ Deletes the input node from the List, preserving the order of the other elements of the List. """ def delete(self, node): - pass + if not self.head and not self.tail: + return + if self.head == self.tail: + self.head = None + self.tail = None + elif self.head is node: + self.head = node.next + node.delete() + elif self.tail is node: + self.tail = node.prev + node.delete() + else: + node.delete() + self.length -= 1 """ Finds and returns the maximum value of all the nodes in the List. """ def get_max(self): - pass \ No newline at end of file + if not self.head: + return None + max_val = self.head.value + current = self.head + while current: + if current.value > max_val: + max_val = current.value + current = current.next + return max_val \ No newline at end of file From ff5a5959ca51cff24b20b637b7eb278929fa8290 Mon Sep 17 00:00:00 2001 From: FabiolaSaga Date: Wed, 23 Sep 2020 20:32:42 -0500 Subject: [PATCH 4/6] Finished part 1 of BST --- binary_search_tree/binary_search_tree.py | 30 +++++++++++++++++------- doubly_linked_list/doubly_linked_list.py | 3 ++- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/binary_search_tree/binary_search_tree.py b/binary_search_tree/binary_search_tree.py index 61b85bdb77..3cb6fe46de 100644 --- a/binary_search_tree/binary_search_tree.py +++ b/binary_search_tree/binary_search_tree.py @@ -22,7 +22,7 @@ def insert(self, value): self.left = BSTNode(value) else: self.left.insert(value) - elif value >= value: + else: if self.right == None: self.right = BSTNode(value) else: @@ -39,7 +39,7 @@ def contains(self, target): return False else: self.left.contains(target) - elif target > self.value: + else: if self.right == None: return False else: @@ -47,11 +47,23 @@ def contains(self, target): # Return the maximum value found in the tree def get_max(self): - pass + if self.right == None and self.left == None: + return None + + if self.right is not None: + return self.right.value + else: + self.right.get_max() + # Call the function `fn` on the value of each node def for_each(self, fn): - pass + fn(self.value) + + if self.left is not None: + self.left.for_each(fn) + if self.right is not None: + self.right.for_each(fn) # Part 2 ----------------------- @@ -99,8 +111,8 @@ def post_order_dft(self): print("elegant methods") print("pre order") -bst.pre_order_dft() -print("in order") -bst.in_order_dft() -print("post order") -bst.post_order_dft() +# bst.pre_order_dft() +# print("in order") +# bst.in_order_dft() +# print("post order") +# bst.post_order_dft() diff --git a/doubly_linked_list/doubly_linked_list.py b/doubly_linked_list/doubly_linked_list.py index 1213ea1112..924071c706 100644 --- a/doubly_linked_list/doubly_linked_list.py +++ b/doubly_linked_list/doubly_linked_list.py @@ -113,13 +113,14 @@ def move_to_front(self, node): def move_to_end(self, node): if node is self.tail: return + value = node.value if node is self.head: self.remove_from_head() else: node.delete() self.length -= 1 - self.add_to_tail(node.value) + self.add_to_tail(value) """ From b8b2d0e19b8f1ded51bbbe976a86d7660402a283 Mon Sep 17 00:00:00 2001 From: FabiolaSaga Date: Wed, 23 Sep 2020 21:00:46 -0500 Subject: [PATCH 5/6] Added missing return --- binary_search_tree/binary_search_tree.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/binary_search_tree/binary_search_tree.py b/binary_search_tree/binary_search_tree.py index 3cb6fe46de..700ebc2b45 100644 --- a/binary_search_tree/binary_search_tree.py +++ b/binary_search_tree/binary_search_tree.py @@ -53,8 +53,7 @@ def get_max(self): if self.right is not None: return self.right.value else: - self.right.get_max() - + return self.right.get_max() # Call the function `fn` on the value of each node def for_each(self, fn): @@ -111,8 +110,8 @@ def post_order_dft(self): print("elegant methods") print("pre order") -# bst.pre_order_dft() -# print("in order") -# bst.in_order_dft() -# print("post order") -# bst.post_order_dft() +bst.pre_order_dft() +print("in order") +bst.in_order_dft() +print("post order") +bst.post_order_dft() From b2b2df1fa68dd772ddb1df294a35d04708eecccd Mon Sep 17 00:00:00 2001 From: FabiolaSaga Date: Wed, 30 Sep 2020 20:27:57 -0500 Subject: [PATCH 6/6] Finished mvp --- binary_search_tree/binary_search_tree.py | 116 +++++++++++++++-------- binary_search_tree/queue.py | 37 ++++++++ binary_search_tree/singly_linked_list.py | 115 ++++++++++++++++++++++ binary_search_tree/stack.py | 33 +++++++ 4 files changed, 263 insertions(+), 38 deletions(-) create mode 100644 binary_search_tree/queue.py create mode 100644 binary_search_tree/singly_linked_list.py create mode 100644 binary_search_tree/stack.py diff --git a/binary_search_tree/binary_search_tree.py b/binary_search_tree/binary_search_tree.py index 700ebc2b45..b4a843f2e0 100644 --- a/binary_search_tree/binary_search_tree.py +++ b/binary_search_tree/binary_search_tree.py @@ -9,6 +9,9 @@ 2. Implement the `in_order_print`, `bft_print`, and `dft_print` methods on the BSTNode class. """ +from queue import Queue +from stack import Stack + class BSTNode: def __init__(self, value): self.value = value @@ -34,26 +37,28 @@ def insert(self, value): def contains(self, target): if self.value == target: return True - if target < self.value: - if self.left == None: - return False - else: - self.left.contains(target) else: - if self.right == None: - return False + if target < self.value: + if self.left == None: + return False + else: + return self.left.contains(target) else: - self.right.contains(target) + if self.right == None: + return False + else: + return self.right.contains(target) # Return the maximum value found in the tree def get_max(self): - if self.right == None and self.left == None: - return None + # if self.right == None and self.left == None: + # return None if self.right is not None: - return self.right.value - else: return self.right.get_max() + else: + return self.value + # Call the function `fn` on the value of each node def for_each(self, fn): @@ -66,29 +71,64 @@ def for_each(self, fn): # Part 2 ----------------------- - # Print all the values in order from low to high - # Hint: Use a recursive, depth first traversal + # # Print all the values in order from low to high + # # Hint: Use a recursive, depth first traversal def in_order_print(self): - pass - - # Print the value of every node, starting with the given node, - # in an iterative breadth first traversal - def bft_print(self): - pass - - # Print the value of every node, starting with the given node, - # in an iterative depth first traversal - def dft_print(self): - pass - - # Stretch Goals ------------------------- - # Note: Research may be required - - # Print Pre-order recursive DFT + # base case + # if there are no more nodes + #return + if self.left == None and self.right == None: + return + + #if there is a node to the left + if self.left is not None: + # call in order print on the left + self.left.in_order_print() + # print the value of the current node (self.value) + print(self.value) + #if there is a node to the right + if self.right is not None: + # call in order print on the right + self.right.in_order_print() + + + # # Print the value of every node, starting with the given node, + # # in an iterative breadth first traversal + def bft_print(self): #queue + #create a queue + queue = Queue() + queue.enqueue(self) + + while queue: + node = queue.dequeue() + print(node.value) + if node.left is not None: + queue.enqueue(node.left) + if node.right is not None: + queue.enqueue(node.right) + + # # Print the value of every node, starting with the given node, + # # in an iterative depth first traversal + def dft_print(self): # stack + stack = Stack() + stack.push(self) + + while stack: + node = stack.pop() + print(node.value) + if node.left is not None: + stack.push(node.left) + if node.right is not None: + stack.push(node.right) + + # # Stretch Goals ------------------------- + # # Note: Research may be required + + # # Print Pre-order recursive DFT def pre_order_dft(self): pass - # Print Post-order recursive DFT + # # Print Post-order recursive DFT def post_order_dft(self): pass @@ -108,10 +148,10 @@ def post_order_dft(self): bst.bft_print() bst.dft_print() -print("elegant methods") -print("pre order") -bst.pre_order_dft() -print("in order") -bst.in_order_dft() -print("post order") -bst.post_order_dft() +# print("elegant methods") +# print("pre order") +# bst.pre_order_dft() +# print("in order") +# bst.in_order_dft() +# print("post order") +# bst.post_order_dft() diff --git a/binary_search_tree/queue.py b/binary_search_tree/queue.py new file mode 100644 index 0000000000..5bafaeddd1 --- /dev/null +++ b/binary_search_tree/queue.py @@ -0,0 +1,37 @@ +""" +A queue is a data structure whose primary purpose is to store and +return elements in First In First Out order. + +1. Implement the Queue class using an array as the underlying storage structure. + Make sure the Queue tests pass. +2. Re-implement the Queue class, this time using the linked list implementation + as the underlying storage structure. + Make sure the Queue tests pass. +3. What is the difference between using an array vs. a linked list when + implementing a Queue? + +Stretch: What if you could only use instances of your Stack class to implement the Queue? + What would that look like? How many Stacks would you need? Try it! +""" +from singly_linked_list import LinkedList + +class Queue: + def __init__(self): + self.size = 0 + self.storage = LinkedList() + + def __len__(self): + return self.size + + def enqueue(self, value): + self.storage.add_to_tail(value) + self.size += 1 + return self.storage + + def dequeue(self): + if self.size >= 1: + value = self.storage.remove_head() + self.size -= 1 + return value + return None + diff --git a/binary_search_tree/singly_linked_list.py b/binary_search_tree/singly_linked_list.py new file mode 100644 index 0000000000..c69a0be73b --- /dev/null +++ b/binary_search_tree/singly_linked_list.py @@ -0,0 +1,115 @@ +class Node: + def __init__(self, value, next_node = None): + # value that the node is holding + self.value = value + # ref to the next node in the chain + self.next_node = next_node + + + def get_value(self): + """ + Method to get the value of a node + """ + return self.value + + def get_next(self): + """ + Method to get the node's "next_node" + """ + return self.next_node + + def set_next(self, new_next): + """ + Method to update the node's "next_node" to the new_next + """ + self.next_node = new_next + +class LinkedList: + def __init__(self): + self.head = None + self.tail = None + self.length = 0 + + def add_to_tail(self, value): + # wrap the value in a new Node + new_node = Node(value) + # check if the linked list is empty + if self.head is None and self.tail is None: + # set the head and tail to the new node + self.head = new_node + self.tail = new_node + # otherwise the list must have at least one item in there + else: + # update the last node's "next_node" to the new node + self.tail.set_next(new_node) # (last node in chain).next_node = new_node + # update the "self.tail" to point to the new node that we just added + self.tail = new_node + + def add_to_head(self, value): + new_node = Node(value, self.head) + self.head = new_node + if self.length == 0: + self.tail = new_node + self.length += 1 + + def remove_tail(self): + """ + remove the last node in the chain and return its value + """ + # check for empty list + if self.head is None and self.tail is None: + # return None + return None + # check if there is only one node + if self.head == self.tail: + # store the value of the node that we are going to remove + value = self.tail.get_value() + # remove the node + # set head and the tail to None + self.head = None + self.tail = None + # return the stored value + return value + # otherwise + else: + # store the value of the node that we are going to remove + value = self.tail.get_value() + # we need to set the "self.tail" to the second to last node + # we can only do this by traversing the whole list from beginning to end + + # starting from the head + current_node = self.head + + # keep iterating until the node after "current_node" is the tail + while current_node.get_next() != self.tail: + # keep looping + current_node = current_node.get_next() + + # at the end of the iteration set "self.tail" to the current_node + self.tail = current_node + # set the new tail's "next_node" to None + self.tail.set_next(None) + # return Value + return value + + def remove_head(self): + # check for empty list + if self.head is None and self.tail is None: + # return None + return None + if self.head == self.tail: + # store the value of the node that we are going to remove + value = self.head.get_value() + # remove the node + # set head and the tail to None + self.head = None + self.tail = None + # return the stored value + return value + else: + # store the old head's value + value = self.head.get_value() + # set self.head to old head's next + self.head = self.head.get_next() + # return the value + return value \ No newline at end of file diff --git a/binary_search_tree/stack.py b/binary_search_tree/stack.py new file mode 100644 index 0000000000..c245ebbd0e --- /dev/null +++ b/binary_search_tree/stack.py @@ -0,0 +1,33 @@ +""" +A stack is a data structure whose primary purpose is to store and +return elements in Last In First Out order. + +1. Implement the Stack class using an array as the underlying storage structure. + Make sure the Stack tests pass. +2. Re-implement the Stack class, this time using the linked list implementation + as the underlying storage structure. + Make sure the Stack tests pass. +3. What is the difference between using an array vs. a linked list when + implementing a Stack? +""" +from singly_linked_list import LinkedList + +class Stack: + def __init__(self): + self.size = 0 + self.storage = LinkedList() + + def __len__(self): + return self.size + + def push(self, value): + self.storage.add_to_head(value) + self.size += 1 + return self.storage + + def pop(self): + if self.size > 0: + value = self.storage.remove_head() + self.size -= 1 + return value + return None \ No newline at end of file