Mini-projets algorithmique, corrigé TP KNN, news, notebooks IA

This commit is contained in:
2026-07-07 10:57:59 +02:00
parent 1647035df2
commit 5a6d602a91
51 changed files with 3614 additions and 33 deletions

156
knn/CORRIGE_TP_KNN.md Normal file
View File

@@ -0,0 +1,156 @@
# Corrigé — TP Choixpeau Magique et KNN
---
## Partie 1 : Modéliser un élève
### Question 1 — Modélisation d'Anthony
```python
anthony = {"nom": "Anthony", "courage": 2, "loyauté": 8, "sagesse": 8, "malice": 3, "maison": "Serdaigle"}
```
### Question 3 — Distance entre Hermione et Adrian
- Hermione : courage=8, loyauté=6, sagesse=6, malice=6
- Adrian : courage=9, loyauté=4, sagesse=7, malice=10
```
distance = |8-9| + |6-4| + |6-7| + |6-10|
= 1 + 2 + 1 + 4
= 8 ✓
```
### Question 4 — Distance entre Arthur et Drago
- Arthur : courage=10, loyauté=4, sagesse=2, malice=5
- Drago : courage=6, loyauté=6, sagesse=5, malice=8
```
distance = |10-6| + |4-6| + |2-5| + |5-8|
= 4 + 2 + 3 + 3
= 12
```
### Question 5 — Fonction distance
```python
def distance(eleve1, eleve2):
return (abs(eleve1["courage"] - eleve2["courage"]) +
abs(eleve1["loyauté"] - eleve2["loyauté"]) +
abs(eleve1["sagesse"] - eleve2["sagesse"]) +
abs(eleve1["malice"] - eleve2["malice"]))
```
---
## Partie 2 : Charger les données en table
### Question 1 — Type de `eleve[0]`
`eleve[0]` est de type `str`. `csv.reader` retourne toutes les valeurs sous forme de chaînes de caractères.
### Question 2 — Pourquoi `int()` ?
`int(eleve[1])` est de type `int`. On a besoin de la conversion car `csv.reader` renvoie tout en `str`, et on a besoin de valeurs numériques pour calculer des distances.
### Question 3 — Type de `poudlard`
`poudlard` est de type `list` (une liste de dictionnaires).
---
## Partie 3 : Trouver la maison majoritaire
```python
def maison_majoritaire(table):
frequences = frequence_des_maisons(table)
maison_max = None
max_freq = 0
for maison, freq in frequences.items():
if freq > max_freq:
max_freq = freq
maison_max = maison
return maison_max
```
---
## Partie 4 : Sept plus proches voisins
### Question 1 — Pseudo-code
```
Algorithme sept_voisins(table, nouveau) :
Données :
- table : liste d'élèves avec leur maison
- nouveau : élève sans maison
Résultat : les 7 élèves de table les plus proches de nouveau
Pour chaque élève de table :
Calculer la distance entre cet élève et nouveau
Stocker (distance, élève)
Trier la liste par distance croissante
Retourner les 7 premiers éléments
```
### Question 2 — Implémentation Python
```python
def sept_voisins(table, nouveau):
distances = []
for eleve in table:
d = distance(eleve, nouveau)
distances.append((d, eleve))
distances.sort(key=lambda x: x[0])
return [eleve for d, eleve in distances[:7]]
```
---
## Partie 5 : Attribuer une maison
```python
def attribuer_maison(table, nouveau):
voisins = sept_voisins(table, nouveau)
return maison_majoritaire(voisins)
```
### Application aux quatre élèves
```python
poudlard = charger_table("choixpeauMagique.csv")
hermione = {"nom": "Hermione", "courage": 8, "loyauté": 6, "sagesse": 6, "malice": 6}
drago = {"nom": "Drago", "courage": 6, "loyauté": 6, "sagesse": 5, "malice": 8}
cho = {"nom": "Cho", "courage": 7, "loyauté": 6, "sagesse": 9, "malice": 6}
cedric = {"nom": "Cédric", "courage": 7, "loyauté": 10, "sagesse": 5, "malice": 6}
for eleve in [hermione, drago, cho, cedric]:
maison = attribuer_maison(poudlard, eleve)
print(f"{eleve['nom']}{maison}")
```
### Résultats attendus
```
Hermione → Gryffondor
Drago → Serpentard
Cho → Serdaigle
Cédric → Poufsouffle
```
Détail des 7 voisins et du vote pour chaque élève :
| Élève | 7 plus proches voisins (distance) | Vote majoritaire |
|----------|------------------------------------------------------------------------------------------|-------------------------|
| Hermione | Cormac (4), Milicent (5), Neville (5), Padma (5), Susan (5), Angelina (6), Colin (6) | Gryffondor 4/7 ✓ |
| Drago | Padma (2), Susan (4), Angelina (5), Gregory (5), Harper (5), Bole (6), Marcus (6) | Serpentard 4/7 ✓ |
| Cho | Terry (5), Gilderoy (6), Lavande (6), Saemus (6), Eddie (7), Marcus (7), Padma (7) | Serdaigle 4/7 ✓ |
| Cédric | Dean (6), Gregory (6), Hannah (6), Norbert (6), Pomona (6), Susan (7), Térence (7) | Poufsouffle 4/7 ✓ |
> Ces résultats sont cohérents avec les personnages du roman : Hermione et Drago sont bien placés dans leurs maisons respectives, Cho Chang est à Serdaigle et Cédric Diggory à Poufsouffle.
---
Auteur : Florian Mathieu — Licence CC BY NC

