def test_removeTail(self):
		dll = DoublyLinkedList(range(10))
		sanity = range(10)
		for i in xrange(10):
			dll.removeTail()
			sanity.pop(-1)
			self.assertEqual(dll, sanity)
	def test_eq(self):
		dll = DoublyLinkedList(range(10))
		dll2 = DoublyLinkedList()
		for i in xrange(10-1):
			dll2.addToTail(i)
			self.assertFalse(dll == dll2)
		dll2.addToTail(i+1)
		self.assertTrue(dll == dll2)
    def test_doubly_linked_list_search(self):

        doubly_linked_list = DoublyLinkedList()
        doubly_linked_list.append(25)
        pos = doubly_linked_list.search(25)
        self.assertIsNotNone(doubly_linked_list)
        self.assertTrue(pos == 0)
        doubly_linked_list.append("Riccardo")
        pos = doubly_linked_list.search("Riccardo")
        self.assertEqual(pos,1)
        doubly_linked_list.insert_head("Prova")
        pos = doubly_linked_list.search("Prova")
        self.assertTrue(pos == 0)
    def testInsertion(self):
        dlist = DoublyLinkedList()
        dlist.insert_beginning(10)
        dlist.insert_beginning(11)

        expected = [11, 10]
        actual = to_array(dlist)
        self.assertEqual(expected, actual)

        dlist.insert_beginning(12)

        actual = to_array(dlist)
        expected = [12, 11, 10]
        self.assertEqual(expected, actual)
Example #5
0
	def setUp(self):
		self.emptyList = DoublyLinkedList()
		self.oneItemList = DoublyLinkedList()
		self.twoItemList = DoublyLinkedList()
		self.fiveItemList = DoublyLinkedList()

		self.one = [3]
		self.two = [2, 9]
		self.five = [6, 1, 0, 5, 8]

		for i in self.one:
			self.oneItemList.append(i)

		for i in self.two:
			self.twoItemList.append(i)

		for i in self.five:
			self.fiveItemList.append(i)
 def test_LinkedList_search(self):
     l1 = DoublyLinkedList()
     l1.insert(0)
     l1.insert(1)
     l1.insert(2)
     Node2 = l1.search(2)
     self.assertEqual(Node2.val, 2)
     Node0 = l1.search(0)
     self.assertEqual(Node0.val, 0)
     Node1 = l1.search(1)
     self.assertEqual(Node1.val, 1)
    def test_DoublyLinkedList___repr__(self):
        l1 = DoublyLinkedList()
        l1.insert(0)
        l1.insert(1)
        l1.insert(2)

        self.assertEquals(l1.__repr__(), "(2, 1, 0)")
    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_insert_head(self):

        doubly_linked_list = DoublyLinkedList()
        doubly_linked_list.insert_head(25)
        self.assertIsNotNone(doubly_linked_list)
        self.assertTrue(doubly_linked_list.__len__() == 1)
        doubly_linked_list.insert_head("Riccardo")
        self.assertTrue(doubly_linked_list.__len__() == 2)
        self.assertTrue(doubly_linked_list.head.item == "Riccardo")
        self.assertFalse(doubly_linked_list.head.next.item == "Riccardo")
        self.assertTrue(doubly_linked_list.head.next.item == 25)
	def test_AddToHead_and_addToTail(self):
		l = DoublyLinkedList()
		sanity = []
		for i in xrange(8):
			if i % 2 == 0:
				l.addToHead(i)
				sanity = [i] + sanity
			else:
				l.addToTail(i)
				sanity.append(i)
			self.assertEqual(list(l), sanity)
		
		l = DoublyLinkedList()
		sanity = []
		for i in xrange(8):
			if i % 2 == 1:
				l.addToHead(i)
				sanity = [i] + sanity
			else:
				l.addToTail(i)
				sanity.append(i)
			self.assertEqual(list(l), sanity)
    def test_doubly_linked_list_append(self):

        doubly_linked_list = DoublyLinkedList()
        doubly_linked_list.append(25)
        self.assertIsNotNone(doubly_linked_list)
        self.assertTrue(doubly_linked_list.__len__() == 1)
        doubly_linked_list.append("Riccardo")
        self.assertTrue(doubly_linked_list.__len__() == 2)
        self.assertTrue(doubly_linked_list.head.item == 25)
        self.assertTrue(doubly_linked_list.tail.item == "Riccardo")
        self.assertEqual(doubly_linked_list.tail.next, None)
        self.assertTrue(doubly_linked_list.head.next.item == "Riccardo")
        self.assertFalse(doubly_linked_list.head.next.item == "25")
        doubly_linked_list.append("Try")
        self.assertTrue(doubly_linked_list.head.item == 25)
        self.assertTrue(doubly_linked_list.head.next.item == "Riccardo")
        self.assertTrue(doubly_linked_list.tail.item == "Try")
        self.assertTrue(doubly_linked_list.head.next.item == "Riccardo")
        self.assertEqual(doubly_linked_list.tail.next, None)
Example #12
0
	def __init__(self, max_size, plan_b_func):
		"max_size: the largest number of items the cache can have."
		"plan_b_func: the function that will be called with the query as its"
		"             argument if a query isn't cached. The result will then"
		"             be associated with the query."
		
		if max_size < 0:
			raise ValueError("max_size must be positive.")
		if not callable(plan_b_func):
			raise TypeError("plan_b_func must be callable.")
			
		self.max_size = max_size
		self.ht = {}
		self.ll = DoublyLinkedList()
		self.plan_b_func = plan_b_func
Example #13
0
 def __init__(self, limit=10):
     self.limit = limit
     self.current_entries = 0
     self.cache = DoublyLinkedList()
     self.storage = {}
