Méthode · Analyse · Conception

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 faireCe 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.

A
Actions demandées — les verbes
Ce que le programme doit faire. Chercher les verbes d'action : créer, afficher, calculer, stocker, vérifier, trier, filtrer, envoyer…
"Écrire", "implémenter", "créer une interface qui permet de…", "calculer et afficher…"
D
Données — les noms
Ce avec quoi on travaille : les entités, les structures, les types. Chercher les noms qui représentent des objets du domaine.
"utilisateur", "note", "produit", "fichier CSV", "liste de commandes", "arbre binaire"
C
Contraintes — les limites
Ce que le programme ne doit pas faire, ou comment il doit le faire. Souvent cachées dans des adverbes ou des conditions.
"sans utiliser de bibliothèque externe", "en O(n log n)", "la saisie doit être validée", "uniquement en POO", "répondre en moins de 200ms"
L
Livrables — ce qui est attendu
Exactement ce qu'il faut rendre : fichiers, fonctions, classes, rapport, démo, tests, README…
"un fichier main.py", "une classe Banque avec ses méthodes", "un rapport PDF de 2 pages", "les tests unitaires"
?
Ambiguïtés — ce qui est flou
Tout ce qui peut être interprété de deux façons différentes. Les signaler, ne pas choisir arbitrairement.
"stocker les données" → en mémoire ? dans un fichier ? en base ? — "l'utilisateur peut modifier" → tous ? seulement les admins ?
📋

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.

Tableau de synthèse — template
┌─────────────────┬──────────────────────────────────┐
│ 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

Action demandée
Donnée / entité
Contrainte
Livrable
Ambiguïté ⚠
📄 Énoncé de TP — Gestion de bibliothèque
Vous devez implémenter un système de gestion de bibliothèque en Python en utilisant uniquement la POO. Le système devra permettre d'ajouter, de rechercher et de supprimer des livres. Chaque livre possède un titre, un auteur, une année de publication et un ISBN.

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.

1
Fermer l'énoncé et résumer en 3 phrases
Sans regarder le texte, expliquer ce qu'on doit faire comme si on le racontait à un camarade. Les trous dans l'explication = zones mal comprises.
"Je dois créer un programme qui gère une bibliothèque. On peut ajouter et chercher des livres. Les ISBN ne peuvent pas être dupliqués."
2
Identifier le problème central
Une seule phrase : quel est le problème principal à résoudre ? Tout le reste est détail d'implémentation.
"Le problème central : gérer un catalogue de livres avec contrainte d'unicité sur l'ISBN."
3
Décrire l'entrée et la sortie
Qu'est-ce qui entre dans le système ? Qu'est-ce qui en sort ? Cette vision "boîte noire" clarifie beaucoup de flous.
Entrée : titre, auteur, année, ISBN → Sortie : confirmation d'ajout ou exception. Entrée : titre → Sortie : liste de livres correspondants.
4
Écrire un exemple concret à la main
Inventer des données fictives et tracer manuellement ce que le programme devrait faire. C'est le test le plus simple — et il révèle des cas oubliés.
Ajout("Python", "Lutz", 2013, "978-1") → OK
Ajout("Java", "Bloch", 2018, "978-1") → ValueError: ISBN déjà existant
Recherche("Lutz") → [Livre("Python", "Lutz", …)]
5
Repérer les cas limites
Que se passe-t-il avec une bibliothèque vide ? Un livre introuvable ? Un ISBN vide ? Une chaîne de 0 caractères comme titre ?
Recherche("") → retourner [] ou tous les livres ?
Suppression d'un livre inexistant → exception ou ignorer silencieusement ?
Reformulation écrite — exemple complet
════════════════════════════════════════
 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.

