Повторение — Пользовательский список
Часть раздела Object Oriented Programming путешествия по Python на Coddy — урок 36 из 64.
Задание
СреднеВ этом испытании вы реализуете полнофункциональный класс CustomList, который имитирует поведение встроенного списка Python, демонстрируя ваше понимание специальных методов.
Редактируйте только файл customlist.py, следуя комментариям TODO, которые шаг за шагом направляют вашу реализацию.
Ваша реализация должна поддерживать:
- Инициализацию с необязательными элементами
- Индексацию (получение/установка значений)
- Проверку длины с помощью
len() - Сложение с другими списками
- Строковое представление
- Итерацию и проверку на вхождение
- Методы:
append,popиclear
Шпаргалка
Класс CustomList может быть реализован с использованием специальных методов (dunder-методов) для имитации поведения встроенного списка Python:
__init__(self, items=None)- Инициализация с необязательными элементами__getitem__(self, index)- Включение индексации для получения значений__setitem__(self, index, value)- Включение индексации для установки значений__len__(self)- Поддержка функцииlen()__add__(self, other)- Поддержка сложения с другими списками__str__(self)- Строковое представление__iter__(self)- Поддержка итерации__contains__(self, item)- Поддержка оператораin
Общие методы списка для реализации:
append(self, item)- Добавление элемента в конецpop(self, index=-1)- Удаление и возврат элемента по индексуclear(self)- Удаление всех элементов
Попробуйте сами
from customlist import CustomList
def test_basic_functionality():
"""Тестирование базовой функциональности CustomList"""
try:
# Тест инициализации
empty_list = CustomList()
assert len(empty_list) == 0, f"Empty list should have length 0, but has {len(empty_list)}"
init_list = CustomList([1, 2, 3])
assert len(init_list) == 3, f"Initialized list should have length 3, but has {len(init_list)}"
# Тест индексации
assert init_list[0] == 1, f"First element should be 1, but got {init_list[0]}"
init_list[1] = 10
assert init_list[1] == 10, f"Element after assignment should be 10, but got {init_list[1]}"
# Тест строкового представления
assert str(init_list) == "[1, 10, 3]", f"String representation incorrect, got {str(init_list)}"
# Тест сложения
combined = init_list + CustomList([4, 5])
assert len(combined) == 5, f"Combined list should have length 5, but has {len(combined)}"
assert combined[3] == 4, f"Fourth element of combined list should be 4, but got {combined[3]}"
# Тест итерации и проверки вхождения
items = []
for item in combined:
items.append(item)
assert items == [1, 10, 3, 4, 5], f"Iteration produced incorrect items: {items}"
assert 10 in combined, "10 should be in the list"
assert 7 not in combined, "7 should not be in the list"
# Тест append и pop
combined.append(6)
assert len(combined) == 6, f"After append, length should be 6, but got {len(combined)}"
assert combined[5] == 6, f"Last element after append should be 6, but got {combined[5]}"
popped = combined.pop()
assert popped == 6, f"Popped value should be 6, but got {popped}"
assert len(combined) == 5, f"After pop, length should be 5, but got {len(combined)}"
# Тест clear
combined.clear()
assert len(combined) == 0, f"After clear, length should be 0, but got {len(combined)}"
print("Basic functionality tests passed!")
return True
except Exception as e:
print(f"Basic functionality test failed: {e}")
return False
def test_edge_cases():
"""Тестирование граничных случаев и условий"""
try:
# Тест операций с пустым списком
empty_list = CustomList()
# Тест pop на пустом списке
try:
empty_list.pop()
assert False, "pop() on empty list should raise IndexError"
except IndexError:
pass # Ожидаемое поведение
# Тест индексации на пустом списке
try:
value = empty_list[0]
assert False, "Indexing empty list should raise IndexError"
except IndexError:
pass # Ожидаемое поведение
# Тест со значениями None
none_list = CustomList([None, None])
assert len(none_list) == 2, f"List with None values should have length 2, got {len(none_list)}"
assert none_list[0] is None, "First element should be None"
# Тест со смешанными типами
mixed_list = CustomList([1, "string", 3.14, [1, 2], {"key": "value"}])
assert len(mixed_list) == 5, f"Mixed type list should have length 5, got {len(mixed_list)}"
assert mixed_list[1] == "string", f"Second element should be 'string', got {mixed_list[1]}"
# Тест сложения с обычным списком
result = mixed_list + [6, 7, 8]
assert len(result) == 8, f"After adding regular list, length should be 8, got {len(result)}"
assert result[5] == 6, f"Sixth element should be 6, got {result[5]}"
# Тест сложения с пустым списком
result = mixed_list + []
assert len(result) == 5, f"After adding empty list, length should be 5, got {len(result)}"
assert result[0] == 1, f"First element should still be 1, got {result[0]}"
# Тест repr
repr_str = repr(CustomList([1, 2, 3]))
assert repr_str == "CustomList([1, 2, 3])", f"repr should be 'CustomList([1, 2, 3])', got {repr_str}"
print("Edge case tests passed!")
return True
except Exception as e:
print(f"Edge case test failed: {e}")
return False
def test_large_lists():
"""Тестирование производительности на больших списках"""
try:
# Создание и тестирование операций на больших списках
# Создание большого списка
large_list = CustomList(range(10000))
assert len(large_list) == 10000, f"Large list should have length 10000, got {len(large_list)}"
# Тест индексации на большом списке
assert large_list[9999] == 9999, f"Last element should be 9999, got {large_list[9999]}"
# Тест вхождения на большом списке
assert 5000 in large_list, "5000 should be in the large list"
assert 10001 not in large_list, "10001 should not be in the large list"
# Тест сложения двух больших списков
other_large = CustomList(range(10000, 20000))
combined = large_list + other_large
assert len(combined) == 20000, f"Combined large lists should have length 20000, got {len(combined)}"
assert combined[0] == 0, f"First element should be 0, got {combined[0]}"
assert combined[19999] == 19999, f"Last element should be 19999, got {combined[19999]}"
print("Large list tests passed!")
return True
except Exception as e:
print(f"Large list test failed: {e}")
return False
def test_nested_lists():
"""Тестирование с вложенными объектами CustomList"""
try:
# Тест вложенных объектов CustomList
inner1 = CustomList([1, 2, 3])
inner2 = CustomList([4, 5, 6])
outer = CustomList([inner1, inner2, 7])
assert len(outer) == 3, f"Outer list should have length 3, got {len(outer)}"
assert outer[0] is inner1, "First element should be inner1"
assert len(outer[0]) == 3, f"First inner list should have length 3, got {len(outer[0])}"
assert outer[0][1] == 2, f"Second element of first inner list should be 2, got {outer[0][1]}"
# Тест изменения вложенного списка
inner1.append(4)
assert len(outer[0]) == 4, f"After append, inner list should have length 4, got {len(outer[0])}"
assert outer[0][3] == 4, f"Fourth element of inner list should be 4, got {outer[0][3]}"
# Тест вложенного сложения
result = outer[0] + outer[1]
assert len(result) == 7, f"Combined inner lists should have length 7, got {len(result)}"
assert result[0] == 1, f"First element should be 1, got {result[0]}"
assert result[6] == 6, f"Last element should be 6, got {result[6]}"
print("Nested list tests passed!")
return True
except Exception as e:
print(f"Nested list test failed: {e}")
return False
def test_custom_operations():
"""Тестирование пользовательских операций и комбинаций"""
try:
# Тест пользовательских операций и комбинаций методов
# Тест цепочки операций
list1 = CustomList([1, 2])
list2 = CustomList([3, 4])
list3 = CustomList([5, 6])
# Цепочка сложений
result = list1 + list2 + list3
assert len(result) == 6, f"Chained addition should have length 6, got {len(result)}"
assert result[5] == 6, f"Last element should be 6, got {result[5]}"
# Тест последовательности append и pop
test_list = CustomList([1, 2, 3])
test_list.append(4)
test_list.append(5)
assert test_list.pop() == 5, "First pop should return 5"
assert test_list.pop() == 4, "Second pop should return 4"
assert len(test_list) == 3, f"After two pops, length should be 3, got {len(test_list)}"
# Тест clear и последующего append
test_list.clear()
assert len(test_list) == 0, f"After clear, length should be 0, got {len(test_list)}"
test_list.append(10)
assert len(test_list) == 1, f"After append to cleared list, length should be 1, got {len(test_list)}"
assert test_list[0] == 10, f"Element should be 10, got {test_list[0]}"
# Тест сложения пустых списков
empty1 = CustomList()
empty2 = CustomList()
empty_sum = empty1 + empty2
assert len(empty_sum) == 0, f"Sum of empty lists should be empty, got length {len(empty_sum)}"
print("Custom operations tests passed!")
return True
except Exception as e:
print(f"Custom operations test failed: {e}")
return False
# Запуск выбранного теста или всех тестов
test_case = input()
if test_case == "basic":
test_basic_functionality()
elif test_case == "edge":
test_edge_cases()
elif test_case == "large":
test_large_lists()
elif test_case == "nested":
test_nested_lists()
elif test_case == "custom":
test_custom_operations()
else:
print("Invalid test case. Running basic tests by default.")
test_basic_functionality()Все уроки раздела Object Oriented Programming
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыПараметр selfМетодыАтрибутыМетод-конструктор (__init__)Повторение — Простой калькулятор4Наследование
Базовое наследованиеФункция super()Переопределение методовМножественное наследованиеПорядок разрешения методовИтоги — Иерархия сотрудников7Специальные методы
Введение в магические методыПерегрузка операторовМагические методы контейнеровПовторение — Пользовательский список10Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн ObserverПаттерн Strategy5Полиморфизм
Снова о переопределении методовУтиная типизацияАбстрактные классы и методыПроектирование интерфейсовИтоги — Калькулятор фигур8Продвинутые концепции ООП
Композиция против наследованияМиксиныСтатические методы и методы классаДекораторы классовМенеджеры контекста11Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн Компоновщик3Свойства классов
Переменные экземпляра и классаДекораторы свойствПриватные атрибутыИтоги — Менеджер банковского счета6Инкапсуляция
Public, Protected, Private члены классаМодификаторы доступаСокрытие данныхДекораторы property: продвинутый уровеньИтоги: Система учета студентов12Проект: Управление библиотекой
Обзор проектаКлассы Book и User