diff --git a/Homework/ArrayList.py b/Homework/ArrayList.py new file mode 100644 index 0000000..a5790a3 --- /dev/null +++ b/Homework/ArrayList.py @@ -0,0 +1,219 @@ +from array import array, ArrayType +from typing import TypeVar, Iterable +from copy import deepcopy + +T = TypeVar("T") + + +class ArrayList(object): + class Iterator(object): + __data: ArrayType + __index: int + + def __init__(self, data: ArrayType): + self.__data = data + self.__index = -1 + + def __iter__(self) -> 'ArrayList.Iterator': + return self + + def __next__(self) -> T: + if self.__index > len(self.__data) - 2: + raise StopIteration() + + self.__index += 1 + return self.__data[self.__index] + + class ReverseIterator(object): + __data: ArrayType + __index: int + + def __init__(self, data: ArrayType): + self.__data = data + self.__index = len(data) + + def __iter__(self) -> 'ArrayList.Iterator': + return self + + def __next__(self): + if self.__index == 0: + raise StopIteration() + + self.__index -= 1 + return self.__data[self.__index] + + __array: ArrayType + + def __init__(self, type_char: str, *args) -> None: + self.__array = array(type_char, args) + + def __str__(self) -> str: + return self.__array.__str__() + + def __getitem__(self, index: int) -> T: + return self.__array[index] + + def __len__(self) -> int: + return len(self.__array) + + def __contains__(self, target: T) -> bool: + for item in self.__array: + if target == item: + return True + + return False + + def __add__(self, other: "ArrayList") -> "ArrayList": + copy = deepcopy(self) + copy += other + return copy + + def __iadd__(self, other: "ArrayList") -> "ArrayList": + self.__array += other.__array + return self + + def __lt__(self, other: "ArrayList") -> bool: + if len(self.__array) < len(other.__array): + return True + + elif len(self.__array) > len(other.__array): + return False + + else: + not_equal = False + + for i, elem in enumerate(self.__array): + if elem > other.__array[i]: + return False + + if elem < other.__array[i]: + not_equal = True + + return not_equal + + def __eq__(self, other: "ArrayList") -> bool: + if len(self.__array) != len(other.__array): + return False + + else: + for i, elem in enumerate(self.__array): + if elem != other.__array[i]: + return False + return True + + def __le__(self, other: "ArrayList") -> bool: + if self < other: + return True + elif self == other: + return True + + return False + + def __ne__(self, other: "ArrayList") -> bool: + return not self == other + + def __gt__(self, other: "ArrayList") -> bool: + return not self <= other + + def __ge__(self, other: "ArrayList") -> bool: + return not self < other + + def __mul__(self, mult: int) -> "ArrayList": + result = deepcopy(self) + result *= mult + + return result + + def __imul__(self, mult: int) -> "ArrayList": + old_len = len(self.__array) + new_len = old_len * mult + new_array = array(self.__array.typecode, [0 for _ in range(new_len)]) + + for i in range(new_len): + new_array[i] = self.__array[i % old_len] + + self.__array = new_array + return self + + def append(self, item: T) -> None: + self.__array += array(self.__array.typecode, [item]) + + def count(self, item: T) -> int: + count = 0 + + for elem in self.__array: + if elem == item: + count += 1 + + return count + + def index(self, target: T, start=0, stop=None) -> int: + stop = stop if stop is not None else len(self.__array) + for i in range(start, stop): + if self.__array[i] == target: + return i + + raise ValueError + + def extend(self, *args: Iterable) -> None: + for elem in args: + self.__array += array(self.__array.typecode, elem) + + def insert(self, index: int, item: T) -> None: + if index == -1: + self.append(item) + return + + elif index < 0: + index = len(self.__array) + index + 1 + + old_array = self.__array + self.__array = array(old_array.typecode) + + for i, elem in enumerate(old_array): + if i == index: + self.append(item) + self.append(elem) + + else: + self.append(elem) + + def __iter__(self) -> 'ArrayList.Iterator': + return ArrayList.Iterator(self.__array) + + def pop(self, index=-1) -> T: + if index < 0: + index = len(self.__array) + index + + if index > len(self.__array) - 1: + raise IndexError + + new_array = array(self.__array.typecode, [0 for _ in range(len(self.__array) - 1)]) + + i = 0 + is_found = False + for elem in self.__array: + if i == index and not is_found: + item = self.__array[i] + is_found = True + continue + + new_array[i] = elem + i += 1 + + self.__array = new_array + + return item + + def remove(self, target: T) -> None: + index = self.index(target) + self.pop(index) + + def __reversed__(self) -> 'ArrayList.ReverseIterator': + return ArrayList.ReverseIterator(self.__array) + + def __setitem__(self, key: int, value: T) -> None: + self.__array[key] = value + + def __delitem__(self, key: int) -> None: + self.pop(key) diff --git a/Homework/ArrayList_test.py b/Homework/ArrayList_test.py new file mode 100644 index 0000000..b01cdb6 --- /dev/null +++ b/Homework/ArrayList_test.py @@ -0,0 +1,193 @@ +import unittest +# import List +from ArrayList import ArrayList +from collections import abc +from sys import getsizeof + + +class TestCase(unittest.TestCase): + def test_init_and_len(self): + # Увы, обычного теста на невылеты нет, так что пусть будет так + list0 = ArrayList('i') + list1 = ArrayList('i', 1, 2, 3, 1, 8, 9) + list2 = ArrayList('u', '1', '2', '3') + list3 = ArrayList('d', 1.1, 2.2, 3.3, 4.4, 5.5) + + self.assertEqual(len(list0), 0) + self.assertEqual(len(list1), 6) + self.assertEqual(len(list2), 3) + self.assertEqual(len(list3), 5) + + def test_to_string(self): + list1 = ArrayList('i', 1, 2, 3, 1, 8, 9) + self.assertEqual(str(list1), "array('i', [1, 2, 3, 1, 8, 9])") + + list2 = ArrayList('u', '1', '2', '3') + self.assertEqual(str(list2), "array('u', '123')") + + def test_contains(self): + list1 = ArrayList('i', 1, 2, 3, 1, 8, 9) + self.assertTrue(2 in list1) + self.assertFalse(0 in list1) + + list2 = ArrayList('u', '1', '2', '3') + self.assertTrue('2' in list2) + self.assertFalse('0' in list2) + + def test_add_iadd(self): + list1 = ArrayList('i', 1, 2, 3, 1, 8, 9) + list01 = ArrayList('i', 0, 0, 0) + + self.assertEqual(ArrayList('i', 1, 2, 3, 1, 8, 9, 0, 0, 0), list1 + list01) + self.assertEqual(ArrayList('i', 1, 2, 3, 1, 8, 9), list1) + self.assertEqual(ArrayList('i', 0, 0, 0), list01) + + list01 += list1 + + self.assertEqual(ArrayList('i', 0, 0, 0, 1, 2, 3, 1, 8, 9), list01) + self.assertEqual(ArrayList('i', 1, 2, 3, 1, 8, 9), list1) + + def test_ordering(self): + list0 = ArrayList('i') + list10 = ArrayList('i', 1, 2, 3, 1, 8, 9) + list11 = ArrayList('i', 1, 2, 3, 1, 8, 9) + list20 = ArrayList('i', 1, 2, 3) + list21 = ArrayList('i', 1, 2, 4) + list3 = ArrayList('i', 1, 2, 3, 4, 5, 6, 7, 8, 9) + + self.assertTrue(list10 == list11) + self.assertTrue(list10 >= list11) + self.assertTrue(list10 <= list11) + + self.assertTrue(list10 > list0) + self.assertFalse(list10 <= list0) + + self.assertTrue(list10 < list3) + self.assertTrue(list20 < list21) + + self.assertTrue(list10 != list0) + self.assertTrue(list20 != list0) + self.assertTrue(list21 != list10) + self.assertTrue(list3 != list10) + + self.assertFalse(list10 != list11) + + def test_mul_imul(self): + list0 = ArrayList('i', 0, 0, 0) + mult = 2 + + self.assertEqual(ArrayList('i', 0, 0, 0, 0, 0, 0), list0 * mult) + self.assertEqual(ArrayList('i', 0, 0, 0), list0) + self.assertEqual(mult, 2) + + mult = 3 + list0 *= mult + + self.assertEqual(ArrayList('i', 0, 0, 0, 0, 0, 0, 0, 0, 0), list0) + self.assertEqual(mult, 3) + + def test_append(self): + list0 = ArrayList('i', 0, 0, 0) + list0.append(1) + + self.assertEqual(ArrayList('i', 0, 0, 0, 1), list0) + + list0.append(2) + + self.assertEqual(ArrayList('i', 0, 0, 0, 1, 2), list0) + + def test_count(self): + list0 = ArrayList('i', 0, 0, 0, 1) + + self.assertEqual(list0.count(0), 3) + self.assertEqual(list0.count(1), 1) + + self.assertEqual(list0.count(25), 0) + + def test_index(self): + list0 = ArrayList('i', 0, 0, 0, 1) + + self.assertEqual(list0.index(0), 0) + self.assertEqual(list0.index(1), 3) + + with self.assertRaises(ValueError): + list0.index(25) + + def test_extend(self): + list0 = ArrayList('i', 0, 0, 0, 1) + + list0.extend([1, 2, 3]) + + self.assertEqual(list0, ArrayList('i', 0, 0, 0, 1, 1, 2, 3)) + + def test_insert(self): + list0 = ArrayList('i', 0, 0, 0) + list0.insert(1, 1) + + self.assertEqual(list0, ArrayList('i', 0, 1, 0, 0)) + + list0.insert(-1, 1) + self.assertEqual(list0, ArrayList('i', 0, 1, 0, 0, 1)) + + list0.insert(-2, 2) + self.assertEqual(list0, ArrayList('i', 0, 1, 0, 0, 2, 1)) + + def test_iterable(self): + list0 = ArrayList('i', 0, 1, 2) + for i, e in enumerate(list0): + self.assertEqual(i, e) + + list1 = ArrayList('i', 0) + iterator = iter(list1) + + self.assertEqual(next(iterator), 0) + + list1.append(2) + + self.assertEqual(next(iterator), 2) + + with self.assertRaises(StopIteration): + next(iterator) + + def test_pop(self): + list0 = ArrayList('i', 0, 1, 2) + + self.assertEqual(list0.pop(), 2) + self.assertEqual(list0, ArrayList('i', 0, 1)) + + self.assertEqual(list0.pop(0), 0) + self.assertEqual(list0, ArrayList('i', 1)) + + def test_reverse(self): + list0 = ArrayList('i', 3, 2, 1, 0) + i = 0 + for e in reversed(list0): + self.assertEqual(e, i) + i += 1 + + def test_remove(self): + list0 = ArrayList('i', 3, 2, 1, 0) + list0.remove(2) + + self.assertEqual(list0, ArrayList('i', 3, 1, 0)) + + def test_del(self): + list0 = ArrayList('i', 3, 2, 1, 0) + del list0[0] + + self.assertEqual(list0, ArrayList('i', 2, 1, 0)) + + def test_is_dz_done(self): + my_array_list = ArrayList('i') + self.assertTrue(isinstance(my_array_list, abc.Reversible)) + self.assertTrue(isinstance(my_array_list, abc.Collection)) + + #self.assertTrue(isinstance(my_array_list, abc.Sequence)) + #self.assertTrue(isinstance(my_array_list, abc.MutableSequence)) + + +def execute_tests(): + unittest.main() + +if __name__ == '__main__': + execute_tests() \ No newline at end of file