Récapitulatif - Liste personnalisée
Fait partie de la section Object Oriented Programming du Journey Python de Coddy — leçon 36 sur 64.
Défi
MoyenDans ce défi, vous allez implémenter une classe CustomList entièrement fonctionnelle qui imite le comportement des listes intégrées de Python tout en démontrant votre compréhension des méthodes spéciales.
Modifiez uniquement le fichier customlist.py en suivant les commentaires TODO qui guident votre implémentation étape par étape.
Votre implémentation doit prendre en charge :
- L'initialisation avec des éléments optionnels
- L'indexation (obtention/définition de valeurs)
- La vérification de la longueur avec
len() - L'addition avec d'autres listes
- La représentation sous forme de chaîne de caractères
- L'itération et les vérifications d'appartenance (contains)
- Les méthodes :
append,pop, etclear
Aide-mémoire
Une classe CustomList peut être implémentée en utilisant des méthodes spéciales (méthodes dunder) pour imiter le comportement des listes intégrées de Python :
__init__(self, items=None)- Initialiser avec des éléments optionnels__getitem__(self, index)- Activer l'indexation pour obtenir des valeurs__setitem__(self, index, value)- Activer l'indexation pour définir des valeurs__len__(self)- Activer la fonctionlen()__add__(self, other)- Activer l'addition avec d'autres listes__str__(self)- Représentation sous forme de chaîne de caractères__iter__(self)- Activer l'itération__contains__(self, item)- Activer l'opérateurin
Méthodes de liste courantes à implémenter :
append(self, item)- Ajouter un élément à la finpop(self, index=-1)- Supprimer et renvoyer l'élément à l'index donnéclear(self)- Supprimer tous les éléments
Essayez vous-même
from customlist import CustomList
def test_basic_functionality():
"""Tester les fonctionnalités de base de CustomList"""
try:
# Test de l'initialisation
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)}"
# Test de l'indexation
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]}"
# Test de la représentation sous forme de chaîne
assert str(init_list) == "[1, 10, 3]", f"String representation incorrect, got {str(init_list)}"
# Test de l'addition
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]}"
# Test de l'itération et de l'appartenance
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"
# Test de append et 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)}"
# Test de 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():
"""Tester les cas limites et les conditions aux bornes"""
try:
# Test avec des opérations sur liste vide
empty_list = CustomList()
# Test de pop sur une liste vide
try:
empty_list.pop()
assert False, "pop() on empty list should raise IndexError"
except IndexError:
pass # Comportement attendu
# Test de l'indexation sur une liste vide
try:
value = empty_list[0]
assert False, "Indexing empty list should raise IndexError"
except IndexError:
pass # Comportement attendu
# Test avec des valeurs 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"
# Test avec des types mixtes
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]}"
# Test de l'addition avec une liste standard
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]}"
# Test de l'addition avec une liste vide
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]}"
# Test de 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():
"""Tester les performances avec de grandes listes"""
try:
# Créer et tester des opérations sur de grandes listes
# Créer une grande liste
large_list = CustomList(range(10000))
assert len(large_list) == 10000, f"Large list should have length 10000, got {len(large_list)}"
# Test de l'indexation sur une grande liste
assert large_list[9999] == 9999, f"Last element should be 9999, got {large_list[9999]}"
# Test de l'appartenance sur une grande liste
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"
# Test de l'addition de deux grandes listes
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():
"""Tester avec des objets CustomList imbriqués"""
try:
# Test d'objets CustomList imbriqués
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]}"
# Test de la modification d'une liste imbriquée
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]}"
# Test d'addition imbriquée
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():
"""Tester les opérations personnalisées et les combinaisons"""
try:
# Test des opérations personnalisées et des combinaisons de méthodes
# Test d'opérations en chaîne
list1 = CustomList([1, 2])
list2 = CustomList([3, 4])
list3 = CustomList([5, 6])
# Additions en chaîne
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]}"
# Test d'une séquence de append et 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)}"
# Test de clear puis 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]}"
# Test de l'addition de listes vides
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
# Exécuter le cas de test sélectionné ou tous les tests
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()Toutes les leçons de Object Oriented Programming
1Les fondamentaux de la POO
Fichiers externesIntroduction à la POOClasses vs ObjetsLe paramètre selfMéthodesAttributsMéthode constructeur (__init__)Récapitulatif - Calculatrice simple4Héritage
Héritage de baseLa fonction super()Redéfinition de méthodeHéritage multipleOrdre de résolution des méthodesRécapitulatif - Hiérarchie des employés7Méthodes spéciales
Introduction aux méthodes magiquesSurcharge d'opérateursMéthodes magiques de conteneurRécapitulatif - Liste personnalisée10Patrons de conception, Partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FactoryPatron ObserverPatron Strategy2Décorateurs
Introduction aux décorateursDécorateur de propriétéDécorateur de méthode statiqueDécorateur de méthode de classe5Polymorphisme
Retour sur la redéfinition de méthodeDuck TypingClasses et méthodes abstraitesConception d'interfacesRécapitulatif - Calculateur de formes8Concepts avancés de la POO
Composition vs HéritageMixinsMéthodes statiques et de classeDécorateurs de classeGestionnaires de contexte11Patrons de conception, Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode TemplatePatron ÉtatPatron Composite3Propriétés de classe
Variables d'instance vs variables de classeDécorateurs de propriétéAttributs privésRécapitulatif - Gestionnaire de compte bancaire