class RingBuffer: def __init__(self, capacity): self.capacity = capacity self.storage = DoublyLinkedList() self.oldest = None def append(self, item): if self.storage.__len__() < self.capacity: self.storage.add_to_tail(item) self.oldest = self.storage.head else: the_oldest = self.oldest if the_oldest.next is not None: next_oldest = the_oldest.next next_oldest.insert_before(item) self.storage.delete(the_oldest) self.storage.length = self.capacity self.oldest = next_oldest else: self.storage.remove_from_tail() self.storage.add_to_tail(item) self.oldest = self.storage.head def get(self): # Note: This is the only [] allowed list_buffer_contents = [] # TODO: Your code here current_node = self.storage.head while current_node is not None: list_buffer_contents.append(current_node.value) current_node = current_node.next return list_buffer_contents
class RingBuffer: def __init__(self, capacity): self.capacity = capacity self.current = None self.storage = DoublyLinkedList() def append(self, item): if not self.current: # If self.current is None, the list isn't full yet self.storage.add_to_tail(item) if self.storage.length == self.capacity: # If this puts the list at capacity, set self.current # to the head. (self.current is basically the node # that will get replaced if a new value is appended.) self.current = self.storage.head else: if self.current is self.storage.head: # Replace the head self.current = self.storage.head.next self.storage.remove_from_head() self.storage.add_to_head(item) elif self.current is self.storage.tail: # Replace the tail self.current = self.storage.head self.storage.remove_from_tail() self.storage.add_to_tail(item) else: # Log self.current's next and prev, then delete it. current_next = self.current.next current_prev = self.current.prev self.storage.delete(self.current) # Set the new self.current self.current = current_next # Keep track of the tail, since we'll be adding the # new value as the tail temporarily. tail = self.storage.tail self.storage.add_to_tail(item) # Set the new node's next and prev to be the same as # the old self.current. new_node = self.storage.tail new_node.next = current_next new_node.prev = current_prev # Also fix the directions for the nodes that surround the new node current_next.prev = new_node current_prev.next = new_node # Finally, set the tail back to being the proper tail, # and make sure it has no "next" node. self.storage.tail = tail self.storage.tail.next = None def get(self): # Note: This is the only [] allowed list_buffer_contents = [] # TODO: Your code here node = self.storage.head while node: list_buffer_contents.append(node.value) node = node.next return list_buffer_contents
class LRUCache: """ Our LRUCache class keeps track of the max number of nodes it can hold, the current number of nodes it is holding, a doubly- linked list that holds the key-value entries in the correct order, as well as a storage dict that provides fast access to every node stored in the cache. """ def __init__(self, limit=10): self.max_nodes = limit self.num_nodes = 0 # values in cache_list are key/value dicts self.cache_list = DLL() # storage holds key, node pairs self.storage = {} """ Retrieves the value associated with the given key. Also needs to move the key-value pair to the end of the order such that the pair is considered most-recently used. Returns the value associated with the key or None if the key-value pair doesn't exist in the cache. """ def get(self, key): if key in self.storage: node = self.storage[key] self.cache_list.move_to_front(node) return node.value[key] else: return None """ Adds the given key-value pair to the cache. The newly- added pair should be considered the most-recently used entry in the cache. If the cache is already at max capacity before this entry is added, then the oldest entry in the cache needs to be removed to make room. Additionally, in the case that the key already exists in the cache, we simply want to overwrite the old value associated with the key with the newly-specified value. """ def set(self, key, value): # if this is an existing key in the storage cache, # delete the corresponding node in the list if key in self.storage: self.cache_list.delete(self.storage[key]) self.num_nodes -= 1 self.cache_list.add_to_head({key: value}) self.storage[key] = self.cache_list.head self.num_nodes += 1 # if cache at max capacity if self.num_nodes > self.max_nodes: remove_key = list(self.cache_list.tail.value.keys())[0] del self.storage[remove_key] self.num_nodes -= 1
class LRUCache: """ Our LRUCache class keeps track of the max number of nodes it can hold, the current number of nodes it is holding, a doubly- linked list that holds the key-value entries in the correct order, as well as a storage dict that provides fast access to every node stored in the cache. """ def __init__(self, limit=10): self.limit = limit self.size = 0 self.storage = DoublyLinkedList() self.cache = {} # key : node pointer """ Retrieves the value associated with the given key. Also needs to move the key-value pair to the end of the order such that the pair is considered most-recently used. Returns the value associated with the key or None if the key-value pair doesn't exist in the cache. """ def get(self, key): if key in self.cache: #if key exists in cache returns value of node node = self.cache[key] self.storage.move_to_front(node) return node.value[1] else: return None #else returns none """ Adds the given key-value pair to the cache. The newly- added pair should be considered the most-recently used entry in the cache. If the cache is already at max capacity before this entry is added, then the oldest entry in the cache needs to be removed to make room. Additionally, in the case that the key already exists in the cache, we simply want to overwrite the old value associated with the key with the newly-specified value. """ def set(self, key, value): if key in self.cache: #Checks if key exists in cache and if yes node = self.cache[key] #grabs the node pointer self.storage.delete(node) #removes node from position in DLL self.storage.add_to_head((key, value)) #adds node to head self.cache[ key] = self.storage.head #updates the pointer in cache to head elif len(self.cache ) >= self.limit: #Checks if cache is over limit, if yes self.cache.pop( self.storage.tail.value[0]) #removes last item from cache self.storage.remove_from_tail() #removed last node from DLL self.storage.add_to_head((key, value)) #adds new node to DLL self.cache[ key] = self.storage.head #adds new item in cache pointing to new node else: self.size += 1 #updates size self.storage.add_to_head((key, value)) #adds new node to DLL self.cache[key] = self.storage.head #adds new pointer to cache
class Queue: def __init__(self): # self.size = 0 # Why is our DLL a good choice to store our elements? self.storage = DoublyLinkedList() self.length = 1 if self.storage == 1 else 0 # self.storage = ? def enqueue(self, value): # should add an item to the back of the queue self.storage.add_to_tail(value) self.length += 1 pass def dequeue(self): # should remove and return an item from the front of the queue if self.length != 0: value = self.storage.head.value self.storage.delete(self.storage.head) self.length -= 1 return value else: pass def len(self): # returns the number of items in the queue return self.length
class RingBuffer: def __init__(self, capacity): self.storage = DoublyLinkedList() self.capacity = capacity self.current_node = None def append(self, item): # normal insert if len(self.storage) < self.capacity: self.storage.add_to_tail(item) self.current_node = self.storage.tail else: if self.current_node == self.storage.tail: self.storage.remove_from_head() self.storage.add_to_head(item) self.current_node = self.storage.head else: self.storage.insert_after(self.current_node, item) self.current_node = self.current_node.next self.storage.delete(self.current_node.next) def get(self): # Note: This is the only [] allowed list_buffer_contents = [] # TODO: Your code here node = self.storage.head while node: list_buffer_contents.append(node.value) node = node.next return list_buffer_contents
class RingBuffer: def __init__(self, capacity): self.capacity = capacity self.current = None self.storage = DoublyLinkedList() def append(self, item): if len(self.storage) < self.capacity: self.storage.add_to_tail(item) self.current = self.storage.tail else: if self.current == self.storage.tail: self.storage.remove_from_head() self.storage.add_to_head(item) self.current = self.storage.head else: self.storage.overwrite(self.current, item) self.current = self.current.next self.storage.delete(self.current.next) def get(self): # Note: This is the only [] allowed list_buffer_contents = [] cur_node = self.storage.head while cur_node: list_buffer_contents.append(cur_node.value) cur_node = cur_node.next return list_buffer_contents
class LRUCache: """ Our LRUCache class keeps track of the max number of nodes it can hold, the current number of nodes it is holding, a doubly- linked list that holds the key-value entries in the correct order, as well as a storage dict that provides fast access to every node stored in the cache. """ def __init__(self, limit=10): self.limit = limit self.cache = DoublyLinkedList() self.dict = {} """ Retrieves the value associated with the given key. Also needs to move the key-value pair to the end of the order such that the pair is considered most-recently used. Returns the value associated with the key or None if the key-value pair doesn't exist in the cache. """ def get(self, key): if key in self.dict: value = self.dict[key] self.cache.move_to_end({key: value}) return value else: return None """ Adds the given key-value pair to the cache. The newly- added pair should be considered the most-recently used entry in the cache. If the cache is already at max capacity before this entry is added, then the oldest entry in the cache needs to be removed to make room. Additionally, in the case that the key already exists in the cache, we simply want to overwrite the old value associated with the key with the newly-specified value. """ def set(self, key, value): if self.cache.length == 0: self.cache.add_to_head({key: value}) self.dict[key] = value elif key in self.dict: self.cache.delete({key: value}) self.cache.add_to_tail({key: value}) self.dict[key] = value elif self.cache.length < self.limit and not key in self.dict: self.cache.add_to_tail({key: value}) self.dict[key] = value elif self.cache.length >= self.limit: deleted = self.cache.remove_from_head() deleted_key = [*deleted][0] del self.dict[deleted_key] self.cache.add_to_tail({key: value}) self.dict[key] = value
class RingBuffer: def __init__(self, capacity): self.capacity = capacity self.current = None self.storage = DoublyLinkedList() def append(self, item): if self.storage.length == self.capacity: # print(self.storage.length == self.capacity) # print(self.current['current'].next,' this is the item ', item) if self.current['count'] == self.storage.length: self.current['current'] = self.storage.head self.current['count'] = 0 if self.current['current'].next: new_current = self.current['current'].next self.current['current'].insert_after(item) self.storage.delete(self.current['current']) self.current['current'] = new_current self.current['count'] += 1 self.storage.add_to_tail(item) if self.current == None: self.current = {"current": self.storage.head, "count": 0} def get(self): # Note: This is the only [] allowed list_buffer_contents = [] node = self.storage.head for i in range(self.storage.length): if node: list_buffer_contents.append(node.value) node = node.next # TODO: Your code here return list_buffer_contents
class RingBuffer: def __init__(self, capacity): self.capacity = capacity self.current = None self.storage = DoublyLinkedList() def append(self, item): if self.storage.length < self.capacity: self.storage.add_to_head(item) self.current = self.storage.head else: if self.current is self.storage.head: self.storage.delete(self.storage.tail) self.storage.add_to_tail(item) self.current = self.storage.tail else: to_delete = self.current.prev self.storage.delete(to_delete) self.storage.insert_before(self.current, item) self.current = self.current.prev def get(self): # Note: This is the only [] allowed list_buffer_contents = [] i = self.storage.tail while i is not None: list_buffer_contents.append(i.value) i = i.prev return list_buffer_contents
class RingBuffer: def __init__(self, capacity): self.capacity = capacity self.current = None self.storage = DoublyLinkedList() def append(self, item): # 2 cases - capacity - length of dll = capacity and not # print("Initial: ", self.get(), " ", # self.storage.length, " Current: ", self.current) if self.storage.length == self.capacity: node = self.storage.head while node.value != self.current: node = node.next # print("val f: ", node.value) # print(self.storage.tail.value) # print(node == self.storage.tail) if node == self.storage.tail: self.storage.remove_from_head() self.storage.add_to_head(item) self.current = item else: if node.next == self.storage.tail: self.storage.remove_from_tail() self.storage.add_to_tail(item) else: self.storage.delete(node.next) node.insert_after(item) self.storage.length += 1 self.current = item # print("After: ", self.get(), " Current: ", self.current) else: self.storage.add_to_tail(item) self.current = item # print("After: ", self.get()) def get(self): # Note: This is the only [] allowed list_buffer_contents = [] # TODO: Your code here node = self.storage.head while node: list_buffer_contents.append(node.value) node = node.next return list_buffer_contents
class RingBuffer: def __init__(self, capacity): self.capacity = capacity self.current = None self.storage = DoublyLinkedList() self.length = 0 def append(self, item): if self.length < self.capacity: self.storage.add_to_tail(item) self.current = self.storage.tail self.length += 1 elif self.current == self.storage.tail: self.storage.remove_from_head() self.storage.add_to_head(item) self.current = self.storage.head else: new_node = ListNode(item, self.current, self.current.next) self.current.next.prev = new_node self.current.next = new_node self.storage.delete(new_node.next) self.current = new_node self.storage.length += 1 def get(self): # Note: This is the only [] allowed list_buffer_contents = [] # TODO: Your code here read_pointer = self.storage.head while len(list_buffer_contents) < self.length: list_buffer_contents.append(read_pointer.value) read_pointer = read_pointer.next return list_buffer_contents
class RingBuffer: def __init__(self, capacity): self.capacity = capacity self.current = None self.storage = DoublyLinkedList() def append(self, item): if self.storage.length < self.capacity: self.storage.add_to_tail(item) else: current_node = None node = self.storage.head while current_node is None and node is not None: if node.value == self.current: current_node = node node = node.next # Edge case for node at tail if current_node is self.storage.tail: self.storage.delete(self.storage.head) self.storage.add_to_head(item) else: current_node.insert_after(item) self.storage.delete(current_node) self.current = item def get(self): list_buffer_contents = [] node = self.storage.head while node is not None: list_buffer_contents.append(node.value) node = node.next return list_buffer_contents
class RingBuffer: def __init__(self, capacity): self.capacity = capacity self.current = None self.storage = DoublyLinkedList() def append(self, item): if self.capacity != self.storage.length: self.storage.add_to_tail(item) self.current = self.storage.tail else: if self.current.next: self.storage.delete(self.current.next) self.current.insert_after(item) self.storage.length += 1 self.current = self.current.next else: self.current = self.storage.head self.storage.delete(self.current) self.storage.add_to_head(item) self.current = self.storage.head def get(self): # Note: This is the only [] allowed list_buffer_contents = [] current = self.storage.head while current: list_buffer_contents.append(current.value) current = current.next return list_buffer_contents
class RingBuffer: def __init__(self, capacity): self.capacity = capacity self.current = None self.storage = DoublyLinkedList() def append(self, item): if self.current is None: self.current = self.storage.head if len(self.storage) == self.capacity: next_current = self.current.next self.current.insert_after(item) self.storage.delete(self.current) self.current = next_current # next_current = self.current.next # self.current.delete() # self.storage.add_to_head(item) # self.current = next_current else: self.storage.add_to_tail(item) def get(self): # Note: This is the only [] allowed list_buffer_contents = [] node = self.storage.head while node is not None: list_buffer_contents.append(node.value) node = node.next return list_buffer_contents
class LRUCache: def __init__(self, limit=10): self.list = DoublyLinkedList() self.dict = {} self.limit = limit def get(self, key): if key in self.dict: node = self.dict[key] self.list.delete(node) self.list.add_to_head(node) return node.value else: return None def set(self, key, value): if key in self.dict: node = self.dict[key] node.value = value if self.list.head is not node: self.list.delete(node) self.list.add_to_head(node) else: new_node = DoublyLinkedList(value) if len(self.list) >= self.limit: self.dict.pop(list(self.dict.keys())[1]) self.list.remove_from_tail() self.list.add_to_head(new_node) self.dict[key] = new_node
class Queue: def __init__(self): self.size = 0 # Why is our DLL a good choice to store our elements? self.storage = DoublyLinkedList() # LIFO - Push to tail/add to end def enqueue(self, value): self.storage.add_to_tail(value) self.size += 1 # Delete head def dequeue(self): if self.size > 0: # Save head node head = self.storage.head # Delete head self.storage.delete(head) self.size -= 1 # Return head value return head.value else: return None def len(self): return self.size
class LRUCache: """ Our LRUCache class keeps track of the max number of nodes it can hold, the current number of nodes it is holding, a doubly- linked list that holds the key-value entries in the correct order, as well as a storage dict that provides fast access to every node stored in the cache. """ def __init__(self, limit=10): self.limit = limit self.keyStorage = {} self.ageStorage = DoublyLinkedList() """ Retrieves the value associated with the given key. Also needs to move the key-value pair to the end of the order such that the pair is considered most-recently used. Returns the value associated with the key or None if the key-value pair doesn't exist in the cache. """ def get(self, key): if self.keyStorage.get(key, None) is None: return None node = self.keyStorage[key] value = node.value self.ageStorage.move_to_front(node) return value """ Adds the given key-value pair to the cache. The newly- added pair should be considered the most-recently used entry in the cache. If the cache is already at max capacity before this entry is added, then the oldest entry in the cache needs to be removed to make room. Additionally, in the case that the key already exists in the cache, we simply want to overwrite the old value associated with the key with the newly-specified value. """ def set(self, key, value): old = self.keyStorage.get(key, None) if old: self.ageStorage.delete(old) self.keyStorage.pop(key, None) if len(self.keyStorage) >= self.limit: tail = self.ageStorage.tail oldKey = tail.key self.keyStorage.pop(oldKey, None) self.ageStorage.remove_from_tail() self.ageStorage.add_to_head(value, key) self.keyStorage[key] = self.ageStorage.head def __len__(self): return len(self.keyStorage)
class LRUCache: """ Our LRUCache class keeps track of the max number of nodes it can hold, the current number of nodes it is holding, a doubly- linked list that holds the key-value entries in the correct order, as well as a storage dict that provides fast access to every node stored in the cache. """ def __init__(self, limit=10): self.limit = limit self.storage = DoublyLinkedList() self.storage_dict = {} """ Retrieves the value associated with the given key. Also needs to move the key-value pair to the end of the order such that the pair is considered most-recently used. Returns the value associated with the key or None if the key-value pair doesn't exist in the cache. """ def get(self, key): if key not in self.storage_dict: # Check if key exists return None node = self.storage_dict[key] # Get key's node self.storage.move_to_front(node) # Move to head self.storage_dict[key] = self.storage.head # Update key return self.storage_dict[key].value """ Adds the given key-value pair to the cache. The newly- added pair should be considered the most-recently used entry in the cache. If the cache is already at max capacity before this entry is added, then the oldest entry in the cache needs to be removed to make room. Additionally, in the case that the key already exists in the cache, we simply want to overwrite the old value associated with the key with the newly-specified value. """ def set(self, key, value): if key in self.storage_dict: # Delete if exists self.storage.delete(self.storage_dict[key]) self.storage.add_to_head( value) # Add value to head and add to the dict self.storage_dict[key] = self.storage.head while len(self.storage) > self.limit: # Cleanup if size > limit node = self.storage.tail keys = list(self.storage_dict.keys()) for i in keys: if self.storage_dict[i] == node: self.storage_dict.pop(i) break self.storage.remove_from_tail()
class LRUCache: """ Our LRUCache class keeps track of the max number of nodes it can hold, the current number of nodes it is holding, a doubly- linked list that holds the key-value entries in the correct order, as well as a storage dict that provides fast access to every node stored in the cache. """ def __init__(self, limit=10): self.limit = limit self.dll = DoublyLinkedList() self.storage = dict() """ Retrieves the value associated with the given key. Also needs to move the key-value pair to the end of the order such that the pair is considered most-recently used. Returns the value associated with the key or None if the key-value pair doesn't exist in the cache. """ def get(self, key): if key in self.storage.keys(): old_node = self.storage[key] new_node = self.dll.move_to_front(old_node) self.storage[key] = new_node return new_node.value[key] else: return None """ Adds the given key-value pair to the cache. The newly- added pair should be considered the most-recently used entry in the cache. If the cache is already at max capacity before this entry is added, then the oldest entry in the cache needs to be removed to make room. Additionally, in the case that the key already exists in the cache, we simply want to overwrite the old value associated with the key with the newly-specified value. """ def set(self, key, value): if key in self.storage.items(): node = self.storage[key] node.value = {key: value} return self.dll.move_to_front(node) new_node = self.dll.add_to_head({key: value}) self.storage[key] = new_node if len(self.storage) > self.limit: node_to_remove = self.dll.tail key_to_remove = next(iter(node_to_remove.value)) self.storage.pop(key_to_remove, None) self.dll.delete(node_to_remove)
class LRUCache: """ Our LRUCache class keeps track of the max number of nodes it can hold, the current number of nodes it is holding, a doubly- linked list that holds the key-value entries in the correct order, as well as a storage dict that provides fast access to every node stored in the cache. """ def __init__(self, limit=10): self.limit = limit self.storage = {} self.dll = DoublyLinkedList() """ Retrieves the value associated with the given key. Also needs to move the key-value pair to the end of the order such that the pair is considered most-recently used. Returns the value associated with the key or None if the key-value pair doesn't exist in the cache. """ def get(self, key): if self.storage.get(key): node = self.storage[key] self.dll.move_to_front(node) return node.value[1] """ Adds the given key-value pair to the cache. The newly- added pair should be considered the most-recently used entry in the cache. If the cache is already at max capacity before this entry is added, then the oldest entry in the cache needs to be removed to make room. Additionally, in the case that the key already exists in the cache, we simply want to overwrite the old value associated with the key with the newly-specified value. """ def set(self, key, value): if self.storage.get(key): node = self.storage[key] node.value = (key, value) self.dll.move_to_front(node) else: node = ListNode((key, value)) self.dll.add_to_head(node) self.storage[node.value[0]] = node print(self.storage) if len(self.storage) > self.limit: node = self.dll.remove_from_tail() print(f"In set function: {node}") self.storage[node.value[0]] = None self.dll.delete(node)
class LRUCache: """ Our LRUCache class keeps track of the max number of nodes it can hold, the current number of nodes it is holding, a doubly- linked list that holds the key-value entries in the correct order, as well as a storage dict that provides fast access to every node stored in the cache. """ def __init__(self, limit=10): self.limit = limit self.storage = DoublyLinkedList() self.dict = {} """ Retrieves the value associated with the given key. Also needs to move the key-value pair to the end of the order such that the pair is considered most-recently used. Returns the value associated with the key or None if the key-value pair doesn't exist in the cache. """ def get(self, key): if key in self.dict: node = self.dict[key] self.storage.move_to_front(node) # Return the value at the 1 index or the actual value as 0 should hold prev value in a doubly linked list return node.value[1] else: return None """ Adds the given key-value pair to the cache. The newly- added pair should be considered the most-recently used entry in the cache. If the cache is already at max capacity before this entry is added, then the oldest entry in the cache needs to be removed to make room. Additionally, in the case that the key already exists in the cache, we simply want to overwrite the old value associated with the key with the newly-specified value. """ def set(self, key, value): # check if the key passed already exists, if so delete the stored value to update at the end if key in self.dict: self.storage.delete(self.dict[key]) # check if limit has been reached and if so removed oldest node from tail elif len(self.storage) >= self.limit: node = self.storage.remove_from_tail() # delete oldest entry del self.dict[node[0]] # add this new value to the head of the list and make updated key in dictionary for reference self.storage.add_to_head((key, value)) self.dict[key] = self.storage.head
class LRUCache: """ Our LRUCache class keeps track of the max number of nodes it can hold, the current number of nodes it is holding, a doubly- linked list that holds the key-value entries in the correct order, as well as a storage dict that provides fast access to every node stored in the cache. """ def __init__(self, limit=10): self.limit = limit self.storage = DoublyLinkedList() """ Retrieves the value associated with the given key. Also needs to move the key-value pair to the end of the order such that the pair is considered most-recently used. Returns the value associated with the key or None if the key-value pair doesn't exist in the cache. """ def get(self, key): temp = self.storage.head while temp: if temp.value[0] == key: self.storage.move_to_front(temp) return temp.value[1] temp = temp.next """ Adds the given key-value pair to the cache. The newly- added pair should be considered the most-recently used entry in the cache. If the cache is already at max capacity before this entry is added, then the oldest entry in the cache needs to be removed to make room. Additionally, in the case that the key already exists in the cache, we simply want to overwrite the old value associated with the key with the newly-specified value. """ def set(self, key, value): temp = self.storage.head while temp: if temp.value[0] == key: self.storage.delete(temp) temp.value = [key, value] self.storage.add_to_head([key, value]) return True temp = temp.next if (self.storage.length >= self.limit): self.storage.remove_from_tail() self.storage.add_to_head([key, value]) return True
class RingBuffer: def __init__(self, capacity): self.capacity = capacity self.current_oldest = None self.storage = DoublyLinkedList() def append(self, item): # If we reach the capacity of the buffer set the current pointer back to the beginning if self.current_oldest is None: self.current_oldest = self.storage.head #Is there anything in our list yet? If not add the first item and #capacity full case if self.storage.length == self.capacity and self.current_oldest == self.storage.head: #yes? self.storage.remove_from_head() self.storage.add_to_head(item) self.current_oldest = self.current_oldest.next # set value #move current_oldest elif self.storage.length == self.capacity and self.current_oldest == self.storage.tail: self.storage.remove_from_tail() self.storage.add_to_tail(item) self.current_oldest = self.storage.head #set value #set current oldnest #capacity not full case #insert item and intialize current oldest value elif self.storage.length >= self.capacity: self.current_oldest.insert_before(item) self.storage.length += 1 temp = self.current_oldest.next self.storage.delete(self.current_oldest) self.current_oldest = temp else: #No? self.storage.add_to_tail(item) def get(self): # Note: This is the only [] allowed list_buffer_contents = [] # TODO: Your code here # getting the current value from head current = self.storage.head # loop till end of list while current: # add the current value to list list_buffer_contents.append(current.value) # set up next value current = current.next return list_buffer_contents
class LRUCache: def __init__(self, limit: int = 10): """ Our LRUCache class keeps track of the max number of nodes it can hold, the current number of nodes it is holding, a doubly- linked list that holds the key-value entries in the correct order, as well as a storage dict that provides fast access to every node stored in the cache. """ self._cache = {} self._storage = DoublyLinkedList() self._limit = limit def get(self, key: str): """ Retrieves the value associated with the given key. Also needs to move the key-value pair to the end of the order such that the pair is considered most-recently used. Returns the value associated with the key or None if the key-value pair doesn't exist in the cache. """ if key in self._cache: self._storage.move_to_front(self._cache[key]) return self._cache[key].value[1] else: return None def set(self, key: str, value): """ Adds the given key-value pair to the cache. The newly- added pair should be considered the most-recently used entry in the cache. If the cache is already at max capacity before this entry is added, then the oldest entry in the cache needs to be removed to make room. Additionally, in the case that the key already exists in the cache, we simply want to overwrite the old value associated with the key with the newly-specified value. """ if key in self._cache: self._storage.delete(self._cache[key]) del self._cache[key] if len(self._storage) >= self._limit: last = self._storage.tail del self._cache[last.value[0]] self._storage.delete(last) self._storage.add_to_head((key, value)) self._cache[key] = self._storage.head
def test_delete_non_existing(self): list = DoublyLinkedList() list.insertLast(1, {"a": 1}) list.insertLast(2, {"b": 2}) list.insertAfter(2, 3, {"c": 3}) self.assertEqual(list.delete(4), None) self.assertEqual(len(list.array()), 3)
class RingBuffer: def __init__(self, capacity): self.capacity = capacity self.current = None self.storage = DoublyLinkedList() def append(self, item): if self.capacity == self.storage.length: # if self.current is the tail if self.current == self.storage.tail: # then remove from head, add item to head, self.storage.remove_from_head() self.storage.add_to_head(item) # and point current to head self.current = self.storage.head # else insert after current else: self.current.insert_after(item) # change current to currents next self.storage.length += 1 self.current = self.current.next # delete what is after the new current self.storage.delete(self.current.next) # else just add the new item to the tail else: self.storage.add_to_tail(item) # make it the current self.current = self.storage.tail def get(self): # Note: This is the only [] allowed list_buffer_contents = [] current = self.storage.head # TODO: Your code here # if it is only one node if self.storage.length == 1: # append head.value to the list[] list_buffer_contents.append(self.storage.head.value) # while next is not pointing to none/while we have not reached the tail elif self.storage.length > 1: while current.next: # append the value of each node to the list list_buffer_contents.append(current.value) # and move current node ahead one step current = current.next list_buffer_contents.append(current.value) return list_buffer_contents
class RingBuffer: def __init__(self, capacity): self.capacity = capacity self.current = None self.storage = DoublyLinkedList() def append(self, item): if self.storage.length == 0: self.storage.add_to_head(item) self.current = self.storage.head #nothing in DLL, add item to start elif self.storage.length < self.capacity: self.storage.add_to_tail(item) self.current = self.storage.tail #still have room in DLL, add item to list elif self.current is self.storage.tail: self.storage.remove_from_head() self.storage.add_to_head(item) self.current = self.storage.head # if current is the last item in list # remove item from start # add this new item to the start # now current is the head of the DLL else: self.current.insert_after(item) self.storage.length += 1 self.current = self.current.next self.storage.delete(self.current.next) # insert item after current # increase length of DLL by 1 # set current to next # deletes the next item to allow new items # in DLL as long as not over capacity. def get(self): # Note: This is the only [] allowed list_buffer_contents = [] #empty list current = self.storage.head #start of DLL set to variable name current while current is not None: # as long as current has a value: list_buffer_contents.append(current.value) #add value of current to end of empty list created current = current.next #and repeat with each num return list_buffer_contents
class RingBuffer: def __init__(self, capacity): self.capacity = capacity self.current = None self.storage = DoublyLinkedList() def append(self, item): # if key in self.storage: if self.storage.length >= 0 and self.storage.length < self.capacity: # node = self.storage[key] # node.value = (key, value) # self.storage.move_to_end(item) self.storage.add_to_tail(item) self.current = self.storage.tail # return # if self.current_num_of_node == self.limit: # elif self.storage.length == self.capacity: elif self.current == self.storage.tail: # del self.storage[self.key_value_entries.head.value[0]] # self.key_value_entries.remove_from_head() self.storage.remove_from_head() self.storage.add_to_head(item) self.current = self.storage.head # self.current_num_of_node -= 1 else: # self.key_value_entries.add_to_tail((key, value)) self.current.insert_after(item) # self.storage[key] = self.key_value_entries.tail # self.current_num_of_node += 1 self.storage.length += 1 self.current = self.current.next self.storage.delete(self.current.next) def get(self): # Note: This is the only [] allowed list_buffer_contents = [] # TODO: Your code here current = self.storage.head while current != None: list_buffer_contents.append(current.value) current = current.next return list_buffer_contents
def test_delete(self): """ Tests that a Node has been deleted from the list """ dll = DoublyLinkedList() dll.add_to_head(1) dll.add_to_head(344) dll.add_to_head(7) node = dll.head dll.add_to_head(3) dll.delete(node) found_val = False current_node = dll.head while current_node: if current_node.value == 7: found_val = True current_node = current_node.next self.assertEqual(found_val, False)
def testDeletionAndSearch(self): dlist = DoublyLinkedList() dlist.insert_beginning(10) dlist.insert_beginning(11) dlist.insert_beginning(16) dlist.insert_beginning(13) found = dlist.search(11) self.assertEqual(found.value, 11) dlist.delete(found) actual = to_array(dlist) expected = [13, 16, 10] self.assertEqual(expected, actual) found = dlist.search(11) self.assertIsNone(found)
def test_doubly_linked_list_delete(self): doubly_linked_list = DoublyLinkedList() doubly_linked_list.append(25) doubly_linked_list.append("Riccardo") doubly_linked_list.append("Try") doubly_linked_list.insert(6, 3) self.assertIsNotNone(doubly_linked_list) self.assertTrue(doubly_linked_list.__len__() == 4) self.assertTrue(doubly_linked_list.tail.item == 6) doubly_linked_list.delete(3) self.assertTrue(doubly_linked_list.__len__() == 3) self.assertTrue(doubly_linked_list.tail.item == "Try") self.assertFalse(doubly_linked_list.tail.item == 6) self.assertTrue(doubly_linked_list.head.item == 25) self.assertFalse(doubly_linked_list.head.next.item == "Try") self.assertTrue(doubly_linked_list.head.next.item == "Riccardo") doubly_linked_list.delete(0) self.assertTrue(doubly_linked_list.head.item == "Riccardo") self.assertTrue(doubly_linked_list.head.next.item == "Try")