class DoublyLinkedListTests(unittest.TestCase):
    def setUp(self):
        self.node = ListNode(1)
        self.dll = DoublyLinkedList(self.node)

    def test_list_remove_from_tail(self):
        self.dll.remove_from_tail()
        self.assertIsNone(self.dll.head)
        self.assertIsNone(self.dll.tail)
        self.assertEqual(len(self.dll), 0)

        self.dll.add_to_tail(33)
        self.assertEqual(self.dll.head.value, 33)
        self.assertEqual(self.dll.tail.value, 33)
        self.assertEqual(len(self.dll), 1)
        self.assertEqual(self.dll.remove_from_tail(), 33)
        self.assertEqual(len(self.dll), 0)

        self.dll.add_to_tail(68)
        self.assertEqual(len(self.dll), 1)
        self.assertEqual(self.dll.remove_from_tail(), 68)
        self.assertEqual(len(self.dll), 0)
    #
    def test_list_remove_from_head(self):
        self.dll.remove_from_head()
        self.assertIsNone(self.dll.head)
        self.assertIsNone(self.dll.tail)
        self.assertEqual(len(self.dll), 0)

        self.dll.add_to_head(2)
        self.assertEqual(self.dll.head.value, 2)
        self.assertEqual(self.dll.tail.value, 2)
        self.assertEqual(len(self.dll), 1)
        self.assertEqual(self.dll.remove_from_head(), 2)
        self.assertEqual(len(self.dll), 0)

        self.dll.add_to_head(55)
        self.assertEqual(len(self.dll), 1)
        self.assertEqual(self.dll.remove_from_head(), 55)
        self.assertEqual(len(self.dll), 0)
    #
    def test_list_add_to_tail(self):
        self.assertEqual(self.dll.tail.value, 1)
        self.assertEqual(len(self.dll), 1)

        self.dll.add_to_tail(30)
        self.assertEqual(self.dll.tail.prev.value, 1)
        self.assertEqual(self.dll.tail.value, 30)
        self.assertEqual(len(self.dll), 2)

        self.dll.add_to_tail(20)
        self.assertEqual(self.dll.tail.prev.value, 30)
        self.assertEqual(self.dll.tail.value, 20)
        self.assertEqual(len(self.dll), 3)
    #
    def test_list_add_to_head(self):
        self.assertEqual(self.dll.head.value, 1)

        self.dll.add_to_head(10)
        self.assertEqual(self.dll.head.value, 10)
        self.assertEqual(self.dll.head.next.value, 1)
        self.assertEqual(len(self.dll), 2)

    def test_list_move_to_end(self):
        self.dll.add_to_head(40)
        self.assertEqual(self.dll.tail.value, 1)
        self.assertEqual(self.dll.head.value, 40)

        self.dll.move_to_end(self.dll.head)
        self.assertEqual(self.dll.tail.value, 40)
        self.assertEqual(self.dll.tail.prev.value, 1)
        self.assertEqual(len(self.dll), 2)

        self.dll.add_to_tail(4)
        self.dll.move_to_end(self.dll.head.next)
        self.assertEqual(self.dll.tail.value, 40)
        self.assertEqual(self.dll.tail.prev.value, 4)
        self.assertEqual(len(self.dll), 3)

    def test_list_move_to_front(self):
        self.dll.add_to_tail(3)
        self.assertEqual(self.dll.head.value, 1)
        self.assertEqual(self.dll.tail.value, 3)

        self.dll.move_to_front(self.dll.tail)
        self.assertEqual(self.dll.head.value, 3)
        self.assertEqual(self.dll.head.next.value, 1)
        self.assertEqual(len(self.dll), 2)

        self.dll.add_to_head(29)
        self.dll.move_to_front(self.dll.head.next)
        self.assertEqual(self.dll.head.value, 3)
        self.assertEqual(self.dll.head.next.value, 29)
        self.assertEqual(len(self.dll), 3)

    def test_list_delete(self):
        self.dll.delete(self.node)
        self.assertIsNone(self.dll.head)
        self.assertIsNone(self.dll.tail)
        self.assertEqual(len(self.dll), 0)

        self.dll.add_to_tail(1)
        self.dll.add_to_head(9)
        self.dll.add_to_tail(6)

        self.dll.delete(self.dll.head)
        self.assertEqual(self.dll.head.value, 1)
        self.assertEqual(self.dll.tail.value, 6)
        self.assertEqual(len(self.dll), 2)

        self.dll.delete(self.dll.head)
        self.assertEqual(self.dll.head.value, 6)
        self.assertEqual(self.dll.tail.value, 6)
        self.assertEqual(len(self.dll), 1)

    def test_get_max(self):
        self.assertEqual(self.dll.get_max(), 1)
        self.dll.add_to_tail(100)
        self.assertEqual(self.dll.get_max(), 100)
        self.dll.add_to_tail(55)
        self.assertEqual(self.dll.get_max(), 100)
        self.dll.add_to_tail(101)
        self.assertEqual(self.dll.get_max(), 101)
Example #15
0
 def __init__(self, init=None):
     self.contents = DoublyLinkedList()
     # check if an init string is provided
     # if so, put the contents of the init string in self.contents
     if init:
         self.append(init)
Example #16
0
 def __init__(self):
     DoublyLinkedList.__init__(self)     # create the empty list
 def test_DoublyLinkedList_size(self):
     l1 = DoublyLinkedList()
     self.assertEqual(l1.size(), 0)
     l1.insert(0)
     self.assertEqual(l1.size(), 1)
     l1.insert(1)
     self.assertEqual(l1.size(), 2)
     l1.insert(2)
     self.assertEqual(l1.size(), 3)
     l1.remove_val(2)
     self.assertEqual(l1.size(), 2)
     l1.remove_val(0)
     self.assertEqual(l1.size(), 1)
     l1.remove_val(1)
     self.assertEqual(l1.size(), 0)
	def test_copy(self):
		dll = DoublyLinkedList(range(10))
		dll2 = dll.copy()
		self.assertEqual(dll, dll2)
		self.assertTrue(dll is not dll2)
	def test_addToTail(self):
		l = DoublyLinkedList()
		for i in xrange(4):
			self.assertIs(l.size, i)
			l.addToTail(i)
			self.assertEqual(list(l), range(0, i+1))
