Projet de synthèse · L3 · Section 1/2
Cadrage & sujet
Progression
#Projet de synthèse
Un projet de synthèse intègre l'ensemble des compétences acquises sur un problème réaliste. Cette édition le traite comme une démarche expérimentale de sciences du logiciel: on formule une hypothèse, on instrumente le système pour la tester, on compare à une ligne de base, on analyse et on rapporte. Le code n'est que la moitié du livrable; l'autre moitié est la preuve reproductible que le code fait ce qu'on prétend.
Prérequis
- Programmation (Python ou JavaScript), tests unitaires, Git collaboratif.
- Un module applicatif de votre parcours: structures de données, bases de données, Web ou systèmes.
- Goûter pour la rigueur scientifique: une affirmation sans mesure n'est qu'une opinion.
Objectifs d'apprentissage
- Formuler une hypothèse falsifiable et dérouler le cycle expérimental complet: instrumenter, mesurer, analyser, rapporter.
- Construire une ligne de base honnête et comparer deux variantes avec statistiques élémentaires (répétitions, dispersion).
- Rendre une expérience reproductible: environnement figé, données versionnées, protocole écrit, résultats archivés.
- Communiquer des résultats avec leur incertitude, sans maquiller les cas défavorables.
#Le cycle expérimental
#Phase 1: question et hypothèse
Toute expérience commence par une question précise, transformée en hypothèse falsifiable. « Mon code est plus rapide » n'est pas une hypothèse; « le remplacement de la liste par un ensemble réduit le temps de construction de l'index de 30% sur le jeu de données de référence, parce que l'appartenance passe de O(n) à O(1) » en est une.
Formulation utile: « Si [changement], alors [métrique] s'améliore de [ordre de grandeur attendu], mesuré par [protocole], parce que [mécanisme]. » Le « parce que » compte: il donne le mécanisme, ce qui permet de prédire quand l'effet disparaîtra (petits n, données différentes).
Le cahier de cadrage explicite le problème, les objectifs mesurables, le périmètre, les risques et le planning. Il aligne l'équipe et sert de référence pendant toute la durée du projet.
#Questions à se poser
- Quel problème résout-on, pour qui, quelle est la valeur apportée ?
- Quelles mesures prouveront le succès ? Avant d'écrire le code, pas après.
- Qu'est-ce qui est dans le périmètre, qu'est-ce qui est explicitement exclu ?
- Quels sont les risques principaux et comment les mitiger ?
#Phase 2: conception instrumentée
Avant de coder, trois décisions: l'architecture, le plan de mesure et le protocole expérimental. Une architecture non instrumentée (aucun point de mesure, aucun journal) rend les phases ultérieures aveugles.
Points clés:
- Architecture: monolithe ou services ? Frontend/backend ? Attention au coût de chaque frontière: chaque ajout non justifié par une hypothèse est de l'over-engineering.
- Instrumentation: chronomètres autour des unités à comparer, compteurs d'événements, journal structuré. Prévoyez-la dès le début; la greffer après coup coûte plus cher.
- Données: un jeu de données de référence versionné dans le dépôt (ou un générateur avec graine fixée). Sans données stables, aucune comparaison n'a de sens.
- Sécurité: quelles données sensibles traversent le système ? Voir le module Sécurité appliquée.
1# Structure recommandée2projet/3├── README.md # usage + comment reproduire les résultats4├── docs/ # protocole expérimental, analyses, journal5├── src/ # code source6├── tests/ # tests automatisés7├── benchmarks/ # scripts de mesure et lignes de base8├── data/ # jeux de données de référence (ou générateurs seedés)9├── results/ # sorties brutes des mesures (CSV/JSON, jamais retouchées)10└── .github/ # CI/CD (GitHub Actions)#Phase 3: développement itératif
On ne code pas tout d'un coup. On procède par itérations courtes: implémenter, mesurer, comparer, décider. Chaque itération se termine par un enregistrement dans le journal d'expérience: date, commit, série de mesures, verdict.
Bonnes pratiques:
- Branches et Pull Requests: chaque fonctionnalité ou variante expérimentale sur une branche, review avant merge.
- CI automatisée: tests, lint, build à chaque push; les benchmarks de santé (non de performance) aussi.
- Commits atomiques: un commit = une modification logique, message clair.
- Journal d'expérience: un fichier
docs/journal.mdoù chaque expérience consigne question, protocole, résultats bruts (liés par hash de commit) et conclusion.
#Phase 4: mesure et analyse
C'est le cœur de la démarche. Trois règles gouvernent tout.
Règle 1: une ligne de base avant tout. Mesurez la version de référence (l'existant, l'implémentation naïve) avec le même protocole que les variantes. Sans ligne de base, un chiffre isolé ne veut rien dire.
Règle 2: répétez et rapportez la dispersion. Une mesure unique dit plus sur l'état de la machine que sur le code. Répétez chaque mesure (au moins 5 à 30 fois selon la variance), rapportez médiane et dispersion (quartiles ou écart-type), pas seulement la moyenne.
Règle 3: ne publiez jamais un chiffre que vous ne savez pas reproduire. Figurez l'environnement: matériel (CPU, RAM, disque), logiciel (OS, versions de bibliothèques, hash du commit), conditions (données utilisées, échauffement effectué).
Protocole minimal Python, à adapter:
1import statistics, time2 3def mesurer(f, *args, repetitions=20, echauffement=3):4 """Mesure un appel répété et retourne (médiane, quartiles) en secondes."""5 for _ in range(echauffement):6 f(*args) # echauffement: caches, JIT, pages memoire7 echantillons = []8 for _ in range(repetitions):9 t0 = time.perf_counter()10 f(*args)11 echantillons.append(time.perf_counter() - t0)12 return statistics.median(echantillons), statistics.quantiles(echantillons, n=4)13 14mediane, (q1, _, q3) = mesurer(construire_index, donnees)Lecture honnête des résultats: si les intervalles interquartiles de la ligne de base et de la variante se recouvrent largement, vous n'avez pas démontré d'amélioration. Si la variante gagne sur le jeu de données de référence mais pas sur des données bruitées, dites-le: la validité externe est une limite, pas un détail.
#Phase 5: reproductibilité
Une expérience n'a de valeur que si un tiers peut la refaire. Concrètement:
- Environnement figé:
requirements.txt/package-lock.jsonversionnés, ou image Docker avec tag précis (paslatest). - Générateur de données avec graine fixée (
random.seed(42)), documenté dans le protocole. - Script unique
make reproduce(ounpm run reproduce) qui enchaîne: générer les données, exécuter les variantes, produire les tableaux et graphiques du rapport. - Résultats bruts archivés dans
results/en CSV/JSON, jamais retouchés à la main; les chiffres du rapport sortent d'un script, pas d'un tableur.
Test d'acceptation simple: un camarade clone le dépôt, lance une commande, obtient des chiffres comparables aux vôtres (à dispersion près). Si ça échoue, le livrable est incomplet, même si le code fonctionne.
#Phase 6: rapport et soutenance
Le rapport suit la structure d'un court article scientifique:
- Problème et hypothèse: ce qu'on affirme et pourquoi le mécanisme le prédit.
- Méthode: système, instrumentation, protocole, environnement. Assez précis pour être rejoué.
- Résultats: tableaux et graphiques avec dispersion; données et scripts disponibles.
- Analyse: les chiffres confirment-ils l'hypothèse ? Quels cas la contredisent ?
- Limites: validité interne (protocole) et externe (généralisation), en toute honnêteté.
- Suite: ce qu'on ferait avec plus de temps, et quelle question reste ouverte.
La démonstration (5-10 minutes) raconte: problème, hypothèse, démo sur données réalistes, résultats avec leur incertitude, limites, suite. Une présentation qui assume un résultat négatif (« l'hypothèse était fausse, voici pourquoi c'est instructif ») est plus forte qu'une autre qui esquive.
#Évaluation suggérée
- Fonctionnalités et démarche (40%): le livrable fonctionne et répond au besoin; l'hypothèse a été effectivement testée.
- Qualité technique (30%): architecture lisible, tests pertinents, instrumentation propre, reproductibilité réelle.
- Analyse et rigueur (15%): lignes de base, répétitions, dispersion, lecture honnête incluant les résultats défavorables.
- Communication (15%): rapport structuré, clarté de la démo, transparence sur les limites.
#Gestion des risques
Identifier les risques tôt: technique (technologie inconnue, mesure instable), humain (disponibilité), externe (API tierce). Mitigation: prototypes, solutions de repli, buffer dans le planning. Le risque spécifique à cette démarche: la mesure qui ne converge pas. Mitigation: réduire le bruit (machine calme, plus de répétitions), ou changer d'échelle de question (comparer des ordres de grandeur plutôt que des pourcentages).
Pivoter si nécessaire: mieux vaut réduire le scope que livrer quelque chose de cassé, et mieux vaut une hypothèse invalidée proprement qu'une affirmation invérifiable.