class Documentation:
Browse filesdef __init__(self):
self.docs = {
"python": "Documentation Python officielle",
"javascript": "Documentation JavaScript MDN",
"api": "Documentation API du projet"
}
def provide_docs(self, topic=""):
if topic in self.docs:
return f"Documentation pour {topic}: {self.docs[topic]}"
return "Documentation générale disponible"
class CodeEditor:
def __init__(self, language="python"):
self.language = language
self.code = ""
self.documentation = Documentation()
self.terminal = Terminal()
self.debugger = Debugger()
self.build_system = BuildSystem(language)
self.version_control = VersionControl()
self.testing_framework = TestingFramework()
self.deployment = Deployment()
def write_code(self, code):
self.code = code
print(f"Code {self.language} écrit:\n{self.code}")
return self.code
def get_suggestions(self):
suggestions = {
"python": ["import ", "def ", "class ", "print(", "if __name__"],
"javascript": ["function ", "const ", "let ", "console.log("]
}
return suggestions.get(self.language, ["// Commencez à coder..."])
def build(self):
print(f"Construction du projet {self.language}...")
return self.build_system.build(self.code)
def debug(self):
print("Débogage en cours...")
return self.debugger.debug(self.code)
def test(self):
print("Exécution des tests...")
return self.testing_framework.run_tests()
def deploy(self, environment="production"):
print(f"Déploiement sur {environment}...")
return self.deployment.deploy(environment)
def commit(self, message="Mise à jour du code"):
print(f"Commit: {message}")
return self.version_control.commit(message)
def run_terminal_command(self, command):
return self.terminal.execute_command(command)
def show_docs(self, topic=""):
return self.documentation.provide_docs(topic)
class Terminal:
def __init__(self):
self.history = []
def execute_command(self, command):
print(f"Terminal: {command}")
self.history.append(command)
commands = {
"ls": "fichier1.py fichier2.js dossier1/",
"pwd": "/home/user/projet",
"python --version": "Python 3.11.0",
"node --version": "v18.12.0"
}
if command in commands:
return commands[command]
return f"Commande exécutée: {command}"
def get_history(self):
return self.history
class Debugger:
def __init__(self):
self.breakpoints = []
def debug(self, code):
issues = self.analyze_code(code)
print(f"{len(issues)} problèmes détectés")
return issues
def analyze_code(self, code):
issues = []
if "print(" in code and "python" in code.lower():
issues.append("Utilisation de print() pour le débogage - considérez un logger")
if "TODO" in code:
issues.append("TODO trouvé dans le code")
if len(code) > 1000:
issues.append("Code très long - considérez la modularisation")
return issues
def add_breakpoint(self, line):
self.breakpoints.append(line)
print(f"Point d'arrêt ajouté à la ligne {line}")
def step_through(self):
print("Exécution pas à pas...")
class BuildSystem:
def __init__(self, language):
self.language = language
self.dependencies = []
def build(self, code):
build_commands = {
"python": "python -m py_compile",
"javascript": "npm run build",
"java": "mvn compile"
}
command = build_commands.get(self.language, "build")
print(f"Exécution: {command}")
if self.language == "python" and "import " in code:
self.dependencies = self.extract_imports(code)
print(f"Dépendances détectées: {self.dependencies}")
return {"status": "succès", "language": self.language}
def extract_imports(self, code):
imports = []
lines = code.split('\n')
for line in lines:
if line.strip().startswith("import "):
imports.append(line.strip())
elif line.strip().startswith("from "):
imports.append(line.strip())
return imports
class VersionControl:
def __init__(self):
self.commits = []
self.branch = "main"
def commit(self, message):
from datetime import datetime
commit = {
"id": len(self.commits) + 1,
"message": message,
"timestamp": datetime.now().isoformat(),
"branch": self.branch
}
self.commits.append(commit)
print(f"Commit #{commit['id']} créé sur la branche {self.branch}")
return commit
def create_branch(self, name):
self.branch = name
print(f"Branche '{name}' créée")
return self.branch
def get_history(self):
return self.commits
class TestingFramework:
def __init__(self):
self.tests = []
def run_tests(self):
print("Exécution des tests automatisés...")
test_results = {
"total": 5,
"passed": 4,
"failed": 1,
"coverage": "85%"
}
print(f"Résultats: {test_results['passed']}/{test_results['total']} tests réussis")
print(f"Couverture de code: {test_results['coverage']}")
return test_results
def add_test(self, test_name, test_function):
self.tests.append({"name": test_name, "function": test_function})
print(f"Test ajouté: {test_name}")
class Deployment:
def __init__(self):
self.environments = ["development", "staging", "production"]
def deploy(self, environment="production"):
if environment not in self.environments:
print(f"Environnement {environment} non reconnu")
return False
print(f"Déploiement sur {environment}...")
deployment_steps = [
"Validation du build",
"Exécution des tests",
"Backup de la version actuelle",
"Déploiement des fichiers",
"Redémarrage des services",
"Vérification de la santé"
]
for step in deployment_steps:
print(f" ✓ {step}")
print("Déploiement terminé avec succès!")
return True
def rollback(self, version):
print(f"Retour à la version {version}...")
return True
# Exemple d'utilisation
if __name__ == "__main__":
print("=== Espace Codage - Environnement de développement intégré ===\n")
# Initialisation de l'éditeur
editeur = CodeEditor(language="python")
# Écriture de code
code_exemple = """
import math
def calculate_circle_area(radius):
\"\"\"Calcule l'aire d'un cercle\"\"\"
return math.pi * radius ** 2
# TODO: Ajouter une fonction pour le périmètre
print("Aire du cercle:", calculate_circle_area(5))
"""
editeur.write_code(code_exemple)
# Affichage des suggestions
print("\nSuggestions de code:")
for suggestion in editeur.get_suggestions():
print(f" - {suggestion}")
# Documentation
print(f"\n{editeur.show_docs('python')}")
# Construction
editeur.build()
# Débogage
issues = editeur.debug()
if issues:
print("\nProblèmes détectés:")
for issue in issues:
print(f" ⚠ {issue}")
# Terminal
print("\nTerminal:")
print(editeur.run_terminal_command("pwd"))
print(editeur.run_terminal_command("ls"))
# Tests
editeur.test()
# Version control
editeur.commit("Ajout fonction calcul aire cercle")
editeur.version_control.create_branch("feature/new-geometry")
editeur.commit("Ajout branche pour nouvelles fonctions géométriques")
# Déploiement
print("\n" + "="*50)
editeur.deploy("staging")
# Affichage historique
print("\nHistorique des commits:")
for commit in editeur.version_control.get_history():
print(f" #{commit['id']}: {commit['message']} ({commit['branch']})")
print("\n=== Espace Codage prêt à l'utilisation ===") from abc import ABC, abstractmethod
from datetime import datetime
import json
# Produit complexe : Un projet de développement complet
class ProjetCodage:
def __init__(self, nom="Nouveau Projet"):
self.nom = nom
self.date_creation = datetime.now()
self.fichiers = []
self.configurations = {}
self.dependances = []
self.environnements = {}
self.statistiques = {
"lignes_code": 0,
"tests": 0,
"complexite": "faible"
}
def ajouter_fichier(self, nom_fichier, contenu=""):
fichier = {
"nom": nom_fichier,
"contenu": contenu,
"date_modification": datetime.now(),
"langage": self._detecter_langage(nom_fichier)
}
self.fichiers.append(fichier)
print(f"✓ Fichier '{nom_fichier}' ajouté au projet")
def _detecter_langage(self, nom_fichier):
extensions = {
'.py': 'Python',
'.js': 'JavaScript',
'.java': 'Java',
'.html': 'HTML',
'.css': 'CSS',
'.md': 'Markdown'
}
for ext, lang in extensions.items():
if nom_fichier.endswith(ext):
return lang
return 'Autre'
def configurer(self, cle, valeur):
self.configurations[cle] = valeur
print(f"✓ Configuration '{cle}' = {valeur}")
def ajouter_dependance(self, dependance, version="latest"):
self.dependance
- README.md +8 -5
- index.html +692 -19
|
@@ -1,10 +1,13 @@
|
|
| 1 |
---
|
| 2 |
-
title: Espace Codage Builder Pattern
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
|
|
|
|
|
|
| 8 |
---
|
| 9 |
|
| 10 |
-
|
|
|
|
|
|
| 1 |
---
|
| 2 |
+
title: Espace Codage - Builder Pattern
|
| 3 |
+
colorFrom: purple
|
| 4 |
+
colorTo: blue
|
| 5 |
+
emoji: 🐳
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
| 8 |
+
tags:
|
| 9 |
+
- deepsite-v3
|
| 10 |
---
|
| 11 |
|
| 12 |
+
# Welcome to your new DeepSite project!
|
| 13 |
+
This project was created with [DeepSite](https://huggingface.co/deepsite).
|
|
@@ -1,19 +1,692 @@
|
|
| 1 |
-
<!
|
| 2 |
-
<html>
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="fr">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8" />
|
| 5 |
+
<title>Espace Codage – Modèle Constructeur (Builder Pattern)</title>
|
| 6 |
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
| 7 |
+
|
| 8 |
+
<!-- Tailwind CSS CDN -->
|
| 9 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
| 10 |
+
<script>
|
| 11 |
+
tailwind.config = {
|
| 12 |
+
theme: {
|
| 13 |
+
extend: {
|
| 14 |
+
colors: {
|
| 15 |
+
primary: {
|
| 16 |
+
DEFAULT: '#4f46e5', // indigo-600
|
| 17 |
+
fg: '#ffffff',
|
| 18 |
+
soft: 'rgba(79,70,229,0.2)',
|
| 19 |
+
},
|
| 20 |
+
secondary: {
|
| 21 |
+
DEFAULT: '#64748b', // slate-500
|
| 22 |
+
fg: '#ffffff',
|
| 23 |
+
soft: 'rgba(100,116,139,0.2)',
|
| 24 |
+
},
|
| 25 |
+
accent: {
|
| 26 |
+
DEFAULT: '#22d3ee', // cyan-400
|
| 27 |
+
soft: 'rgba(34,211,238,0.2)',
|
| 28 |
+
},
|
| 29 |
+
success: '#22c55e',
|
| 30 |
+
danger: '#ef4444',
|
| 31 |
+
warning: '#f59e0b',
|
| 32 |
+
surface: {
|
| 33 |
+
DEFAULT: '#0b1020',
|
| 34 |
+
soft: '#0f172a',
|
| 35 |
+
},
|
| 36 |
+
card: {
|
| 37 |
+
DEFAULT: '#0f172a',
|
| 38 |
+
soft: '#111827',
|
| 39 |
+
},
|
| 40 |
+
code: '#0b132b',
|
| 41 |
+
grid: 'rgba(255,255,255,0.06)',
|
| 42 |
+
border: 'rgba(255,255,255,0.12)',
|
| 43 |
+
},
|
| 44 |
+
boxShadow: {
|
| 45 |
+
soft: '0 18px 45px rgba(0,0,0,0.6)',
|
| 46 |
+
},
|
| 47 |
+
borderRadius: {
|
| 48 |
+
xl: '1rem',
|
| 49 |
+
'2xl': '1.25rem',
|
| 50 |
+
},
|
| 51 |
+
fontFamily: {
|
| 52 |
+
mono: ['JetBrains Mono','ui-monospace','SFMono-Regular','Menlo','Monaco','Consolas','Liberation Mono','Courier New','monospace'],
|
| 53 |
+
display: ['Inter','ui-sans-serif','system-ui','-apple-system','BlinkMacSystemFont','Segoe UI','Roboto','Helvetica Neue','Arial','Noto Sans','sans-serif','Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol','Noto Color Emoji'],
|
| 54 |
+
},
|
| 55 |
+
},
|
| 56 |
+
},
|
| 57 |
+
darkMode: 'class',
|
| 58 |
+
}
|
| 59 |
+
</script>
|
| 60 |
+
|
| 61 |
+
<!-- Google Fonts -->
|
| 62 |
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&family=JetBrains+Mono:wght@400;600&display=swap" rel="stylesheet">
|
| 63 |
+
|
| 64 |
+
<style>
|
| 65 |
+
:root { color-scheme: dark; }
|
| 66 |
+
body { background-color: #050714; }
|
| 67 |
+
/* subtle grid background */
|
| 68 |
+
.grid-bg {
|
| 69 |
+
background-image:
|
| 70 |
+
linear-gradient(to bottom, var(--tw-colors-grid) 1px, transparent 1px),
|
| 71 |
+
linear-gradient(to right, var(--tw-colors-grid) 1px, transparent 1px);
|
| 72 |
+
background-size: 40px 40px, 40px 40px;
|
| 73 |
+
}
|
| 74 |
+
</style>
|
| 75 |
+
</head>
|
| 76 |
+
<body class="bg-surface text-slate-100 font-display antialiased selection:bg-primary/30 selection:text-white">
|
| 77 |
+
<main class="max-w-7xl mx-auto px-5 py-8 md:px-8 md:py-10">
|
| 78 |
+
<!-- Header -->
|
| 79 |
+
<header class="relative overflow-hidden rounded-2xl border border-border bg-gradient-to-br from-card to-surface shadow-soft p-5 md:p-7" data-animate="1">
|
| 80 |
+
<div class="absolute inset-0 pointer-events-none opacity-30">
|
| 81 |
+
<div class="absolute -top-24 -left-20 w-72 h-72 rounded-full bg-primary/20 blur-3xl"></div>
|
| 82 |
+
<div class="absolute -bottom-24 -right-20 w-72 h-72 rounded-full bg-accent/20 blur-3xl"></div>
|
| 83 |
+
</div>
|
| 84 |
+
<div class="relative flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
|
| 85 |
+
<div class="flex items-center gap-3">
|
| 86 |
+
<div class="w-10 h-10 rounded-full bg-gradient-to-br from-primary to-accent animate-spin-slow"></div>
|
| 87 |
+
<div>
|
| 88 |
+
<div class="text-xs uppercase tracking-[0.2em] text-slate-400">Espace Codage</div>
|
| 89 |
+
<h1 class="text-xl md:text-2xl font-bold tracking-wide">Modèle Constructeur · Builder Pattern</h1>
|
| 90 |
+
</div>
|
| 91 |
+
</div>
|
| 92 |
+
<p class="text-sm text-slate-400 max-w-2xl">
|
| 93 |
+
Visualisation de l'espace de codage et implémentation du pattern
|
| 94 |
+
<span class="text-white font-semibold">Builder</span> pour créer un
|
| 95 |
+
<span class="text-white font-semibold">ProjetEspaceCodage</span> étape par étape.
|
| 96 |
+
</p>
|
| 97 |
+
</div>
|
| 98 |
+
</header>
|
| 99 |
+
|
| 100 |
+
<div class="mt-6 grid grid-cols-1 lg:grid-cols-2 gap-6">
|
| 101 |
+
<!-- Diagramme Espace Codage -->
|
| 102 |
+
<section class="relative rounded-2xl border border-border bg-gradient-to-br from-card to-surface shadow-soft p-5" data-animate="2" aria-label="Schéma Espace Codage">
|
| 103 |
+
<div class="flex items-center justify-between mb-3">
|
| 104 |
+
<div>
|
| 105 |
+
<h2 class="text-sm uppercase tracking-[0.2em] text-accent">Espace Codage</h2>
|
| 106 |
+
<p class="text-xs text-slate-400">Vue conceptuelle des outils : éditeur, terminal, build, tests, déploiement…</p>
|
| 107 |
+
</div>
|
| 108 |
+
<span class="text-[10px] uppercase tracking-[0.25em] text-slate-500">SCHEMA</span>
|
| 109 |
+
</div>
|
| 110 |
+
|
| 111 |
+
<div class="relative grid-bg rounded-xl border border-border p-4 md:p-5 min-h-[420px]">
|
| 112 |
+
<!-- Overlay SVG pour les flèches -->
|
| 113 |
+
<svg class="absolute inset-0 w-full h-full pointer-events-none" id="arrowLayer" style="z-index: 0;"></svg>
|
| 114 |
+
|
| 115 |
+
<div class="relative grid grid-rows-[auto,1fr,auto] gap-4 h-full" id="schemaRoot" style="z-index: 1;">
|
| 116 |
+
<!-- Ligne du haut : Documentation -->
|
| 117 |
+
<div class="flex justify-center">
|
| 118 |
+
<button class="node-btn" data-id="documentation" data-name="Documentation" title="Documentation">
|
| 119 |
+
Documentation
|
| 120 |
+
</button>
|
| 121 |
+
</div>
|
| 122 |
+
|
| 123 |
+
<!-- Ligne centrale -->
|
| 124 |
+
<div class="grid grid-cols-3 gap-3 md:gap-4 items-center">
|
| 125 |
+
<!-- Version Control (gauche) -->
|
| 126 |
+
<div class="flex justify-center">
|
| 127 |
+
<button class="node-btn" data-id="version" data-name="Version Control" title="Version Control">
|
| 128 |
+
Version Control
|
| 129 |
+
</button>
|
| 130 |
+
</div>
|
| 131 |
+
|
| 132 |
+
<!-- Colonne centrale -->
|
| 133 |
+
<div class="flex flex-col items-center gap-3">
|
| 134 |
+
<!-- Code Editor (centre principal) -->
|
| 135 |
+
<button class="node-btn node-main" data-id="editor" data-name="Code Editor" title="Code Editor">
|
| 136 |
+
Code Editor
|
| 137 |
+
</button>
|
| 138 |
+
|
| 139 |
+
<!-- Terminal + Debugger -->
|
| 140 |
+
<div class="flex gap-3">
|
| 141 |
+
<button class="node-btn" data-id="terminal" data-name="Terminal" title="Terminal">
|
| 142 |
+
Terminal
|
| 143 |
+
</button>
|
| 144 |
+
<button class="node-btn" data-id="debugger" data-name="Debugger" title="Debugger">
|
| 145 |
+
Debugger
|
| 146 |
+
</button>
|
| 147 |
+
</div>
|
| 148 |
+
|
| 149 |
+
<!-- Testing Framework -->
|
| 150 |
+
<button class="node-btn" data-id="testing" data-name="Testing Framework" title="Testing Framework">
|
| 151 |
+
Testing Framework
|
| 152 |
+
</button>
|
| 153 |
+
</div>
|
| 154 |
+
|
| 155 |
+
<!-- Build System (droite) -->
|
| 156 |
+
<div class="flex justify-center">
|
| 157 |
+
<button class="node-btn" data-id="build" data-name="Build System" title="Build System">
|
| 158 |
+
Build System
|
| 159 |
+
</button>
|
| 160 |
+
</div>
|
| 161 |
+
</div>
|
| 162 |
+
|
| 163 |
+
<!-- Ligne du bas : Deployment -->
|
| 164 |
+
<div class="flex justify-center">
|
| 165 |
+
<button class="node-btn" data-id="deploy" data-name="Deployment" title="Deployment">
|
| 166 |
+
Deployment
|
| 167 |
+
</button>
|
| 168 |
+
</div>
|
| 169 |
+
</div>
|
| 170 |
+
</div>
|
| 171 |
+
|
| 172 |
+
<div class="mt-4 text-xs text-slate-400">
|
| 173 |
+
Cliquez sur un nœud pour voir une info rapide. Utilisez les boutons de démonstration ci-dessous pour simuler la construction.
|
| 174 |
+
</div>
|
| 175 |
+
</section>
|
| 176 |
+
|
| 177 |
+
<!-- Code + Démonstration Builder -->
|
| 178 |
+
<section class="rounded-2xl border border-border bg-gradient-to-br from-card to-surface shadow-soft p-5" data-animate="3" aria-label="Code Builder Pattern">
|
| 179 |
+
<div class="flex items-start justify-between gap-3">
|
| 180 |
+
<div>
|
| 181 |
+
<h2 class="text-sm uppercase tracking-[0.2em] text-primary">Code · Builder Pattern</h2>
|
| 182 |
+
<p class="text-xs text-slate-400">
|
| 183 |
+
Implémentation en <strong class="text-white">Python</strong> du pattern
|
| 184 |
+
<strong class="text-white">Builder</strong> pour un <em>ProjetEspaceCodage</em> complexe.
|
| 185 |
+
</p>
|
| 186 |
+
<div class="mt-2 flex flex-wrap gap-2">
|
| 187 |
+
<span class="badge">Builder Pattern</span>
|
| 188 |
+
<span class="badge">Objet complexe</span>
|
| 189 |
+
<span class="badge">Python</span>
|
| 190 |
+
<span class="badge">Espace Codage</span>
|
| 191 |
+
</div>
|
| 192 |
+
</div>
|
| 193 |
+
<span class="text-[10px] uppercase tracking-[0.25em] text-slate-500">BUILDER</span>
|
| 194 |
+
</div>
|
| 195 |
+
|
| 196 |
+
<!-- Editeur simulé -->
|
| 197 |
+
<div class="mt-4 rounded-xl border border-border bg-code shadow-soft overflow-hidden">
|
| 198 |
+
<div class="flex items-center justify-between px-3 py-2 border-b border-border bg-slate-900/50">
|
| 199 |
+
<div class="flex items-center gap-1.5">
|
| 200 |
+
<span class="w-2.5 h-2.5 rounded-full bg-danger"></span>
|
| 201 |
+
<span class="w-2.5 h-2.5 rounded-full bg-warning"></span>
|
| 202 |
+
<span class="w-2.5 h-2.5 rounded-full bg-success"></span>
|
| 203 |
+
</div>
|
| 204 |
+
<div class="flex items-center gap-2 text-[10px] uppercase tracking-[0.18em] text-slate-400">
|
| 205 |
+
espace_codage_builder.py · Python
|
| 206 |
+
</div>
|
| 207 |
+
<div></div>
|
| 208 |
+
</div>
|
| 209 |
+
<pre class="font-mono text-[11px] leading-5 p-3 md:p-4 overflow-auto max-h-[420px]"><code><span class="text-slate-400"># === ESPACE CODAGE · MODÈLE CONSTRUCTEUR (BUILDER) ===</span>
|
| 210 |
+
<span class="text-slate-400"># Situation :</span>
|
| 211 |
+
<span class="text-slate-400"># - on veut créer un "objet complexe" ProjetEspaceCodage</span>
|
| 212 |
+
<span class="text-slate-400"># indépendamment de la manière dont chaque partie est construite.</span>
|
| 213 |
+
<span class="text-slate-400"># - différents Builders produisent différentes représentations</span>
|
| 214 |
+
<span class="text-slate-400"># (projet minimal, projet full‑stack, etc.).</span>
|
| 215 |
+
|
| 216 |
+
<span class="text-primary">from</span> abc <span class="text-primary">import</span> ABC, abstractmethod
|
| 217 |
+
<span class="text-primary">from</span> typing <span class="text-primary">import</span> List, Dict
|
| 218 |
+
|
| 219 |
+
|
| 220 |
+
<span class="text-accent">class</span> <span class="text-white">ProjetEspaceCodage</span>:
|
| 221 |
+
<span class="text-slate-400">"""Produit complexe : représente l'espace de codage complet."""</span>
|
| 222 |
+
|
| 223 |
+
<span class="text-primary">def</span> <span class="text-accent">__init__</span>(<span class="text-white">self</span>, <span class="text-white">nom</span>: <span class="text-secondary">str</span> = <span class="text-warning">"Nouveau Projet"</span>) -> <span class="text-primary">None</span>:
|
| 224 |
+
<span class="text-white">self</span>.nom = nom
|
| 225 |
+
<span class="text-white">self</span>.composants: List[str] = []
|
| 226 |
+
<span class="text-white">self</span>.configurations: Dict[str, str] = {}
|
| 227 |
+
<span class="text-white">self</span>.etapes: List[str] = []
|
| 228 |
+
|
| 229 |
+
<span class="text-primary">def</span> <span class="text-accent">ajouter_composant</span>(<span class="text-white">self</span>, <span class="text-white">description</span>: <span class="text-secondary">str</span>) -> <span class="text-primary">None</span>:
|
| 230 |
+
<span class="text-white">self</span>.composants.append(description)
|
| 231 |
+
|
| 232 |
+
<span class="text-primary">def</span> <span class="text-accent">ajouter_configuration</span>(<span class="text-white">self</span>, <span class="text-white">cle</span>: <span class="text-secondary">str</span>, <span class="text-white">valeur</span>: <span class="text-secondary">str</span>) -> <span class="text-primary">None</span>:
|
| 233 |
+
<span class="text-white">self</span>.configurations[cle] = valeur
|
| 234 |
+
|
| 235 |
+
<span class="text-primary">def</span> <span class="text-accent">ajouter_etape</span>(<span class="text-white">self</span>, <span class="text-white">etape</span>: <span class="text-secondary">str</span>) -> <span class="text-primary">None</span>:
|
| 236 |
+
<span class="text-white">self</span>.etapes.append(etape)
|
| 237 |
+
|
| 238 |
+
<span class="text-primary">def</span> <span class="text-accent">decrire</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
|
| 239 |
+
<span class="text-primary">print</span>(<span class="text-warning">f"</span><span class="text-warning">=== ESPACE CODAGE : {</span><span class="text-white">self</span>.nom<span class="text-warning">} ==="</span>)
|
| 240 |
+
<span class="text-primary">print</span>(<span class="text-warning">"Composants :"</span>)
|
| 241 |
+
<span class="text-primary">for</span> i, comp <span class="text-primary">in</span> <span class="text-primary">enumerate</span>(<span class="text-white">self</span>.composants, <span class="text-warning">1</span>):
|
| 242 |
+
<span class="text-primary">print</span>(<span class="text-warning">f"</span><span class="text-warning"> {i}. {comp}"</span>)
|
| 243 |
+
|
| 244 |
+
<span class="text-primary">if</span> <span class="text-white">self</span>.configurations:
|
| 245 |
+
<span class="text-primary">print</span>(<span class="text-warning">"</span><span class="text-warning">Configurations :"</span>)
|
| 246 |
+
<span class="text-primary">for</span> cle, val <span class="text-primary">in</span> <span class="text-white">self</span>.configurations.items():
|
| 247 |
+
<span class="text-primary">print</span>(<span class="text-warning">f"</span><span class="text-warning"> • {cle}: {val}"</span>)
|
| 248 |
+
|
| 249 |
+
<span class="text-primary">if</span> <span class="text-white">self</span>.etapes:
|
| 250 |
+
<span class="text-primary">print</span>(<span class="text-warning">"</span><span class="text-warning">Étapes de construction :"</span>)
|
| 251 |
+
<span class="text-primary">for</span> etape <span class="text-primary">in</span> <span class="text-white">self</span>.etapes:
|
| 252 |
+
<span class="text-primary">print</span>(<span class="text-warning">f"</span><span class="text-warning"> → {etape}"</span>)
|
| 253 |
+
|
| 254 |
+
|
| 255 |
+
<span class="text-accent">class</span> <span class="text-white">ConstructeurEspaceCodage</span>(ABC):
|
| 256 |
+
<span class="text-slate-400">"""Interface d'assemblage & construction."""</span>
|
| 257 |
+
|
| 258 |
+
<span class="text-primary">def</span> <span class="text-accent">__init__</span>(<span class="text-white">self</span>, <span class="text-white">nom_projet</span>: <span class="text-secondary">str</span>) -> <span class="text-primary">None</span>:
|
| 259 |
+
<span class="text-white">self</span>.projet = ProjetEspaceCodage(nom_projet)
|
| 260 |
+
|
| 261 |
+
@abstractmethod
|
| 262 |
+
<span class="text-primary">def</span> <span class="text-accent">configurer_documentation</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>: <span class="text-primary">pass</span>
|
| 263 |
+
|
| 264 |
+
@abstractmethod
|
| 265 |
+
<span class="text-primary">def</span> <span class="text-accent">configurer_editeur</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>: <span class="text-primary">pass</span>
|
| 266 |
+
|
| 267 |
+
@abstractmethod
|
| 268 |
+
<span class="text-primary">def</span> <span class="text-accent">configurer_terminal_debugger</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>: <span class="text-primary">pass</span>
|
| 269 |
+
|
| 270 |
+
@abstractmethod
|
| 271 |
+
<span class="text-primary">def</span> <span class="text-accent">configurer_build_system</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>: <span class="text-primary">pass</span>
|
| 272 |
+
|
| 273 |
+
@abstractmethod
|
| 274 |
+
<span class="text-primary">def</span> <span class="text-accent">configurer_tests</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>: <span class="text-primary">pass</span>
|
| 275 |
+
|
| 276 |
+
@abstractmethod
|
| 277 |
+
<span class="text-primary">def</span> <span class="text-accent">configurer_deploiement</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>: <span class="text-primary">pass</span>
|
| 278 |
+
|
| 279 |
+
<span class="text-primary">def</span> <span class="text-accent">obtenir_projet</span>(<span class="text-white">self</span>) -> ProjetEspaceCodage:
|
| 280 |
+
<span class="text-primary">return</span> <span class="text-white">self</span>.projet
|
| 281 |
+
|
| 282 |
+
<span class="text-primary">def</span> <span class="text-accent">operation_optionnelle</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>: <span class="text-primary">pass</span>
|
| 283 |
+
|
| 284 |
+
|
| 285 |
+
<span class="text-accent">class</span> <span class="text-white">ConstructeurMinimal</span>(ConstructeurEspaceCodage):
|
| 286 |
+
|
| 287 |
+
<span class="text-primary">def</span> <span class="text-accent">configurer_documentation</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
|
| 288 |
+
<span class="text-white">self</span>.projet.ajouter_composant(<span class="text-warning">"Documentation : README.md simple"</span>)
|
| 289 |
+
<span class="text-white">self</span>.projet.ajouter_etape(<span class="text-warning">"Documentation minimale configurée"</span>)
|
| 290 |
+
|
| 291 |
+
<span class="text-primary">def</span> <span class="text-accent">configurer_editeur</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
|
| 292 |
+
<span class="text-white">self</span>.projet.ajouter_composant(<span class="text-warning">"Code Editor : VS Code avec thème par défaut"</span>)
|
| 293 |
+
<span class="text-white">self</span>.projet.ajouter_configuration(<span class="text-warning">"editor.theme"</span>, <span class="text-warning">"default-dark"</span>)
|
| 294 |
+
<span class="text-white">self</span>.projet.ajouter_etape(<span class="text-warning">"Éditeur de code configuré"</span>)
|
| 295 |
+
|
| 296 |
+
<span class="text-primary">def</span> <span class="text-accent">configurer_terminal_debugger</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
|
| 297 |
+
<span class="text-white">self</span>.projet.ajouter_composant(<span class="text-warning">"Terminal intégré + debug minimal (print)"</span>)
|
| 298 |
+
<span class="text-white">self</span>.projet.ajouter_etape(<span class="text-warning">"Terminal et debugger basique configurés"</span>)
|
| 299 |
+
|
| 300 |
+
<span class="text-primary">def</span> <span class="text-accent">configurer_build_system</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
|
| 301 |
+
<span class="text-white">self</span>.projet.ajouter_composant(<span class="text-warning">"Build System : exécution directe du script"</span>)
|
| 302 |
+
<span class="text-white">self</span>.projet.ajouter_etape(<span class="text-warning">"Système de build minimal configuré"</span>)
|
| 303 |
+
|
| 304 |
+
<span class="text-primary">def</span> <span class="text-accent">configurer_tests</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
|
| 305 |
+
<span class="text-white">self</span>.projet.ajouter_composant(<span class="text-warning">"Tests : quelques tests manuels"</span>)
|
| 306 |
+
<span class="text-white">self</span>.projet.ajouter_etape(<span class="text-warning">"Tests manuels configurés"</span>)
|
| 307 |
+
|
| 308 |
+
<span class="text-primary">def</span> <span class="text-accent">configurer_deploiement</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
|
| 309 |
+
<span class="text-white">self</span>.projet.ajouter_composant(<span class="text-warning">"Déploiement : exécution locale seulement"</span>)
|
| 310 |
+
<span class="text-white">self</span>.projet.ajouter_configuration(<span class="text-warning">"deployment.target"</span>, <span class="text-warning">"local"</span>)
|
| 311 |
+
<span class="text-white">self</span>.projet.ajouter_etape(<span class="text-warning">"Déploiement local configuré"</span>)
|
| 312 |
+
|
| 313 |
+
|
| 314 |
+
<span class="text-accent">class</span> <span class="text-white">ConstructeurFullStack</span>(ConstructeurEspaceCodage):
|
| 315 |
+
|
| 316 |
+
<span class="text-primary">def</span> <span class="text-accent">configurer_documentation</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
|
| 317 |
+
<span class="text-white">self</span>.projet.ajouter_composant(<span class="text-warning">"Documentation : wiki, UML, API complète"</span>)
|
| 318 |
+
<span class="text-white">self</span>.projet.ajouter_configuration(<span class="text-warning">"docs.format"</span>, <span class="text-warning">"OpenAPI + Markdown"</span>)
|
| 319 |
+
<span class="text-white">self</span>.projet.ajouter_etape(<span class="text-warning">"Documentation complète configurée"</span>)
|
| 320 |
+
|
| 321 |
+
<span class="text-primary">def</span> <span class="text-accent">configurer_editeur</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
|
| 322 |
+
<span class="text-white">self</span>.projet.ajouter_composant(<span class="text-warning">"Code Editor : IDE complet + plugins"</span>)
|
| 323 |
+
<span class="text-white">self</span>.projet.ajouter_configuration(<span class="text-warning">"editor.plugins"</span>, <span class="text-warning">"lint, format, refactor, git, ..."</span>)
|
| 324 |
+
<span class="text-white">self</span>.projet.ajouter_etape(<span class="text-warning">"Éditeur avancé configuré"</span>)
|
| 325 |
+
|
| 326 |
+
<span class="text-primary">def</span> <span class="text-accent">configurer_terminal_debugger</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
|
| 327 |
+
<span class="text-white">self</span>.projet.ajouter_composant(<span class="text-warning">"Terminal multi‑onglets + debugger graphique"</span>)
|
| 328 |
+
<span class="text-white">self</span>.projet.ajouter_configuration(<span class="text-warning">"debugger.features"</span>, <span class="text-warning">"breakpoints, watch, stack, step-by-step"</span>)
|
| 329 |
+
<span class="text-white">self</span>.projet.ajouter_etape(<span class="text-warning">"Terminal et debugger avancés configurés"</span>)
|
| 330 |
+
|
| 331 |
+
<span class="text-primary">def</span> <span class="text-accent">configurer_build_system</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
|
| 332 |
+
<span class="text-white">self</span>.projet.ajouter_composant(<span class="text-warning">"Build System : pipeline CI/CD automatisé"</span>)
|
| 333 |
+
<span class="text-white">self</span>.projet.ajouter_configuration(<span class="text-warning">"build.pipeline"</span>, <span class="text-warning">"tests → build → packaging → deployment"</span>)
|
| 334 |
+
<span class="text-white">self</span>.projet.ajouter_etape(<span class="text-warning">"Système de build avancé configuré"</span>)
|
| 335 |
+
|
| 336 |
+
<span class="text-primary">def</span> <span class="text-accent">configurer_tests</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
|
| 337 |
+
<span class="text-white">self</span>.projet.ajouter_composant(<span class="text-warning">"Testing Framework : unitaires, intégration, e2e"</span>)
|
| 338 |
+
<span class="text-white">self</span>.projet.ajouter_configuration(<span class="text-warning">"testing.coverage"</span>, <span class="text-warning">">= 90%"</span>)
|
| 339 |
+
<span class="text-white">self</span>.projet.ajouter_etape(<span class="text-warning">"Framework de tests complet configuré"</span>)
|
| 340 |
+
|
| 341 |
+
<span class="text-primary">def</span> <span class="text-accent">configurer_deploiement</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
|
| 342 |
+
<span class="text-white">self</span>.projet.ajouter_composant(<span class="text-warning">"Déploiement : CI/CD vers staging/production (cloud)"</span>)
|
| 343 |
+
<span class="text-white">self</span>.projet.ajouter_configuration(<span class="text-warning">"deployment.providers"</span>, <span class="text-warning">"AWS, Docker, Kubernetes"</span>)
|
| 344 |
+
<span class="text-white">self</span>.projet.ajouter_etape(<span class="text-warning">"Déploiement cloud configuré"</span>)
|
| 345 |
+
|
| 346 |
+
<span class="text-primary">def</span> <span class="text-accent">operation_optionnelle</span>(<span class="text-white">self</span>) -> <span class="text-primary">None</span>:
|
| 347 |
+
<span class="text-white">self</span>.projet.ajouter_composant(<span class="text-warning">"Analyse statique + métriques + revues automatisées"</span>)
|
| 348 |
+
<span class="text-white">self</span>.projet.ajouter_configuration(<span class="text-warning">"quality.metrics"</span>, <span class="text-warning">"complexité, dette technique, vulnérabilités"</span>)
|
| 349 |
+
<span class="text-white">self</span>.projet.ajouter_etape(<span class="text-warning">"Analyses avancées configurées (optionnel)"</span>)
|
| 350 |
+
|
| 351 |
+
|
| 352 |
+
<span class="text-accent">class</span> <span class="text-white">DirecteurEspaceCodage</span>:
|
| 353 |
+
<span class="text-slate-400">"""Le Directeur orchestre les étapes de construction."""</span>
|
| 354 |
+
|
| 355 |
+
<span class="text-primary">def</span> <span class="text-accent">__init__</span>(<span class="text-white">self</span>, <span class="text-white">builder</span>: ConstructeurEspaceCodage) -> <span class="text-primary">None</span>:
|
| 356 |
+
<span class="text-white">self</span>._builder = builder
|
| 357 |
+
|
| 358 |
+
<span class="text-primary">def</span> <span class="text-accent">construire_espace_codage</span>(<span class="text-white">self</span>) -> ProjetEspaceCodage:
|
| 359 |
+
<span class="text-white">self</span>._builder.configurer_documentation()
|
| 360 |
+
<span class="text-white">self</span>._builder.configurer_editeur()
|
| 361 |
+
<span class="text-white">self</span>._builder.configurer_terminal_debugger()
|
| 362 |
+
<span class="text-white">self</span>._builder.configurer_build_system()
|
| 363 |
+
<span class="text-white">self</span>._builder.configurer_tests()
|
| 364 |
+
<span class="text-white">self</span>._builder.configurer_deploiement()
|
| 365 |
+
<span class="text-white">self</span>._builder.operation_optionnelle()
|
| 366 |
+
<span class="text-primary">return</span> <span class="text-white">self</span>._builder.obtenir_projet()
|
| 367 |
+
|
| 368 |
+
|
| 369 |
+
<span class="text-primary">if</span> __name__ == <span class="text-warning">"__main__"</span>:
|
| 370 |
+
<span class="text-primary">print</span>(<span class="text-warning">"=== ESPACE CODAGE · PROJET MINIMAL ==="</span>)
|
| 371 |
+
directeur = DirecteurEspaceCodage(ConstructeurMinimal(<span class="text-warning">"Script Python Simple"</span>))
|
| 372 |
+
projet_min = directeur.construire_espace_codage()
|
| 373 |
+
projet_min.decrire()
|
| 374 |
+
|
| 375 |
+
<span class="text-primary">print</span>(<span class="text-warning">"</span><span class="text-warning">=== ESPACE CODAGE · PROJET FULL‑STACK ==="</span>)
|
| 376 |
+
directeur = DirecteurEspaceCodage(ConstructeurFullStack(<span class="text-warning">"Application Web Avancée"</span>))
|
| 377 |
+
projet_full = directeur.construire_espace_codage()
|
| 378 |
+
projet_full.decrire()
|
| 379 |
+
</code></pre>
|
| 380 |
+
</div>
|
| 381 |
+
|
| 382 |
+
<!-- Démonstration Builder -->
|
| 383 |
+
<div class="mt-5 rounded-xl border border-border bg-slate-900/40 p-4">
|
| 384 |
+
<div class="flex items-center justify-between">
|
| 385 |
+
<h3 class="text-xs uppercase tracking-[0.2em] text-accent">Démonstration du Builder Pattern</h3>
|
| 386 |
+
<div class="text-[10px] uppercase tracking-[0.2em] text-slate-500">DEMO</div>
|
| 387 |
+
</div>
|
| 388 |
+
<div class="mt-3 flex flex-wrap gap-2">
|
| 389 |
+
<button class="btn-primary" id="btn-minimal">Construire Projet Minimal</button>
|
| 390 |
+
<button class="btn-secondary" id="btn-fullstack">Construire Projet Full‑Stack</button>
|
| 391 |
+
<button class="btn-ghost" id="btn-reset">Réinitialiser</button>
|
| 392 |
+
</div>
|
| 393 |
+
<div id="demoOutput" class="mt-4 rounded-lg border border-border bg-black/40 p-3 font-mono text-[12px] leading-5 max-h-56 overflow-auto text-accent">
|
| 394 |
+
<div>Prêt à construire un espace de codage…</div>
|
| 395 |
+
</div>
|
| 396 |
+
</div>
|
| 397 |
+
|
| 398 |
+
<div class="mt-4 text-xs text-slate-400">
|
| 399 |
+
<strong class="text-white">Note :</strong> Le <strong>modèle Constructeur</strong> se concentre sur un seul
|
| 400 |
+
<em>objet complexe</em> (ProjetEspaceCodage) construit étape par étape. Une
|
| 401 |
+
<strong>Abstract Factory</strong> fournirait plusieurs familles d’objets (éditeur, terminal, debugger, …)
|
| 402 |
+
sans orchestrer le processus de construction comme le fait le <code>DirecteurEspaceCodage</code>.
|
| 403 |
+
</div>
|
| 404 |
+
</section>
|
| 405 |
+
</div>
|
| 406 |
+
</main>
|
| 407 |
+
|
| 408 |
+
<!-- Tooltip flottant -->
|
| 409 |
+
<div id="nodeTooltip" class="hidden absolute z-50 max-w-[240px] rounded-lg border border-primary/40 bg-slate-900/95 px-3 py-2 text-[11px] leading-5 shadow-xl backdrop-blur">
|
| 410 |
+
<div class="text-primary font-semibold" id="nodeTitle"></div>
|
| 411 |
+
<div class="text-slate-300" id="nodeDesc"></div>
|
| 412 |
+
</div>
|
| 413 |
+
|
| 414 |
+
<script>
|
| 415 |
+
// Animation helpers
|
| 416 |
+
const animateItems = document.querySelectorAll('[data-animate]');
|
| 417 |
+
animateItems.forEach(el => {
|
| 418 |
+
el.style.opacity = '0';
|
| 419 |
+
el.style.transform = 'translateY(10px)';
|
| 420 |
+
setTimeout(() => {
|
| 421 |
+
el.style.transition = 'all .6s cubic-bezier(.2,.7,.2,1)';
|
| 422 |
+
el.style.opacity = '1';
|
| 423 |
+
el.style.transform = 'translateY(0)';
|
| 424 |
+
}, 120);
|
| 425 |
+
});
|
| 426 |
+
|
| 427 |
+
// Node definitions and info
|
| 428 |
+
const nodeInfo = {
|
| 429 |
+
documentation: {
|
| 430 |
+
title: 'Documentation',
|
| 431 |
+
desc: 'Système de documentation intégré avec recherche et exemples (wiki, API, UML).'
|
| 432 |
+
},
|
| 433 |
+
editor: {
|
| 434 |
+
title: 'Code Editor',
|
| 435 |
+
desc: 'Éditeur de code avec coloration syntaxique, auto-complétion, refactorisations.'
|
| 436 |
+
},
|
| 437 |
+
terminal: {
|
| 438 |
+
title: 'Terminal',
|
| 439 |
+
desc: 'Terminal intégré multi‑onglets avec support de plusieurs shells et historique.'
|
| 440 |
+
},
|
| 441 |
+
debugger: {
|
| 442 |
+
title: 'Debugger',
|
| 443 |
+
desc: 'Debugger graphique avec breakpoints, inspection, watch, step‑by‑step.'
|
| 444 |
+
},
|
| 445 |
+
version: {
|
| 446 |
+
title: 'Version Control',
|
| 447 |
+
desc: 'Contrôle de version (Git) avec interface graphique, branches et historial.'
|
| 448 |
+
},
|
| 449 |
+
testing: {
|
| 450 |
+
title: 'Testing Framework',
|
| 451 |
+
desc: 'Tests unitaires, d’intégration et end‑to‑end. Couverture de code et rapports.'
|
| 452 |
+
},
|
| 453 |
+
build: {
|
| 454 |
+
title: 'Build System',
|
| 455 |
+
desc: 'Pipeline de build et CI/CD : compilation, packaging et déploiement automatisés.'
|
| 456 |
+
},
|
| 457 |
+
deploy: {
|
| 458 |
+
title: 'Deployment',
|
| 459 |
+
desc: 'Déploiement vers staging/production (cloud), rollback et monitoring.'
|
| 460 |
+
},
|
| 461 |
+
};
|
| 462 |
+
|
| 463 |
+
// Connections for arrows (visual only)
|
| 464 |
+
const connections = [
|
| 465 |
+
{ from: 'documentation', to: 'editor', label: 'docs' },
|
| 466 |
+
{ from: 'editor', to: 'terminal', label: 'exec' },
|
| 467 |
+
{ from: 'editor', to: 'debugger', label: 'debug' },
|
| 468 |
+
{ from: 'editor', to: 'build', label: 'build' },
|
| 469 |
+
{ from: 'version', to: 'editor', label: 'vcs' },
|
| 470 |
+
{ from: 'terminal', to: 'testing', label: 'test' },
|
| 471 |
+
{ from: 'debugger', to: 'testing', label: 'verify' },
|
| 472 |
+
{ from: 'testing', to: 'deploy', label: 'deploy' },
|
| 473 |
+
{ from: 'build', to: 'deploy', label: 'package' },
|
| 474 |
+
{ from: 'deploy', to: 'version', label: 'release' },
|
| 475 |
+
];
|
| 476 |
+
|
| 477 |
+
// Build arrows
|
| 478 |
+
function drawArrows() {
|
| 479 |
+
const svg = document.getElementById('arrowLayer');
|
| 480 |
+
if (!svg) return;
|
| 481 |
+
svg.innerHTML = '';
|
| 482 |
+
|
| 483 |
+
const root = document.getElementById('schemaRoot');
|
| 484 |
+
const rootRect = root.getBoundingClientRect();
|
| 485 |
+
|
| 486 |
+
function centerOf(id) {
|
| 487 |
+
const el = root.querySelector(`[data-id="${id}"]`);
|
| 488 |
+
if (!el) return { x: 0, y: 0 };
|
| 489 |
+
const r = el.getBoundingClientRect();
|
| 490 |
+
return {
|
| 491 |
+
x: r.left - rootRect.left + r.width / 2,
|
| 492 |
+
y: r.top - rootRect.top + r.height / 2
|
| 493 |
+
};
|
| 494 |
+
}
|
| 495 |
+
|
| 496 |
+
connections.forEach((c, idx) => {
|
| 497 |
+
const from = centerOf(c.from);
|
| 498 |
+
const to = centerOf(c.to);
|
| 499 |
+
|
| 500 |
+
// Curved path
|
| 501 |
+
const dx = to.x - from.x;
|
| 502 |
+
const dy = to.y - from.y;
|
| 503 |
+
const dist = Math.hypot(dx, dy);
|
| 504 |
+
const curve = Math.min(80, Math.max(30, dist * 0.25));
|
| 505 |
+
|
| 506 |
+
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
| 507 |
+
const d = `M ${from.x} ${from.y}
|
| 508 |
+
C ${from.x + curve} ${from.y}
|
| 509 |
+
${to.x - curve} ${to.y}
|
| 510 |
+
${to.x} ${to.y}`;
|
| 511 |
+
path.setAttribute('d', d);
|
| 512 |
+
path.setAttribute('fill', 'none');
|
| 513 |
+
path.setAttribute('stroke', 'rgba(148,163,184,0.55)');
|
| 514 |
+
path.setAttribute('stroke-width', '1.25');
|
| 515 |
+
path.setAttribute('marker-end', 'url(#arrowHead)');
|
| 516 |
+
svg.appendChild(path);
|
| 517 |
+
});
|
| 518 |
+
|
| 519 |
+
// Marker
|
| 520 |
+
let defs = svg.querySelector('defs');
|
| 521 |
+
if (!defs) {
|
| 522 |
+
defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
|
| 523 |
+
svg.appendChild(defs);
|
| 524 |
+
}
|
| 525 |
+
let marker = svg.querySelector('#arrowHead');
|
| 526 |
+
if (!marker) {
|
| 527 |
+
marker = document.createElementNS('http://www.w3.org/2000/svg', 'marker');
|
| 528 |
+
marker.setAttribute('id', 'arrowHead');
|
| 529 |
+
marker.setAttribute('viewBox', '0 0 10 10');
|
| 530 |
+
marker.setAttribute('refX', '8');
|
| 531 |
+
marker.setAttribute('refY', '5');
|
| 532 |
+
marker.setAttribute('markerWidth', '6');
|
| 533 |
+
marker.setAttribute('markerHeight', '6');
|
| 534 |
+
marker.setAttribute('orient', 'auto-start-reverse');
|
| 535 |
+
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
| 536 |
+
path.setAttribute('d', 'M 0 0 L 10 5 L 0 10 z');
|
| 537 |
+
path.setAttribute('fill', 'rgba(148,163,184,0.9)');
|
| 538 |
+
marker.appendChild(path);
|
| 539 |
+
defs.appendChild(marker);
|
| 540 |
+
}
|
| 541 |
+
}
|
| 542 |
+
|
| 543 |
+
// Node interactions + tooltip
|
| 544 |
+
function setupNodes() {
|
| 545 |
+
const tooltip = document.getElementById('nodeTooltip');
|
| 546 |
+
const title = document.getElementById('nodeTitle');
|
| 547 |
+
const desc = document.getElementById('nodeDesc');
|
| 548 |
+
|
| 549 |
+
document.querySelectorAll('.node-btn').forEach(btn => {
|
| 550 |
+
btn.addEventListener('click', (e) => {
|
| 551 |
+
const id = btn.dataset.id;
|
| 552 |
+
const info = nodeInfo[id];
|
| 553 |
+
if (!info) return;
|
| 554 |
+
|
| 555 |
+
// Visual pulse
|
| 556 |
+
btn.classList.add('ring-2', 'ring-primary/60');
|
| 557 |
+
setTimeout(() => btn.classList.remove('ring-2', 'ring-primary/60'), 600);
|
| 558 |
+
|
| 559 |
+
// Tooltip content
|
| 560 |
+
title.textContent = info.title;
|
| 561 |
+
desc.textContent = info.desc;
|
| 562 |
+
tooltip.classList.remove('hidden');
|
| 563 |
+
|
| 564 |
+
// Position near button
|
| 565 |
+
const r = btn.getBoundingClientRect();
|
| 566 |
+
tooltip.style.left = `${Math.min(window.innerWidth - 260, r.right + 10)}px`;
|
| 567 |
+
tooltip.style.top = `${r.top + window.scrollY}px`;
|
| 568 |
+
|
| 569 |
+
setTimeout(() => tooltip.classList.add('hidden'), 2800);
|
| 570 |
+
});
|
| 571 |
+
});
|
| 572 |
+
|
| 573 |
+
document.addEventListener('click', (e) => {
|
| 574 |
+
if (!e.target.closest('.node-btn')) {
|
| 575 |
+
tooltip.classList.add('hidden');
|
| 576 |
+
}
|
| 577 |
+
});
|
| 578 |
+
}
|
| 579 |
+
|
| 580 |
+
// Builder demo logic
|
| 581 |
+
function setupBuilderDemo() {
|
| 582 |
+
const output = document.getElementById('demoOutput');
|
| 583 |
+
const btnMinimal = document.getElementById('btn-minimal');
|
| 584 |
+
const btnFullstack = document.getElementById('btn-fullstack');
|
| 585 |
+
const btnReset = document.getElementById('btn-reset');
|
| 586 |
+
|
| 587 |
+
function clearOutput() {
|
| 588 |
+
output.innerHTML = '<div>Prêt à construire un espace de codage…</div>';
|
| 589 |
+
}
|
| 590 |
+
function addLine(text, kind = 'info') {
|
| 591 |
+
const line = document.createElement('div');
|
| 592 |
+
line.className = 'mb-1';
|
| 593 |
+
if (kind === 'ok') line.classList.add('text-success');
|
| 594 |
+
if (kind === 'warn') line.classList.add('text-warning');
|
| 595 |
+
line.textContent = text;
|
| 596 |
+
output.appendChild(line);
|
| 597 |
+
output.scrollTop = output.scrollHeight;
|
| 598 |
+
}
|
| 599 |
+
function highlightNode(id) {
|
| 600 |
+
const node = document.querySelector(`[data-id="${id}"]`);
|
| 601 |
+
if (!node) return;
|
| 602 |
+
node.classList.add('ring-2', 'ring-accent/70');
|
| 603 |
+
setTimeout(() => node.classList.remove('ring-2', 'ring-accent/70'), 900);
|
| 604 |
+
}
|
| 605 |
+
|
| 606 |
+
const minimalSteps = [
|
| 607 |
+
{ id: 'documentation', msg: 'Configuration de la documentation simple (README).' },
|
| 608 |
+
{ id: 'editor', msg: 'Configuration de l’éditeur VS Code (thème par défaut).' },
|
| 609 |
+
{ id: 'terminal', msg: 'Configuration du terminal intégré et du debug minimal.' },
|
| 610 |
+
{ id: 'build', msg: 'Configuration du système de build minimal (exécution directe).' },
|
| 611 |
+
{ id: 'testing', msg: 'Configuration des tests manuels.' },
|
| 612 |
+
{ id: 'deploy', msg: 'Configuration du déploiement local.' },
|
| 613 |
+
];
|
| 614 |
+
|
| 615 |
+
const fullstackSteps = [
|
| 616 |
+
{ id: 'documentation', msg: 'Configuration de la documentation complète (wiki, UML, API).' },
|
| 617 |
+
{ id: 'editor', msg: 'Configuration de l’IDE avancé et des plugins.' },
|
| 618 |
+
{ id: 'terminal', msg: 'Configuration du terminal multi‑onglets et debugger graphique.' },
|
| 619 |
+
{ id: 'build', msg: 'Configuration du pipeline CI/CD automatisé.' },
|
| 620 |
+
{ id: 'testing', msg: 'Configuration du framework de tests complet (unitaires, intégration, e2e).' },
|
| 621 |
+
{ id: 'deploy', msg: 'Configuration du déploiement cloud (AWS, Docker, Kubernetes).' },
|
| 622 |
+
];
|
| 623 |
+
|
| 624 |
+
function runDemo(type) {
|
| 625 |
+
clearOutput();
|
| 626 |
+
const steps = type === 'minimal' ? minimalSteps : fullstackSteps;
|
| 627 |
+
|
| 628 |
+
let delay = 0;
|
| 629 |
+
steps.forEach((s, i) => {
|
| 630 |
+
setTimeout(() => {
|
| 631 |
+
addLine(`→ ${s.msg}`);
|
| 632 |
+
highlightNode(s.id);
|
| 633 |
+
}, delay);
|
| 634 |
+
delay += 650;
|
| 635 |
+
});
|
| 636 |
+
|
| 637 |
+
// Completion
|
| 638 |
+
setTimeout(() => {
|
| 639 |
+
addLine('✅ Projet ' + (type === 'minimal' ? 'minimal' : 'full‑stack') + ' construit avec succès.', 'ok');
|
| 640 |
+
}, delay + 200);
|
| 641 |
+
}
|
| 642 |
+
|
| 643 |
+
btnMinimal.addEventListener('click', () => runDemo('minimal'));
|
| 644 |
+
btnFullstack.addEventListener('click', () => runDemo('fullstack'));
|
| 645 |
+
btnReset.addEventListener('click', () => clearOutput());
|
| 646 |
+
}
|
| 647 |
+
|
| 648 |
+
// Initial draw
|
| 649 |
+
window.addEventListener('load', () => {
|
| 650 |
+
drawArrows();
|
| 651 |
+
setupNodes();
|
| 652 |
+
setupBuilderDemo();
|
| 653 |
+
});
|
| 654 |
+
window.addEventListener('resize', () => {
|
| 655 |
+
// Throttle redraw
|
| 656 |
+
clearTimeout(window.__arrowTimer);
|
| 657 |
+
window.__arrowTimer = setTimeout(drawArrows, 120);
|
| 658 |
+
});
|
| 659 |
+
</script>
|
| 660 |
+
|
| 661 |
+
<!-- Tailwind utilities via @apply -->
|
| 662 |
+
<style type="text/tailwindcss">
|
| 663 |
+
@layer utilities {
|
| 664 |
+
.animate-spin-slow {
|
| 665 |
+
animation: spin 8s linear infinite;
|
| 666 |
+
}
|
| 667 |
+
@keyframes spin {
|
| 668 |
+
to { transform: rotate(360deg); }
|
| 669 |
+
}
|
| 670 |
+
.node-btn {
|
| 671 |
+
@apply inline-flex items-center justify-center px-4 py-2 text-[11px] tracking-[0.18em] uppercase rounded-full border border-border bg-slate-900/60 hover:bg-slate-800/70 transition;
|
| 672 |
+
}
|
| 673 |
+
.node-main {
|
| 674 |
+
@apply border-primary/70 bg-gradient-to-br from-primary/15 to-accent/10 text-white;
|
| 675 |
+
}
|
| 676 |
+
.btn-primary {
|
| 677 |
+
@apply inline-flex items-center gap-2 px-4 py-2 rounded-full border border-primary/60 bg-primary/15 hover:bg-primary/25 text-primary transition;
|
| 678 |
+
}
|
| 679 |
+
.btn-secondary {
|
| 680 |
+
@apply inline-flex items-center gap-2 px-4 py-2 rounded-full border border-secondary/60 bg-secondary/15 hover:bg-secondary/25 text-secondary transition;
|
| 681 |
+
}
|
| 682 |
+
.btn-ghost {
|
| 683 |
+
@apply inline-flex items-center gap-2 px-4 py-2 rounded-full border border-border bg-transparent hover:bg-slate-800/50 text-slate-300 transition;
|
| 684 |
+
}
|
| 685 |
+
.badge {
|
| 686 |
+
@apply text-[10px] uppercase tracking-[0.18em] rounded-full border border-border px-2 py-0.5 text-slate-300;
|
| 687 |
+
}
|
| 688 |
+
}
|
| 689 |
+
</style>
|
| 690 |
+
<script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
|
| 691 |
+
</body>
|
| 692 |
+
</html>
|