09 — Carnet de contacts

Niveau requis : 5 pour la v1, 6 pour la v2 / Difficulté : 4/5 / Durée estimée : 3 h (v1) + 3 h (v2)

Objectif

Un carnet d'adresses en ligne de commande : ajouter un contact (nom, téléphone, email), lister, rechercher par nom, modifier, supprimer. Les contacts sont sauvegardés en JSON et survivent aux relances.

Deux versions :

C'est le projet le plus exigeant avant les niveaux 9-10 : prends les deux sessions au sérieux.

Notions utilisées

Cahier des charges

Commun :

Spécifique v2 :

Étapes de construction

v1 — niveau 5

  1. Structure de données + listing : liste de dicts en dur, fonction show_contacts(contacts). Lance, vérifie l'affichage.
  2. Menu en boucle + add_contact(contacts) avec validation du nom non vide et refus des doublons. Teste le doublon avec des casses différentes.
  3. find_contacts(contacts, query) : retourne une LISTE de résultats (pas le premier trouvé), affichage à part. Teste « mar », « MAR », requête sans résultat.
  4. Persistance : save_contacts(contacts) / load_contacts() sur le modèle du projet 06 (JSON, with, FileNotFoundError[]). Sauvegarde après chaque changement. Teste le cycle quitter/relancer.
  5. edit_contact (champ par champ, Entrée = conserver) et delete_contact (par nom exact, avec confirmation o/n). Teste tout le menu. Commit v1.

v2 — niveau 6

  1. Dans contacts_v2.py, écris la classe Contact seule : __init__, __str__, to_dict, from_dict. Teste-la dans le REPL ou sous if __name__ == "__main__": — créer, afficher, convertir aller-retour (Contact.from_dict(c.to_dict())).
  2. Écris ContactBook avec add, find, remove en mémoire (sans JSON). Teste ses méthodes directement, sans menu.
  3. Ajoute save(path) / load(path) au carnet : save convertit chaque contact avec to_dict, load reconstruit avec from_dict. Charge ton contacts.json de la v1 : il doit passer tel quel.
  4. Rebranche le menu de la v1 sur le carnet (l'interface appelle les méthodes, ne touche plus aux dicts). Déroule le même scénario complet que la v1 et compare. Commit v2.

Extensions possibles

  1. Trier le listing par nom (sorted avec key=).
  2. Valider grossièrement l'email (contient @ et un point après) — la vraie validation est un puits sans fond, reste simple.
  3. Export CSV (csv.writer) pour ouvrir le carnet dans un tableur.
  4. v2 : une méthode merge(other_book) qui fusionne deux fichiers de contacts en gérant les doublons — bon exercice de conception.

Erreurs fréquentes sur ce projet

Critères de réussite

Commit conseillé

git add projects/mini-projects/09-carnet-de-contacts/
git commit -m "project: add contact book"
# ... puis, apres la v2 :
git commit -m "project: add contact book OOP version"

Puis entrée de journal + git push. Comme au projet 06 : contacts.json dans .gitignore si tu y mets de vrais contacts.