class LinkedListMap(IMap): class KeyValue: __slots__ = ("key", "value") def __init__(self, key, value): self.key, self.value = key, value def __eq__(self, other: "KeyValue<K, T>") -> "bool": return self.key == other.key def __init__(self, data: "Iterable<(K, T)> or IMap<K, T>"=[]): if isinstance(data, IMap): data = tuple(data.items()) self._linkedlist = LinkedList(data) def _get_keyvalue_by_key(self, key: "K") -> "KeyValue<K, T>": for item in self._linkedlist: if item.key == key: return item return None def __contains__(self, key: "K") -> "bool": return self._get_keyvalue_by_key(key) != None def __getitem__(self, key: "K") -> "T": kv = self._get_keyvalue_by_key(key) if kv == None: raise KeyError("") return kv.value def __setitem__(self, key: "K", value: "T") -> "T": kv = self._get_keyvalue_by_key(key) if kv == None: kv = LinkedListMap.KeyValue(key, value) self._linkedlist.append(kv) else: kv.value = value return kv.value def __delitem__(self, key: "K", value: "T"): self._linkedlist.remove(LinkedListMap.KeyValue(key, value)) def __len__(self) -> "int": return len(self._linkedlist)
def __init__( self, data: "Iterable<T>" = [], createList: "Iterable<T> -> IList<T>" = lambda data: LinkedList(data)): self._list = createList(data)
def test_remove_aNonExistingItem_shouldRaiseError(self): ll = LinkedList() self.assertRaises(ValueError, ll.remove, 0)
def test_remove_fromEmptyList_shouldRaiseException(self): ll = LinkedList() self.assertRaises(ValueError, ll.remove, 0)
def setUp(self): self.seq = list(list(range(100)) * 2) self.ll = LinkedList(self.seq)
def test_del_firstElementOfEmptyList_shouldShrinkIt(self): ll = LinkedList() self.assertRaises(IndexError, ll.__delitem__, 0)
class TestLinkedList(unittest.TestCase): def setUp(self): self.seq = list(list(range(100)) * 2) self.ll = LinkedList(self.seq) def test_len_onLinkedList_shouldReturnNumberOfItems(self): self.assertEqual(len(self.seq), len(self.ll)) def test_len_onEmptyLinkedList_shouldReturnZero(self): self.assertEqual(len(LinkedList()), 0) def test_append_newItem_shouldEnlargeIt(self): self.seq.append(1000) self.ll.append(1000) self.assertEqual(len(self.seq), len(self.ll)) def test_append_newItem_shouldPlaceItInLastPos(self): self.seq.append(1000) self.ll.append(1000) self.assertEqual(self.seq[len(self.seq) - 1], self.ll[len(self.ll) - 1]) self.assertEqual(self.seq[-1], self.ll[-1]) def test_insert_itemAtZeroIndex_shouldEnlargeIt(self): self.seq[:0] = [1000] self.ll.insert(0, 1000) self.assertEqual(len(self.seq), len(self.ll)) def test_insert_itemAtZeroIndex_shouldPlaceItInFirstPos(self): self.seq[:0] = [1000] self.ll.insert(0, 1000) self.assertEqual(self.seq[0], self.ll[0]) def test_pop_onList_shouldShrinkIt(self): self.seq.pop() self.ll.pop() self.assertEqual(list(self.ll), self.seq) def test_pop_onList_shouldShrinkReturnLastItem(self): x = self.seq.pop() y = self.ll.pop() self.assertEqual(x, y) def test_pop_onEmptyList_shouldRaiseException(self): ll = LinkedList() self.assertRaises(IndexError, ll.pop) def test_del_firstElementOfList_shouldShrinkIt(self): del self.seq[0] del self.ll[0] self.assertEqual(list(self.ll), self.seq) def test_del_firstElementOfEmptyList_shouldShrinkIt(self): ll = LinkedList() self.assertRaises(IndexError, ll.__delitem__, 0) def test_remove_anItemFromList_shouldShrinkIt(self): self.ll.remove(10) self.seq.remove(10) self.assertEqual(list(self.ll), self.seq) def test_remove_severalItemsFromList_shouldShrinkIt(self): for i in range(5, 20): self.ll.remove(i) self.seq.remove(i) self.assertEqual(list(self.ll), self.seq) def test_remove_repeatedItemFromList_shouldEliminateIt(self): for i in 10, 19: self.ll.remove(i) self.seq.remove(i) self.ll.remove(i) self.seq.remove(i) self.assertFalse(19 in self.ll) self.assertFalse(10 in self.ll) def test_remove_fromEmptyList_shouldRaiseException(self): ll = LinkedList() self.assertRaises(ValueError, ll.remove, 0) def test_remove_aNonExistingItem_shouldRaiseError(self): ll = LinkedList() self.assertRaises(ValueError, ll.remove, 0) def test_iter_shouldYieldAllItsContents(self): for i, v in enumerate(self.ll): self.assertEqual(v, self.seq[i]) def test_contains_existingItem_shouldReturnTrue(self): self.assertTrue(0 in self.ll) self.assertTrue(99 in self.ll) def test_contains_nonExistingItem_shouldReturnFalse(self): self.assertFalse(1000 in self.ll) self.assertFalse(-1 in self.ll) def test_getitem_atValidIndex_shouldReturnItsValue(self): for i in range(99, -1, -1): self.assertEqual(self.ll[i], i) for i in range(100): self.assertEqual(self.ll[i], i) for i in range(len(self.ll)): self.assertEqual(self.seq[i], self.ll[i]) def test_getitem_atValidNegativeIndex_shouldReturnItsValue(self): for i in range(-1, -100, -1): self.assertEqual(self.ll[i], 100 + i) for i in range(len(self.ll)): self.assertEqual(self.seq[i], self.ll[i]) self.assertEqual(self.ll[-len(self.ll)], self.ll[0]) def test_getitem_atNegativeOrEquivalentPositiveIndex_shouldReturnSameValue( self): self.assertEqual(self.ll[-len(self.ll)], self.ll[0]) def test_setitem_atAnyPosition_shouldSetValue(self): for i in range(100): self.ll[i] = -i for i in range(100): self.assertEqual(self.ll[i], -i) def test_delitem_atSeveralPlaces_shouldRemoveItems(self): for i in range(199, -1, -2): del self.ll[i] for i in range(100): if i % 2 == 1: self.assertFalse(i in self.ll) else: self.assertTrue(i in self.ll) def test_delitem_oneByOne_shouldReturnEmptyList(self): while len(self.ll) > 0: del self.ll[0] self.assertRaises(IndexError, self.ll.__delitem__, 0) def test_delitem_onEmptyList_shouldRaiseException(self): self.assertRaises(IndexError, LinkedList().__delitem__, 0) def test_insert_atFirstPos_shouldCreateANewFirstElement(self): self.ll.insert(0, 1000) self.assertTrue(self.ll[0], 1000) def test_insert_atLastPos_shouldCreateANewLastElement(self): self.ll.insert(len(self.ll) - 1, 2000) self.assertTrue(len(self.ll) - 1, 2000) def test_insert_atMidPos_shouldCreateANewMidElement(self): self.ll.insert(len(self.ll) // 2, 3000) self.assertTrue(len(self.ll) // 2, 3000) def test_insert_atInvalidPos_shouldRaiseException(self): self.assertRaises(IndexError, self.ll.insert, 10000, 0) def test_insert_atNegativePos_shouldCreateANewItemThere(self): self.ll.insert(len(self.ll), -10) self.assertEquals(self.ll[len(self.ll) - 1], -10) def test_len_onList_shouldReturnItsLength(self): self.assertEqual(len(self.ll), 200) def test_len_onEmptyList_shouldReturnZero(self): self.assertEqual(len(LinkedList()), 0) def test_repr_ofList_shouldCreateEvaluableString(self): self.assertEqual(list(self.ll), list(eval(repr(self.ll))))
def test_pop_onEmptyList_shouldRaiseException(self): ll = LinkedList() self.assertRaises(IndexError, ll.pop)
def test_len_onEmptyList_shouldReturnZero(self): self.assertEqual(len(LinkedList()), 0)
def test_delitem_onEmptyList_shouldRaiseException(self): self.assertRaises(IndexError, LinkedList().__delitem__, 0)
def __init__(self, data: "Iterable<(K, T)> or IMap<K, T>"=[]): if isinstance(data, IMap): data = tuple(data.items()) self._linkedlist = LinkedList(data)
#coding: latin1 #< full from algoritmia.datastructures.lists import LinkedList a = LinkedList() a.append(1) a.insert(0, 2) a.extend((5, 15)) print(a) print(a.pop()) print(a) #> full