📖 Ce que je ne comprends pas
  • Termes du domaine inconnus
  • Concepts techniques non maîtrisés
  • Acronymes non définis dans l'énoncé
  • → Chercher, lire la doc, demander
    ❓ Ce que l'énoncé ne dit pas
  • Comportement attendu sur les cas limites
  • Format exact des données d'entrée/sortie
  • Priorités entre fonctionnalités
  • → Poser la question au client / prof
    🎯 Ce que je dois choisir
  • Structure de données à utiliser
  • Architecture du code
  • Bibliothèques et outils
  • → Décider et documenter le choix
    Journal des inconnues — à tenir à jour
    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.

    📐 Questions sur le périmètre Champ du projet
    • 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 ?)
    📊 Questions sur les données Format & volume
    • 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é…)
    🎯 Questions sur les livrables Critères de succès
    • 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" ?
    ⚙️ Questions sur les contraintes techniques Stack & règles
    • 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…)
    🧪 Questions sur les cas limites Robustesse
    • 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à.

    PHASE 1
    Structures de données
  • Définir les classes / structs
  • Choisir les types de données
  • Écrire les attributs sans logique
  • Tester l'instanciation de base
  • PHASE 2
    Fonctionnalités core
  • Implémenter la fonction principale
  • Tester avec l'exemple concret
  • Valider les cas nominaux
  • Avant les cas d'erreur
  • PHASE 3
    Robustesse
  • Gérer les cas limites
  • Lever les bonnes exceptions
  • Valider les entrées
  • Tester les cas d'erreur
  • PHASE 4
    Tests & livrables
  • Écrire les tests unitaires
  • Vérifier les contraintes
  • Relire l'énoncé / CDC
  • Préparer les livrables
  • Plan d'attaque — exemple rédigé
    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

    🔴 Lire en diagonal et manquer des contraintes
    L'énoncé dit "sans utiliser de bibliothèque externe" à la ligne 8. On l'a lu, on n'y a plus pensé, on a quand même importé numpy. Résultat : fonctionnalité à refaire entièrement.
    Créer une checklist de contraintes et la cocher explicitement après avoir fini. Relire l'énoncé une dernière fois avant de rendre.
    🔴 Implémenter ce qui n'est pas demandé
    On trouve le problème trop simple, on ajoute une interface graphique, une base de données, une API REST… Le prof évalue la qualité du code demandé, pas le volume.
    Faire le MVP parfait avant tout ajout. Si du temps reste, demander si des bonus sont appréciés — ne pas supposer.
    🔴 Confondre "ou" et "et"
    "Filtrer les produits par catégorie ou par prix" — filtre catégorie ET prix simultanément, ou l'un OU l'autre ? En langage naturel, "ou" est souvent ambigu.
    Toujours clarifier les connecteurs logiques. En cas de doute, implémenter les deux et demander lequel est attendu.
    🔴 Oublier les cas d'erreur
    "La fonction doit retourner la moyenne" — et si la liste est vide ? Si elle contient des None ? La plupart des énoncés omettent les cas d'erreur en supposant qu'ils sont évidents.
    Pour chaque fonction, toujours se demander : que se passe-t-il avec une entrée vide, None, ou invalide ?
    🔴 Prendre les exemples pour des spécifications complètes
    L'énoncé donne un exemple avec 3 étudiants. On code une solution qui fonctionne avec exactement 3 étudiants, avec ces noms précis, dans cet ordre.
    Les exemples illustrent — ils ne définissent pas. Tester systématiquement avec des données différentes de l'exemple fourni.
    🔴 Ne pas distinguer besoin et solution
    Le client dit "je veux un bouton pour exporter en Excel". Le vrai besoin est "je veux partager les données avec mes collègues". La solution Excel est peut-être la mauvaise.
    Demander toujours pourquoi une fonctionnalité est demandée. La solution proposée par le client n'est pas toujours la meilleure pour son besoin.
    🔴 Assumer que le client sait ce qu'il veut
    Le client dit "une interface simple". Pour lui ça veut dire quelque chose. Pour toi ça veut dire autre chose. Deux semaines plus tard, la démo est un désastre.
    Demander de montrer un exemple existant qui ressemble à ce qu'il imagine. Ou faire une maquette papier à valider avant de coder.
    🔴 Livrer sans relire les critères
    On rend le projet, convaincu d'avoir tout fait. On a oublié le fichier README, les tests sont absents, et la contrainte de nommage des fonctions n'a pas été respectée.
    La dernière étape avant tout rendu : relire l'énoncé/CDC ligne par ligne et cocher chaque exigence. Traiter ça comme une checklist de départ en vol.

    Énoncé de TP — analyse complète

    Action
    Donnée
    Contrainte
    Livrable
    Ambigu
    📄 TP — Simulateur de compte bancaire
    Implémenter un compte bancaire en Python en POO. Le compte doit permettre les opérations de dépôt et de retrait.

    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.
    Analyse complète — tableau de synthèse
    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.

    Contexte
    Nous sommes une agence immobilière de 12 agents. Actuellement nous gérons nos annonces sur un fichier Excel partagé sur Google Drive, ce qui crée des problèmes de versions multiples et de conflits. Nous souhaitons une application web simple pour remplacer cet Excel.
    Le problème réel : plusieurs agents modifient le même fichier → conflits. L'application doit être multi-utilisateurs avec accès concurrent géré.
    Fonctionnalités demandées
    Chaque agent doit pouvoir ajouter, modifier et supprimer des annonces. Une annonce contient : l'adresse, le type de bien, le prix, la surface, le nombre de pièces, des photos et une description. Seul le directeur peut supprimer une annonce définitivement — les agents peuvent la "archiver".
    ❓ "Archiver" = masquer des recherches ? Inaccessible ? Récupérable ? → À clarifier impérativement.
    Les clients doivent pouvoir rechercher des biens sur le site sans se connecter. La recherche doit fonctionner par ville, type de bien, fourchette de prix.
    Contraintes
    Nous voudrions que l'application soit simple à utiliser, même pour des agents peu à l'aise avec l'informatique. Le budget est de 5 000€ et nous souhaitons une première version dans 2 mois.
    ❓ "Simple à utiliser" est subjectif → Demander de montrer une application existante qui leur convient comme référence.
    5 000€ et 2 mois = contraintes fortes. Il faudra probablement réduire le périmètre. Clarifier le MVP dès le départ.
    Ce qui n'est pas mentionné (à demander)
    Mobilité : les agents travaillent-ils depuis des tablettes sur le terrain ? Application mobile nécessaire ?
    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 ?
    Questions à poser avant de chiffrer
    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 ?
    Proposition de MVP — réponse au budget/délai
    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ètreQu'est-ce qui est hors scope ?
    DonnéesFormat exact ? Volumes ? Erreurs ?
    LivrablesCritère de succès ? MVP ?
    ContraintesStack ? Performance ? Style ?
    Cas limitesVide ? 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
    Checklist avant de commencer à coder
    □ 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
    Checklist avant de rendre
    □ 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