Mini-projets algorithmique, corrigé TP KNN, news, notebooks IA
This commit is contained in:
163
algorithmes/mini-projets/09_generateur_web/starter.py
Normal file
163
algorithmes/mini-projets/09_generateur_web/starter.py
Normal file
@@ -0,0 +1,163 @@
|
||||
# Projet 09 — Le Générateur Web
|
||||
# Algorithmes : Tri par insertion + Dichotomie → page HTML/CSS
|
||||
|
||||
import webbrowser
|
||||
|
||||
jeux = [
|
||||
{"titre": "The Legend of Zelda: BotW", "studio": "Nintendo", "annee": 2017, "score": 97},
|
||||
{"titre": "Red Dead Redemption 2", "studio": "Rockstar", "annee": 2018, "score": 97},
|
||||
{"titre": "Grand Theft Auto V", "studio": "Rockstar", "annee": 2013, "score": 97},
|
||||
{"titre": "The Witcher 3", "studio": "CD Projekt", "annee": 2015, "score": 93},
|
||||
{"titre": "Elden Ring", "studio": "FromSoftware", "annee": 2022, "score": 96},
|
||||
{"titre": "Minecraft", "studio": "Mojang", "annee": 2011, "score": 93},
|
||||
{"titre": "Portal 2", "studio": "Valve", "annee": 2011, "score": 95},
|
||||
{"titre": "Hollow Knight", "studio": "Team Cherry", "annee": 2017, "score": 90},
|
||||
{"titre": "Hades", "studio": "Supergiant", "annee": 2020, "score": 93},
|
||||
{"titre": "Celeste", "studio": "Maddy Makes", "annee": 2018, "score": 94},
|
||||
{"titre": "Disco Elysium", "studio": "ZA/UM", "annee": 2019, "score": 97},
|
||||
{"titre": "Death Stranding", "studio": "Kojima Prod.", "annee": 2019, "score": 82},
|
||||
]
|
||||
|
||||
def tri_insertion_jeux(jeux):
|
||||
"""
|
||||
Trie les jeux par score DÉCROISSANT (tri par insertion).
|
||||
Le meilleur score doit être en premier.
|
||||
"""
|
||||
for i in range(1, len(jeux)):
|
||||
x = jeux[i]
|
||||
j = i
|
||||
# TODO : condition pour trier par ordre décroissant
|
||||
# Indice : pour l'ordre décroissant, on décale quand le score précédent est INFÉRIEUR
|
||||
while j > 0 and ...:
|
||||
jeux[j] = jeux[j - 1]
|
||||
j -= 1
|
||||
jeux[j] = x
|
||||
return jeux
|
||||
|
||||
def rechercher_score(jeux_tries, score):
|
||||
"""
|
||||
Recherche dichotomique d'un jeu par score exact.
|
||||
ATTENTION : la liste est triée par score DÉCROISSANT.
|
||||
Les comparaisons < et > sont inversées par rapport au cours !
|
||||
"""
|
||||
a = 0
|
||||
b = len(jeux_tries) - 1
|
||||
while a <= b:
|
||||
m = (a + b) // 2
|
||||
score_m = jeux_tries[m]["score"]
|
||||
if score_m == score:
|
||||
return jeux_tries[m]
|
||||
elif score_m > score:
|
||||
# Le score du milieu est trop grand → chercher à droite
|
||||
# TODO
|
||||
pass
|
||||
else:
|
||||
# Le score du milieu est trop petit → chercher à gauche
|
||||
# TODO
|
||||
pass
|
||||
return None
|
||||
|
||||
def generer_html(jeux_tries, fichier="classement.html"):
|
||||
"""Génère une page HTML affichant le classement."""
|
||||
COULEURS_PODIUM = ["#FFD700", "#C0C0C0", "#CD7F32"] # or, argent, bronze
|
||||
|
||||
lignes_html = ""
|
||||
for i, jeu in enumerate(jeux_tries, 1):
|
||||
if i <= 3:
|
||||
bg = f'style="background-color: {COULEURS_PODIUM[i-1]}; font-weight: bold;"'
|
||||
else:
|
||||
bg = 'style="background-color: #f9f9f9;"' if i % 2 == 0 else ""
|
||||
|
||||
lignes_html += f"""
|
||||
<tr {bg}>
|
||||
<td>{i}</td>
|
||||
<td>{jeu['titre']}</td>
|
||||
<td>{jeu['studio']}</td>
|
||||
<td>{jeu['annee']}</td>
|
||||
<td>{jeu['score']}/100</td>
|
||||
</tr>"""
|
||||
|
||||
html = f"""<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Top Jeux Vidéo</title>
|
||||
<style>
|
||||
body {{
|
||||
font-family: Arial, sans-serif;
|
||||
max-width: 800px;
|
||||
margin: 40px auto;
|
||||
background: #1a1a2e;
|
||||
color: #eee;
|
||||
}}
|
||||
h1 {{
|
||||
text-align: center;
|
||||
color: #FFD700;
|
||||
font-size: 2em;
|
||||
}}
|
||||
table {{
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
background: white;
|
||||
color: #333;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 20px rgba(0,0,0,0.5);
|
||||
}}
|
||||
th {{
|
||||
background: #16213e;
|
||||
color: white;
|
||||
padding: 12px 16px;
|
||||
text-align: left;
|
||||
}}
|
||||
td {{
|
||||
padding: 10px 16px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}}
|
||||
tr:last-child td {{ border-bottom: none; }}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>🎮 Classement des meilleurs jeux</h1>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Titre</th>
|
||||
<th>Studio</th>
|
||||
<th>Année</th>
|
||||
<th>Score</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{lignes_html}
|
||||
</tbody>
|
||||
</table>
|
||||
<p style="text-align:center; margin-top:20px; color:#aaa;">
|
||||
Généré par Python avec tri par insertion — NSI Première
|
||||
</p>
|
||||
</body>
|
||||
</html>"""
|
||||
|
||||
with open(fichier, "w", encoding="utf-8") as f:
|
||||
f.write(html)
|
||||
print(f"Page générée : {fichier}")
|
||||
|
||||
|
||||
# --- Programme principal ---
|
||||
print("=== Générateur de classement HTML ===")
|
||||
|
||||
tri_insertion_jeux(jeux)
|
||||
|
||||
print("Classement (5 premiers) :")
|
||||
for i, jeu in enumerate(jeux[:5], 1):
|
||||
print(f" {i}. {jeu['titre']} — {jeu['score']}/100")
|
||||
|
||||
# Recherche
|
||||
jeu_trouve = rechercher_score(jeux, 95)
|
||||
if jeu_trouve:
|
||||
print(f"\nJeu avec score 95 : {jeu_trouve['titre']}")
|
||||
|
||||
# Génération HTML
|
||||
generer_html(jeux)
|
||||
webbrowser.open("classement.html")
|
||||
51
algorithmes/mini-projets/09_generateur_web/sujet.md
Normal file
51
algorithmes/mini-projets/09_generateur_web/sujet.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# 09 — Le Générateur Web
|
||||
|
||||
**Algorithmes :** Tri par insertion + Recherche dichotomique → génération HTML/CSS
|
||||
**Difficulté :** Difficile
|
||||
**Durée estimée :** 1h15 — 1h30
|
||||
|
||||
---
|
||||
|
||||
## Contexte
|
||||
|
||||
Sans JavaScript, une page web ne peut pas exécuter d'algorithme. Mais Python peut **générer** une page HTML ! Vous allez trier des données en Python, puis produire un fichier `.html` affichant le résultat avec un style CSS.
|
||||
|
||||
---
|
||||
|
||||
## Étapes
|
||||
|
||||
### Étape 1 — Trier les données
|
||||
Implémentez `tri_insertion_jeux(jeux)` qui trie la liste de jeux vidéo par **score décroissant** (le meilleur en premier).
|
||||
|
||||
> **Indication** : pour trier par ordre **décroissant**, inversez la condition : `tab[j-1][1] < x[1]` au lieu de `>`.
|
||||
|
||||
### Étape 2 — Recherche dichotomique
|
||||
Implémentez `rechercher_score(jeux_tries, score)` qui retourne le jeu avec ce score exact, ou `None`.
|
||||
|
||||
> Attention : la liste est triée par score **décroissant**. La dichotomie doit être adaptée (les comparaisons `<` et `>` sont inversées).
|
||||
|
||||
### Étape 3 — Générer la page HTML
|
||||
Implémentez `generer_html(jeux_tries, fichier)` qui écrit un fichier `.html` contenant un tableau du classement, stylisé avec du CSS intégré.
|
||||
|
||||
La page doit afficher au minimum :
|
||||
- Le rang, le titre, le studio, l'année et le score de chaque jeu
|
||||
- Les 3 premiers avec une couleur distincte (or, argent, bronze)
|
||||
- Un titre et un style propre
|
||||
|
||||
### Étape 4 — Ouvrir la page automatiquement
|
||||
À la fin du programme, ouvrez la page générée dans le navigateur avec :
|
||||
|
||||
```python
|
||||
import webbrowser
|
||||
webbrowser.open("classement.html")
|
||||
```
|
||||
|
||||
### Étape 5 — Extension (si vous avez le temps)
|
||||
Ajoutez un deuxième tableau sur la même page : les jeux triés par **année de sortie** (vous pouvez faire un deuxième tri sur une copie).
|
||||
|
||||
---
|
||||
|
||||
## Ce que vous devez rendre
|
||||
- Le fichier `starter.py` qui tourne et génère `classement.html`
|
||||
- La page `classement.html` ouverte dans le navigateur
|
||||
- Réponse : pourquoi Python peut-il générer du HTML, alors qu'HTML ne peut pas exécuter Python ?
|
||||
Reference in New Issue
Block a user