Example #20
0
 def __init__(self, limit=10):
     self.max = limit
     self.cache = DoublyLinkedList()
     self.size = 0
     self.storage = dict()
Example #21
0
# Count += 1

# If length/2  != old middle
#     Update the middle
#     New_middle = old_middle.next
#     If same
#         Continue
#     If current_node.next == None:
#         break

import sys

sys.path.append('G:/Data/Lambda/CS/Data-Structures/doubly_linked_list')
from doubly_linked_list import DoublyLinkedList

test_list = DoublyLinkedList()

a = [1, 34, 54, 3, 4, 6, 5, 3, 2]
for i in a:
    test_list.add_to_tail(i)


def find_middle(sll):
    count = 0
    current_node = sll.head  # maybe we can't use head ? come back and check.
    middle_value = current_node.value
    middle_node = current_node
    middle_position = 0
    # todo edge case for length of 1
    while True:
        current_node = current_node.next
Example #22
0
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.storage = dict()
        self.order = DoublyLinkedList()
        self.size = 0
        self.limit = limit

    """
    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):
        # Get the item or handle none
        # Move to front
        if key in self.storage:
            node = self.storage[key]
            self.order.move_to_end(node)
            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):
        if key in self.storage:
            node = self.storage[key]
            node.value = (key, value)
            self.order.move_to_end(node)
            return
        if self.size == self.limit:
            node = self.order.head  # Get the oldest node in the cache
            node_value = node.value  # Tuple storing (key, value)
            key_for_dict = node_value[0]  # get key for dict
            del self.storage[key_for_dict]
            self.order.remove_from_head()
            # del self.storage[self.order.remove_from_head()[0]] # Another way to write above 2 lines
            self.size -= 1

        # Adds the given key-value pair to the cache.
        # Add to LL at the tail
        self.order.add_to_tail((key, value))
        # Add to dictionary
        self.storage[key] = self.order.tail
        self.size += 1
Example #23
0
 def __init__(self):
     """Create new instance of Queue class object."""
     self.queue = DoublyLinkedList()
     self.is_empty = True
Example #24
0
 def __init__(self, init=None):
     self.contents = DoublyLinkedList()
     if init:
         for char in init:
             self.contents.add_to_tail(char)
    def test_DoublyLinkedList_append(self):
        l1 = DoublyLinkedList()
        l1.append(0)

        # ensure Node(0) added to list
        Node0 = l1.head
        self.assertIsNotNone(l1.head)
        self.assertIsNotNone(l1.tail)
        self.assertEqual(Node0.val, 0)
        self.assertIsNone(Node0.link)

        # ensure Node(1) appended to back of list
        l1.append(1)
        Node0 = l1.head
        self.assertEqual(Node0.val, 0)
        self.assertIsNotNone(Node0.link)

        # ensure Node(0) is next in list
        Node1 = Node0.link
        self.assertEqual(Node1.val, 1)
        self.assertIsNone(Node1.link)

        # ensure adding 'None' adds something
        sz1 = l1.size()
        l1.append(None)
        self.assertEqual(sz1+1, l1.size())

        # ensure adding recursively adds nothing
        sz1 = l1.size()
        l1.append(l1)
        self.assertEqual(sz1, l1.size())
    def test_DoublyLinkedList_insert(self):
        l1 = DoublyLinkedList()
        l1.insert(0)

        # ensure Node(0) added to list
        Node0 = l1.head
        self.assertEqual(Node0.val, 0)
        self.assertIsNone(Node0.link)
        self.assertIsNone(Node0.link2)

        # ensure Node(1) added to front of list
        l1.insert(1)
        Node1 = l1.head
        self.assertEqual(Node1.val, 1)
        self.assertIsNotNone(Node1.link)
        self.assertEqual(Node1.link, Node0)
        self.assertEqual(Node0.link2, Node1)

        # ensure Node(0) is next in list
        Node0 = Node1.link
        self.assertEqual(Node0.val, 0)
        self.assertIsNone(Node0.link)
        self.assertIsNotNone(Node0.link2)

        # ensure adding 'None' adds something
        sz1 = l1.size()
        l1.insert(None)
        self.assertEqual(sz1+1, l1.size())

        # ensure adding recursively adds nothing
        sz1 = l1.size()
        l1.insert(l1)
        self.assertEqual(sz1, l1.size())
Example #27
0
 def __init__(self):
     self.size = 0
     # Why is our DLL a good choice to store our elements?
     self.storage = DoublyLinkedList()
Example #28
0
 def __init__(self):
     """Initialize Deque using DoublyLinkedList methods."""
     self._doubly_linked_list = DoublyLinkedList()
class TestDoublyLinkedList(unittest.TestCase):

    def setUp(self):
        self.my_list = DoublyLinkedList()

    def test_basic_initialization_and_repr(self):
        self.assertEqual(repr(self.my_list), '[]')

    def test_append(self):
        self.my_list.append(4)
        self.my_list.append(3)
        self.my_list.append(7)
        self.my_list.append(-17)
        self.assertEqual(repr(self.my_list), '[4, 3, 7, -17]')

    def test_prepend(self):
        self.my_list.prepend(4)
        self.my_list.prepend(3)
        self.my_list.prepend(7)
        self.my_list.prepend(-17)
        self.assertEqual(repr(self.my_list), '[-17, 7, 3, 4]')

    def test_insert_after(self):
        self.my_list.insert_after(None, 4)
        self.my_list.insert_after(None, 3)
        self.my_list.insert_after(self.my_list.tail, 7)
        self.my_list.insert_after(self.my_list.head, -17)
        self.assertEqual(repr(self.my_list), '[3, -17, 4, 7]')

    def test_insert_sorted(self):
        self.my_list.insert_after(None, 4)
        self.my_list.insert_after(None, 3)
        self.my_list.insert_after(None, 7)
        self.assertEqual(repr(self.my_list), '[7, 3, 4]')
        self.my_list.insert_sorted(2)
        self.my_list.insert_sorted(8)
        self.assertEqual(repr(self.my_list), '[2, 7, 3, 4, 8]')
        self.my_list.remove(self.my_list.head)
        self.my_list.remove(self.my_list.head)
        self.my_list.remove(self.my_list.head)
        self.my_list.remove(self.my_list.head)
        self.my_list.remove(self.my_list.head)
        self.my_list.insert_sorted(8)
        self.my_list.insert_sorted(7)
        self.my_list.insert_sorted(6)
        self.my_list.insert_sorted(5)
        self.assertEqual(repr(self.my_list), '[5, 6, 7, 8]')

    def test_remove(self):
        self.my_list.append(4)
        self.my_list.append(3)
        self.my_list.append(7)
        self.my_list.append(-17)
        self.assertEqual(repr(self.my_list), '[4, 3, 7, -17]')
        self.my_list.remove(self.my_list.head)
        self.assertEqual(repr(self.my_list), '[3, 7, -17]')
        self.my_list.remove(self.my_list.head.next)
        self.assertEqual(repr(self.my_list), '[3, -17]')
        self.my_list.remove(self.my_list.tail)
        self.assertEqual(repr(self.my_list), '[3]')
        self.my_list.remove(self.my_list.head)
        self.my_list.remove(self.my_list.head)
        self.assertEqual(repr(self.my_list), '[]')

    def test_array(self):
        self.my_list.append(4)
        self.my_list.append(3)
        self.my_list.append(7)
        self.my_list.append(-17)
        self.assertEqual(self.my_list.array(), [4, 3, 7, -17])

    def test_reverse_array(self):
        self.my_list.append(4)
        self.my_list.append(3)
        self.my_list.append(7)
        self.my_list.append(-17)
        self.assertEqual(self.my_list.reverse_array(), [-17, 7, 3, 4])

    def test_search(self):
        self.my_list.append(4)
        self.my_list.append(3)
        self.my_list.append(-17)
        self.my_list.append(7)
        self.assertEqual(self.my_list.search(4).data, 4)
        self.assertEqual(self.my_list.search(3).data, 3)
        self.assertEqual(self.my_list.search(-17).data, -17)
        self.assertEqual(self.my_list.search(17), None)

    def test_reverse(self):
        self.my_list.append(4)
        self.my_list.append(3)
        self.my_list.append(7)
        self.my_list.append(-17)
        self.assertEqual(repr(self.my_list), '[4, 3, 7, -17]')
        self.my_list.reverse()
        self.assertEqual(repr(self.my_list), '[-17, 7, 3, 4]')
        self.my_list.reverse()
        self.assertEqual(repr(self.my_list), '[4, 3, 7, -17]')

    def test_remove_duplicates(self):
        self.my_list.append(4)
        self.my_list.append(3)
        self.my_list.append(3)
        self.my_list.append(3)
        self.my_list.append(7)
        self.my_list.append(-17)
        self.assertEqual(repr(self.my_list), '[4, 3, 3, 3, 7, -17]')
        self.my_list.remove_duplicates()
        self.assertEqual(repr(self.my_list), '[4, 3, 7, -17]')
Example #30
0
 def __init__(self, limit=10):
     self.limit = limit
     self.currentNumberOfNode = 0
     self.list = DoublyLinkedList()
     self.storage = {}
    def test_doubly_linked_list_insert(self):

        doubly_linked_list = DoublyLinkedList()
        with self.assertRaises(ValueError):
            doubly_linked_list.insert(99, 5)
        print doubly_linked_list.append(25)
        print doubly_linked_list.append("Riccardo")
        print doubly_linked_list.append("Try")
        print doubly_linked_list.insert(6, 3)
        self.assertTrue(doubly_linked_list.tail.previous.item == "Try")
        self.assertEqual(doubly_linked_list.tail.next, None)
        self.assertTrue(doubly_linked_list.tail.item == 6)
Example #32
0
 def __init__(self, limit=10):
     self.limit = limit
     self.tm = 0
     self.cache = DoublyLinkedList()
     self.storage = {}
	def test_moveToHead(self):
		l = DoublyLinkedList()
		sanity = []
		for i in xrange(8):
			if i % 2 == 0:
				l.addToHead(i)
				sanity = [i] + sanity
			else:
				l.addToTail(i)
				sanity.append(i)
			self.assertEqual(list(l), sanity)
			
			original_dll = l.copy()
			original_sanity = sanity[::]
			for j in xrange(i):
				#Move each item to the head once
				l.moveToHead(l.getNodeByIndex(j))
				list_move_to_head(sanity, j)
				try:
					self.assertEqual(list(l), sanity)
				except:
					import code; code.interact(local=locals())
			l = original_dll
			sanity = original_sanity
		
		l = DoublyLinkedList()
		sanity = []
		for i in xrange(8):
			if i % 2 == 1:
				l.addToHead(i)
				sanity = [i] + sanity
			else:
				l.addToTail(i)
				sanity.append(i)
			self.assertEqual(list(l), sanity)
			
			original_dll = l.copy()
			original_sanity = sanity[::]
			for j in xrange(i):
				#Move each item to the head once
				l.moveToHead(l.getNodeByIndex(j))
				list_move_to_head(sanity, j)
				self.assertEqual(list(l), sanity)
			l = original_dll
			sanity = original_sanity
Example #34
0
	def __init__(self, stack_size = 0):
		self.stack_size = stack_size
		self.element_list = DoublyLinkedList(self.stack_size)
Example #35
0
class LruCacher(object):
	def __init__(self, max_size, plan_b_func):
		"max_size: the largest number of items the cache can have."
		"plan_b_func: the function that will be called with the query as its"
		"             argument if a query isn't cached. The result will then"
		"             be associated with the query."
		
		if max_size < 0:
			raise ValueError("max_size must be positive.")
		if not callable(plan_b_func):
			raise TypeError("plan_b_func must be callable.")
			
		self.max_size = max_size
		self.ht = {}
		self.ll = DoublyLinkedList()
		self.plan_b_func = plan_b_func
		
	def lookup(self, query):
		"Perform a query on the cache. The elements of the cache are "
		"automatically adjusted. If the query is in the cache, move it to the "
		"front of the linked list then return it. If it's not in the cache, "
		"remove the last query in the linked list, queries the plan_b_func for"
		"the result, adds it to the cache, and returns it. This should be a "
		"decorator."
		
		"Cached items have their queries as keys in the hashtable, which point"
		"to elements in a doubly linked list. Linked lsit nodes have two "
		"attributesdata: data, which is the result of calling plan_b_func, and"
		"and query, which is the query itself."
		
		found_in_cache = None
		if query not in self.ht:
			found_in_cache = False
			result = self.plan_b_func(query)
			if len(self.ht) == self.max_size and self.max_size is not 0:
				if self.ll.tail is not None:
					del self.ht[self.ll.tail.query]
					self.ll.removeTail()
			if self.max_size != 0:
				self.ll.addToHead(result)
				self.ll.head.query = query
				self.ht[query] = self.ll.head
		else:
			#The query was in the cache. Move it to the front of 
			#the linked list.
			found_in_cache = True
			node = self.ht[query]
			result = node.data
		
		return result, found_in_cache
		
	def update(self, query, val):
		"Update the value stored in the cache pointed to by query. If query "
		"isn't cached, nothing happens."
		
		if query not in self.ht:
			return
		
		node = self.ht[query]
		node.data = val
		
	def size(self):
		return len(self.ht)
Example #36
0
 def __init__(self):
     self.size = 0
     # Why is our DLL a good choice to store our elements?
     #it is a good choice because it allows us to use our created functions to get these
     #stack and queue methods to work more efficiently
     self.storage = DoublyLinkedList()
Example #37
0
 def __init__(self, capacity):
     self.capacity = capacity
     self.current = None
     self.storage = DoublyLinkedList()
Example #38
0
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.order = 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):
        # Key is not in cache - return none
        if key not in self.storage:
            return None
        else:
            # key is in cache
            # move it to recently used
            node = self.storage[key]
            self.order.move_to_end(node)
            # return value
            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):
        # Different scenarios

        # If item/key already exists
        if key in self.storage:
            # overwrite the value
            # Where is the value stored
            node = self.storage[key]
            node.value = (key, value)
            self.order.move_to_end(node)
            return

        # size at limit
        if len(self.order) == self.limit:
            # Evict the oldest one
            # We need to remove the references and the dictonary
            # The oldest is the head, and the value[0] is the key
            #in the tuple
            index_of_oldest = self.order.head.value[0]
            # This deletes that from the dict
            del self.storage[index_of_oldest]
            # Then we know it was the head, so we just remove the head
            self.order.remove_from_head()


        # add to order
        self.order.add_to_tail((key, value))
        # add to storage
        self.storage[key] = self.order.tail
 def setUp(self):
     self.node = ListNode(1)
     self.dll = DoublyLinkedList(self.node)
Example #40
0
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
        # dont need size, but its in the spec
        self.size = 0

        self.order = 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:
            node = self.storage[key]
            self.order.move_to_end(node)
            return node.value[1]
        else:
            return None


        '''
        if key in self.storage:
            node = self.storage[key]
            self.order.move_to_end(node)
            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):
        #Create a node if key not found and move to front
        # move node to fron if key found 
        # if full remove last node from linked list AND dictionary
        
        if key in self.storage:
            node = self.storage[key]
            node.value = (key, value)
            self.order.move_to_end(node)
            return

        if self.size == self.limit:
            del self.storage[self.order.head.value[0]]
            self.order.remove_from_head()
            self.size -=1


        self.order.add_to_tail((key, value))
        self.storage[key] = self.order.tail
        self.size += 1








        '''
Example #41
0
 def __init__(self, limit=10):
     self.length = 0
     self.limit = limit
     self.order = DoublyLinkedList()
     self.dic = {}
class DoublyLinkedListTests(unittest.TestCase):
    def setUp(self):
        self.node = ListNode(1)
        self.dll = DoublyLinkedList(self.node)

    def test_list_remove_from_tail(self):
        self.dll.remove_from_tail()
        self.assertIsNone(self.dll.head)
        self.assertIsNone(self.dll.tail)
        self.assertEqual(len(self.dll), 0)

        self.dll.add_to_tail(33)
        self.assertEqual(self.dll.head.value, 33)
        self.assertEqual(self.dll.tail.value, 33)
        self.assertEqual(len(self.dll), 1)
        self.assertEqual(self.dll.remove_from_tail(), 33)
        self.assertEqual(len(self.dll), 0)

        self.dll.add_to_tail(68)
        self.assertEqual(len(self.dll), 1)
        self.assertEqual(self.dll.remove_from_tail(), 68)
        self.assertEqual(len(self.dll), 0)

    def test_list_remove_from_head(self):
        self.dll.remove_from_head()
        self.assertIsNone(self.dll.head)
        self.assertIsNone(self.dll.tail)
        self.assertEqual(len(self.dll), 0)

        self.dll.add_to_head(2)
        self.assertEqual(self.dll.head.value, 2)
        self.assertEqual(self.dll.tail.value, 2)
        self.assertEqual(len(self.dll), 1)
        self.assertEqual(self.dll.remove_from_head(), 2)
        self.assertEqual(len(self.dll), 0)

        self.dll.add_to_head(55)
        self.assertEqual(len(self.dll), 1)
        self.assertEqual(self.dll.remove_from_head(), 55)
        self.assertEqual(len(self.dll), 0)

    def test_list_add_to_tail(self):
        self.assertEqual(self.dll.tail.value, 1)
        self.assertEqual(len(self.dll), 1)

        self.dll.add_to_tail(30)
        self.assertEqual(self.dll.tail.prev.value, 1)
        self.assertEqual(self.dll.tail.value, 30)
        self.assertEqual(len(self.dll), 2)

        self.dll.add_to_tail(20)
        self.assertEqual(self.dll.tail.prev.value, 30)
        self.assertEqual(self.dll.tail.value, 20)
        self.assertEqual(len(self.dll), 3)

    def test_node_delete(self):
        node_1 = ListNode(3)
        node_2 = ListNode(4)
        node_3 = ListNode(5)

        node_1.next = node_2
        node_2.next = node_3
        node_2.prev = node_1
        node_3.prev = node_2

        node_2.reset_links()

        self.assertEqual(node_1.next, node_3)
        self.assertEqual(node_3.prev, node_1)

    def test_node_insert_before(self):
        self.node.insert_before(0)
        self.assertEqual(self.node.prev.value, 0)

    def test_list_add_to_head(self):
        self.assertEqual(self.dll.head.value, 1)

        self.dll.add_to_head(10)
        self.assertEqual(self.dll.head.value, 10)
        self.assertEqual(self.dll.head.next.value, 1)
        self.assertEqual(len(self.dll), 2)

    def test_node_insert_after(self):
        self.node.insert_after(2)
        self.assertEqual(self.node.next.value, 2)

    def test_list_move_to_end(self):
        self.dll.add_to_head(40)
        self.assertEqual(self.dll.tail.value, 1)
        self.assertEqual(self.dll.head.value, 40)

        self.dll.move_to_end(self.dll.head)
        self.assertEqual(self.dll.tail.value, 40)
        self.assertEqual(self.dll.tail.prev.value, 1)
        self.assertEqual(len(self.dll), 2)

        self.dll.add_to_tail(4)
        self.dll.move_to_end(self.dll.head.next)
        self.assertEqual(self.dll.tail.value, 40)
        self.assertEqual(self.dll.tail.prev.value, 4)
        self.assertEqual(len(self.dll), 3)

    def test_list_move_to_front(self):
        self.dll.add_to_tail(3)
        self.assertEqual(self.dll.head.value, 1)
        self.assertEqual(self.dll.tail.value, 3)

        self.dll.move_to_front(self.dll.tail)
        self.assertEqual(self.dll.head.value, 3)
        self.assertEqual(self.dll.head.next.value, 1)
        self.assertEqual(len(self.dll), 2)

        self.dll.add_to_head(29)
        self.dll.move_to_front(self.dll.head.next)
        self.assertEqual(self.dll.head.value, 3)
        self.assertEqual(self.dll.head.next.value, 29)
        self.assertEqual(len(self.dll), 3)

    def test_list_delete(self):
        self.dll.delete(self.node)
        self.assertIsNone(self.dll.head)
        self.assertIsNone(self.dll.tail)
        self.assertEqual(len(self.dll), 0)

        self.dll.add_to_tail(1)
        self.dll.add_to_head(9)
        self.dll.add_to_tail(6)

        self.dll.delete(self.dll.head)
        self.assertEqual(self.dll.head.value, 1)
        self.assertEqual(self.dll.tail.value, 6)
        self.assertEqual(len(self.dll), 2)

        self.dll.delete(self.dll.head)
        self.assertEqual(self.dll.head.value, 6)
        self.assertEqual(self.dll.tail.value, 6)
        self.assertEqual(len(self.dll), 1)

    def test_get_max(self):
        self.assertEqual(self.dll.get_max(), 1)
        self.dll.add_to_tail(100)
        self.assertEqual(self.dll.get_max(), 100)
        self.dll.add_to_tail(55)
        self.assertEqual(self.dll.get_max(), 100)
        self.dll.add_to_tail(101)
        self.assertEqual(self.dll.get_max(), 101)
Example #43
0
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.current_entries = 0
        self.cache = DoublyLinkedList()
        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 is in storage
        if key in self.storage:
            #grab node from storage[key]
            node = self.storage[key]
            #move node to front
            self.cache.move_to_front(node)
            #return node.value
            return node.value
        #if key dose not exist in storage
        else:
            #return None
            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 already exists update value and move to front
        if key in self.storage:
            #update node value in storage
            self.storage[key].value = value
            #grab node and move to front
            self.cache.move_to_front(self.storage[key])

        #if cache is full delete oldest entry and add new item to front
        elif self.current_entries == self.limit:
            #delete key/value from storage
            key_to_delete = self.cache.tail.key
            del self.storage[key_to_delete]
            #delete tail node from cache
            self.cache.remove_from_tail()
            #add new node to front
            self.cache.add_to_head(key, value)
            #add new key and value/node into storage
            new_node = self.cache.head
            new_storage = {key: new_node}
            self.storage.update(new_storage)

        #otherwise insert new entry into cache at front
        else:
            #add new node to front of cache
            self.cache.add_to_head(key, value)
            #add key value/node to storage
            new_node = self.cache.head
            new_storage = {key: new_node}
            self.storage.update(new_storage)
            #add 1 to current_entries
            self.current_entries += 1
Example #44
0
 def __init__(self):
     self.size = 0
     self.storage = DoublyLinkedList()
Example #45
0
class TextBuffer:
    # init gives us the option to initialize some text in the
    # buffer right off the bat
    def __init__(self, init=None):
        self.contents = DoublyLinkedList()
        # check if an init string is provided
        # if so, put the contents of the init string in self.contents
        if init:
            self.append(init)

    def __str__(self):
        # needs to return a string to print
        s = ""
        current = self.contents.head
        while current:
            s += current.value
            current = current.next
        return s

    def append(self, string_to_add):
        for char in string_to_add:
            self.contents.add_to_tail(char)

    def prepend(self, string_to_add):
        # reverse the incoming string to maintain correct
        # order when adding to the front of the text buffer
        for char in string_to_add[::-1]:
            self.contents.add_to_head(char)

    def delete_front(self, chars_to_remove):
        for i in range(chars_to_remove):
            self.contents.remove_from_head()

    def delete_back(self, chars_to_remove):
        for i in range(chars_to_remove):
            self.contents.remove_from_tail()

    """
    Join other_buffer to self
    The input buffer gets concatenated to the end of this buffer 
    The tail of the concatenated buffer will be the tail of the other buffer 
    The head of the concatenated buffer will be the head of this buffer 
    """

    def join(self, other_buffer):
        # we might want to check that other_buffer is indeed a text buffer
        if (other_buffer.contents.length == 0):
            print("ERROR: Other buffer is empty")
            return
        if isinstance(other_buffer, TextBuffer):
            # set self list tail's next node to be the head of the other buffer
            self.contents.tail.next = other_buffer.contents.head
            # set other_buffer head's prev node to be the tail of this buffer
            other_buffer.contents.head.prev = self.contents.tail
            self.contents.tail = other_buffer.contents.tail
            self.contents.length += other_buffer.contents.length
        else:
            print("ERROR: Argument is not a text buffer")
            return

    # if we get fed a string instead of a text buffer instance,
    # initialize a new text buffer with this string and then
    # call the join method
    def join_string(self, string_to_join):
        new_buffer = TextBuffer(string_to_join)
        self.join(new_buffer)
    def test_DoublyLinkedList_pop(self):
        l1 = DoublyLinkedList()
        l1.insert(0)
        self.assertEqual(l1.size(), 1)
        l1.insert(1)
        self.assertEqual(l1.size(), 2)

        # ensure Node(0) added to list
        Val1 = l1.pop()
        self.assertEqual(l1.size(), 1)
        self.assertEqual(Val1, 1)

        Val0 = l1.pop()
        self.assertEqual(l1.size(), 0)
        self.assertEqual(Val0, 0)

        # if the list is empty and you pop, raise ValueError
        with self.assertRaises(ValueError):
            ValNone = l1.pop()
 def setUp(self):
     self.my_list = DoublyLinkedList()
Example #48
0
 def __init__(self):
     self.size = 0
     # Why is our DLL a good choice to store our elements?
     # Just adding and removing from tail better memory space than using an array
     self.storage = DoublyLinkedList()
    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")
Example #50
0
 def __init__(self, limit=10):
     self.limit = limit
     self.dll = DoublyLinkedList()
     self.storage = dict()
	def test_addToHead(self):
		l = DoublyLinkedList()
		for i in xrange(4):
			self.assertIs(l.size, i)
			l.addToHead(i)
			self.assertEqual(list(l), range(i, -1, -1))
Example #52
0
 def __init__(self, limit=10):
     self.limit = limit  # 1
     # self.size = 0  # 2
     self.order = DoublyLinkedList()  # 3
     self.storage = {}  # 4
    def test_doubly_linked_list_empty(self):

        doubly_linked_list = DoublyLinkedList()
        self.assertTrue(doubly_linked_list.__len__() == 0)
        self.assertEqual(doubly_linked_list.head, None)
Example #54
0
 def __init__(self, limit=10):
     self.limit = limit
     self.size = 0
     self.storage = {}
     self.order = DoublyLinkedList()
Example #55
0
class TestDoublyLinkedList(unittest.TestCase):

	def setUp(self):
		self.emptyList = DoublyLinkedList()
		self.oneItemList = DoublyLinkedList()
		self.twoItemList = DoublyLinkedList()
		self.fiveItemList = DoublyLinkedList()

		self.one = [3]
		self.two = [2, 9]
		self.five = [6, 1, 0, 5, 8]

		for i in self.one:
			self.oneItemList.append(i)

		for i in self.two:
			self.twoItemList.append(i)

		for i in self.five:
			self.fiveItemList.append(i)

	def testEmptyAppend(self):
		self.emptyList.append(4)
		self.assertEqual(self.emptyList.getPosition(0), 4)

	def testOneAppend(self):
		self.oneItemList.append(1)
		self.assertEqual(self.oneItemList.getPosition(0), 3)
		self.assertEqual(self.oneItemList.getPosition(1), 1)

	def testTwoAppend(self):
		self.twoItemList.append(6)
		self.assertEqual(self.twoItemList.getPosition(0), 2)
		self.assertEqual(self.twoItemList.getPosition(1), 9)
		self.assertEqual(self.twoItemList.getPosition(2), 6)

	def testEmptyPrepend(self):
		self.emptyList.prepend(4)
		self.assertEqual(self.emptyList.getPosition(0), 4)

	def testOnePrepend(self):
		self.oneItemList.prepend(1)
		self.assertEqual(self.oneItemList.getPosition(0), 1)

	def testTwoPrepend(self):
		self.twoItemList.prepend(6)
		self.assertEqual(self.twoItemList.getPosition(0), 6)
		self.assertEqual(self.twoItemList.getPosition(1), 2)
		self.assertEqual(self.twoItemList.getPosition(2), 9)

	def testEmptyInsertAfter(self):
		self.assertFalse(self.emptyList.insertAfter(1, 3))

	def testOneInsertAfter(self):
		self.assertTrue(self.oneItemList.insertAfter(2, 0))
		self.assertEqual(self.oneItemList.getPosition(1), 2)
		self.assertFalse(self.oneItemList.find(7))

	def testTwoInsertAfter(self):
		self.assertTrue(self.twoItemList.insertAfter(7, 0))
		self.assertEqual(self.twoItemList.getPosition(1), 7)
		self.assertFalse(self.twoItemList.find(3))

	def testEmptyRemoveBeginning(self):
		self.assertFalse(self.emptyList.removeBeginning())

	def testOneRemoveBeginning(self):
		self.assertTrue(self.oneItemList.removeBeginning())
		self.assertFalse(self.oneItemList.getPosition(0))

	def testTwoRemoveBeginning(self):
		self.assertTrue(self.twoItemList.removeBeginning())
		self.assertEqual(self.twoItemList.getPosition(0), 9)

	def testEmptyRemoveEnd(self):
		self.assertFalse(self.emptyList.removeEnd())

	def testOneRemoveEnd(self):
		self.assertTrue(self.oneItemList.removeEnd())
		self.assertFalse(self.oneItemList.getPosition(0))

	def testTwoRemoveEnd(self):
		self.assertTrue(self.twoItemList.removeEnd())
		self.assertEqual(self.twoItemList.getPosition(0), 2)

	#def testRemoveAfter(self):

	def testEmptyFind(self):
		self.assertFalse(self.emptyList.find(0))

	def testOneFind(self):
		self.assertFalse(self.oneItemList.find(0))
		self.assertTrue(self.oneItemList.find(3))

	def testTwoFind(self):
		self.assertTrue(self.fiveItemList.find(8))
		self.assertFalse(self.fiveItemList.find(3))

	def testFiveFind(self):
		self.assertTrue(self.fiveItemList.find(0))
		self.assertFalse(self.fiveItemList.find(2))
Example #56
0
 def __init__(self, limit=10):
     self.limit = limit
     self.dll = DoublyLinkedList(None)
     # self.size = self.dll.length
     self.dic = {}
Example #57
0
'''
Created on 29 de abr de 2016

@author: Filipe Mei
'''
from doubly_linked_list import DoublyLinkedList, Stack

import sys

fileIn = open(sys.argv[1], mode = 'r')
fileOut = open(sys.argv[2], mode = 'w')

y = 0
undo = Stack()
text = Stack()
form = DoublyLinkedList()
while True:
    line = fileIn.readline().split()
    if line == []:
        break
    elif line[0].lower() == 'adicionar':
        undo.clean_out()
        for i in range(1, len(line)):
            text.push(line[i])
    elif line[0].lower() == 'italico' or line[0].lower() == 'negrito':
        if form.isEmpty() is True:
            form.insertAtEnd(line[0].lower())
        else:
            s = form.search(line[0].lower())
            if s is None:
                form.insertAtEnd(line[0].lower())
Example #58
0
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(None)
        # self.size = self.dll.length
        self.dic = {}

    """
    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.dic.keys():
            value = self.dic[key]
            checkingnode = self.dll.head
            while checkingnode is not None:
                if checkingnode.key == key:
                    self.dll.move_to_front(checkingnode)

                checkingnode = checkingnode.next

            self.dll.set_tail()
            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 key in self.dic.keys():

            self.dic.update({key: value})

            checkingnode = self.dll.head
            while checkingnode is not None:
                if checkingnode.key == key:
                    checkingnode.value = value

                checkingnode = checkingnode.next

        else:
            if self.dll.length < self.limit:
                self.dll.add_to_head(key, value)
                self.dic.update({key: value})
            else:
                # self.dll.delete(self.dll.tail)
                self.dic.pop(self.dll.tail.key, None)
                self.dll.remove_from_tail()
                self.dll.add_to_head(key, value)
                self.dic.update({key: value})
