Résoudre un problème
Comprendre vraiment un énoncé avant de coder. Décomposer, reformuler, identifier les zones d'ombre, poser les bonnes questions — du TP de 1ère année au cahier des charges client.
Pourquoi c'est difficile
La première erreur des développeurs débutants — et de beaucoup d'expérimentés — est de commencer à coder avant de comprendre le problème. On suppose avoir compris, on part dans une direction, et on se retrouve à tout refaire au bout de deux heures parce qu'on n'avait pas lu la bonne contrainte.
La règle de Polya (mathématicien, 1945) — toujours d'actualité en informatique :
1. Comprendre le problème
2. Concevoir un plan
3. Exécuter le plan
4. Vérifier et tirer les leçons
La majorité des erreurs viennent de sauter l'étape 1.
| Ce qu'on croit faire | Ce qu'on fait vraiment |
|---|---|
| "J'ai lu l'énoncé" | On a parcouru le texte en cherchant des mots-clés familiers |
| "J'ai compris" | On a une idée vague qui correspond à ce qu'on a déjà fait |
| "Je commence à coder" | On code la solution qu'on avait en tête avant de lire |
| "C'est presque fini" | La fonctionnalité principale fonctionne, mais 40% des contraintes manquent |
Investir 20 minutes d'analyse au départ évite souvent 3 heures de réécriture. La compréhension du problème n'est pas du temps perdu — c'est du temps de développement compressé.
Décomposer un énoncé
Tout énoncé — qu'il soit un TP de 3 lignes ou un CDC de 20 pages — contient les mêmes catégories d'information. Apprendre à les repérer systématiquement.
Une fois les catégories identifiées, les organiser dans un tableau de synthèse. Ce tableau devient la source de vérité du projet — ce à quoi on revient quand on doute, et ce qu'on montre au client / chargé de cours pour validation.
┌─────────────────┬──────────────────────────────────┐
│ ACTIONS │ Ce que le programme fait │
├─────────────────┼──────────────────────────────────┤
│ • Lire │ un fichier CSV de produits │
│ • Filtrer │ par catégorie et prix max │
│ • Afficher │ les résultats formatés │
│ • Exporter │ vers un nouveau CSV │
├─────────────────┼──────────────────────────────────┤
│ DONNÉES │ Entités & structures │
├─────────────────┼──────────────────────────────────┤
│ • Produit │ nom, catégorie, prix, stock │
│ • Catalogue │ liste de Produit │
├─────────────────┼──────────────────────────────────┤
│ CONTRAINTES │ Limites & règles │
├─────────────────┼──────────────────────────────────┤
│ • POO │ Obligatoire (classe Produit) │
│ • Pas de pandas │ Seulement csv et builtins │
│ • Prix négatif │ → lever une ValueError │
├─────────────────┼──────────────────────────────────┤
│ LIVRABLES │ Ce qu'on rend │
├─────────────────┼──────────────────────────────────┤
│ • main.py │ + produit.py, catalogue.py │
│ • tests/ │ 5 tests minimum │
├─────────────────┼──────────────────────────────────┤
│ AMBIGUÏTÉS │ À clarifier avant de commencer │
├─────────────────┼──────────────────────────────────┤
│ • "filtrer" │ → ET ou OU entre les critères ? │
│ • "formatés" │ → tableau ASCII ? JSON ? autre ? │
└─────────────────┴──────────────────────────────────┘
Annoter un énoncé — en pratique
La recherche doit fonctionner par titre ou par auteur. L'ISBN doit être unique dans la bibliothèque — toute tentative d'ajout d'un doublon devra lever une exception. Aucune bibliothèque externe n'est autorisée, pas même json.
Vous rendrez un fichier bibliotheque.py, un fichier main.py de démonstration et un fichier tests_bibliotheque.py contenant au minimum 8 tests. La persistance des données n'est pas demandée pour ce TP.
Ambiguïté 1 — "par titre ou par auteur" : est-ce que la recherche renvoie tous les livres qui correspondent à l'un ou à l'autre ? Ou faut-il choisir le critère à l'avance ? La méthode accepte-t-elle un seul paramètre ou deux ? → À clarifier.
Ambiguïté 2 — "la persistance n'est pas demandée pour ce TP" : sous-entendu qu'elle pourrait être demandée plus tard ? Ou qu'on peut quand même la faire si on veut ? → Confirmer pour ne pas travailler pour rien ou rater des points bonus.
Reformuler le problème avec ses propres mots
Reformuler n'est pas paraphraser — c'est reconstruire le problème dans son propre modèle mental. Si tu ne peux pas l'expliquer à quelqu'un d'autre sans regarder l'énoncé, tu ne l'as pas vraiment compris.
Ajout("Java", "Bloch", 2018, "978-1") → ValueError: ISBN déjà existant
Recherche("Lutz") → [Livre("Python", "Lutz", …)]
Suppression d'un livre inexistant → exception ou ignorer silencieusement ?
════════════════════════════════════════
MA COMPRÉHENSION DU PROBLÈME
════════════════════════════════════════
Problème central :
Créer un gestionnaire de bibliothèque POO
qui garantit l'unicité des ISBN.
Ce que le programme fait :
• Maintenir une collection de livres en mémoire
• Ajouter un livre (avec vérification ISBN)
• Rechercher par titre OU auteur
• Supprimer par ISBN
• Lever des exceptions sur les erreurs
Ce que le programme ne fait PAS :
• Pas de sauvegarde sur disque
• Pas d'interface graphique
• Pas de tri (non mentionné)
Structures de données envisagées :
class Livre : titre, auteur, annee, isbn
class Bibliotheque : dict {isbn → Livre}
→ dict = recherche ISBN en O(1)
Cas limites à traiter :
• ISBN en double → ValueError
• Recherche sans résultat → liste vide
• Suppression ISBN inexistant → ? ← à clarifier
Questions ouvertes :
1. Recherche "ou" : les deux champs en même temps ?
2. Suppression inexistant : exception ou pass ?
3. La persistance peut-elle être faite en bonus ?
════════════════════════════════════════
Écrire cette reformulation avant de créer le moindre fichier. Si tu bloques sur une phrase, c'est qu'il y a quelque chose que tu n'as pas compris — retourner à l'énoncé pour ce point précis.
Identifier ce qu'on ne sait pas encore
Il existe plusieurs types d'inconnues — et chacune a une façon différente d'être résolue. Les identifier clairement évite de bloquer ou de partir dans la mauvaise direction.
INCONNUES — Projet bibliothèque
Mis à jour : 2025-01-15
════════════════════════════════════
🔴 BLOQUANT (à résoudre avant de commencer)
───────────────────────────────────────────
□ Recherche "par titre OU auteur" :
→ méthode unique avec un paramètre ?
→ deux méthodes séparées ?
→ Statut : À demander au prof
□ Suppression d'un ISBN inexistant :
→ lever KeyError ? retourner False ?
→ Statut : À demander au prof
🟡 IMPORTANT (à résoudre dans les 24h)
───────────────────────────────────────────
□ Format d'affichage des résultats :
→ __str__ sur Livre ? tableau ? dict ?
→ Statut : Choix personnel documenté → __repr__ + __str__
🟢 OPTIONNEL (si on a le temps)
───────────────────────────────────────────
□ La persistance peut-elle être ajoutée ?
→ Statut : Demanderait des points bonus ?
RÉSOLUES
───────────────────────────────────────────
✓ Bibliothèques externes → interdites (confirmé)
✓ 8 tests minimum → pas "exactement 8"
Classer les inconnues par urgence : une inconnue qui bloque toute l'architecture doit être résolue avant de commencer. Une inconnue qui ne concerne qu'un détail d'affichage peut attendre.
Poser les bonnes questions
Une question bien formulée obtient une réponse utilisable. Une mauvaise question obtient une réponse vague qui génère de nouvelles ambiguïtés — ou pire, une réponse qu'on interprétera mal.
- Qu'est-ce qui est hors périmètre ? Mieux vaut le savoir avant d'implémenter une fonctionnalité non demandée.
- Quelle est la priorité entre les fonctionnalités si le temps manque ?
- Y a-t-il des fonctionnalités qui seront ajoutées plus tard et dont je dois tenir compte dès maintenant dans la conception ?
- Ce cas d'utilisation est-il inclus ? (ex : un administrateur peut-il faire X, ou seulement Y ?)
- Quel est le format exact des données d'entrée ? Exemple de fichier CSV réel, plage de valeurs, encodage.
- Que se passe-t-il si une donnée est manquante ou malformée ? Erreur fatale ? Valeur par défaut ? Ignorer la ligne ?
- Quel est l'ordre de grandeur des volumes ? 100 lignes ou 10 millions ?
- Les données peuvent-elles changer en cours d'exécution ? (accès concurrent, fichier modifié…)
- Comment va-t-on évaluer que c'est "correct" ? Tests automatiques ? Démo manuelle ? Relecture de code ?
- Y a-t-il un exemple de sortie attendue que tu peux me montrer ?
- Quel est le critère minimum pour que ce soit acceptable (MVP) ?
- Qu'est-ce qui ferait que c'est "excellent" par rapport à "suffisant" ?
- Quelles bibliothèques ou frameworks sont autorisés / imposés ?
- Y a-t-il des contraintes de performance ? Temps de réponse, mémoire maximale.
- Sur quel environnement le code sera-t-il exécuté ? Version Python, OS, hardware spécifique.
- Y a-t-il des conventions de nommage ou de style imposées ? (PEP 8, camelCase, structure de dossiers…)
- Que se passe-t-il avec une entrée vide ? (liste vide, chaîne vide, fichier vide)
- Que se passe-t-il avec des valeurs extrêmes ? (0, négatif, très grand nombre, None)
- L'utilisateur peut-il faire des erreurs de saisie ? Faut-il les gérer ?
- Que faire en cas d'erreur irrécupérable ? (fichier introuvable, connexion perdue)
Formuler une bonne question : toujours inclure (1) le contexte, (2) ce qu'on a compris, (3) l'ambiguïté précise, (4) les options envisagées. Exemple : "Dans l'énoncé, il est dit que la recherche fonctionne par titre ou auteur. J'ai compris que c'est une seule méthode. Doit-elle accepter les deux en même temps, ou choisir un critère à la fois ?"
Questions à éviter : "Est-ce que j'ai bien compris ?" (trop vague), "C'est normal que ça marche pas ?" (pas de contexte), "Qu'est-ce que je dois faire ?" (montre qu'on n'a pas lu l'énoncé).
Passer de l'analyse au plan d'attaque
Une fois les ambiguïtés levées et le problème bien compris, il faut planifier avant de coder. Un plan d'attaque n'est pas un diagramme UML de 30 classes — c'est une liste ordonnée de ce qu'on va faire, dans quel ordre, et pourquoi cet ordre-là.
PLAN D'ATTAQUE — Bibliothèque Python
═══════════════════════════════════════
Estimation : ~4h
1. [30min] Structures de données
→ Classe Livre(titre, auteur, annee, isbn)
→ Classe Bibliotheque(dict isbn→Livre)
→ Validation : créer 2-3 livres, afficher
2. [45min] Ajout avec validation ISBN
→ Bibliotheque.ajouter(livre)
→ Lever ValueError si ISBN existe déjà
→ Test : ajouter doublon → exception
3. [45min] Recherche
→ Bibliotheque.rechercher(terme)
→ Cherche dans titre ET auteur
→ Retourne liste (vide si pas trouvé)
4. [30min] Suppression
→ Bibliotheque.supprimer(isbn)
→ Comportement si inexistant → Exception
(confirmé avec prof)
5. [60min] Tests unitaires (8 minimum)
→ test_ajout_normal
→ test_ajout_doublon_isbn
→ test_recherche_par_titre
→ test_recherche_par_auteur
→ test_recherche_inexistante → []
→ test_suppression
→ test_suppression_inexistante
→ test_bibliotheque_vide
6. [30min] main.py de démonstration
→ Scénario réaliste complet
7. [20min] Relecture de l'énoncé
→ Cocher chaque exigence une par une
Erreurs classiques d'interprétation
numpy. Résultat : fonctionnalité à refaire entièrement.Énoncé de TP — analyse complète
Chaque compte a un solde initial et un titulaire. Un retrait supérieur au solde doit être refusé avec une exception appropriée. Les montants négatifs doivent également être rejetés.
On devra pouvoir consulter l'historique des opérations avec leur date. Le solde ne peut jamais être négatif.
Rendre un fichier compte.py et un fichier test_compte.py. Les tests doivent couvrir au moins les cas nominaux et les cas d'erreur.
ACTIONS : déposer, retirer, consulter historique,
rejeter les opérations invalides
DONNÉES : Compte(titulaire, solde),
Opération(type, montant, date)
Historique = liste d'Opération
CONTRAINTES :
✓ POO obligatoire
✓ Solde jamais négatif → exception
✓ Montants négatifs → exception
✓ Tests : cas nominaux + cas d'erreur
LIVRABLES : compte.py, test_compte.py
AMBIGUÏTÉS À CLARIFIER :
⚠ "montants négatifs rejetés" → s'applique
au dépôt seulement ? au retrait aussi ?
(un retrait est-il déjà négatif par nature ?)
⚠ "leur date" → date système automatique ?
ou passée en paramètre ? Quel format ?
⚠ "exception appropriée" → ValueError ?
une classe custom InsufficientFunds ?
EXEMPLES CONCRETS :
compte = Compte("Alice", 1000)
compte.deposer(500) → solde : 1500
compte.retirer(200) → solde : 1300
compte.retirer(2000) → exception !
compte.deposer(-50) → exception !
compte.historique() → [Dépôt 500, Retrait 200]
PLAN (estimé 3h) :
1. Classe Compte + Opération (30min)
2. deposer() + retirer() (45min)
3. historique() (20min)
4. Exceptions et validation (30min)
5. Tests (45min)
CDC client — analyse complète
Un CDC (Cahier des Charges) client est plus long et plus flou qu'un énoncé de TP — le client n'est pas développeur, il décrit son besoin en termes métier, pas techniques. La méthode est la même, mais il faut en plus traduire le vocabulaire métier en concepts techniques et identifier les hypothèses implicites que le client n'a pas pensé à préciser.
Hébergement : qui gère le serveur ? Budget prévu pour l'hosting ?
Données existantes : faut-il migrer l'Excel actuel ?
Statistiques : ont-ils besoin de rapports, tableaux de bord ?
AVANT DE COMMENCER — 10 questions prioritaires
1. Qu'est-ce qu'"archiver" signifie exactement ?
→ L'annonce est encore visible par le directeur ?
→ On peut la "désarchiver" ?
2. L'application doit-elle fonctionner sur mobile ?
→ Les agents ont des smartphones/tablettes ?
3. Avez-vous un exemple d'application qui ressemble
à ce que vous imaginez ?
4. Faut-il migrer les données de l'Excel actuel ?
→ Combien d'annonces ? Sur quelle période ?
5. Qui gère l'hébergement après livraison ?
→ Budget prévu pour le serveur / maintenance ?
6. La recherche des clients : sur votre site actuel
ou une nouvelle page publique ?
7. Les photos : stockage illimité ou quota ?
→ Taille max par photo ?
8. Que doit-il se passer si deux agents modifient
la même annonce en même temps ?
9. Avez-vous besoin de statistiques ?
→ Nombre de vues par annonce, etc ?
10. Quel est le périmètre strict pour les 2 mois ?
→ Qu'est-ce qui peut attendre une V2 ?
MVP (2 mois, 5 000€) — périmètre suggéré :
✓ Authentification agents (login simple)
✓ CRUD annonces (ajouter/modifier/archiver)
✓ Rôle directeur (suppression définitive)
✓ Upload de photos (3 max par annonce)
✓ Page publique de recherche (ville, type, prix)
✓ Fiche annonce publique
✗ Hors MVP — Phase 2 :
- Statistiques et tableaux de bord
- Application mobile native
- Messagerie entre agents
- Intégration portails (SeLoger, LeBonCoin)
- Signature électronique
Questions qui conditionnent l'architecture :
- Mobile web ou app native ? → impact coût x3
- Hébergement inclus ? → +500€/an
- Migration données Excel ? → +2 jours
→ Valider ce périmètre avant tout devis
Cheat Sheet — Résolution de problèmes
📋 Décomposer un énoncé
| Actions (A) | Les verbes — que faire ? |
| Données (D) | Les noms — avec quoi ? |
| Contraintes (C) | Les limites — comment ? |
| Livrables (L) | Ce qu'on rend |
| Ambiguïtés (?) | Ce qui est flou → clarifier |
🔄 Reformuler
| 1. | Fermer l'énoncé, résumer en 3 phrases |
| 2. | Identifier LE problème central |
| 3. | Décrire entrée et sortie |
| 4. | Tracer un exemple à la main |
| 5. | Repérer les cas limites |
❓ Questions prioritaires
| Périmètre | Qu'est-ce qui est hors scope ? |
| Données | Format exact ? Volumes ? Erreurs ? |
| Livrables | Critère de succès ? MVP ? |
| Contraintes | Stack ? Performance ? Style ? |
| Cas limites | Vide ? None ? Valeur extrême ? |
🚨 Erreurs à éviter
| ✗ | Coder avant de comprendre |
| ✗ | Implémenter ce qui n'est pas demandé |
| ✗ | Confondre "ou" et "et" |
| ✗ | Oublier les cas d'erreur |
| ✗ | Ne pas relire les critères avant de rendre |
□ J'ai lu l'énoncé/CDC deux fois en entier
□ J'ai identifié toutes les actions demandées
□ J'ai listé toutes les contraintes (même celles en milieu de phrase)
□ Je sais exactement ce qu'il faut rendre
□ J'ai listé toutes les ambiguïtés
□ J'ai clarifié les ambiguïtés bloquantes
□ J'ai reformulé le problème avec mes propres mots
□ J'ai tracé un exemple concret à la main
□ J'ai réfléchi aux cas limites
□ J'ai un plan d'attaque avec des étapes ordonnées
□ J'ai relu l'énoncé/CDC ligne par ligne
□ Chaque action demandée est implémentée
□ Chaque contrainte est respectée
□ Tous les livrables sont présents
□ Les cas limites sont gérés
□ Les tests couvrent le nominal ET l'erreur
□ Le code tourne sans erreur sur un exemple neuf
□ J'ai testé avec des données différentes de l'exemple
□ Le README / la doc demandée est présente
□ J'ai vérifié les conventions de nommage