View File

@@ -26,7 +26,7 @@ Le Choixpeau magique dispose d'un [fichier csv](choixpeauMagique.csv) avec les
Et voici les élèves que le Choipeaux magique doit orienter :
Et voici les élèves que le Choixpeau magique doit orienter :
| Nom | Courage | Loyauté | Sagesse | Malice |
| -------- | ------- | ------- | ------- | ------ |
@@ -78,7 +78,7 @@ def charger_table(nom_fichier):
table= []
with open(nom_fichier, 'r',newline="",encoding="utf-8") as csvfile:
eleve_reader = csv. reader(csvfile, delimiter=";")
eleve_reader = csv.reader(csvfile, delimiter=";")
eleve_reader.__next__()
for eleve in eleve_reader:
table.append({ "nom": eleve[0],
@@ -97,9 +97,9 @@ L'instruction suivante permet de charger les informations dans une variable **po
poudlard = charger_table("choixpeauMagique.csv")
```
1. Dans le code de la fonction charger _table, à la ligne 14, quel est le type de la variable eleve[0] ?
1. Dans le code de la fonction charger_table, à la ligne 14, quel est le type de la variable eleve[0] ?
2. Quel est le type de int ( eleve [ 0] ) ? Pourquoi a-t-on besoin de la fonction int() ici?
2. Quel est le type de int(eleve[1]) ? Pourquoi a-t-on besoin de la fonction int() ici ?
3. Quel est le type de la variable poudlard ?

View File

@@ -1,51 +1,51 @@
Nom;Courage;Loyauté;Sagesse;Malice;Maison
Adrian;9;4;7;10;Serpentar
Andrew;9;3;4;7;Griffondor
Angelina;10;6;5;9;Griffondor
Adrian;9;4;7;10;Serpentard
Andrew;9;3;4;7;Gryffondor
Angelina;10;6;5;9;Gryffondor
Anthony;2;8;8;3;Serdaigle
Arthur;10;4;2;5;Griffondor
Bellatrix;10;4;9;9;Serpentar
Bole;7;4;6;10;Serpentar
Colin;10;7;4;7;Griffondor
Cormac;9;6;5;4;Griffondor
Dean;9;8;4;7;Griffondor
Demelza;10;6;5;3;Griffondor
Derrick;5;4;6;5;Serpentar
Arthur;10;4;2;5;Gryffondor
Bellatrix;10;4;9;9;Serpentard
Bole;7;4;6;10;Serpentard
Colin;10;7;4;7;Gryffondor
Cormac;9;6;5;4;Gryffondor
Dean;9;8;4;7;Gryffondor
Demelza;10;6;5;3;Gryffondor
Derrick;5;4;6;5;Serpentard
Eddie;5;7;10;3;Serdaigle
Ernie;4;8;7;4;Poufsouffle
Euan;9;2;7;4;Griffondor
Euan;9;2;7;4;Gryffondor
Gilderoy;7;9;9;9;Serdaigle
Gregory;6;9;7;8;Serpentar
Gregory;6;9;7;8;Serpentard
Hannah;8;10;2;4;Poufsouffle
Harper;6;3;5;10;Serpentar
Jimmy;9;9;9;10;Griffondor
Harper;6;3;5;10;Serpentard
Jimmy;9;9;9;10;Gryffondor
Justin;5;10;7;10;Poufsouffle
Katie;10;2;3;9;Griffondor
Lavande;10;8;8;6;Griffondor
Lee;10;2;2;8;Griffondor
Katie;10;2;3;9;Gryffondor
Lavande;10;8;8;6;Gryffondor
Lee;10;2;2;8;Gryffondor
Luna;2;9;9;2;Serdaigle
Marcus;6;5;8;10;Serpentar
Marcus;6;5;8;10;Serpentard
Marietta;10;8;10;9;Serdaigle
Michael;4;2;6;5;Serdaigle
Milicent;9;3;5;6;Serpentar
Milicent;9;3;5;6;Serpentard
Mimi;4;4;9;10;Serdaigle
Montague;5;7;2;10;Serpentar
Neville;10;5;6;4;Griffondor
Montague;5;7;2;10;Serpentard
Neville;10;5;6;4;Gryffondor
Norbert;3;10;7;6;Poufsouffle
Nymphadora;2;5;3;8;Poufsouffle
Padma;6;6;6;9;Serdaigle
Paenny;2;8;9;8;Poufsouffle
Pansy;4;4;10;8;Serpentar
Parvati;10;5;2;6;Griffondor
Pansy;4;4;10;8;Serpentard
Parvati;10;5;2;6;Gryffondor
Pomona;5;10;7;8;Poufsouffle
Quirinus;7;10;10;2;Serdaigle
Roger;9;10;10;8;Serdaigle
Romilda;10;6;2;9;Griffondor
Saemus;7;4;8;3;Griffondor
Sirius;10;8;10;7;Griffondor
Romilda;10;6;2;9;Gryffondor
Saemus;7;4;8;3;Gryffondor
Sirius;10;8;10;7;Gryffondor
Susan;5;6;5;5;Poufsouffle
Susan;4;10;10;5;Poufsouffle
Ted;5;9;8;4;Poufsouffle
Térence;6;9;2;8;Serpentar
Térence;6;9;2;8;Serpentard
Terry;8;4;10;5;Serdaigle
Vincent;4;9;2;10;Serpentar
Vincent;4;9;2;10;Serpentard
1 Nom Courage Loyauté Sagesse Malice Maison
2 Adrian 9 4 7 10 Serpentar Serpentard
3 Andrew 9 3 4 7 Griffondor Gryffondor
4 Angelina 10 6 5 9 Griffondor Gryffondor
5 Anthony 2 8 8 3 Serdaigle
6 Arthur 10 4 2 5 Griffondor Gryffondor
7 Bellatrix 10 4 9 9 Serpentar Serpentard
8 Bole 7 4 6 10 Serpentar Serpentard
9 Colin 10 7 4 7 Griffondor Gryffondor
10 Cormac 9 6 5 4 Griffondor Gryffondor
11 Dean 9 8 4 7 Griffondor Gryffondor
12 Demelza 10 6 5 3 Griffondor Gryffondor
13 Derrick 5 4 6 5 Serpentar Serpentard
14 Eddie 5 7 10 3 Serdaigle
15 Ernie 4 8 7 4 Poufsouffle
16 Euan 9 2 7 4 Griffondor Gryffondor
17 Gilderoy 7 9 9 9 Serdaigle
18 Gregory 6 9 7 8 Serpentar Serpentard
19 Hannah 8 10 2 4 Poufsouffle
20 Harper 6 3 5 10 Serpentar Serpentard
21 Jimmy 9 9 9 10 Griffondor Gryffondor
22 Justin 5 10 7 10 Poufsouffle
23 Katie 10 2 3 9 Griffondor Gryffondor
24 Lavande 10 8 8 6 Griffondor Gryffondor
25 Lee 10 2 2 8 Griffondor Gryffondor
26 Luna 2 9 9 2 Serdaigle
27 Marcus 6 5 8 10 Serpentar Serpentard
28 Marietta 10 8 10 9 Serdaigle
29 Michael 4 2 6 5 Serdaigle
30 Milicent 9 3 5 6 Serpentar Serpentard
31 Mimi 4 4 9 10 Serdaigle
32 Montague 5 7 2 10 Serpentar Serpentard
33 Neville 10 5 6 4 Griffondor Gryffondor
34 Norbert 3 10 7 6 Poufsouffle
35 Nymphadora 2 5 3 8 Poufsouffle
36 Padma 6 6 6 9 Serdaigle
37 Paenny 2 8 9 8 Poufsouffle
38 Pansy 4 4 10 8 Serpentar Serpentard
39 Parvati 10 5 2 6 Griffondor Gryffondor
40 Pomona 5 10 7 8 Poufsouffle
41 Quirinus 7 10 10 2 Serdaigle
42 Roger 9 10 10 8 Serdaigle
43 Romilda 10 6 2 9 Griffondor Gryffondor
44 Saemus 7 4 8 3 Griffondor Gryffondor
45 Sirius 10 8 10 7 Griffondor Gryffondor
46 Susan 5 6 5 5 Poufsouffle
47 Susan 4 10 10 5 Poufsouffle
48 Ted 5 9 8 4 Poufsouffle
49 Térence 6 9 2 8 Serpentar Serpentard
50 Terry 8 4 10 5 Serdaigle
51 Vincent 4 9 2 10 Serpentar Serpentard

159
knn/test_choixpeau.py Normal file
View File

@@ -0,0 +1,159 @@
import csv
import time
# ── Chargement des données ────────────────────────────────────────────────────
def charger_table(nom_fichier):
table = []
with open(nom_fichier, 'r', newline="", encoding="utf-8") as csvfile:
eleve_reader = csv.reader(csvfile, delimiter=";")
eleve_reader.__next__()
for eleve in eleve_reader:
table.append({
"nom": eleve[0],
"courage": int(eleve[1]),
"loyauté": int(eleve[2]),
"sagesse": int(eleve[3]),
"malice": int(eleve[4]),
"maison": eleve[5].strip()
})
return table
# ── Algorithme KNN ────────────────────────────────────────────────────────────
def distance(eleve1, eleve2):
return (abs(eleve1["courage"] - eleve2["courage"]) +
abs(eleve1["loyauté"] - eleve2["loyauté"]) +
abs(eleve1["sagesse"] - eleve2["sagesse"]) +
abs(eleve1["malice"] - eleve2["malice"]))
def sept_voisins(table, nouveau):
distances = [(distance(eleve, nouveau), eleve) for eleve in table]
distances.sort(key=lambda x: x[0])
return [eleve for d, eleve in distances[:7]]
def maison_majoritaire(voisins):
frequences = {}
for eleve in voisins:
maison = eleve["maison"]
frequences[maison] = frequences.get(maison, 0) + 1
return max(frequences, key=frequences.get), frequences
# ── Affichage ─────────────────────────────────────────────────────────────────
MAISONS = {
"Gryffondor": {
"traits": "Courage, chevalerie et determination",
"message": "Tu es du genre a te jeter dans la bataille sans trop reflechir.\nPoudlard a besoin de toi sur le terrain de Quidditch !"
},
"Serpentard": {
"traits": "Malice, ambition et ressource",
"message": "Tu sais ce que tu veux, et tu sais comment l'obtenir.\nMefie-toi quand meme de Lord Voldemort dans les couloirs."
},
"Serdaigle": {
"traits": "Sagesse, creativite et esprit",
"message": "Tu preferes comprendre avant d'agir. La bibliotheque\nde Poudlard va devenir ton deuxieme chez-toi."
},
"Poufsouffle": {
"traits": "Loyaute, patience et equite",
"message": "On peut compter sur toi. Toujours. Sans exception.\nCedric Diggory etait de Poufsouffle — ca dit tout."
}
}
def afficher_banniere(maison):
largeur = 42
print()
print("=" * largeur)
print("|" + " " * (largeur - 2) + "|")
ligne = f" Le Choixpeau a decide : {maison.upper()}"
print("|" + ligne.ljust(largeur - 2) + "|")
print("|" + " " * (largeur - 2) + "|")
infos = MAISONS.get(maison, {})
traits = f" {infos.get('traits', '')}"
print("|" + traits.ljust(largeur - 2) + "|")
print("|" + " " * (largeur - 2) + "|")
print("=" * largeur)
print()
print(infos.get("message", ""))
print()
def afficher_voisins(voisins, moi):
print("-" * 42)
print(" Les 7 eleves de Poudlard qui te ressemblent le plus :")
print()
for v in voisins:
d = distance(v, moi)
print(f" {v['nom']:<12} ({v['maison']:<12}) distance : {d}")
print("-" * 42)
print()
# ── Saisie avec validation ────────────────────────────────────────────────────
QUESTIONS = [
("courage", "Face au danger, tu fonces sans hesiter "),
("loyauté", "Tu es fidele a tes amis, quoi qu'il arrive "),
("sagesse", "Tu reflechis avant d'agir, tu observes, tu analyses "),
("malice", "Tu sais trouver des strategies pour arriver a tes fins"),
]
def poser_question(trait, description):
while True:
try:
rep = input(f" {description} (1 a 10) : ").strip()
valeur = int(rep)
if 1 <= valeur <= 10:
return valeur
print(" --> Donne une valeur entre 1 et 10.")
except ValueError:
print(" --> Entre un nombre entier.")
# ── Programme principal ───────────────────────────────────────────────────────
def main():
print()
print("=" * 42)
print("| |")
print("| CHOIXPEAU MAGIQUE -- KNN |")
print("| |")
print("=" * 42)
print()
try:
poudlard = charger_table("choixpeauMagique.csv")
except FileNotFoundError:
print("Erreur : le fichier 'choixpeauMagique.csv' est introuvable.")
print("Place-le dans le meme dossier que ce script.")
return
prenom = input("Quel est ton prenom ? ").strip()
if not prenom:
prenom = "Mystere"
print()
print(f"Bien, {prenom}. Reponds honnêtement à ces quatre questions.")
print("Note-toi de 1 (pas du tout) à 10 (totalement).")
print()
eleve = {"nom": prenom}
for trait, description in QUESTIONS:
eleve[trait] = poser_question(trait, description)
print()
print("Le Choixpeau murmure quelque chose...")
time.sleep(1)
print("Il se tait.")
time.sleep(1)
print("Puis il crie :")
time.sleep(0.8)
voisins = sept_voisins(poudlard, eleve)
maison, frequences = maison_majoritaire(voisins)
afficher_banniere(maison)
time.sleep(0.5)
afficher_voisins(voisins, eleve)
print(f" Repartition du vote : {frequences}")
print()
main()