Example #59
0
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):
        #set up the has table
        self.storage = dict()
        #bring in the double link list
        self.order = DoublyLinkedList()
        #current size of the cache
        self.size = 0
        #get the limit from creation
        self.limit = limit

    """
    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 the key exists
        if key in self.storage:
            #set the node equal that key in the dictionary
            node = self.storage[key]
            self.order.move_to_end(node)
            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):
        #If the key already exists
        if key in self.storage:
            #Set a node with the already existing data
            node = self.storage[key]
            #Change the value of the node
            node.value = (key, value)
            #Move the node to most recently used
            self.order.move_to_end(node)
            return
        #If the cache is at its limit
        if self.size == self.limit:
            #set a node for the least recently used data
            node = self.order.head
            #Get the key from the node value
            key_for_dict = node.value[0]
            #delete the storage in the dictionary
            del self.storage[key_for_dict]
            #delete the head of the dll
            self.order.remove_from_head()
            #change the size of the cache to reflect the change
            self.size -= 1

        #Otherwise add to the tail the data and key
        self.order.add_to_tail((key, value))
        #Set the storage of the key
        self.storage[key] = self.order.tail
        #increase the cache size
        self.size += 1
    def test_DoublyLinkedList_remove(self):
        l1 = DoublyLinkedList()
        l1.insert(0)
        l1.insert(1)
        l1.insert(2)

        with self.assertRaises(ValueError):
            l1.remove(3)

        self.assertEqual(l1.size(), 3)
        l1.remove(2)
        self.assertEqual(l1.size(), 2)
        l1.remove(0)
        self.assertEqual(l1.size(), 1)
        l1.remove(1)
        self.assertEqual(l1.size(), 0)

        with self.assertRaises(ValueError):
            l1.remove(1)
            l1.remove(0)
            l1.remove(2)