Mini-projets algorithmique, corrigé TP KNN, news, notebooks IA
This commit is contained in:
88
algorithmes/mini-projets/04_annuaire/starter.py
Normal file
88
algorithmes/mini-projets/04_annuaire/starter.py
Normal file
@@ -0,0 +1,88 @@
|
||||
# Projet 04 — L'Annuaire
|
||||
# Algorithmes : Tri par insertion + Recherche dichotomique
|
||||
|
||||
# L'annuaire est une liste de dictionnaires, toujours triée par "nom"
|
||||
annuaire = [
|
||||
{"nom": "Dupont", "prenom": "Alice", "tel": "06 11 22 33 44"},
|
||||
{"nom": "Garcia", "prenom": "Carlos", "tel": "07 55 66 77 88"},
|
||||
{"nom": "Martin", "prenom": "Sophie", "tel": "06 99 88 77 66"},
|
||||
{"nom": "Petit", "prenom": "Luc", "tel": "07 12 34 56 78"},
|
||||
{"nom": "Rousseau", "prenom": "Emma", "tel": "06 44 55 66 77"},
|
||||
]
|
||||
|
||||
def afficher_annuaire(annuaire):
|
||||
"""Affiche tous les contacts sous forme de tableau."""
|
||||
print(f"\n{'Nom':<15} {'Prénom':<12} {'Téléphone'}")
|
||||
print("-" * 40)
|
||||
for contact in annuaire:
|
||||
print(f"{contact['nom']:<15} {contact['prenom']:<12} {contact['tel']}")
|
||||
print()
|
||||
|
||||
def ajouter_contact(annuaire, contact):
|
||||
"""
|
||||
Insère le contact à la bonne place pour maintenir l'ordre alphabétique.
|
||||
Principe : tri par insertion (un seul élément à insérer).
|
||||
"""
|
||||
annuaire.append(contact) # on l'ajoute à la fin temporairement
|
||||
j = len(annuaire) - 1
|
||||
# TODO : décaler vers la droite tant que le nom précédent est > au nom du contact
|
||||
# Indice : comparer annuaire[j-1]["nom"] et contact["nom"]
|
||||
while j > 0 and ...:
|
||||
annuaire[j] = annuaire[j - 1]
|
||||
j -= 1
|
||||
annuaire[j] = contact
|
||||
|
||||
def rechercher(annuaire, nom):
|
||||
"""
|
||||
Recherche dichotomique par nom.
|
||||
Retourne le contact (dict) si trouvé, None sinon.
|
||||
"""
|
||||
a = 0
|
||||
b = len(annuaire) - 1
|
||||
while a <= b:
|
||||
m = (a + b) // 2
|
||||
nom_m = annuaire[m]["nom"]
|
||||
if nom_m == nom:
|
||||
return annuaire[m]
|
||||
elif nom_m < nom:
|
||||
# TODO
|
||||
pass
|
||||
else:
|
||||
# TODO
|
||||
pass
|
||||
return None
|
||||
|
||||
def menu():
|
||||
"""Boucle de menu interactif."""
|
||||
while True:
|
||||
print("=== Annuaire ===")
|
||||
print("1 — Afficher tous les contacts")
|
||||
print("2 — Ajouter un contact")
|
||||
print("3 — Rechercher un contact")
|
||||
print("4 — Quitter")
|
||||
choix = input("Votre choix : ")
|
||||
|
||||
if choix == "1":
|
||||
afficher_annuaire(annuaire)
|
||||
|
||||
elif choix == "2":
|
||||
nom = input("Nom : ").strip().capitalize()
|
||||
prenom = input("Prénom : ").strip().capitalize()
|
||||
tel = input("Téléphone : ").strip()
|
||||
ajouter_contact(annuaire, {"nom": nom, "prenom": prenom, "tel": tel})
|
||||
print(f"{nom} ajouté !")
|
||||
|
||||
elif choix == "3":
|
||||
nom = input("Nom à rechercher : ").strip().capitalize()
|
||||
# TODO : appeler rechercher() et afficher le résultat
|
||||
pass
|
||||
|
||||
elif choix == "4":
|
||||
print("Au revoir !")
|
||||
break
|
||||
else:
|
||||
print("Choix invalide.")
|
||||
|
||||
|
||||
# --- Programme principal ---
|
||||
menu()
|
||||
46
algorithmes/mini-projets/04_annuaire/sujet.md
Normal file
46
algorithmes/mini-projets/04_annuaire/sujet.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# 04 — L'Annuaire
|
||||
|
||||
**Algorithmes :** Tri par insertion + Recherche dichotomique
|
||||
**Difficulté :** Moyen
|
||||
**Durée estimée :** 1h — 1h15
|
||||
|
||||
---
|
||||
|
||||
## Contexte
|
||||
|
||||
Vous créez un mini-annuaire de contacts. Il doit toujours rester **trié par nom** pour que la recherche dichotomique fonctionne.
|
||||
|
||||
Chaque fois qu'on ajoute un contact, on l'insère directement à la bonne place (comme dans le tri par insertion). Chaque fois qu'on cherche, on utilise la dichotomie.
|
||||
|
||||
---
|
||||
|
||||
## Étapes
|
||||
|
||||
### Étape 1 — Afficher l'annuaire
|
||||
Lancez le starter, vérifiez que `afficher_annuaire()` fonctionne.
|
||||
|
||||
### Étape 2 — Implémenter `ajouter_contact(annuaire, contact)`
|
||||
Cette fonction insère le nouveau contact **à la bonne position** pour maintenir l'ordre alphabétique.
|
||||
|
||||
> **Indication** : c'est le principe du tri par insertion, mais appliqué à un seul élément. On parcourt depuis la fin et on décale les contacts dont le nom est alphabétiquement après le nouveau.
|
||||
>
|
||||
> Pour comparer des chaînes alphabétiquement en Python : `"Dupont" < "Martin"` → `True`
|
||||
|
||||
### Étape 3 — Implémenter `rechercher(annuaire, nom)`
|
||||
Recherche dichotomique : retourne le contact (dictionnaire complet) si trouvé, `None` sinon.
|
||||
|
||||
### Étape 4 — Menu interactif
|
||||
Complétez la boucle `menu()` pour que l'utilisateur puisse :
|
||||
- `1` — Afficher tous les contacts
|
||||
- `2` — Ajouter un contact
|
||||
- `3` — Rechercher un contact par nom
|
||||
- `4` — Quitter
|
||||
|
||||
### Étape 5 — Extension (si vous avez le temps)
|
||||
Ajoutez une option `5` pour supprimer un contact par nom (cherchez-le d'abord avec la dichotomie, puis supprimez-le de la liste).
|
||||
|
||||
---
|
||||
|
||||
## Ce que vous devez rendre
|
||||
- Le programme avec le menu fonctionnel
|
||||
- Réponse : dans quel cas la dichotomie est-elle inutilisable directement ?
|
||||
Reference in New Issue
Block a user