supprime le dossier evaluation du dépôt (évaluations sur Capytale)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-29 23:56:31 +01:00
parent 34d9764752
commit bf7626401f
21 changed files with 1 additions and 7170 deletions

1
.gitignore vendored
View File

@@ -25,3 +25,4 @@ Licence_IA*.jpeg
# Vidéos
*.webm
AMELIORATIONS.md
representation_construits/evaluation/

View File

@@ -1,476 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "cell-0",
"metadata": {},
"source": [
"# TP Évaluation - Gestion de Playlists Spotify\n",
"\n",
"**Durée : 1h30**\n",
"\n",
"**Nom :** \n",
"\n",
"**Prénom :**\n",
"\n",
"---\n",
"\n",
"Dans ce TP, vous allez manipuler des structures de données Python pour gérer des playlists musicales.\n",
"\n",
"**Compétences évaluées :**\n",
"- Manipulation de listes et dictionnaires\n",
"- Parcours et filtrage de données\n",
"- Écriture de fonctions"
]
},
{
"cell_type": "markdown",
"id": "cell-1",
"metadata": {},
"source": [
"## Données initiales\n",
"\n",
"Voici les données avec lesquelles vous allez travailler. **Exécutez cette cellule avant de commencer.**"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-2",
"metadata": {},
"outputs": [],
"source": [
"# Base de données de chansons\n",
"# Chaque chanson est un dictionnaire avec : titre, artiste, duree (en secondes), annee, streams\n",
"catalogue = [\n",
" {\"titre\": \"Blinding Lights\", \"artiste\": \"The Weeknd\", \"duree\": 203, \"annee\": 2020, \"streams\": 3500000000},\n",
" {\"titre\": \"Shape of You\", \"artiste\": \"Ed Sheeran\", \"duree\": 234, \"annee\": 2017, \"streams\": 3400000000},\n",
" {\"titre\": \"Dance Monkey\", \"artiste\": \"Tones and I\", \"duree\": 210, \"annee\": 2019, \"streams\": 2800000000},\n",
" {\"titre\": \"Rockstar\", \"artiste\": \"Post Malone\", \"duree\": 218, \"annee\": 2017, \"streams\": 2700000000},\n",
" {\"titre\": \"One Dance\", \"artiste\": \"Drake\", \"duree\": 173, \"annee\": 2016, \"streams\": 2600000000},\n",
" {\"titre\": \"Sunflower\", \"artiste\": \"Post Malone\", \"duree\": 158, \"annee\": 2018, \"streams\": 2500000000},\n",
" {\"titre\": \"Closer\", \"artiste\": \"The Chainsmokers\", \"duree\": 244, \"annee\": 2016, \"streams\": 2400000000},\n",
" {\"titre\": \"Starboy\", \"artiste\": \"The Weeknd\", \"duree\": 230, \"annee\": 2016, \"streams\": 2300000000},\n",
" {\"titre\": \"Perfect\", \"artiste\": \"Ed Sheeran\", \"duree\": 263, \"annee\": 2017, \"streams\": 2200000000},\n",
" {\"titre\": \"Heat Waves\", \"artiste\": \"Glass Animals\", \"duree\": 239, \"annee\": 2020, \"streams\": 2100000000},\n",
" {\"titre\": \"Bad Guy\", \"artiste\": \"Billie Eilish\", \"duree\": 194, \"annee\": 2019, \"streams\": 2000000000},\n",
" {\"titre\": \"Levitating\", \"artiste\": \"Dua Lipa\", \"duree\": 203, \"annee\": 2020, \"streams\": 1900000000},\n",
" {\"titre\": \"Save Your Tears\", \"artiste\": \"The Weeknd\", \"duree\": 216, \"annee\": 2020, \"streams\": 1800000000},\n",
" {\"titre\": \"Thinking Out Loud\", \"artiste\": \"Ed Sheeran\", \"duree\": 281, \"annee\": 2014, \"streams\": 1700000000},\n",
" {\"titre\": \"Stay\", \"artiste\": \"The Kid LAROI\", \"duree\": 141, \"annee\": 2021, \"streams\": 1600000000}\n",
"]\n",
"\n",
"# Playlist de l'utilisateur (initialement vide)\n",
"ma_playlist = []"
]
},
{
"cell_type": "markdown",
"id": "cell-3",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 1 - Exploration du catalogue (25 min)\n",
"\n",
"### 1.1 Affichage formaté (4 pts)\n",
"\n",
"Écrivez une fonction `afficher_chanson(chanson)` qui prend un dictionnaire représentant une chanson et affiche ses informations.\n",
"\n",
"Exemple de sortie attendue :\n",
"```\n",
"Blinding Lights - The Weeknd (2020) | 3:23\n",
"```\n",
"\n",
"*Aide : la durée est en secondes. Pour convertir : minutes = duree // 60, secondes = duree % 60*"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-4",
"metadata": {},
"outputs": [],
"source": [
"def afficher_chanson(chanson):\n",
" # Récupérer les informations\n",
" titre = chanson[\"titre\"]\n",
" artiste = chanson[\"artiste\"]\n",
" annee = chanson[\"annee\"]\n",
" duree = chanson[\"duree\"]\n",
" \n",
" # Convertir la durée en minutes:secondes\n",
" minutes = duree // 60\n",
" secondes = duree % 60\n",
" \n",
" # Afficher (compléter le print)\n",
" # Votre code ici\n",
" pass\n",
"\n",
"# Test\n",
"afficher_chanson(catalogue[0])"
]
},
{
"cell_type": "markdown",
"id": "cell-5",
"metadata": {},
"source": [
"### 1.2 Statistiques de base (4 pts)\n",
"\n",
"Écrivez une fonction `statistiques_catalogue(liste_chansons)` qui renvoie un dictionnaire contenant :\n",
"- `\"nombre\"` : le nombre total de chansons\n",
"- `\"duree_totale\"` : la durée totale en secondes\n",
"- `\"streams_total\"` : le nombre total de streams"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-6",
"metadata": {},
"outputs": [],
"source": [
"def statistiques_catalogue(liste_chansons):\n",
" nombre = 0\n",
" duree_totale = 0\n",
" streams_total = 0\n",
" \n",
" for chanson in liste_chansons:\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return {\n",
" \"nombre\": nombre,\n",
" \"duree_totale\": duree_totale,\n",
" \"streams_total\": streams_total\n",
" }\n",
"\n",
"# Test\n",
"stats = statistiques_catalogue(catalogue)\n",
"print(\"Nombre de chansons :\", stats[\"nombre\"])\n",
"print(\"Duree totale :\", stats[\"duree_totale\"], \"secondes\")\n",
"print(\"Streams total :\", stats[\"streams_total\"])"
]
},
{
"cell_type": "markdown",
"id": "cell-7",
"metadata": {},
"source": [
"### 1.3 Liste des artistes (4 pts)\n",
"\n",
"Écrivez une fonction `artistes_uniques(liste_chansons)` qui renvoie la **liste sans doublons** de tous les artistes présents dans le catalogue, triée par ordre alphabétique.\n",
"\n",
"*Aide : vous pouvez utiliser `liste.sort()` pour trier une liste, et vérifier si un élément est déjà dans la liste avec `if element not in liste`*"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-8",
"metadata": {},
"outputs": [],
"source": [
"def artistes_uniques(liste_chansons):\n",
" artistes = []\n",
" \n",
" for chanson in liste_chansons:\n",
" artiste = chanson[\"artiste\"]\n",
" # Ajouter l'artiste s'il n'est pas déjà dans la liste\n",
" # Votre code ici\n",
" pass\n",
" \n",
" # Trier la liste\n",
" artistes.sort()\n",
" return artistes\n",
"\n",
"# Test\n",
"print(\"Artistes :\", artistes_uniques(catalogue))"
]
},
{
"cell_type": "markdown",
"id": "cell-9",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 2 - Gestion de playlist (35 min)\n",
"\n",
"### 2.1 Recherche de chansons (5 pts)\n",
"\n",
"Écrivez une fonction `rechercher_par_artiste(liste_chansons, artiste)` qui renvoie la liste des chansons d'un artiste donné."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-10",
"metadata": {},
"outputs": [],
"source": [
"def rechercher_par_artiste(liste_chansons, artiste):\n",
" resultats = []\n",
" \n",
" for chanson in liste_chansons:\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return resultats\n",
"\n",
"# Test\n",
"print(\"Chansons de The Weeknd :\")\n",
"for c in rechercher_par_artiste(catalogue, \"The Weeknd\"):\n",
" afficher_chanson(c)"
]
},
{
"cell_type": "markdown",
"id": "cell-11",
"metadata": {},
"source": [
"### 2.2 Recherche par année (5 pts)\n",
"\n",
"Écrivez une fonction `rechercher_par_annee(liste_chansons, annee)` qui renvoie la liste des chansons d'une année donnée."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-12",
"metadata": {},
"outputs": [],
"source": [
"def rechercher_par_annee(liste_chansons, annee):\n",
" resultats = []\n",
" \n",
" for chanson in liste_chansons:\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return resultats\n",
"\n",
"# Test\n",
"print(\"Chansons de 2020 :\")\n",
"for c in rechercher_par_annee(catalogue, 2020):\n",
" afficher_chanson(c)"
]
},
{
"cell_type": "markdown",
"id": "cell-13",
"metadata": {},
"source": [
"### 2.3 Ajouter et retirer des chansons (6 pts)\n",
"\n",
"Écrivez deux fonctions :\n",
"\n",
"1. `ajouter_a_playlist(playlist, chanson)` : ajoute une chanson à la playlist **si elle n'y est pas déjà** (vérification par le titre). Renvoie `True` si l'ajout a réussi, `False` sinon.\n",
"\n",
"2. `retirer_de_playlist(playlist, titre)` : retire la chanson ayant ce titre de la playlist. Renvoie `True` si la suppression a réussi, `False` si la chanson n'était pas dans la playlist."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-14",
"metadata": {},
"outputs": [],
"source": [
"def ajouter_a_playlist(playlist, chanson):\n",
" # Vérifier si la chanson est déjà dans la playlist\n",
" for c in playlist:\n",
" if c[\"titre\"] == chanson[\"titre\"]:\n",
" return False\n",
" \n",
" # Si on arrive ici, la chanson n'est pas dans la playlist\n",
" # Votre code ici\n",
" pass\n",
"\n",
"def retirer_de_playlist(playlist, titre):\n",
" # Chercher la chanson avec ce titre\n",
" for i in range(len(playlist)):\n",
" if playlist[i][\"titre\"] == titre:\n",
" # Votre code ici (utiliser del ou pop)\n",
" pass\n",
" \n",
" return False\n",
"\n",
"# Tests\n",
"ma_playlist = []\n",
"print(ajouter_a_playlist(ma_playlist, catalogue[0])) # True\n",
"print(ajouter_a_playlist(ma_playlist, catalogue[0])) # False (deja present)\n",
"print(ajouter_a_playlist(ma_playlist, catalogue[1])) # True\n",
"print(\"Playlist :\", len(ma_playlist), \"chansons\")\n",
"print(retirer_de_playlist(ma_playlist, \"Blinding Lights\")) # True\n",
"print(retirer_de_playlist(ma_playlist, \"Blinding Lights\")) # False\n",
"print(\"Playlist :\", len(ma_playlist), \"chansons\")"
]
},
{
"cell_type": "markdown",
"id": "cell-15",
"metadata": {},
"source": [
"### 2.4 Top artistes (6 pts)\n",
"\n",
"Écrivez une fonction `compter_streams_par_artiste(liste_chansons)` qui renvoie un **dictionnaire** où les clés sont les noms d'artistes et les valeurs sont leur nombre total de streams.\n",
"\n",
"*Aide : utilisez `dico.get(cle, 0)` pour récupérer une valeur avec une valeur par défaut de 0 si la clé n'existe pas*"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-16",
"metadata": {},
"outputs": [],
"source": [
"def compter_streams_par_artiste(liste_chansons):\n",
" streams_par_artiste = {}\n",
" \n",
" for chanson in liste_chansons:\n",
" artiste = chanson[\"artiste\"]\n",
" streams = chanson[\"streams\"]\n",
" \n",
" # Ajouter les streams au total de l'artiste\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return streams_par_artiste\n",
"\n",
"# Test\n",
"streams = compter_streams_par_artiste(catalogue)\n",
"print(\"Streams par artiste :\")\n",
"for artiste, total in streams.items():\n",
" print(\" \", artiste, \":\", total)"
]
},
{
"cell_type": "markdown",
"id": "cell-17",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 3 - Bonus (20 min)\n",
"\n",
"### 3.1 Chanson la plus populaire (4 pts)\n",
"\n",
"Écrivez une fonction `chanson_plus_populaire(liste_chansons)` qui renvoie la chanson (dictionnaire) ayant le plus de streams."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-18",
"metadata": {},
"outputs": [],
"source": [
"def chanson_plus_populaire(liste_chansons):\n",
" if len(liste_chansons) == 0:\n",
" return None\n",
" \n",
" meilleure = liste_chansons[0]\n",
" \n",
" for chanson in liste_chansons:\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return meilleure\n",
"\n",
"# Test\n",
"top = chanson_plus_populaire(catalogue)\n",
"print(\"Chanson la plus populaire :\")\n",
"afficher_chanson(top)"
]
},
{
"cell_type": "markdown",
"id": "cell-19",
"metadata": {},
"source": [
"### 3.2 Trier par streams (4 pts)\n",
"\n",
"Écrivez une fonction `trier_par_streams(liste_chansons)` qui renvoie une **nouvelle liste** des chansons triées par nombre de streams décroissant.\n",
"\n",
"*Aide : utilisez `sorted(liste, key=..., reverse=True)`. La clé peut être une fonction lambda : `lambda c: c[\"streams\"]`*"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-20",
"metadata": {},
"outputs": [],
"source": [
"def trier_par_streams(liste_chansons):\n",
" # Votre code ici\n",
" pass\n",
"\n",
"# Test\n",
"print(\"Top 5 des chansons :\")\n",
"top5 = trier_par_streams(catalogue)[:5]\n",
"for c in top5:\n",
" afficher_chanson(c)"
]
},
{
"cell_type": "markdown",
"id": "cell-21",
"metadata": {},
"source": [
"### 3.3 Créer une playlist automatique (6 pts)\n",
"\n",
"Écrivez une fonction `creer_playlist_auto(liste_chansons, duree_max)` qui crée une playlist en ajoutant les chansons les plus populaires tant que la durée totale ne dépasse pas `duree_max` (en secondes).\n",
"\n",
"Renvoie la playlist créée."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-22",
"metadata": {},
"outputs": [],
"source": [
"def creer_playlist_auto(liste_chansons, duree_max):\n",
" # Trier par streams décroissant\n",
" chansons_triees = trier_par_streams(liste_chansons)\n",
" \n",
" playlist = []\n",
" duree_actuelle = 0\n",
" \n",
" for chanson in chansons_triees:\n",
" # Vérifier si on peut ajouter cette chanson\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return playlist\n",
"\n",
"# Test : playlist de 10 minutes max (600 secondes)\n",
"playlist_auto = creer_playlist_auto(catalogue, 600)\n",
"print(\"Playlist automatique :\")\n",
"duree_totale = 0\n",
"for c in playlist_auto:\n",
" afficher_chanson(c)\n",
" duree_totale = duree_totale + c[\"duree\"]\n",
"print(\"Duree totale :\", duree_totale, \"secondes\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.9.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -1,128 +0,0 @@
# Aide - TP01 Spotify
## Rappels utiles
### Acceder aux elements d'un dictionnaire
```python
chanson = {"titre": "Blinding Lights", "artiste": "The Weeknd", "duree": 203}
print(chanson["titre"]) # Blinding Lights
print(chanson.get("note", 0)) # 0 (valeur par defaut si cle absente)
```
### Convertir des secondes en minutes:secondes
```python
duree = 203 # secondes
minutes = duree // 60 # Division entiere
secondes = duree % 60 # Reste (modulo)
print(minutes, ":", secondes) # 3 : 23
```
### Parcourir une liste de dictionnaires
```python
for chanson in catalogue:
print(chanson["titre"])
```
---
## Exercice 1
### 1.1 - Affichage formate
- Utilisez print() avec des virgules : `print("Titre:", titre)`
- Pour le formatage minutes:secondes, pensez a `//` et `%`
- Concatenation avec `+` si besoin : `str(minutes) + ":" + str(secondes)`
### 1.2 - Statistiques
- Initialisez un dictionnaire vide pour le resultat
- Parcourez la liste avec une boucle for pour calculer la somme
- `round(valeur)` arrondit a l'entier
```python
total = 0
for chanson in catalogue:
total = total + chanson["duree"]
```
### 1.3 - Artistes uniques
- Parcourez et ajoutez dans une liste si pas deja present
- `sorted(liste)` trie par ordre alphabetique
```python
artistes = []
for chanson in catalogue:
if chanson["artiste"] not in artistes:
artistes.append(chanson["artiste"])
artistes.sort()
```
---
## Exercice 2
### 2.1 - Recherche
- Utilisez `if critere == "artiste":` pour differencier les cas
- Pour la recherche insensible a la casse : `"star".lower() in titre.lower()`
- Renvoyez une nouvelle liste (ne modifiez pas l'originale)
### 2.2 - Ajouter/Retirer
- Pour verifier si un titre existe deja :
```python
for chanson in playlist:
if chanson["titre"] == nouveau_titre:
return False # Deja present
```
- Pour retirer, parcourez avec l'indice :
```python
for i in range(len(playlist)):
if playlist[i]["titre"] == titre:
playlist.pop(i)
return True
```
### 2.3 - Top artistes
- Creez d'abord un dictionnaire `{artiste: total_streams}`
- Parcourez le catalogue et cumulez les streams
- Triez avec `sorted(dico.items(), key=lambda x: x[1], reverse=True)`
```python
compteur = {}
for chanson in catalogue:
artiste = chanson["artiste"]
if artiste not in compteur:
compteur[artiste] = 0
compteur[artiste] = compteur[artiste] + chanson["streams"]
```
---
## Exercice 3 (Bonus)
### 3.1 - Filtrage
```python
# Filtrer les chansons courtes
resultat = []
for chanson in catalogue:
if chanson["duree"] < 200:
resultat.append(chanson["titre"])
```
### 3.2 - Recommandations
1. D'abord, recuperez les artistes de la playlist utilisateur
2. Ensuite, filtrez le catalogue pour ces artistes
3. Excluez les chansons deja dans la playlist
4. Triez par streams decroissant
### 3.3 - Playlist automatique
- Triez d'abord le catalogue par streams decroissant
- Parcourez et ajoutez si `duree_actuelle + chanson["duree"] <= duree_cible + tolerance`
- Arretez quand `duree_actuelle >= duree_cible - tolerance`
---
## Pieges a eviter
1. **Ne pas modifier la liste originale** lors des recherches
2. **Attention aux comparaisons de chaines** : utilisez `.lower()` pour ignorer la casse
3. **Division par zero** : verifiez que la liste n'est pas vide avant de calculer une moyenne
4. **Arrondi** : `round(x, 2)` pour 2 decimales, `round(x)` pour un entier

View File

@@ -1,491 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "cell-0",
"metadata": {},
"source": [
"# TP Évaluation - Système d'inventaire Minecraft\n",
"\n",
"**Durée : 1h30**\n",
"\n",
"**Nom :** \n",
"\n",
"**Prénom :**\n",
"\n",
"---\n",
"\n",
"Dans ce TP, vous allez créer un système de gestion d'inventaire et de craft inspiré de Minecraft.\n",
"\n",
"**Compétences évaluées :**\n",
"- Manipulation de dictionnaires\n",
"- Parcours et modification de structures\n",
"- Algorithmes de vérification"
]
},
{
"cell_type": "markdown",
"id": "cell-1",
"metadata": {},
"source": [
"## Données initiales\n",
"\n",
"**Exécutez cette cellule avant de commencer.**"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-2",
"metadata": {},
"outputs": [],
"source": [
"# Inventaire du joueur : {nom_item: quantite}\n",
"inventaire = {\n",
" \"bois\": 64,\n",
" \"pierre\": 128,\n",
" \"fer\": 32,\n",
" \"or\": 8,\n",
" \"diamant\": 3,\n",
" \"charbon\": 45,\n",
" \"cuir\": 12,\n",
" \"plume\": 24,\n",
" \"ficelle\": 16\n",
"}\n",
"\n",
"# Recettes de craft : {nom_resultat: {ingredient: quantite_necessaire}}\n",
"recettes = {\n",
" \"planche\": {\"bois\": 1},\n",
" \"baton\": {\"planche\": 2},\n",
" \"torche\": {\"baton\": 1, \"charbon\": 1},\n",
" \"pioche_bois\": {\"planche\": 3, \"baton\": 2},\n",
" \"pioche_pierre\": {\"pierre\": 3, \"baton\": 2},\n",
" \"pioche_fer\": {\"fer\": 3, \"baton\": 2},\n",
" \"pioche_diamant\": {\"diamant\": 3, \"baton\": 2},\n",
" \"epee_fer\": {\"fer\": 2, \"baton\": 1},\n",
" \"epee_diamant\": {\"diamant\": 2, \"baton\": 1},\n",
" \"coffre\": {\"planche\": 8},\n",
" \"four\": {\"pierre\": 8}\n",
"}\n",
"\n",
"# Quantites produites par craft (par defaut 1, sauf exceptions)\n",
"quantites_produites = {\n",
" \"planche\": 4,\n",
" \"baton\": 4,\n",
" \"torche\": 4\n",
"}\n",
"\n",
"# Valeurs des items en emeraudes\n",
"valeurs = {\n",
" \"bois\": 1, \"pierre\": 1, \"fer\": 5, \"or\": 10, \"diamant\": 50,\n",
" \"charbon\": 2, \"cuir\": 3, \"plume\": 1, \"ficelle\": 2,\n",
" \"planche\": 1, \"baton\": 1, \"torche\": 3\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "cell-3",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 1 - Gestion de l'inventaire (25 min)\n",
"\n",
"### 1.1 Affichage de l'inventaire (4 pts)\n",
"\n",
"Écrivez une fonction `afficher_inventaire(inv)` qui affiche l'inventaire de manière formatée.\n",
"\n",
"Exemple de sortie :\n",
"```\n",
"=== INVENTAIRE ===\n",
"bois : 64\n",
"pierre : 128\n",
"fer : 32\n",
"...\n",
"==================\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-4",
"metadata": {},
"outputs": [],
"source": [
"def afficher_inventaire(inv):\n",
" print(\"=== INVENTAIRE ===\")\n",
" \n",
" for item, quantite in inv.items():\n",
" # Votre code ici\n",
" pass\n",
" \n",
" print(\"==================\")\n",
"\n",
"# Test\n",
"afficher_inventaire(inventaire)"
]
},
{
"cell_type": "markdown",
"id": "cell-5",
"metadata": {},
"source": [
"### 1.2 Ajouter un item (4 pts)\n",
"\n",
"Écrivez une fonction `ajouter_item(inv, item, quantite)` qui ajoute la quantité à l'item.\n",
"\n",
"Si l'item n'existe pas dans l'inventaire, il doit être créé.\n",
"\n",
"*Aide : utilisez `inv.get(item, 0)` pour obtenir la quantité actuelle (0 si l'item n'existe pas)*"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-6",
"metadata": {},
"outputs": [],
"source": [
"def ajouter_item(inv, item, quantite):\n",
" # Votre code ici\n",
" pass\n",
"\n",
"# Tests\n",
"test_inv = {\"bois\": 10}\n",
"ajouter_item(test_inv, \"bois\", 5)\n",
"print(\"Apres ajout de 5 bois :\", test_inv)\n",
"ajouter_item(test_inv, \"fer\", 3)\n",
"print(\"Apres ajout de 3 fer :\", test_inv)"
]
},
{
"cell_type": "markdown",
"id": "cell-7",
"metadata": {},
"source": [
"### 1.3 Retirer un item (4 pts)\n",
"\n",
"Écrivez une fonction `retirer_item(inv, item, quantite)` qui retire la quantité de l'item.\n",
"\n",
"- Renvoie `True` si le retrait a réussi\n",
"- Renvoie `False` si la quantité est insuffisante (et ne modifie pas l'inventaire)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-8",
"metadata": {},
"outputs": [],
"source": [
"def retirer_item(inv, item, quantite):\n",
" # Verifier si l'item existe et en quantite suffisante\n",
" quantite_actuelle = inv.get(item, 0)\n",
" \n",
" if quantite_actuelle < quantite:\n",
" return False\n",
" \n",
" # Retirer la quantite\n",
" # Votre code ici\n",
" pass\n",
"\n",
"# Tests\n",
"test_inv = {\"bois\": 10, \"pierre\": 5}\n",
"print(\"Retirer 5 bois :\", retirer_item(test_inv, \"bois\", 5))\n",
"print(\"Inventaire :\", test_inv)\n",
"print(\"Retirer 100 bois :\", retirer_item(test_inv, \"bois\", 100))\n",
"print(\"Inventaire :\", test_inv)"
]
},
{
"cell_type": "markdown",
"id": "cell-9",
"metadata": {},
"source": [
"### 1.4 Valeur de l'inventaire (4 pts)\n",
"\n",
"Écrivez une fonction `calculer_valeur(inv, valeurs)` qui renvoie la valeur totale de l'inventaire.\n",
"\n",
"*Note : si un item n'a pas de valeur définie, il vaut 0*"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-10",
"metadata": {},
"outputs": [],
"source": [
"def calculer_valeur(inv, valeurs):\n",
" total = 0\n",
" \n",
" for item, quantite in inv.items():\n",
" # Recuperer la valeur de l'item (0 si pas definie)\n",
" valeur_unitaire = valeurs.get(item, 0)\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return total\n",
"\n",
"# Test\n",
"print(\"Valeur totale :\", calculer_valeur(inventaire, valeurs), \"emeraudes\")"
]
},
{
"cell_type": "markdown",
"id": "cell-11",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 2 - Système de craft (35 min)\n",
"\n",
"### 2.1 Vérifier si un craft est possible (5 pts)\n",
"\n",
"Écrivez une fonction `peut_crafter(inv, recette)` qui renvoie `True` si l'inventaire contient tous les ingrédients nécessaires pour la recette, `False` sinon.\n",
"\n",
"*Note : `recette` est un dictionnaire `{ingredient: quantite_necessaire}`*"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-12",
"metadata": {},
"outputs": [],
"source": [
"def peut_crafter(inv, recette):\n",
" for ingredient, quantite_necessaire in recette.items():\n",
" quantite_disponible = inv.get(ingredient, 0)\n",
" \n",
" # Verifier si on a assez\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return True\n",
"\n",
"# Tests\n",
"print(\"Peut crafter planche ?\", peut_crafter(inventaire, recettes[\"planche\"]))\n",
"print(\"Peut crafter pioche_diamant ?\", peut_crafter(inventaire, recettes[\"pioche_diamant\"]))"
]
},
{
"cell_type": "markdown",
"id": "cell-13",
"metadata": {},
"source": [
"### 2.2 Effectuer un craft (6 pts)\n",
"\n",
"Écrivez une fonction `crafter(inv, nom_item, recettes, quantites_produites)` qui :\n",
"1. Vérifie si le craft est possible\n",
"2. Si oui, retire les ingrédients et ajoute le résultat\n",
"3. Renvoie `True` si le craft a réussi, `False` sinon\n",
"\n",
"*Note : utilisez `quantites_produites.get(nom_item, 1)` pour obtenir la quantité produite (1 par défaut)*"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-14",
"metadata": {},
"outputs": [],
"source": [
"def crafter(inv, nom_item, recettes, quantites_produites):\n",
" # Verifier que la recette existe\n",
" if nom_item not in recettes:\n",
" print(\"Recette inconnue :\", nom_item)\n",
" return False\n",
" \n",
" recette = recettes[nom_item]\n",
" \n",
" # Verifier si le craft est possible\n",
" if not peut_crafter(inv, recette):\n",
" print(\"Ingredients insuffisants pour\", nom_item)\n",
" return False\n",
" \n",
" # Retirer les ingredients\n",
" for ingredient, quantite in recette.items():\n",
" retirer_item(inv, ingredient, quantite)\n",
" \n",
" # Ajouter le resultat\n",
" quantite_produite = quantites_produites.get(nom_item, 1)\n",
" # Votre code ici\n",
" pass\n",
"\n",
"# Test\n",
"test_inv = {\"bois\": 10, \"charbon\": 5}\n",
"print(\"Inventaire avant :\", test_inv)\n",
"\n",
"crafter(test_inv, \"planche\", recettes, quantites_produites)\n",
"print(\"Apres craft de planches :\", test_inv)\n",
"\n",
"crafter(test_inv, \"baton\", recettes, quantites_produites)\n",
"print(\"Apres craft de batons :\", test_inv)\n",
"\n",
"crafter(test_inv, \"torche\", recettes, quantites_produites)\n",
"print(\"Apres craft de torches :\", test_inv)"
]
},
{
"cell_type": "markdown",
"id": "cell-15",
"metadata": {},
"source": [
"### 2.3 Lister les crafts possibles (6 pts)\n",
"\n",
"Écrivez une fonction `lister_crafts_possibles(inv, recettes)` qui renvoie la **liste des noms** de tous les items qu'il est possible de crafter avec l'inventaire actuel."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-16",
"metadata": {},
"outputs": [],
"source": [
"def lister_crafts_possibles(inv, recettes):\n",
" possibles = []\n",
" \n",
" for nom_item, recette in recettes.items():\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return possibles\n",
"\n",
"# Test\n",
"print(\"Crafts possibles :\")\n",
"print(lister_crafts_possibles(inventaire, recettes))"
]
},
{
"cell_type": "markdown",
"id": "cell-17",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 3 - Bonus (20 min)\n",
"\n",
"### 3.1 Nombre maximum de crafts (5 pts)\n",
"\n",
"Écrivez une fonction `nb_max_craft(inv, recette)` qui renvoie le nombre maximum de fois qu'on peut effectuer un craft avec l'inventaire actuel.\n",
"\n",
"*Aide : pour chaque ingrédient, calculez `quantite_disponible // quantite_necessaire`, puis prenez le minimum*"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-18",
"metadata": {},
"outputs": [],
"source": [
"def nb_max_craft(inv, recette):\n",
" if not peut_crafter(inv, recette):\n",
" return 0\n",
" \n",
" ratios = []\n",
" \n",
" for ingredient, quantite_necessaire in recette.items():\n",
" quantite_disponible = inv.get(ingredient, 0)\n",
" # Calculer combien de crafts possibles avec cet ingredient\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return min(ratios)\n",
"\n",
"# Tests\n",
"print(\"Nb max de planches :\", nb_max_craft(inventaire, recettes[\"planche\"]))\n",
"print(\"Nb max de torches :\", nb_max_craft(inventaire, recettes[\"torche\"]))\n",
"print(\"Nb max de pioche_diamant :\", nb_max_craft(inventaire, recettes[\"pioche_diamant\"]))"
]
},
{
"cell_type": "markdown",
"id": "cell-19",
"metadata": {},
"source": [
"### 3.2 Crafts avec compteur (5 pts)\n",
"\n",
"Écrivez une fonction `crafts_avec_compteur(inv, recettes)` qui renvoie un **dictionnaire** `{nom_item: nombre_max}` pour tous les items qu'on peut crafter au moins une fois."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-20",
"metadata": {},
"outputs": [],
"source": [
"def crafts_avec_compteur(inv, recettes):\n",
" resultat = {}\n",
" \n",
" for nom_item, recette in recettes.items():\n",
" nb = nb_max_craft(inv, recette)\n",
" # Ajouter au resultat si nb > 0\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return resultat\n",
"\n",
"# Test\n",
"print(\"Crafts disponibles :\")\n",
"for item, nb in crafts_avec_compteur(inventaire, recettes).items():\n",
" print(\" \", item, \":\", nb, \"x\")"
]
},
{
"cell_type": "markdown",
"id": "cell-21",
"metadata": {},
"source": [
"### 3.3 Item le plus rentable (4 pts)\n",
"\n",
"Écrivez une fonction `item_plus_rentable(inv, recettes, valeurs)` qui renvoie le nom de l'item craftable qui a la meilleure valeur de revente parmi ceux qu'on peut crafter."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-22",
"metadata": {},
"outputs": [],
"source": [
"def item_plus_rentable(inv, recettes, valeurs):\n",
" possibles = lister_crafts_possibles(inv, recettes)\n",
" \n",
" if len(possibles) == 0:\n",
" return None\n",
" \n",
" meilleur = possibles[0]\n",
" meilleure_valeur = valeurs.get(meilleur, 0)\n",
" \n",
" for item in possibles:\n",
" valeur = valeurs.get(item, 0)\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return meilleur\n",
"\n",
"# Test\n",
"print(\"Item le plus rentable a crafter :\", item_plus_rentable(inventaire, recettes, valeurs))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.9.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -1,133 +0,0 @@
# Aide - TP02 Minecraft
## Rappels utiles
### Verifier si une cle existe dans un dictionnaire
```python
inventaire = {"bois": 64, "pierre": 32}
if "fer" in inventaire:
print("Vous avez du fer")
else:
print("Pas de fer")
# Ou avec get (renvoie 0 si absent)
quantite = inventaire.get("fer", 0)
```
### Modifier un dictionnaire
```python
# Ajouter ou modifier
inventaire["fer"] = 10
# Supprimer
del inventaire["fer"]
# Ajouter a une valeur existante
inventaire["bois"] = inventaire.get("bois", 0) + 5
```
### Trier un dictionnaire par valeur
```python
# Trier par valeur decroissante
items_tries = sorted(inventaire.items(), key=lambda x: x[1], reverse=True)
# Resultat : [("bois", 64), ("pierre", 32)]
```
---
## Exercice 1
### 1.1 - Affichage inventaire
- `sorted(inv.items(), key=lambda x: x[1], reverse=True)` pour trier par quantite
- Utilisez print() avec des virgules pour afficher
```python
for item, quantite in inventaire.items():
print(item, ":", quantite)
```
### 1.2 - Operations
- Pour ajouter : `inv[item] = inv.get(item, 0) + quantite`
- Pour retirer, **verifiez d'abord** que la quantite est suffisante
- Ne modifiez l'inventaire que si l'operation est possible
### 1.3 - Valeur
```python
total = 0
for item, qte in inv.items():
if item in valeurs:
total = total + qte * valeurs[item]
```
---
## Exercice 2
### 2.1 - Verifier craft possible
```python
def peut_crafter(inv, recette):
for ingredient, qte_necessaire in recette.items():
if inv.get(ingredient, 0) < qte_necessaire:
return False
return True
```
### 2.2 - Effectuer un craft
1. Verifiez d'abord avec `peut_crafter`
2. Si possible, retirez les ingredients
3. Ajoutez le resultat (attention a `quantites_produites`)
```python
qte_produite = quantites.get(nom_item, 1) # Par defaut 1
```
### 2.3 - Crafts disponibles
- Pour chaque recette, calculez combien de fois on peut la faire
- Le nombre max = minimum des ratios `inv[ingredient] // qte_necessaire`
```python
def nb_max_craft(inv, recette):
ratios = []
for ing, qte in recette.items():
if inv.get(ing, 0) < qte:
return 0
ratios.append(inv[ing] // qte)
return min(ratios)
```
---
## Exercice 3 (Bonus)
### 3.1 - Chaine de craft (recursivite)
```python
def ingredients_totaux(nom_item, recettes, quantite):
if nom_item not in recettes:
# C'est une matiere premiere
return {nom_item: quantite}
resultat = {}
for ingredient, qte in recettes[nom_item].items():
sous_ingredients = ingredients_totaux(ingredient, recettes, qte * quantite)
for ing, q in sous_ingredients.items():
resultat[ing] = resultat.get(ing, 0) + q
return resultat
```
### 3.2 - Meilleur equipement
- Definissez les tiers : `tiers = {"diamant": 4, "fer": 3, "pierre": 2, "bois": 1}`
- Pour chaque type (pioche, epee, armure), testez du meilleur au moins bon
- Utilisez `peut_crafter` pour verifier
### 3.3 - Liste de courses
1. Calculez les ingredients totaux pour chaque objectif
2. Soustrayez ce qui est deja dans l'inventaire
3. Ne gardez que les quantites positives (ce qui manque)
---
## Pieges a eviter
1. **Quantites produites** : un craft de planches donne 4 planches, pas 1 !
2. **Modification de dictionnaire** : creez une copie si necessaire avec `inv.copy()`
3. **Division entiere** : utilisez `//` pour obtenir un entier
4. **Recette inexistante** : verifiez que `nom_item in recettes`

View File

@@ -1,509 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "cell-0",
"metadata": {},
"source": [
"# TP Évaluation - Analyse de réseau social Instagram\n",
"\n",
"**Durée : 1h30**\n",
"\n",
"**Nom :** \n",
"\n",
"**Prénom :**\n",
"\n",
"---\n",
"\n",
"Dans ce TP, vous allez analyser un mini réseau social inspiré d'Instagram.\n",
"\n",
"**Compétences évaluées :**\n",
"- Manipulation de dictionnaires imbriqués\n",
"- Parcours de structures complexes\n",
"- Algorithmes de recherche et filtrage"
]
},
{
"cell_type": "markdown",
"id": "cell-1",
"metadata": {},
"source": [
"## Données initiales\n",
"\n",
"**Exécutez cette cellule avant de commencer.**"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-2",
"metadata": {},
"outputs": [],
"source": [
"# Base de données des utilisateurs\n",
"# Structure : {username: {infos du profil}}\n",
"utilisateurs = {\n",
" \"@music_lover\": {\n",
" \"nom\": \"Emma Martin\",\n",
" \"bio\": \"Fan de musique\",\n",
" \"verifie\": False,\n",
" \"followers\": [\"@tech_geek\", \"@foodie_paris\", \"@travel_adventures\"],\n",
" \"following\": [\"@tech_geek\", \"@fashion_style\"],\n",
" \"posts\": [\n",
" {\"id\": 1, \"type\": \"photo\", \"likes\": 234, \"commentaires\": 12},\n",
" {\"id\": 2, \"type\": \"reel\", \"likes\": 1520, \"commentaires\": 89}\n",
" ]\n",
" },\n",
" \"@tech_geek\": {\n",
" \"nom\": \"Lucas Bernard\",\n",
" \"bio\": \"Developpeur Python\",\n",
" \"verifie\": True,\n",
" \"followers\": [\"@music_lover\", \"@foodie_paris\", \"@fashion_style\", \"@travel_adventures\"],\n",
" \"following\": [\"@music_lover\", \"@foodie_paris\"],\n",
" \"posts\": [\n",
" {\"id\": 3, \"type\": \"photo\", \"likes\": 567, \"commentaires\": 34},\n",
" {\"id\": 4, \"type\": \"photo\", \"likes\": 892, \"commentaires\": 67},\n",
" {\"id\": 5, \"type\": \"reel\", \"likes\": 3420, \"commentaires\": 156}\n",
" ]\n",
" },\n",
" \"@foodie_paris\": {\n",
" \"nom\": \"Sophie Dubois\",\n",
" \"bio\": \"Food blogger Paris\",\n",
" \"verifie\": True,\n",
" \"followers\": [\"@tech_geek\", \"@fashion_style\"],\n",
" \"following\": [\"@music_lover\", \"@tech_geek\", \"@fashion_style\", \"@travel_adventures\"],\n",
" \"posts\": [\n",
" {\"id\": 6, \"type\": \"photo\", \"likes\": 1205, \"commentaires\": 78},\n",
" {\"id\": 7, \"type\": \"reel\", \"likes\": 4532, \"commentaires\": 234}\n",
" ]\n",
" },\n",
" \"@fashion_style\": {\n",
" \"nom\": \"Marie Laurent\",\n",
" \"bio\": \"Mode et tendances\",\n",
" \"verifie\": False,\n",
" \"followers\": [\"@music_lover\", \"@foodie_paris\"],\n",
" \"following\": [\"@tech_geek\", \"@foodie_paris\", \"@travel_adventures\"],\n",
" \"posts\": [\n",
" {\"id\": 8, \"type\": \"photo\", \"likes\": 2341, \"commentaires\": 123},\n",
" {\"id\": 9, \"type\": \"photo\", \"likes\": 1876, \"commentaires\": 98},\n",
" {\"id\": 10, \"type\": \"reel\", \"likes\": 5678, \"commentaires\": 321}\n",
" ]\n",
" },\n",
" \"@travel_adventures\": {\n",
" \"nom\": \"Pierre Moreau\",\n",
" \"bio\": \"Tour du monde\",\n",
" \"verifie\": True,\n",
" \"followers\": [\"@foodie_paris\", \"@fashion_style\"],\n",
" \"following\": [\"@music_lover\"],\n",
" \"posts\": [\n",
" {\"id\": 11, \"type\": \"photo\", \"likes\": 3456, \"commentaires\": 187},\n",
" {\"id\": 12, \"type\": \"reel\", \"likes\": 8901, \"commentaires\": 456}\n",
" ]\n",
" }\n",
"}"
]
},
{
"cell_type": "markdown",
"id": "cell-3",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 1 - Exploration des profils (25 min)\n",
"\n",
"### 1.1 Afficher un profil (4 pts)\n",
"\n",
"Écrivez une fonction `afficher_profil(username, utilisateurs)` qui affiche les informations d'un utilisateur.\n",
"\n",
"Exemple de sortie :\n",
"```\n",
"@tech_geek (verifie)\n",
"Nom : Lucas Bernard\n",
"Bio : Developpeur Python\n",
"Followers : 4 | Following : 2\n",
"Posts : 3\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-4",
"metadata": {},
"outputs": [],
"source": [
"def afficher_profil(username, utilisateurs):\n",
" # Verifier que l'utilisateur existe\n",
" if username not in utilisateurs:\n",
" print(\"Utilisateur non trouve\")\n",
" return\n",
" \n",
" profil = utilisateurs[username]\n",
" \n",
" # Afficher le badge verifie si necessaire\n",
" badge = \"\"\n",
" if profil[\"verifie\"]:\n",
" badge = \" (verifie)\"\n",
" \n",
" print(username + badge)\n",
" print(\"Nom :\", profil[\"nom\"])\n",
" # Completer l'affichage\n",
" # Votre code ici\n",
" pass\n",
"\n",
"# Test\n",
"afficher_profil(\"@tech_geek\", utilisateurs)"
]
},
{
"cell_type": "markdown",
"id": "cell-5",
"metadata": {},
"source": [
"### 1.2 Compter les likes et commentaires (4 pts)\n",
"\n",
"Écrivez une fonction `stats_engagement(username, utilisateurs)` qui renvoie un dictionnaire contenant :\n",
"- `\"total_likes\"` : somme des likes de tous les posts\n",
"- `\"total_commentaires\"` : somme des commentaires\n",
"- `\"nb_posts\"` : nombre de posts"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-6",
"metadata": {},
"outputs": [],
"source": [
"def stats_engagement(username, utilisateurs):\n",
" profil = utilisateurs[username]\n",
" posts = profil[\"posts\"]\n",
" \n",
" total_likes = 0\n",
" total_commentaires = 0\n",
" \n",
" for post in posts:\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return {\n",
" \"total_likes\": total_likes,\n",
" \"total_commentaires\": total_commentaires,\n",
" \"nb_posts\": len(posts)\n",
" }\n",
"\n",
"# Test\n",
"stats = stats_engagement(\"@tech_geek\", utilisateurs)\n",
"print(\"Stats de @tech_geek :\")\n",
"print(\" Likes :\", stats[\"total_likes\"])\n",
"print(\" Commentaires :\", stats[\"total_commentaires\"])\n",
"print(\" Posts :\", stats[\"nb_posts\"])"
]
},
{
"cell_type": "markdown",
"id": "cell-7",
"metadata": {},
"source": [
"### 1.3 Liste des comptes vérifiés (4 pts)\n",
"\n",
"Écrivez une fonction `comptes_verifies(utilisateurs)` qui renvoie la liste des usernames des comptes vérifiés."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-8",
"metadata": {},
"outputs": [],
"source": [
"def comptes_verifies(utilisateurs):\n",
" verifies = []\n",
" \n",
" for username, profil in utilisateurs.items():\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return verifies\n",
"\n",
"# Test\n",
"print(\"Comptes verifies :\", comptes_verifies(utilisateurs))"
]
},
{
"cell_type": "markdown",
"id": "cell-9",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 2 - Relations entre utilisateurs (35 min)\n",
"\n",
"### 2.1 Vérifier si deux utilisateurs sont amis mutuels (5 pts)\n",
"\n",
"Deux utilisateurs sont \"amis mutuels\" s'ils se suivent mutuellement (A suit B ET B suit A).\n",
"\n",
"Écrivez une fonction `sont_amis_mutuels(user1, user2, utilisateurs)` qui renvoie `True` ou `False`."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-10",
"metadata": {},
"outputs": [],
"source": [
"def sont_amis_mutuels(user1, user2, utilisateurs):\n",
" # Recuperer les listes de following\n",
" following_user1 = utilisateurs[user1][\"following\"]\n",
" following_user2 = utilisateurs[user2][\"following\"]\n",
" \n",
" # Verifier si user1 suit user2 ET user2 suit user1\n",
" # Votre code ici\n",
" pass\n",
"\n",
"# Tests\n",
"print(\"@music_lover et @tech_geek sont amis mutuels ?\", sont_amis_mutuels(\"@music_lover\", \"@tech_geek\", utilisateurs))\n",
"print(\"@foodie_paris et @travel_adventures sont amis mutuels ?\", sont_amis_mutuels(\"@foodie_paris\", \"@travel_adventures\", utilisateurs))"
]
},
{
"cell_type": "markdown",
"id": "cell-11",
"metadata": {},
"source": [
"### 2.2 Trouver tous les amis mutuels d'un utilisateur (6 pts)\n",
"\n",
"Écrivez une fonction `liste_amis_mutuels(username, utilisateurs)` qui renvoie la liste des usernames avec lesquels cet utilisateur est ami mutuel."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-12",
"metadata": {},
"outputs": [],
"source": [
"def liste_amis_mutuels(username, utilisateurs):\n",
" amis = []\n",
" \n",
" # Pour chaque utilisateur qu'on suit\n",
" for user_suivi in utilisateurs[username][\"following\"]:\n",
" # Verifier s'il nous suit aussi\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return amis\n",
"\n",
"# Test\n",
"print(\"Amis mutuels de @tech_geek :\", liste_amis_mutuels(\"@tech_geek\", utilisateurs))"
]
},
{
"cell_type": "markdown",
"id": "cell-13",
"metadata": {},
"source": [
"### 2.3 Classement par nombre de followers (6 pts)\n",
"\n",
"Écrivez une fonction `classement_followers(utilisateurs)` qui renvoie une liste de tuples `(username, nb_followers)` triée par nombre de followers décroissant.\n",
"\n",
"*Aide : utilisez `sorted(liste, key=lambda x: x[1], reverse=True)`*"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-14",
"metadata": {},
"outputs": [],
"source": [
"def classement_followers(utilisateurs):\n",
" classement = []\n",
" \n",
" for username, profil in utilisateurs.items():\n",
" nb_followers = len(profil[\"followers\"])\n",
" # Ajouter le tuple (username, nb_followers)\n",
" # Votre code ici\n",
" pass\n",
" \n",
" # Trier par nb_followers decroissant\n",
" classement = sorted(classement, key=lambda x: x[1], reverse=True)\n",
" return classement\n",
"\n",
"# Test\n",
"print(\"Classement par followers :\")\n",
"for username, nb in classement_followers(utilisateurs):\n",
" print(\" \", username, \":\", nb, \"followers\")"
]
},
{
"cell_type": "markdown",
"id": "cell-15",
"metadata": {},
"source": [
"### 2.4 Suggestions d'amis (6 pts)\n",
"\n",
"Écrivez une fonction `suggestions_amis(username, utilisateurs)` qui suggère des comptes à suivre.\n",
"\n",
"Une suggestion est un compte que nos amis suivent mais que nous ne suivons pas encore (et qui n'est pas nous-même)."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-16",
"metadata": {},
"outputs": [],
"source": [
"def suggestions_amis(username, utilisateurs):\n",
" suggestions = []\n",
" mes_suivis = utilisateurs[username][\"following\"]\n",
" \n",
" # Pour chaque personne que je suis\n",
" for ami in mes_suivis:\n",
" # Regarder qui cet ami suit\n",
" for suggestion in utilisateurs[ami][\"following\"]:\n",
" # Verifier que ce n'est pas moi et que je ne le suis pas deja\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return suggestions\n",
"\n",
"# Test\n",
"print(\"Suggestions pour @music_lover :\", suggestions_amis(\"@music_lover\", utilisateurs))"
]
},
{
"cell_type": "markdown",
"id": "cell-17",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 3 - Bonus (20 min)\n",
"\n",
"### 3.1 Posts populaires (5 pts)\n",
"\n",
"Écrivez une fonction `posts_populaires(utilisateurs, seuil_likes)` qui renvoie la liste de tous les posts ayant plus de `seuil_likes` likes.\n",
"\n",
"Chaque élément de la liste est un dictionnaire avec `\"auteur\"`, `\"post_id\"` et `\"likes\"`."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-18",
"metadata": {},
"outputs": [],
"source": [
"def posts_populaires(utilisateurs, seuil_likes):\n",
" populaires = []\n",
" \n",
" for username, profil in utilisateurs.items():\n",
" for post in profil[\"posts\"]:\n",
" if post[\"likes\"] > seuil_likes:\n",
" # Ajouter le post a la liste\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return populaires\n",
"\n",
"# Test\n",
"print(\"Posts avec plus de 3000 likes :\")\n",
"for p in posts_populaires(utilisateurs, 3000):\n",
" print(\" \", p[\"auteur\"], \"- post\", p[\"post_id\"], \":\", p[\"likes\"], \"likes\")"
]
},
{
"cell_type": "markdown",
"id": "cell-19",
"metadata": {},
"source": [
"### 3.2 Meilleur taux d'engagement (5 pts)\n",
"\n",
"Le taux d'engagement = (total_likes + total_commentaires) / nb_followers\n",
"\n",
"Écrivez une fonction `meilleur_engagement(utilisateurs)` qui renvoie le username ayant le meilleur taux d'engagement."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-20",
"metadata": {},
"outputs": [],
"source": [
"def meilleur_engagement(utilisateurs):\n",
" meilleur_user = None\n",
" meilleur_taux = 0\n",
" \n",
" for username, profil in utilisateurs.items():\n",
" # Calculer les stats\n",
" stats = stats_engagement(username, utilisateurs)\n",
" nb_followers = len(profil[\"followers\"])\n",
" \n",
" # Eviter division par zero\n",
" if nb_followers == 0:\n",
" continue\n",
" \n",
" taux = (stats[\"total_likes\"] + stats[\"total_commentaires\"]) / nb_followers\n",
" \n",
" # Comparer avec le meilleur\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return meilleur_user\n",
"\n",
"# Test\n",
"print(\"Meilleur taux d'engagement :\", meilleur_engagement(utilisateurs))"
]
},
{
"cell_type": "markdown",
"id": "cell-21",
"metadata": {},
"source": [
"### 3.3 Compter les reels (4 pts)\n",
"\n",
"Écrivez une fonction `compter_par_type(utilisateurs)` qui renvoie un dictionnaire avec le nombre total de posts de chaque type (\"photo\" et \"reel\")."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-22",
"metadata": {},
"outputs": [],
"source": [
"def compter_par_type(utilisateurs):\n",
" compteur = {\"photo\": 0, \"reel\": 0}\n",
" \n",
" for username, profil in utilisateurs.items():\n",
" for post in profil[\"posts\"]:\n",
" type_post = post[\"type\"]\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return compteur\n",
"\n",
"# Test\n",
"print(\"Nombre de posts par type :\", compter_par_type(utilisateurs))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.9.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -1,181 +0,0 @@
# Aide - TP03 Instagram
## Rappels utiles
### Acceder a des structures imbriquees
```python
utilisateurs = {
"@music_lover": {
"nom": "Emma Martin",
"followers": ["@tech_geek", "@foodie_paris"],
"posts": [
{"id": 1, "likes": 234}
]
}
}
# Acceder au nom
nom = utilisateurs["@music_lover"]["nom"]
# Acceder au premier post
premier_post = utilisateurs["@music_lover"]["posts"][0]
# Nombre de followers
nb_followers = len(utilisateurs["@music_lover"]["followers"])
```
### Parcourir un dictionnaire de dictionnaires
```python
for username, profil in utilisateurs.items():
print(username, ":", profil["nom"])
```
---
## Exercice 1
### 1.1 - Affichage profil
- Verifiez `profil["verifie"]` pour le badge
- `len(profil["posts"])` pour le nombre de posts
- `len(profil["followers"])` et `len(profil["following"])`
```python
def afficher_profil(username, users):
profil = users[username]
print(username, "-", profil["nom"])
print("Followers:", len(profil["followers"]))
print("Posts:", len(profil["posts"]))
```
### 1.2 - Statistiques d'engagement
```python
total_likes = 0
for post in profil["posts"]:
total_likes = total_likes + post["likes"]
total_commentaires = 0
for post in profil["posts"]:
total_commentaires = total_commentaires + post["commentaires"]
nb_followers = len(profil["followers"])
# Attention a la division par zero !
if nb_followers > 0:
taux = (total_likes + total_commentaires) / nb_followers
else:
taux = 0
```
### 1.3 - Relations mutuelles
```python
def sont_amis_mutuels(user1, user2, users):
# user1 suit user2 ET user2 suit user1
suit_user2 = user2 in users[user1]["following"]
suit_user1 = user1 in users[user2]["following"]
return suit_user2 and suit_user1
```
---
## Exercice 2
### 2.1 - Top influenceurs
```python
# Creer liste de tuples (username, nb_followers)
classement = []
for user, profil in users.items():
classement.append((user, len(profil["followers"])))
# Trier par nb_followers decroissant
classement = sorted(classement, key=lambda x: x[1], reverse=True)
# Renvoyer les n premiers
return classement[:n]
```
### 2.2 - Posts viraux
1. Parcourez tous les utilisateurs et leurs posts
2. Filtrez les posts avec likes > 2000
3. Creez un dictionnaire avec les infos demandees
4. Triez par likes decroissant
```python
viraux = []
for username, profil in users.items():
for post in profil["posts"]:
if post["likes"] > 2000:
viraux.append({
"auteur": username,
"post_id": post["id"],
"likes": post["likes"]
})
```
### 2.3 - Suggestions
1. Recuperez qui l'utilisateur suit
2. Pour chacun, recuperez qui ILS suivent
3. Comptez les occurrences (dictionnaire)
4. Excluez l'utilisateur et ceux deja suivis
```python
suggestions = {}
for ami in users[username]["following"]:
for suggestion in users[ami]["following"]:
if suggestion != username and suggestion not in users[username]["following"]:
if suggestion not in suggestions:
suggestions[suggestion] = 0
suggestions[suggestion] = suggestions[suggestion] + 1
```
---
## Exercice 3 (Bonus)
### 3.1 - Comptes verifies
```python
verifies = []
for user, profil in users.items():
if profil["verifie"]:
verifies.append(user)
```
### 3.2 - Total likes par user
```python
likes_par_user = {}
for user, profil in users.items():
total = 0
for post in profil["posts"]:
total = total + post["likes"]
likes_par_user[user] = total
```
### 3.3 - Feed personnalise
```python
def generer_feed(username, users, n):
posts_feed = []
suivis = users[username]["following"]
for auteur in suivis:
est_ami_mutuel = username in users[auteur]["following"]
for post in users[auteur]["posts"]:
score = post["likes"] + post["commentaires"] * 3
if post["type"] == "reel":
score = score * 1.5
if est_ami_mutuel:
score = score * 1.2
posts_feed.append({"auteur": auteur, "post": post, "score": score})
posts_feed = sorted(posts_feed, key=lambda x: x["score"], reverse=True)
return posts_feed[:n]
```
---
## Pieges a eviter
1. **KeyError** : utilisez `users.get(username)` ou verifiez `if username in users`
2. **Doublons** : verifiez avec `if element not in liste` avant d'ajouter
3. **Ami mutuel vs follower** : un follower vous suit, un ami mutuel = vous vous suivez mutuellement
4. **Division par zero** : verifiez `nb_followers > 0` avant de diviser

View File

@@ -1,500 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "cell-0",
"metadata": {},
"source": [
"# TP Évaluation - Catalogue Netflix\n",
"\n",
"**Durée : 1h30**\n",
"\n",
"**Nom :** \n",
"\n",
"**Prénom :**\n",
"\n",
"---\n",
"\n",
"Dans ce TP, vous allez manipuler un catalogue de films et séries inspiré de Netflix.\n",
"\n",
"**Compétences évaluées :**\n",
"- Manipulation de listes de dictionnaires\n",
"- Filtrage et tri de données\n",
"- Algorithmes de recherche"
]
},
{
"cell_type": "markdown",
"id": "cell-1",
"metadata": {},
"source": [
"## Données initiales\n",
"\n",
"**Exécutez cette cellule avant de commencer.**"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-2",
"metadata": {},
"outputs": [],
"source": [
"# Catalogue de contenus\n",
"# type: \"film\" ou \"serie\"\n",
"# duree: en minutes (pour les films)\n",
"# saisons et duree_moy: pour les series (duree moyenne par episode)\n",
"catalogue = [\n",
" {\"titre\": \"Stranger Things\", \"type\": \"serie\", \"genre\": [\"SF\", \"Horreur\"], \"annee\": 2016, \"note\": 8.7, \"saisons\": 4, \"duree_moy\": 50},\n",
" {\"titre\": \"Breaking Bad\", \"type\": \"serie\", \"genre\": [\"Drame\", \"Thriller\"], \"annee\": 2008, \"note\": 9.5, \"saisons\": 5, \"duree_moy\": 47},\n",
" {\"titre\": \"The Crown\", \"type\": \"serie\", \"genre\": [\"Drame\", \"Historique\"], \"annee\": 2016, \"note\": 8.6, \"saisons\": 6, \"duree_moy\": 58},\n",
" {\"titre\": \"Squid Game\", \"type\": \"serie\", \"genre\": [\"Thriller\", \"Drame\"], \"annee\": 2021, \"note\": 8.0, \"saisons\": 1, \"duree_moy\": 55},\n",
" {\"titre\": \"Wednesday\", \"type\": \"serie\", \"genre\": [\"Comedie\", \"Fantastique\"], \"annee\": 2022, \"note\": 8.1, \"saisons\": 1, \"duree_moy\": 45},\n",
" {\"titre\": \"Inception\", \"type\": \"film\", \"genre\": [\"SF\", \"Action\"], \"annee\": 2010, \"note\": 8.8, \"duree\": 148},\n",
" {\"titre\": \"The Dark Knight\", \"type\": \"film\", \"genre\": [\"Action\", \"Drame\"], \"annee\": 2008, \"note\": 9.0, \"duree\": 152},\n",
" {\"titre\": \"Pulp Fiction\", \"type\": \"film\", \"genre\": [\"Drame\", \"Thriller\"], \"annee\": 1994, \"note\": 8.9, \"duree\": 154},\n",
" {\"titre\": \"Interstellar\", \"type\": \"film\", \"genre\": [\"SF\", \"Drame\"], \"annee\": 2014, \"note\": 8.6, \"duree\": 169},\n",
" {\"titre\": \"The Matrix\", \"type\": \"film\", \"genre\": [\"SF\", \"Action\"], \"annee\": 1999, \"note\": 8.7, \"duree\": 136},\n",
" {\"titre\": \"Parasite\", \"type\": \"film\", \"genre\": [\"Thriller\", \"Comedie\"], \"annee\": 2019, \"note\": 8.5, \"duree\": 132},\n",
" {\"titre\": \"Don't Look Up\", \"type\": \"film\", \"genre\": [\"Comedie\", \"SF\"], \"annee\": 2021, \"note\": 7.2, \"duree\": 138}\n",
"]\n",
"\n",
"# Historique de visionnage\n",
"historique = [\n",
" {\"titre\": \"Stranger Things\", \"episodes_vus\": 34, \"note_perso\": 9},\n",
" {\"titre\": \"Inception\", \"note_perso\": 10},\n",
" {\"titre\": \"The Matrix\", \"note_perso\": 8},\n",
" {\"titre\": \"Wednesday\", \"episodes_vus\": 8, \"note_perso\": 7}\n",
"]\n",
"\n",
"# Ma liste (watchlist)\n",
"ma_liste = [\"Breaking Bad\", \"Interstellar\", \"Parasite\"]"
]
},
{
"cell_type": "markdown",
"id": "cell-3",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 1 - Exploration du catalogue (25 min)\n",
"\n",
"### 1.1 Afficher un contenu (4 pts)\n",
"\n",
"Écrivez une fonction `afficher_contenu(contenu)` qui affiche les informations d'un film ou d'une série.\n",
"\n",
"Pour un film : `Inception (2010) - Film | 2h28 | Note: 8.8`\n",
"\n",
"Pour une série : `Stranger Things (2016) - Serie | 4 saisons | Note: 8.7`\n",
"\n",
"*Aide : pour convertir les minutes en heures, utilisez `duree // 60` et `duree % 60`*"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-4",
"metadata": {},
"outputs": [],
"source": [
"def afficher_contenu(contenu):\n",
" titre = contenu[\"titre\"]\n",
" annee = contenu[\"annee\"]\n",
" note = contenu[\"note\"]\n",
" \n",
" if contenu[\"type\"] == \"film\":\n",
" duree = contenu[\"duree\"]\n",
" heures = duree // 60\n",
" minutes = duree % 60\n",
" # Afficher les infos du film\n",
" # Votre code ici\n",
" pass\n",
" else:\n",
" saisons = contenu[\"saisons\"]\n",
" # Afficher les infos de la serie\n",
" # Votre code ici\n",
" pass\n",
"\n",
"# Tests\n",
"afficher_contenu(catalogue[0]) # Serie\n",
"afficher_contenu(catalogue[5]) # Film"
]
},
{
"cell_type": "markdown",
"id": "cell-5",
"metadata": {},
"source": [
"### 1.2 Compter films et séries (4 pts)\n",
"\n",
"Écrivez une fonction `compter_par_type(catalogue)` qui renvoie un dictionnaire avec le nombre de films et de séries."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-6",
"metadata": {},
"outputs": [],
"source": [
"def compter_par_type(catalogue):\n",
" compteur = {\"film\": 0, \"serie\": 0}\n",
" \n",
" for contenu in catalogue:\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return compteur\n",
"\n",
"# Test\n",
"print(\"Contenu du catalogue :\", compter_par_type(catalogue))"
]
},
{
"cell_type": "markdown",
"id": "cell-7",
"metadata": {},
"source": [
"### 1.3 Liste des genres (4 pts)\n",
"\n",
"Écrivez une fonction `tous_les_genres(catalogue)` qui renvoie la liste de tous les genres présents dans le catalogue, sans doublons, triée par ordre alphabétique."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-8",
"metadata": {},
"outputs": [],
"source": [
"def tous_les_genres(catalogue):\n",
" genres = []\n",
" \n",
" for contenu in catalogue:\n",
" for genre in contenu[\"genre\"]:\n",
" if genre not in genres:\n",
" # Votre code ici\n",
" pass\n",
" \n",
" genres.sort()\n",
" return genres\n",
"\n",
"# Test\n",
"print(\"Genres disponibles :\", tous_les_genres(catalogue))"
]
},
{
"cell_type": "markdown",
"id": "cell-9",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 2 - Recherche et filtrage (35 min)\n",
"\n",
"### 2.1 Rechercher par genre (5 pts)\n",
"\n",
"Écrivez une fonction `rechercher_par_genre(catalogue, genre)` qui renvoie la liste des contenus ayant ce genre."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-10",
"metadata": {},
"outputs": [],
"source": [
"def rechercher_par_genre(catalogue, genre):\n",
" resultats = []\n",
" \n",
" for contenu in catalogue:\n",
" if genre in contenu[\"genre\"]:\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return resultats\n",
"\n",
"# Test\n",
"print(\"Contenus SF :\")\n",
"for c in rechercher_par_genre(catalogue, \"SF\"):\n",
" afficher_contenu(c)"
]
},
{
"cell_type": "markdown",
"id": "cell-11",
"metadata": {},
"source": [
"### 2.2 Filtrer par note minimum (5 pts)\n",
"\n",
"Écrivez une fonction `filtrer_par_note(catalogue, note_min)` qui renvoie la liste des contenus ayant une note supérieure ou égale à `note_min`."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-12",
"metadata": {},
"outputs": [],
"source": [
"def filtrer_par_note(catalogue, note_min):\n",
" resultats = []\n",
" \n",
" for contenu in catalogue:\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return resultats\n",
"\n",
"# Test\n",
"print(\"Contenus avec note >= 8.5 :\")\n",
"for c in filtrer_par_note(catalogue, 8.5):\n",
" afficher_contenu(c)"
]
},
{
"cell_type": "markdown",
"id": "cell-13",
"metadata": {},
"source": [
"### 2.3 Trier par note (6 pts)\n",
"\n",
"Écrivez une fonction `trier_par_note(catalogue)` qui renvoie une nouvelle liste triée par note décroissante.\n",
"\n",
"*Aide : utilisez `sorted(liste, key=lambda x: x[\"note\"], reverse=True)`*"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-14",
"metadata": {},
"outputs": [],
"source": [
"def trier_par_note(catalogue):\n",
" # Votre code ici\n",
" pass\n",
"\n",
"# Test\n",
"print(\"Top 5 par note :\")\n",
"for c in trier_par_note(catalogue)[:5]:\n",
" afficher_contenu(c)"
]
},
{
"cell_type": "markdown",
"id": "cell-15",
"metadata": {},
"source": [
"### 2.4 Recherche combinée (6 pts)\n",
"\n",
"Écrivez une fonction `recherche_avancee(catalogue, type_contenu, genre, note_min)` qui filtre selon plusieurs critères.\n",
"\n",
"- `type_contenu` : \"film\", \"serie\" ou None (tous)\n",
"- `genre` : un genre ou None (tous)\n",
"- `note_min` : note minimum ou None (pas de filtre)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-16",
"metadata": {},
"outputs": [],
"source": [
"def recherche_avancee(catalogue, type_contenu, genre, note_min):\n",
" resultats = []\n",
" \n",
" for contenu in catalogue:\n",
" # Verifier le type (si specifie)\n",
" if type_contenu != None and contenu[\"type\"] != type_contenu:\n",
" continue\n",
" \n",
" # Verifier le genre (si specifie)\n",
" if genre != None and genre not in contenu[\"genre\"]:\n",
" continue\n",
" \n",
" # Verifier la note (si specifiee)\n",
" # Votre code ici\n",
" \n",
" resultats.append(contenu)\n",
" \n",
" return resultats\n",
"\n",
"# Test\n",
"print(\"Films SF avec note >= 8.5 :\")\n",
"for c in recherche_avancee(catalogue, \"film\", \"SF\", 8.5):\n",
" afficher_contenu(c)"
]
},
{
"cell_type": "markdown",
"id": "cell-17",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 3 - Bonus (20 min)\n",
"\n",
"### 3.1 Temps de visionnage (5 pts)\n",
"\n",
"Écrivez une fonction `temps_visionne(historique, catalogue)` qui calcule le temps total de visionnage en minutes.\n",
"\n",
"Pour un film : la durée complète.\n",
"Pour une série : `episodes_vus * duree_moy`"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-18",
"metadata": {},
"outputs": [],
"source": [
"def temps_visionne(historique, catalogue):\n",
" total_minutes = 0\n",
" \n",
" for h in historique:\n",
" # Trouver le contenu dans le catalogue\n",
" contenu = None\n",
" for c in catalogue:\n",
" if c[\"titre\"] == h[\"titre\"]:\n",
" contenu = c\n",
" break\n",
" \n",
" if contenu == None:\n",
" continue\n",
" \n",
" if contenu[\"type\"] == \"film\":\n",
" # Ajouter la duree du film\n",
" # Votre code ici\n",
" pass\n",
" else:\n",
" # Ajouter duree des episodes vus\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return total_minutes\n",
"\n",
"# Test\n",
"minutes = temps_visionne(historique, catalogue)\n",
"heures = minutes // 60\n",
"print(\"Temps total visionne :\", heures, \"h\", minutes % 60, \"min\")"
]
},
{
"cell_type": "markdown",
"id": "cell-19",
"metadata": {},
"source": [
"### 3.2 Recommandation simple (5 pts)\n",
"\n",
"Écrivez une fonction `recommander(historique, catalogue)` qui recommande un contenu basé sur les genres préférés de l'utilisateur.\n",
"\n",
"1. Trouvez les genres des contenus dans l'historique\n",
"2. Trouvez un contenu non vu qui a au moins un genre en commun\n",
"3. Renvoyez le contenu avec la meilleure note"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-20",
"metadata": {},
"outputs": [],
"source": [
"def recommander(historique, catalogue):\n",
" # Collecter les genres des contenus vus\n",
" genres_aimes = []\n",
" titres_vus = []\n",
" \n",
" for h in historique:\n",
" titres_vus.append(h[\"titre\"])\n",
" # Trouver le contenu pour recuperer ses genres\n",
" for c in catalogue:\n",
" if c[\"titre\"] == h[\"titre\"]:\n",
" for g in c[\"genre\"]:\n",
" if g not in genres_aimes:\n",
" genres_aimes.append(g)\n",
" \n",
" # Trouver le meilleur contenu non vu avec un genre en commun\n",
" meilleur = None\n",
" meilleure_note = 0\n",
" \n",
" for c in catalogue:\n",
" # Verifier que non vu\n",
" if c[\"titre\"] in titres_vus:\n",
" continue\n",
" \n",
" # Verifier qu'il a un genre en commun\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return meilleur\n",
"\n",
"# Test\n",
"reco = recommander(historique, catalogue)\n",
"if reco:\n",
" print(\"Recommandation :\")\n",
" afficher_contenu(reco)"
]
},
{
"cell_type": "markdown",
"id": "cell-21",
"metadata": {},
"source": [
"### 3.3 Note moyenne par genre (4 pts)\n",
"\n",
"Écrivez une fonction `note_moyenne_par_genre(catalogue)` qui renvoie un dictionnaire `{genre: note_moyenne}`."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-22",
"metadata": {},
"outputs": [],
"source": [
"def note_moyenne_par_genre(catalogue):\n",
" # Dictionnaire pour stocker somme et compteur par genre\n",
" sommes = {}\n",
" compteurs = {}\n",
" \n",
" for contenu in catalogue:\n",
" for genre in contenu[\"genre\"]:\n",
" if genre not in sommes:\n",
" sommes[genre] = 0\n",
" compteurs[genre] = 0\n",
" sommes[genre] = sommes[genre] + contenu[\"note\"]\n",
" compteurs[genre] = compteurs[genre] + 1\n",
" \n",
" # Calculer les moyennes\n",
" moyennes = {}\n",
" for genre in sommes:\n",
" moyennes[genre] = round(sommes[genre] / compteurs[genre], 1)\n",
" \n",
" return moyennes\n",
"\n",
"# Test\n",
"print(\"Note moyenne par genre :\")\n",
"for genre, note in note_moyenne_par_genre(catalogue).items():\n",
" print(\" \", genre, \":\", note)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.9.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -1,232 +0,0 @@
# Aide - TP04 Netflix
## Rappels utiles
### Differencier films et series
```python
contenu = catalogue[0]
if contenu["type"] == "serie":
print(contenu["saisons"], "saisons")
else:
print("Duree:", contenu["duree"], "min")
```
### Verifier si un element est dans une liste
```python
genres = ["SF", "Action"]
if "SF" in genres:
print("C'est de la science-fiction")
```
### Joindre une liste en chaine
```python
genres = ["SF", "Action", "Thriller"]
genres_str = ", ".join(genres) # "SF, Action, Thriller"
```
---
## Exercice 1
### 1.1 - Affichage formate
- Films : affichez la duree en heures:minutes (`duree // 60` et `duree % 60`)
- Series : affichez le nombre de saisons et la duree moyenne par episode
- Genres : `", ".join(contenu["genre"])` pour les separer par des virgules
```python
def afficher_contenu(contenu):
print(contenu["titre"], "(", contenu["annee"], ")")
print("Genres:", ", ".join(contenu["genre"]))
if contenu["type"] == "film":
heures = contenu["duree"] // 60
minutes = contenu["duree"] % 60
print("Duree:", heures, "h", minutes, "min")
else:
print("Saisons:", contenu["saisons"])
```
### 1.2 - Statistiques
```python
nb_films = 0
nb_series = 0
for c in catalogue:
if c["type"] == "film":
nb_films = nb_films + 1
else:
nb_series = nb_series + 1
```
Pour les genres uniques :
```python
tous_genres = []
for c in catalogue:
for g in c["genre"]:
if g not in tous_genres:
tous_genres.append(g)
genres_tries = sorted(tous_genres)
```
### 1.3 - Recherche par criteres
```python
def rechercher(catalogue, type_contenu, genre, note_min):
resultats = []
for c in catalogue:
# Verifier chaque critere
if type_contenu is not None and c["type"] != type_contenu:
continue
if genre is not None and genre not in c["genre"]:
continue
if note_min is not None and c["note"] < note_min:
continue
resultats.append(c)
return resultats
```
---
## Exercice 2
### 2.1 - Temps de visionnage
```python
def temps_visionne(hist, cat):
total_minutes = 0
for h in hist:
# Trouver le contenu dans le catalogue
contenu = None
for c in cat:
if c["titre"] == h["titre"]:
contenu = c
break
if contenu == None:
continue
if contenu["type"] == "serie":
total_minutes = total_minutes + h["episodes_vus"] * contenu["duree_moy"]
else:
total_minutes = total_minutes + contenu["duree"]
heures = total_minutes // 60
minutes = total_minutes % 60
return total_minutes, str(heures) + "h" + str(minutes)
```
### 2.2 - Profil preferences
- Comptez les genres ponderes par les notes utilisateur
- Utilisez un dictionnaire `{genre: score_total}`
- Triez par score decroissant
```python
scores_genres = {}
for h in historique:
# Trouver le contenu
for c in catalogue:
if c["titre"] == h["titre"]:
for genre in c["genre"]:
if genre not in scores_genres:
scores_genres[genre] = 0
scores_genres[genre] = scores_genres[genre] + h["note"]
break
```
### 2.3 - Gestion watchlist
```python
def trier_watchlist(wl, cat, critere):
# Creer une liste avec les infos completes
avec_infos = []
for titre in wl:
for c in cat:
if c["titre"] == titre:
avec_infos.append(c)
break
# Trier selon le critere
if critere == "note":
avec_infos = sorted(avec_infos, key=lambda x: x["note"], reverse=True)
elif critere == "annee":
avec_infos = sorted(avec_infos, key=lambda x: x["annee"], reverse=True)
# Renvoyer juste les titres
titres = []
for c in avec_infos:
titres.append(c["titre"])
return titres
```
---
## Exercice 3 (Bonus)
### 3.1 - Recommandations similaires
```python
def similarite(c1, c2):
score = 0
# Genres en commun
for g in c1["genre"]:
if g in c2["genre"]:
score = score + 2
# Meme type
if c1["type"] == c2["type"]:
score = score + 1
# Meme decennie
if c1["annee"] // 10 == c2["annee"] // 10:
score = score + 1
return score
```
### 3.2 - Recommandations personnalisees
1. Calculez le profil utilisateur (genres preferes, note moyenne)
2. Pour chaque contenu non vu, calculez un score
3. Triez par score decroissant
### 3.3 - Soiree cinema
C'est un probleme d'optimisation (type "sac a dos") :
```python
def soiree_cinema(cat, duree_max, genres_voulus):
# Filtrer les contenus valides
valides = []
for c in cat:
for g in c["genre"]:
if g in genres_voulus:
valides.append(c)
break
# Trier par note decroissante
valides = sorted(valides, key=lambda x: x["note"], reverse=True)
selection = []
duree_totale = 0
a_serie = False
for c in valides:
if c["type"] == "film":
duree_c = c["duree"]
else:
duree_c = c["duree_moy"] * 3
if c["type"] == "serie" and a_serie:
continue # Deja une serie
if duree_totale + duree_c <= duree_max:
selection.append(c)
duree_totale = duree_totale + duree_c
if c["type"] == "serie":
a_serie = True
return selection, duree_totale
```
---
## Pieges a eviter
1. **Films vs series** : les films ont `duree`, les series ont `duree_moy` et `saisons`
2. **Genre est une liste** : utilisez `in` pour verifier si un genre est present
3. **Contenu non trouve** : verifiez que le titre existe avant d'acceder a ses proprietes
4. **Tri stable** : si deux elements ont le meme score, leur ordre relatif est conserve

View File

@@ -1,527 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "cell-0",
"metadata": {},
"source": [
"# TP Évaluation - Gestion d'équipe de Football\n",
"\n",
"**Durée : 1h30**\n",
"\n",
"**Nom :** \n",
"\n",
"**Prénom :**\n",
"\n",
"---\n",
"\n",
"Dans ce TP, vous allez créer un système de gestion d'équipe de football.\n",
"\n",
"**Compétences évaluées :**\n",
"- Manipulation de tuples et listes\n",
"- Dictionnaires et structures imbriquées\n",
"- Algorithmes de sélection"
]
},
{
"cell_type": "markdown",
"id": "cell-1",
"metadata": {},
"source": [
"## Données initiales\n",
"\n",
"**Exécutez cette cellule avant de commencer.**"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-2",
"metadata": {},
"outputs": [],
"source": [
"# Effectif de l'equipe\n",
"# Chaque joueur est un tuple : (nom, poste, note_globale, stats)\n",
"# stats est un dictionnaire avec les caracteristiques\n",
"\n",
"effectif = [\n",
" (\"Mbappe\", \"ATT\", 91, {\"vitesse\": 97, \"tir\": 89, \"passe\": 80, \"dribble\": 92, \"defense\": 36, \"physique\": 78}),\n",
" (\"Griezmann\", \"ATT\", 87, {\"vitesse\": 80, \"tir\": 86, \"passe\": 84, \"dribble\": 88, \"defense\": 56, \"physique\": 72}),\n",
" (\"Dembele\", \"ATT\", 86, {\"vitesse\": 93, \"tir\": 78, \"passe\": 82, \"dribble\": 90, \"defense\": 32, \"physique\": 63}),\n",
" (\"Thuram\", \"ATT\", 84, {\"vitesse\": 86, \"tir\": 80, \"passe\": 72, \"dribble\": 82, \"defense\": 42, \"physique\": 84}),\n",
" (\"Tchouameni\", \"MIL\", 86, {\"vitesse\": 74, \"tir\": 72, \"passe\": 80, \"dribble\": 76, \"defense\": 82, \"physique\": 86}),\n",
" (\"Kante\", \"MIL\", 88, {\"vitesse\": 78, \"tir\": 66, \"passe\": 75, \"dribble\": 81, \"defense\": 87, \"physique\": 82}),\n",
" (\"Rabiot\", \"MIL\", 82, {\"vitesse\": 72, \"tir\": 75, \"passe\": 79, \"dribble\": 80, \"defense\": 76, \"physique\": 80}),\n",
" (\"Camavinga\", \"MIL\", 83, {\"vitesse\": 82, \"tir\": 64, \"passe\": 78, \"dribble\": 82, \"defense\": 76, \"physique\": 78}),\n",
" (\"Hernandez\", \"DEF\", 85, {\"vitesse\": 84, \"tir\": 65, \"passe\": 76, \"dribble\": 78, \"defense\": 82, \"physique\": 82}),\n",
" (\"Upamecano\", \"DEF\", 84, {\"vitesse\": 80, \"tir\": 48, \"passe\": 62, \"dribble\": 58, \"defense\": 86, \"physique\": 88}),\n",
" (\"Konate\", \"DEF\", 84, {\"vitesse\": 78, \"tir\": 42, \"passe\": 56, \"dribble\": 52, \"defense\": 87, \"physique\": 86}),\n",
" (\"Saliba\", \"DEF\", 86, {\"vitesse\": 76, \"tir\": 38, \"passe\": 65, \"dribble\": 60, \"defense\": 88, \"physique\": 84}),\n",
" (\"Maignan\", \"GK\", 87, {\"plongeon\": 88, \"reflexes\": 89, \"placement\": 84, \"jeu_pied\": 78}),\n",
" (\"Lloris\", \"GK\", 85, {\"plongeon\": 86, \"reflexes\": 87, \"placement\": 86, \"jeu_pied\": 72})\n",
"]\n",
"\n",
"# Formation 4-3-3 : nombre de joueurs par poste\n",
"formation = {\n",
" \"GK\": 1, # Gardien\n",
" \"DEF\": 4, # Defenseurs\n",
" \"MIL\": 3, # Milieux\n",
" \"ATT\": 3 # Attaquants\n",
"}\n",
"\n",
"# Historique des matchs : (adversaire, buts_pour, buts_contre, buteurs)\n",
"matchs = [\n",
" (\"Allemagne\", 2, 1, [\"Mbappe\", \"Griezmann\"]),\n",
" (\"Belgique\", 3, 0, [\"Mbappe\", \"Mbappe\", \"Dembele\"]),\n",
" (\"Espagne\", 1, 2, [\"Thuram\"]),\n",
" (\"Italie\", 2, 2, [\"Griezmann\", \"Mbappe\"]),\n",
" (\"Portugal\", 0, 1, []),\n",
" (\"Angleterre\", 3, 1, [\"Mbappe\", \"Griezmann\", \"Dembele\"])\n",
"]"
]
},
{
"cell_type": "markdown",
"id": "cell-3",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 1 - Gestion de l'effectif (25 min)\n",
"\n",
"### 1.1 Affichage des joueurs (4 pts)\n",
"\n",
"Écrivez une fonction `afficher_joueur(joueur)` qui affiche un joueur de manière formatée.\n",
"\n",
"Exemple pour un joueur de champ :\n",
"```\n",
"Mbappe (ATT) - Note: 91\n",
" VIT:97 | TIR:89 | PAS:80 | DRI:92\n",
"```\n",
"\n",
"Pour les gardiens (poste \"GK\"), afficher leurs stats spécifiques (plongeon, reflexes, etc.)."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-4",
"metadata": {},
"outputs": [],
"source": [
"def afficher_joueur(joueur):\n",
" # Extraire les infos du tuple\n",
" nom = joueur[0]\n",
" poste = joueur[1]\n",
" note = joueur[2]\n",
" stats = joueur[3]\n",
" \n",
" print(nom, \"(\" + poste + \") - Note:\", note)\n",
" \n",
" if poste == \"GK\":\n",
" # Afficher stats gardien\n",
" # Votre code ici\n",
" pass\n",
" else:\n",
" # Afficher stats joueur de champ\n",
" # Votre code ici\n",
" pass\n",
"\n",
"# Tests\n",
"afficher_joueur(effectif[0]) # Joueur de champ\n",
"print()\n",
"afficher_joueur(effectif[12]) # Gardien"
]
},
{
"cell_type": "markdown",
"id": "cell-5",
"metadata": {},
"source": [
"### 1.2 Filtrage par poste (4 pts)\n",
"\n",
"Écrivez une fonction `joueurs_par_poste(effectif, poste)` qui renvoie la liste des joueurs d'un poste donné, triés par note décroissante."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-6",
"metadata": {},
"outputs": [],
"source": [
"def joueurs_par_poste(effectif, poste):\n",
" joueurs = []\n",
" \n",
" for joueur in effectif:\n",
" if joueur[1] == poste:\n",
" joueurs.append(joueur)\n",
" \n",
" # Trier par note (indice 2) decroissante\n",
" joueurs = sorted(joueurs, key=lambda j: j[2], reverse=True)\n",
" return joueurs\n",
"\n",
"# Test\n",
"print(\"Attaquants :\")\n",
"for j in joueurs_par_poste(effectif, \"ATT\"):\n",
" print(\" \", j[0], \"-\", j[2])"
]
},
{
"cell_type": "markdown",
"id": "cell-7",
"metadata": {},
"source": [
"### 1.3 Meilleur dans une stat (4 pts)\n",
"\n",
"Écrivez une fonction `meilleur_stat(effectif, stat)` qui renvoie le tuple `(nom_joueur, valeur)` du joueur ayant la meilleure valeur pour cette statistique.\n",
"\n",
"*Attention : les gardiens n'ont pas les mêmes stats que les joueurs de champ.*"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-8",
"metadata": {},
"outputs": [],
"source": [
"def meilleur_stat(effectif, stat):\n",
" meilleur_nom = None\n",
" meilleure_valeur = -1\n",
" \n",
" for joueur in effectif:\n",
" nom = joueur[0]\n",
" stats = joueur[3]\n",
" \n",
" # Verifier si le joueur a cette stat\n",
" if stat in stats:\n",
" valeur = stats[stat]\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return (meilleur_nom, meilleure_valeur)\n",
"\n",
"# Tests\n",
"print(\"Plus rapide :\", meilleur_stat(effectif, \"vitesse\"))\n",
"print(\"Meilleur tireur :\", meilleur_stat(effectif, \"tir\"))\n",
"print(\"Meilleurs reflexes :\", meilleur_stat(effectif, \"reflexes\"))"
]
},
{
"cell_type": "markdown",
"id": "cell-9",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 2 - Composition d'équipe (35 min)\n",
"\n",
"### 2.1 Générer le XI de départ (6 pts)\n",
"\n",
"Écrivez une fonction `generer_xi(effectif, formation)` qui génère automatiquement le meilleur XI possible.\n",
"\n",
"Pour chaque poste, sélectionner les meilleurs joueurs (par note globale) en respectant le nombre requis.\n",
"\n",
"Renvoie un dictionnaire `{poste: [liste des joueurs sélectionnés]}`"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-10",
"metadata": {},
"outputs": [],
"source": [
"def generer_xi(effectif, formation):\n",
" xi = {}\n",
" \n",
" for poste, nb_joueurs in formation.items():\n",
" # Recuperer les joueurs de ce poste, tries par note\n",
" candidats = joueurs_par_poste(effectif, poste)\n",
" \n",
" # Prendre les n meilleurs\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return xi\n",
"\n",
"# Test\n",
"xi = generer_xi(effectif, formation)\n",
"print(\"=== XI de depart ===\")\n",
"for poste, joueurs in xi.items():\n",
" print(poste + \":\")\n",
" for j in joueurs:\n",
" print(\" -\", j[0], \"(\", j[2], \")\")"
]
},
{
"cell_type": "markdown",
"id": "cell-11",
"metadata": {},
"source": [
"### 2.2 Note moyenne du XI (5 pts)\n",
"\n",
"Écrivez une fonction `note_equipe(xi)` qui calcule la note moyenne de l'équipe sélectionnée."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-12",
"metadata": {},
"outputs": [],
"source": [
"def note_equipe(xi):\n",
" total_notes = 0\n",
" nb_joueurs = 0\n",
" \n",
" for poste, joueurs in xi.items():\n",
" for joueur in joueurs:\n",
" # Votre code ici\n",
" pass\n",
" \n",
" if nb_joueurs == 0:\n",
" return 0\n",
" \n",
" return round(total_notes / nb_joueurs, 1)\n",
"\n",
"# Test\n",
"print(\"Note de l'equipe :\", note_equipe(xi))"
]
},
{
"cell_type": "markdown",
"id": "cell-13",
"metadata": {},
"source": [
"### 2.3 Statistiques des matchs (6 pts)\n",
"\n",
"Écrivez une fonction `stats_matchs(matchs)` qui renvoie un dictionnaire avec :\n",
"- `\"victoires\"` : nombre de victoires\n",
"- `\"nuls\"` : nombre de matchs nuls\n",
"- `\"defaites\"` : nombre de défaites\n",
"- `\"buts_pour\"` : total des buts marqués\n",
"- `\"buts_contre\"` : total des buts encaissés"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-14",
"metadata": {},
"outputs": [],
"source": [
"def stats_matchs(matchs):\n",
" victoires = 0\n",
" nuls = 0\n",
" defaites = 0\n",
" buts_pour = 0\n",
" buts_contre = 0\n",
" \n",
" for match in matchs:\n",
" adversaire = match[0]\n",
" bp = match[1] # buts pour\n",
" bc = match[2] # buts contre\n",
" \n",
" buts_pour = buts_pour + bp\n",
" buts_contre = buts_contre + bc\n",
" \n",
" if bp > bc:\n",
" victoires = victoires + 1\n",
" elif bp == bc:\n",
" nuls = nuls + 1\n",
" else:\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return {\n",
" \"victoires\": victoires,\n",
" \"nuls\": nuls,\n",
" \"defaites\": defaites,\n",
" \"buts_pour\": buts_pour,\n",
" \"buts_contre\": buts_contre\n",
" }\n",
"\n",
"# Test\n",
"stats = stats_matchs(matchs)\n",
"print(\"Bilan :\", stats[\"victoires\"], \"V\", stats[\"nuls\"], \"N\", stats[\"defaites\"], \"D\")\n",
"print(\"Buts :\", stats[\"buts_pour\"], \"-\", stats[\"buts_contre\"])"
]
},
{
"cell_type": "markdown",
"id": "cell-15",
"metadata": {},
"source": [
"### 2.4 Classement des buteurs (6 pts)\n",
"\n",
"Écrivez une fonction `classement_buteurs(matchs)` qui renvoie une liste de tuples `(joueur, nb_buts)` triée par nombre de buts décroissant."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-16",
"metadata": {},
"outputs": [],
"source": [
"def classement_buteurs(matchs):\n",
" # Dictionnaire pour compter les buts par joueur\n",
" buts_par_joueur = {}\n",
" \n",
" for match in matchs:\n",
" buteurs = match[3] # liste des buteurs\n",
" for buteur in buteurs:\n",
" if buteur not in buts_par_joueur:\n",
" buts_par_joueur[buteur] = 0\n",
" buts_par_joueur[buteur] = buts_par_joueur[buteur] + 1\n",
" \n",
" # Convertir en liste de tuples et trier\n",
" classement = []\n",
" for joueur, buts in buts_par_joueur.items():\n",
" classement.append((joueur, buts))\n",
" \n",
" classement = sorted(classement, key=lambda x: x[1], reverse=True)\n",
" return classement\n",
"\n",
"# Test\n",
"print(\"Classement des buteurs :\")\n",
"for i, (joueur, buts) in enumerate(classement_buteurs(matchs), 1):\n",
" print(\" \", i, \".\", joueur, \":\", buts, \"but(s)\")"
]
},
{
"cell_type": "markdown",
"id": "cell-17",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 3 - Bonus (20 min)\n",
"\n",
"### 3.1 Points forts et faibles (5 pts)\n",
"\n",
"Écrivez une fonction `analyser_joueur(joueur)` qui renvoie un dictionnaire avec :\n",
"- `\"points_forts\"` : liste des stats >= 85\n",
"- `\"points_faibles\"` : liste des stats <= 60"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-18",
"metadata": {},
"outputs": [],
"source": [
"def analyser_joueur(joueur):\n",
" stats = joueur[3]\n",
" points_forts = []\n",
" points_faibles = []\n",
" \n",
" for stat, valeur in stats.items():\n",
" if valeur >= 85:\n",
" points_forts.append(stat)\n",
" # Votre code ici pour les points faibles\n",
" pass\n",
" \n",
" return {\n",
" \"points_forts\": points_forts,\n",
" \"points_faibles\": points_faibles\n",
" }\n",
"\n",
"# Test\n",
"analyse = analyser_joueur(effectif[0]) # Mbappe\n",
"print(\"Analyse de Mbappe :\")\n",
"print(\" Points forts :\", analyse[\"points_forts\"])\n",
"print(\" Points faibles :\", analyse[\"points_faibles\"])"
]
},
{
"cell_type": "markdown",
"id": "cell-19",
"metadata": {},
"source": [
"### 3.2 Rechercher un joueur (4 pts)\n",
"\n",
"Écrivez une fonction `rechercher_joueur(effectif, nom)` qui renvoie le joueur correspondant au nom (ou None si non trouvé)."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-20",
"metadata": {},
"outputs": [],
"source": [
"def rechercher_joueur(effectif, nom):\n",
" for joueur in effectif:\n",
" if joueur[0] == nom:\n",
" return joueur\n",
" return None\n",
"\n",
"# Test\n",
"joueur = rechercher_joueur(effectif, \"Kante\")\n",
"if joueur:\n",
" afficher_joueur(joueur)"
]
},
{
"cell_type": "markdown",
"id": "cell-21",
"metadata": {},
"source": [
"### 3.3 Performance d'un joueur (5 pts)\n",
"\n",
"Écrivez une fonction `performance_buteur(nom, matchs)` qui renvoie le nombre de buts et la moyenne de buts par match pour un joueur donné."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cell-22",
"metadata": {},
"outputs": [],
"source": [
"def performance_buteur(nom, matchs):\n",
" nb_buts = 0\n",
" nb_matchs = len(matchs)\n",
" \n",
" for match in matchs:\n",
" buteurs = match[3]\n",
" for buteur in buteurs:\n",
" if buteur == nom:\n",
" nb_buts = nb_buts + 1\n",
" \n",
" moyenne = 0\n",
" if nb_matchs > 0:\n",
" moyenne = round(nb_buts / nb_matchs, 2)\n",
" \n",
" return {\n",
" \"buts\": nb_buts,\n",
" \"matchs\": nb_matchs,\n",
" \"moyenne\": moyenne\n",
" }\n",
"\n",
"# Test\n",
"perf = performance_buteur(\"Mbappe\", matchs)\n",
"print(\"Performance de Mbappe :\")\n",
"print(\" Buts :\", perf[\"buts\"])\n",
"print(\" Moyenne par match :\", perf[\"moyenne\"])"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.9.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@@ -1,201 +0,0 @@
# Aide - TP05 Football
## Rappels utiles
### Structure des tuples
```python
# Joueur = (nom, poste, note_globale, stats)
joueur = effectif[0]
nom = joueur[0] # "Mbappe"
poste = joueur[1] # "ATT"
note = joueur[2] # 91
stats = joueur[3] # {"vitesse": 97, "tir": 89, ...}
# Acces direct
vitesse = joueur[3]["vitesse"]
```
### Parcourir une liste de tuples
```python
for joueur in effectif:
nom = joueur[0]
poste = joueur[1]
note = joueur[2]
stats = joueur[3]
print(nom, "-", poste, "- Note:", note)
```
### Filtrer une liste de tuples
```python
attaquants = []
for j in effectif:
if j[1] == "ATT":
attaquants.append(j)
```
---
## Exercice 1
### 1.1 - Affichage joueur
- Verifiez si c'est un gardien (`poste == "GK"`) car les stats sont differentes
```python
def afficher_joueur(joueur):
nom = joueur[0]
poste = joueur[1]
note = joueur[2]
stats = joueur[3]
print(nom, "(", poste, ") - Note:", note)
if poste == "GK":
print(" Plongeon:", stats["plongeon"])
print(" Reflexes:", stats["reflexes"])
else:
print(" Vitesse:", stats["vitesse"])
print(" Tir:", stats["tir"])
```
### 1.2 - Filtrage par poste
```python
def joueurs_par_poste(eff, poste):
filtre = []
for j in eff:
if j[1] == poste:
filtre.append(j)
# Trier par note (indice 2) decroissante
filtre = sorted(filtre, key=lambda j: j[2], reverse=True)
return filtre
```
### 1.3 - Meilleur dans une stat
```python
def meilleur_stat(eff, stat):
meilleur = None
max_val = -1
for joueur in eff:
nom = joueur[0]
stats = joueur[3]
if stat in stats and stats[stat] > max_val:
max_val = stats[stat]
meilleur = nom
return (meilleur, max_val)
```
---
## Exercice 2
### 2.1 - Generer le XI
```python
def generer_xi(eff, formation):
xi = {}
for poste, nb_joueurs in formation.items():
# Recuperer les joueurs de ce poste, tries par note
candidats = joueurs_par_poste(eff, poste)
# Prendre les n meilleurs
xi[poste] = candidats[:nb_joueurs]
return xi
```
### 2.2 - Note moyenne ponderee
```python
def note_equipe(xi):
poids = {"ATT": 1.2, "MIL": 1.1, "DEF": 1.0, "GK": 0.9}
total_pondere = 0
total_poids = 0
for poste, joueurs in xi.items():
for j in joueurs:
note = j[2]
p = poids[poste]
total_pondere = total_pondere + note * p
total_poids = total_poids + p
return total_pondere / total_poids
```
### 2.3 - Equipe specialisee
```python
def score_priorite(joueur, priorite):
stats = joueur[3]
if priorite == "offensive":
return stats.get("tir", 0) + stats.get("dribble", 0)
elif priorite == "defensive":
return stats.get("defense", 0) + stats.get("physique", 0)
elif priorite == "technique":
return stats.get("passe", 0) + stats.get("dribble", 0)
return 0
```
---
## Exercice 3 (Bonus)
### 3.1 - Statistiques des matchs
```python
def stats_matchs(matchs):
victoires = 0
nuls = 0
defaites = 0
buts_pour = 0
buts_contre = 0
for match in matchs:
adversaire = match[0]
score_eq = match[1]
score_adv = match[2]
buteurs = match[3]
buts_pour = buts_pour + score_eq
buts_contre = buts_contre + score_adv
if score_eq > score_adv:
victoires = victoires + 1
elif score_eq == score_adv:
nuls = nuls + 1
else:
defaites = defaites + 1
return {
"victoires": victoires,
"nuls": nuls,
"defaites": defaites,
"buts_pour": buts_pour,
"buts_contre": buts_contre,
"difference": buts_pour - buts_contre,
"points": victoires * 3 + nuls
}
```
### 3.2 - Classement buteurs
```python
def classement_buteurs(matchs):
compteur = {}
for match in matchs:
buteurs = match[3]
for buteur in buteurs:
if buteur not in compteur:
compteur[buteur] = 0
compteur[buteur] = compteur[buteur] + 1
# sorted renvoie une liste de tuples triee
return sorted(compteur.items(), key=lambda x: x[1], reverse=True)
```
### 3.3 - Performance joueur
- Trouvez le joueur dans l'effectif pour ses stats
- Comptez ses buts dans les matchs
- Identifiez ses points forts (>= 85) et faibles (<= 60)
---
## Pieges a eviter
1. **Gardiens differents** : les GK n'ont pas les memes stats (pas de "vitesse", mais "plongeon", "reflexes"...)
2. **Tuples immutables** : vous ne pouvez pas modifier un tuple, creez-en un nouveau si besoin
3. **Division par zero** : verifiez que le diviseur est > 0
4. **Acces par indice** : joueur[0] = nom, joueur[1] = poste, joueur[2] = note, joueur[3] = stats

View File

@@ -1,471 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# TP Évaluation - Pokédex\n",
"\n",
"**Durée : 1h30**\n",
"\n",
"**Nom :** \n",
"\n",
"**Prénom :**\n",
"\n",
"---\n",
"\n",
"Dans ce TP, vous allez créer un système de gestion de Pokédex.\n",
"\n",
"**Compétences évaluées :**\n",
"- Manipulation de tuples et listes\n",
"- Dictionnaires et structures imbriquées\n",
"- Algorithmes de filtrage et tri"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Données initiales\n",
"\n",
"**Exécutez cette cellule avant de commencer.**"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Pokedex (liste de tuples)\n",
"# Chaque Pokemon : (nom, types, pv, attaque, defense, vitesse, evolution)\n",
"# types est un tuple de 1 ou 2 types\n",
"# evolution est None si pas d'evolution\n",
"\n",
"pokedex = [\n",
" (\"Bulbizarre\", (\"Plante\", \"Poison\"), 45, 49, 49, 45, \"Herbizarre\"),\n",
" (\"Herbizarre\", (\"Plante\", \"Poison\"), 60, 62, 63, 60, \"Florizarre\"),\n",
" (\"Florizarre\", (\"Plante\", \"Poison\"), 80, 82, 83, 80, None),\n",
" (\"Salameche\", (\"Feu\",), 39, 52, 43, 65, \"Reptincel\"),\n",
" (\"Reptincel\", (\"Feu\",), 58, 64, 58, 80, \"Dracaufeu\"),\n",
" (\"Dracaufeu\", (\"Feu\", \"Vol\"), 78, 84, 78, 100, None),\n",
" (\"Carapuce\", (\"Eau\",), 44, 48, 65, 43, \"Carabaffe\"),\n",
" (\"Carabaffe\", (\"Eau\",), 59, 63, 80, 58, \"Tortank\"),\n",
" (\"Tortank\", (\"Eau\",), 79, 83, 100, 78, None),\n",
" (\"Pikachu\", (\"Electrique\",), 35, 55, 40, 90, \"Raichu\"),\n",
" (\"Raichu\", (\"Electrique\",), 60, 90, 55, 110, None),\n",
" (\"Evoli\", (\"Normal\",), 55, 55, 50, 55, \"Multiple\"),\n",
" (\"Aquali\", (\"Eau\",), 130, 65, 60, 65, None),\n",
" (\"Voltali\", (\"Electrique\",), 65, 65, 60, 130, None),\n",
" (\"Pyroli\", (\"Feu\",), 65, 130, 60, 65, None),\n",
" (\"Mewtwo\", (\"Psy\",), 106, 110, 90, 130, None),\n",
" (\"Mew\", (\"Psy\",), 100, 100, 100, 100, None),\n",
" (\"Dracolosse\", (\"Dragon\", \"Vol\"), 91, 134, 95, 80, None),\n",
" (\"Leviator\", (\"Eau\", \"Vol\"), 95, 125, 79, 81, None),\n",
" (\"Lokhlass\", (\"Eau\", \"Glace\"), 130, 85, 80, 60, None)\n",
"]\n",
"\n",
"# Table des faiblesses (type_attaquant -> liste des types faibles)\n",
"faiblesses = {\n",
" \"Feu\": [\"Plante\", \"Glace\"],\n",
" \"Eau\": [\"Feu\", \"Sol\"],\n",
" \"Plante\": [\"Eau\", \"Sol\"],\n",
" \"Electrique\": [\"Eau\", \"Vol\"],\n",
" \"Glace\": [\"Dragon\", \"Vol\", \"Plante\"],\n",
" \"Psy\": [\"Poison\"],\n",
" \"Dragon\": [\"Dragon\"],\n",
" \"Vol\": [\"Plante\"]\n",
"}\n",
"\n",
"# Equipe du joueur (liste de noms)\n",
"mon_equipe = [\"Pikachu\", \"Dracaufeu\", \"Tortank\", \"Dracolosse\", \"Mewtwo\", \"Evoli\"]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 1 - Exploration du Pokédex (25 min)\n",
"\n",
"### 1.1 Affichage d'un Pokémon (4 pts)\n",
"\n",
"Écrivez une fonction `afficher_pokemon(pokemon)` qui affiche les infos d'un Pokémon.\n",
"\n",
"Exemple :\n",
"```\n",
"DRACAUFEU (Feu/Vol)\n",
"PV: 78 | ATK: 84 | DEF: 78 | VIT: 100\n",
"Evolution: Forme finale\n",
"```\n",
"\n",
"*Rappel : pokemon[0] = nom, pokemon[1] = types, pokemon[2] = pv, pokemon[3] = attaque, pokemon[4] = defense, pokemon[5] = vitesse, pokemon[6] = evolution*"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def afficher_pokemon(pokemon):\n",
" nom = pokemon[0]\n",
" types = pokemon[1]\n",
" pv = pokemon[2]\n",
" attaque = pokemon[3]\n",
" defense = pokemon[4]\n",
" vitesse = pokemon[5]\n",
" evolution = pokemon[6]\n",
" \n",
" # Afficher le nom et les types\n",
" # Votre code ici\n",
" pass\n",
" \n",
" # Afficher les stats\n",
" # Votre code ici\n",
" pass\n",
" \n",
" # Afficher l'evolution (\"Forme finale\" si None)\n",
" # Votre code ici\n",
" pass\n",
"\n",
"# Test\n",
"afficher_pokemon(pokedex[5]) # Dracaufeu"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 1.2 Recherche par type (4 pts)\n",
"\n",
"Écrivez une fonction `pokemon_par_type(dex, type_recherche)` qui renvoie tous les Pokémon ayant ce type (principal ou secondaire), triés par PV décroissants.\n",
"\n",
"*Aide : utilisez `sorted(liste, key=lambda p: p[2], reverse=True)` pour trier par PV*"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def pokemon_par_type(dex, type_recherche):\n",
" resultats = []\n",
" \n",
" for pokemon in dex:\n",
" types = pokemon[1]\n",
" # Verifier si le type recherche est dans les types du pokemon\n",
" # Votre code ici\n",
" pass\n",
" \n",
" # Trier par PV (indice 2) decroissants\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return resultats\n",
"\n",
"# Test\n",
"print(\"Pokemon de type Eau :\")\n",
"for p in pokemon_par_type(pokedex, \"Eau\"):\n",
" print(\" \", p[0], \"-\", p[2], \"PV\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 1.3 Compter les types (4 pts)\n",
"\n",
"Écrivez une fonction `compter_types(dex)` qui renvoie un dictionnaire `{type: nombre}` comptant combien de Pokémon ont chaque type."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def compter_types(dex):\n",
" compteur = {}\n",
" \n",
" for pokemon in dex:\n",
" types = pokemon[1]\n",
" for t in types:\n",
" # Ajouter le type au compteur\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return compteur\n",
"\n",
"# Test\n",
"print(\"Nombre de Pokemon par type :\")\n",
"types_compteur = compter_types(pokedex)\n",
"for t, nb in types_compteur.items():\n",
" print(\" \", t, \":\", nb)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 2 - Gestion d'équipe (35 min)\n",
"\n",
"### 2.1 Charger une équipe (5 pts)\n",
"\n",
"Écrivez une fonction `charger_equipe(noms, dex)` qui renvoie la liste des tuples Pokemon correspondant aux noms donnés.\n",
"\n",
"Si un nom n'existe pas dans le Pokédex, l'ignorer."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def charger_equipe(noms, dex):\n",
" equipe = []\n",
" \n",
" for nom_recherche in noms:\n",
" # Chercher le pokemon dans le pokedex\n",
" for pokemon in dex:\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return equipe\n",
"\n",
"# Test\n",
"equipe = charger_equipe(mon_equipe, pokedex)\n",
"print(\"Equipe chargee :\")\n",
"for p in equipe:\n",
" print(\" \", p[0])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.2 Force totale de l'équipe (5 pts)\n",
"\n",
"Écrivez une fonction `force_equipe(equipe)` qui calcule la force totale de l'équipe.\n",
"\n",
"Force d'un Pokémon = PV + Attaque + Défense + Vitesse"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def force_equipe(equipe):\n",
" force_totale = 0\n",
" \n",
" for pokemon in equipe:\n",
" # Calculer la force du pokemon et l'ajouter au total\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return force_totale\n",
"\n",
"# Test\n",
"print(\"Force totale de l'equipe :\", force_equipe(equipe))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.3 Pokémon le plus fort (5 pts)\n",
"\n",
"Écrivez une fonction `plus_fort(equipe)` qui renvoie le Pokémon ayant la meilleure attaque."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def plus_fort(equipe):\n",
" if len(equipe) == 0:\n",
" return None\n",
" \n",
" meilleur = equipe[0]\n",
" meilleure_attaque = equipe[0][3]\n",
" \n",
" for pokemon in equipe:\n",
" # Comparer l'attaque avec la meilleure\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return meilleur\n",
"\n",
"# Test\n",
"fort = plus_fort(equipe)\n",
"if fort:\n",
" print(\"Pokemon le plus fort :\", fort[0], \"avec\", fort[3], \"d'attaque\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.4 Types couverts par l'équipe (6 pts)\n",
"\n",
"Écrivez une fonction `types_couverts(equipe)` qui renvoie la liste (sans doublons) de tous les types présents dans l'équipe."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def types_couverts(equipe):\n",
" types_liste = []\n",
" \n",
" for pokemon in equipe:\n",
" types = pokemon[1]\n",
" for t in types:\n",
" # Ajouter le type s'il n'est pas deja dans la liste\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return types_liste\n",
"\n",
"# Test\n",
"print(\"Types couverts par l'equipe :\", types_couverts(equipe))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 3 - Bonus (20 min)\n",
"\n",
"### 3.1 Chaîne d'évolution (5 pts)\n",
"\n",
"Écrivez une fonction `chaine_evolution(nom, dex)` qui renvoie la chaîne d'évolution complète d'un Pokémon.\n",
"\n",
"Exemple : `chaine_evolution(\"Bulbizarre\", pokedex)` → `[\"Bulbizarre\", \"Herbizarre\", \"Florizarre\"]`"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def chaine_evolution(nom, dex):\n",
" chaine = [nom]\n",
" \n",
" # Chercher le pokemon actuel\n",
" pokemon_actuel = None\n",
" for p in dex:\n",
" if p[0] == nom:\n",
" pokemon_actuel = p\n",
" break\n",
" \n",
" if pokemon_actuel == None:\n",
" return chaine\n",
" \n",
" # Suivre les evolutions\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return chaine\n",
"\n",
"# Tests\n",
"print(chaine_evolution(\"Bulbizarre\", pokedex))\n",
"print(chaine_evolution(\"Pikachu\", pokedex))\n",
"print(chaine_evolution(\"Mewtwo\", pokedex))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3.2 Vérifier efficacité (5 pts)\n",
"\n",
"Écrivez une fonction `est_efficace(attaquant, defenseur, faiblesses)` qui renvoie `True` si l'attaquant a un type efficace contre le défenseur."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def est_efficace(attaquant, defenseur, faiblesses):\n",
" types_attaquant = attaquant[1]\n",
" types_defenseur = defenseur[1]\n",
" \n",
" # Pour chaque type de l'attaquant, verifier s'il est efficace\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return False\n",
"\n",
"# Tests\n",
"pikachu = pokedex[9]\n",
"tortank = pokedex[8]\n",
"dracaufeu = pokedex[5]\n",
"\n",
"print(\"Pikachu efficace contre Tortank ?\", est_efficace(pikachu, tortank, faiblesses))\n",
"print(\"Dracaufeu efficace contre Tortank ?\", est_efficace(dracaufeu, tortank, faiblesses))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3.3 Meilleur contre un adversaire (4 pts)\n",
"\n",
"Écrivez une fonction `meilleur_contre(adversaire, equipe, faiblesses)` qui renvoie le Pokémon de l'équipe le plus efficace contre l'adversaire.\n",
"\n",
"S'il n'y a pas de Pokémon efficace, renvoyer le plus fort en attaque."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def meilleur_contre(adversaire, equipe, faiblesses):\n",
" # D'abord chercher un pokemon efficace\n",
" # Votre code ici\n",
" pass\n",
" \n",
" # Sinon renvoyer le plus fort en attaque\n",
" return plus_fort(equipe)\n",
"\n",
"# Test\n",
"leviator = pokedex[18]\n",
"choix = meilleur_contre(leviator, equipe, faiblesses)\n",
"if choix:\n",
" print(\"Meilleur choix contre Leviator :\", choix[0])"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.9.0"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

View File

@@ -1,214 +0,0 @@
# Aide - TP06 Pokemon
## Rappels utiles
### Structure des tuples Pokemon
```python
# Pokemon = (nom, types, pv, attaque, defense, vitesse, evolution)
pokemon = pokedex[0]
nom = pokemon[0] # "Bulbizarre"
types = pokemon[1] # ("Plante", "Poison")
pv = pokemon[2] # 45
attaque = pokemon[3] # 49
defense = pokemon[4] # 49
vitesse = pokemon[5] # 45
evolution = pokemon[6] # "Herbizarre"
```
### Types multiples
```python
pokemon = pokedex[5] # Dracaufeu
# types est un tuple : ("Feu", "Vol")
print(pokemon[1][0]) # "Feu" (type principal)
if "Feu" in pokemon[1]:
print("C'est un type Feu")
```
---
## Exercice 1
### 1.1 - Affichage Pokemon
```python
def afficher_pokemon(pokemon):
nom = pokemon[0]
types = pokemon[1]
pv = pokemon[2]
attaque = pokemon[3]
defense = pokemon[4]
vitesse = pokemon[5]
evolution = pokemon[6]
# Afficher les types
if len(types) == 2:
types_str = types[0] + "/" + types[1]
else:
types_str = types[0]
print(nom, "(", types_str, ")")
print("PV:", pv, "| ATK:", attaque, "| DEF:", defense, "| VIT:", vitesse)
if evolution == None:
print("Evolution: Forme finale")
else:
print("Evolution:", evolution)
```
### 1.2 - Recherche par type
```python
def pokemon_par_type(dex, type_recherche):
resultat = []
for p in dex:
if type_recherche in p[1]: # p[1] = types
resultat.append(p)
# Trier par PV (indice 2) decroissants
resultat = sorted(resultat, key=lambda p: p[2], reverse=True)
return resultat
```
### 1.3 - Compter les types
```python
def compter_types(dex):
compteur = {}
for pokemon in dex:
types = pokemon[1]
for t in types:
if t not in compteur:
compteur[t] = 0
compteur[t] = compteur[t] + 1
return compteur
```
---
## Exercice 2
### 2.1 - Charger equipe
```python
def charger_equipe(noms, dex):
equipe = []
for nom_recherche in noms:
# Chercher le pokemon dans le pokedex
for pokemon in dex:
if pokemon[0] == nom_recherche:
equipe.append(pokemon)
break
return equipe
```
### 2.2 - Force de l'equipe
```python
def force_equipe(equipe):
force_totale = 0
for pokemon in equipe:
pv = pokemon[2]
attaque = pokemon[3]
defense = pokemon[4]
vitesse = pokemon[5]
force_pokemon = pv + attaque + defense + vitesse
force_totale = force_totale + force_pokemon
return force_totale
```
### 2.3 - Pokemon le plus fort
```python
def plus_fort(equipe):
if len(equipe) == 0:
return None
meilleur = equipe[0]
meilleure_attaque = equipe[0][3] # indice 3 = attaque
for pokemon in equipe:
if pokemon[3] > meilleure_attaque:
meilleur = pokemon
meilleure_attaque = pokemon[3]
return meilleur
```
### 2.4 - Types couverts
```python
def types_couverts(equipe):
types_liste = []
for pokemon in equipe:
types = pokemon[1]
for t in types:
if t not in types_liste:
types_liste.append(t)
return types_liste
```
---
## Exercice 3 (Bonus)
### 3.1 - Chaine d'evolution
```python
def chaine_evolution(nom, dex):
chaine = [nom]
# Chercher le pokemon actuel
pokemon_actuel = None
for p in dex:
if p[0] == nom:
pokemon_actuel = p
break
if pokemon_actuel == None:
return chaine
# Suivre les evolutions
evolution = pokemon_actuel[6]
while evolution != None and evolution != "Multiple":
chaine.append(evolution)
# Chercher le pokemon suivant
for p in dex:
if p[0] == evolution:
evolution = p[6]
break
return chaine
```
### 3.2 - Verifier efficacite
```python
def est_efficace(attaquant, defenseur, faiblesses):
types_attaquant = attaquant[1]
types_defenseur = defenseur[1]
# Pour chaque type de l'attaquant
for type_att in types_attaquant:
# Verifier si ce type est efficace
if type_att in faiblesses:
types_faibles = faiblesses[type_att]
# Verifier si le defenseur a un type faible
for type_def in types_defenseur:
if type_def in types_faibles:
return True
return False
```
### 3.3 - Meilleur contre un adversaire
```python
def meilleur_contre(adversaire, equipe, faiblesses):
# D'abord chercher un pokemon efficace
for pokemon in equipe:
if est_efficace(pokemon, adversaire, faiblesses):
return pokemon
# Sinon renvoyer le plus fort en attaque
return plus_fort(equipe)
```
---
## Pieges a eviter
1. **Types en tuple** : meme un seul type est un tuple `("Feu",)` - notez la virgule !
2. **Tuples immutables** : vous ne pouvez pas modifier `pokemon[2] = 50`
3. **Faiblesses unidirectionnelles** : Feu bat Plante, mais Plante ne bat pas Feu
4. **PV negatifs** : verifiez `pv > 0` et non `pv >= 0`
5. **Acces par indice** : pokemon[0]=nom, pokemon[1]=types, pokemon[2]=pv, pokemon[3]=attaque, pokemon[4]=defense, pokemon[5]=vitesse, pokemon[6]=evolution

View File

@@ -1,268 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# TP Évaluation - Collection Manga\n",
"\n",
"**Durée : 1h30**\n",
"\n",
"**Nom :** \n",
"\n",
"**Prénom :**\n",
"\n",
"---\n",
"\n",
"Dans ce TP, vous allez gérer une collection de mangas.\n",
"\n",
"**Compétences évaluées :**\n",
"- Listes de dictionnaires\n",
"- Algorithmes de filtrage et tri\n",
"- Manipulation de données"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Données initiales\n",
"\n",
"**Exécutez cette cellule avant de commencer.**"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Collection de mangas\n",
"# Chaque manga est un dictionnaire\n",
"mangas = [\n",
" {\"titre\": \"One Piece\", \"auteur\": \"Eiichiro Oda\", \"genres\": [\"Aventure\", \"Action\"], \"tomes\": 107, \"termine\": False, \"note\": 9.2},\n",
" {\"titre\": \"Naruto\", \"auteur\": \"Masashi Kishimoto\", \"genres\": [\"Action\", \"Aventure\"], \"tomes\": 72, \"termine\": True, \"note\": 8.5},\n",
" {\"titre\": \"Death Note\", \"auteur\": \"Tsugumi Ohba\", \"genres\": [\"Thriller\", \"Psychologique\"], \"tomes\": 12, \"termine\": True, \"note\": 9.0},\n",
" {\"titre\": \"Attack on Titan\", \"auteur\": \"Hajime Isayama\", \"genres\": [\"Action\", \"Drame\"], \"tomes\": 34, \"termine\": True, \"note\": 9.1},\n",
" {\"titre\": \"My Hero Academia\", \"auteur\": \"Kohei Horikoshi\", \"genres\": [\"Action\", \"Super-heros\"], \"tomes\": 40, \"termine\": False, \"note\": 8.3},\n",
" {\"titre\": \"Demon Slayer\", \"auteur\": \"Koyoharu Gotouge\", \"genres\": [\"Action\", \"Surnaturel\"], \"tomes\": 23, \"termine\": True, \"note\": 8.7},\n",
" {\"titre\": \"Jujutsu Kaisen\", \"auteur\": \"Gege Akutami\", \"genres\": [\"Action\", \"Surnaturel\"], \"tomes\": 25, \"termine\": False, \"note\": 8.8},\n",
" {\"titre\": \"Chainsaw Man\", \"auteur\": \"Tatsuki Fujimoto\", \"genres\": [\"Action\", \"Horreur\"], \"tomes\": 16, \"termine\": False, \"note\": 8.9},\n",
" {\"titre\": \"Spy x Family\", \"auteur\": \"Tatsuya Endo\", \"genres\": [\"Action\", \"Comedie\"], \"tomes\": 12, \"termine\": False, \"note\": 8.6},\n",
" {\"titre\": \"Dragon Ball\", \"auteur\": \"Akira Toriyama\", \"genres\": [\"Action\", \"Aventure\"], \"tomes\": 42, \"termine\": True, \"note\": 8.8},\n",
" {\"titre\": \"Fullmetal Alchemist\", \"auteur\": \"Hiromu Arakawa\", \"genres\": [\"Action\", \"Aventure\", \"Fantasy\"], \"tomes\": 27, \"termine\": True, \"note\": 9.3},\n",
" {\"titre\": \"Tokyo Ghoul\", \"auteur\": \"Sui Ishida\", \"genres\": [\"Action\", \"Horreur\"], \"tomes\": 14, \"termine\": True, \"note\": 8.4}\n",
"]\n",
"\n",
"# Ma collection personnelle (tomes possedes par manga)\n",
"ma_collection = {\n",
" \"Death Note\": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],\n",
" \"One Piece\": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],\n",
" \"Demon Slayer\": [1, 2, 3, 4, 5],\n",
" \"Spy x Family\": [1, 2, 3, 4]\n",
"}\n",
"\n",
"# Liste de souhaits\n",
"liste_souhaits = [\"Chainsaw Man\", \"Jujutsu Kaisen\", \"Fullmetal Alchemist\"]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 1 - Exploration du catalogue (25 min)\n",
"\n",
"### 1.1 Affichage d'un manga (4 pts)\n",
"\n",
"Écrivez une fonction `afficher_manga(manga)` qui affiche les informations d'un manga.\n",
"\n",
"Exemple :\n",
"```\n",
"Death Note - Tsugumi Ohba\n",
"Genres : Thriller, Psychologique\n",
"12 tomes (Termine) | Note : 9.0\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": "def afficher_manga(manga):\n titre = manga[\"titre\"]\n auteur = manga[\"auteur\"]\n genres = manga[\"genres\"]\n tomes = manga[\"tomes\"]\n termine = manga[\"termine\"]\n note = manga[\"note\"]\n \n # Afficher : titre - auteur\n # Votre code ici\n pass\n \n # Afficher les genres séparés par des virgules\n # Votre code ici\n pass\n \n # Afficher le statut : \"Termine\" ou \"En cours\"\n # Votre code ici\n pass\n\n# Tests\nafficher_manga(mangas[2]) # Death Note\nprint()\nafficher_manga(mangas[0]) # One Piece"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 1.2 Recherche par genre (4 pts)\n",
"\n",
"Écrivez une fonction `rechercher_par_genre(mangas, genre)` qui renvoie la liste des mangas contenant ce genre."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": "def rechercher_par_genre(mangas, genre):\n resultats = []\n \n for manga in mangas:\n # Votre code ici\n pass\n \n return resultats\n\n# Test\nprint(\"Mangas d'Horreur :\")\nfor m in rechercher_par_genre(mangas, \"Horreur\"):\n print(\" \", m[\"titre\"])"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 1.3 Mangas terminés (4 pts)\n",
"\n",
"Écrivez une fonction `mangas_termines(mangas)` qui renvoie la liste des mangas terminés, triés par note décroissante."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": "def mangas_termines(mangas):\n termines = []\n \n for manga in mangas:\n # Votre code ici\n pass\n \n # Trier par note decroissante\n # Votre code ici\n pass\n \n return termines\n\n# Test\nprint(\"Mangas termines (par note) :\")\nfor m in mangas_termines(mangas):\n print(\" \", m[\"titre\"], \"-\", m[\"note\"])"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 2 - Gestion de collection (35 min)\n",
"\n",
"### 2.1 Avancement de lecture (6 pts)\n",
"\n",
"Écrivez une fonction `avancement_collection(ma_coll, mangas)` qui calcule l'avancement pour chaque manga possédé.\n",
"\n",
"Renvoie une liste de dictionnaires avec `titre`, `possede`, `total`, `pourcentage`, `complet` (booléen)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": "def avancement_collection(ma_coll, mangas):\n avancement = []\n \n for titre, tomes_possedes in ma_coll.items():\n # Trouver le manga dans le catalogue\n total_tomes = 0\n for manga in mangas:\n # Votre code ici\n pass\n \n nb_possedes = len(tomes_possedes)\n \n # Calculer le pourcentage (arrondi)\n # Votre code ici\n pourcentage = 0\n \n # Determiner si la collection est complete\n # Votre code ici\n complet = False\n \n avancement.append({\n \"titre\": titre,\n \"possede\": nb_possedes,\n \"total\": total_tomes,\n \"pourcentage\": pourcentage,\n \"complet\": complet\n })\n \n return avancement\n\n# Test\nprint(\"Avancement de ma collection :\")\nfor item in avancement_collection(ma_collection, mangas):\n statut = \"Complet\" if item[\"complet\"] else str(item[\"pourcentage\"]) + \"%\"\n print(\" \", item[\"titre\"], \":\", item[\"possede\"], \"/\", item[\"total\"], \"(\", statut, \")\")"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.2 Tomes manquants (5 pts)\n",
"\n",
"Écrivez une fonction `tomes_manquants(titre, ma_coll, mangas)` qui renvoie la liste des numéros de tomes manquants pour un manga donné."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": "def tomes_manquants(titre, ma_coll, mangas):\n # Trouver le nombre total de tomes\n total_tomes = 0\n for manga in mangas:\n # Votre code ici\n pass\n \n # Recuperer les tomes possedes\n if titre in ma_coll:\n possedes = ma_coll[titre]\n else:\n possedes = []\n \n # Trouver les manquants\n manquants = []\n for i in range(1, total_tomes + 1):\n # Votre code ici\n pass\n \n return manquants\n\n# Test\nmanq = tomes_manquants(\"One Piece\", ma_collection, mangas)\nprint(\"Tomes manquants de One Piece :\", len(manq), \"tomes\")\nprint(\"Premiers manquants :\", manq[:10])"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.3 Valeur de la collection (5 pts)\n",
"\n",
"Écrivez une fonction `valeur_collection(ma_coll, prix_par_tome)` qui calcule la valeur totale de la collection.\n",
"\n",
"Renvoie un dictionnaire avec `nb_tomes` et `valeur_totale`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": "def valeur_collection(ma_coll, prix_par_tome):\n nb_tomes = 0\n \n for titre, tomes in ma_coll.items():\n # Votre code ici\n pass\n \n # Calculer la valeur totale\n # Votre code ici\n valeur = 0\n \n return {\n \"nb_tomes\": nb_tomes,\n \"valeur_totale\": valeur\n }\n\n# Test (7 euros par tome)\nval = valeur_collection(ma_collection, 7)\nprint(\"Ma collection :\", val[\"nb_tomes\"], \"tomes\")\nprint(\"Valeur estimee :\", val[\"valeur_totale\"], \"euros\")"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.4 Note moyenne des mangas possédés (5 pts)\n",
"\n",
"Écrivez une fonction `note_moyenne_collection(ma_coll, mangas)` qui calcule la note moyenne des mangas de la collection."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": "def note_moyenne_collection(ma_coll, mangas):\n total_notes = 0\n nb_mangas = 0\n \n for titre in ma_coll.keys():\n # Trouver le manga dans le catalogue\n for manga in mangas:\n # Votre code ici\n pass\n \n if nb_mangas == 0:\n return 0\n \n return round(total_notes / nb_mangas, 2)\n\n# Test\nprint(\"Note moyenne de ma collection :\", note_moyenne_collection(ma_collection, mangas))"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 3 - Bonus (20 min)\n",
"\n",
"### 3.1 Recommandation (5 pts)\n",
"\n",
"Écrivez une fonction `recommander(ma_coll, mangas)` qui recommande un manga non possédé basé sur les genres de la collection.\n",
"\n",
"Score = nombre de genres en commun + note du manga"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": "def recommander(ma_coll, mangas):\n # Collecter les genres de ma collection\n mes_genres = []\n for titre in ma_coll.keys():\n for manga in mangas:\n if manga[\"titre\"] == titre:\n for g in manga[\"genres\"]:\n if g not in mes_genres:\n mes_genres.append(g)\n \n # Chercher le meilleur manga non possede\n meilleur = None\n meilleur_score = 0\n \n for manga in mangas:\n if manga[\"titre\"] not in ma_coll:\n # Compter les genres en commun\n genres_communs = 0\n for g in manga[\"genres\"]:\n # Votre code ici\n pass\n \n score = genres_communs + manga[\"note\"]\n \n # Votre code ici : mettre a jour meilleur si score est superieur\n pass\n \n return meilleur\n\n# Test\nreco = recommander(ma_collection, mangas)\nif reco:\n print(\"Recommandation :\")\n afficher_manga(reco)"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3.2 Liste des auteurs (4 pts)\n",
"\n",
"Écrivez une fonction `auteurs_uniques(mangas)` qui renvoie la liste des auteurs (sans doublons), triée par ordre alphabétique."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": "def auteurs_uniques(mangas):\n auteurs = []\n \n for manga in mangas:\n # Votre code ici : ajouter l'auteur s'il n'est pas deja dans la liste\n pass\n \n auteurs.sort()\n return auteurs\n\n# Test\nprint(\"Auteurs :\", auteurs_uniques(mangas))"
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3.3 Statistiques par genre (5 pts)\n",
"\n",
"Écrivez une fonction `stats_par_genre(mangas)` qui renvoie un dictionnaire avec pour chaque genre : le nombre de mangas et la note moyenne."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": "def stats_par_genre(mangas):\n # Collecter les donnees par genre\n donnees = {}\n \n for manga in mangas:\n for genre in manga[\"genres\"]:\n if genre not in donnees:\n donnees[genre] = {\"nb\": 0, \"total_notes\": 0}\n # Votre code ici : incrementer nb et ajouter la note\n pass\n \n # Calculer les moyennes\n stats = {}\n for genre, data in donnees.items():\n # Votre code ici : calculer la moyenne et remplir stats\n pass\n \n return stats\n\n# Test\nprint(\"Statistiques par genre :\")\nfor genre, data in stats_par_genre(mangas).items():\n print(\" \", genre, \":\", data[\"nombre\"], \"mangas, note moyenne\", data[\"note_moyenne\"])"
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.9.0"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

View File

@@ -1,264 +0,0 @@
# Aide - TP07 Manga
## Rappels utiles
### Structure des mangas (dictionnaires)
```python
# Chaque manga est un dictionnaire
manga = mangas[0]
print(manga["titre"]) # "One Piece"
print(manga["auteur"]) # "Eiichiro Oda"
print(manga["genres"]) # ["Aventure", "Action"]
print(manga["tomes"]) # 107
print(manga["termine"]) # False
print(manga["note"]) # 9.2
```
### Collection personnelle (dictionnaire)
```python
# ma_collection = {titre: [liste des tomes possedes]}
ma_collection = {
"Death Note": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
"One Piece": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
}
# Acceder aux tomes d'un manga
tomes_possedes = ma_collection["Death Note"]
print(len(tomes_possedes)) # 12
```
### Parcourir la collection
```python
for titre, tomes_possedes in ma_collection.items():
print(titre, ":", len(tomes_possedes), "tomes")
```
---
## Exercice 1
### 1.1 - Affichage d'un manga
```python
def afficher_manga(manga):
titre = manga["titre"]
auteur = manga["auteur"]
genres = manga["genres"]
tomes = manga["tomes"]
termine = manga["termine"]
note = manga["note"]
print(titre, "-", auteur)
# Afficher les genres
genres_str = ", ".join(genres)
print("Genres:", genres_str)
# Afficher le statut
if termine:
statut = "Termine"
else:
statut = "En cours"
print(tomes, "tomes (", statut, ") | Note:", note)
```
### 1.2 - Recherche par genre
```python
def rechercher_par_genre(mangas, genre):
resultats = []
for manga in mangas:
if genre in manga["genres"]:
resultats.append(manga)
return resultats
```
### 1.3 - Mangas termines
```python
def mangas_termines(mangas):
termines = []
for manga in mangas:
if manga["termine"] == True:
termines.append(manga)
# Trier par note decroissante
termines = sorted(termines, key=lambda m: m["note"], reverse=True)
return termines
```
---
## Exercice 2
### 2.1 - Avancement de lecture
```python
def avancement_collection(ma_coll, mangas):
avancement = []
for titre, tomes_possedes in ma_coll.items():
# Trouver le manga dans le catalogue
total_tomes = 0
for manga in mangas:
if manga["titre"] == titre:
total_tomes = manga["tomes"]
break
nb_possedes = len(tomes_possedes)
if total_tomes > 0:
pourcentage = round(nb_possedes / total_tomes * 100)
else:
pourcentage = 0
complet = (nb_possedes == total_tomes)
avancement.append({
"titre": titre,
"possede": nb_possedes,
"total": total_tomes,
"pourcentage": pourcentage,
"complet": complet
})
return avancement
```
### 2.2 - Tomes manquants
```python
def tomes_manquants(titre, ma_coll, mangas):
# Trouver le nombre total de tomes
total_tomes = 0
for manga in mangas:
if manga["titre"] == titre:
total_tomes = manga["tomes"]
break
# Recuperer les tomes possedes
if titre in ma_coll:
possedes = ma_coll[titre]
else:
possedes = []
# Trouver les manquants
manquants = []
for i in range(1, total_tomes + 1):
if i not in possedes:
manquants.append(i)
return manquants
```
### 2.3 - Valeur de la collection
```python
def valeur_collection(ma_coll, prix_par_tome):
nb_tomes = 0
for titre, tomes in ma_coll.items():
nb_tomes = nb_tomes + len(tomes)
valeur = nb_tomes * prix_par_tome
return {
"nb_tomes": nb_tomes,
"valeur_totale": valeur
}
```
### 2.4 - Note moyenne des mangas possedes
```python
def note_moyenne_collection(ma_coll, mangas):
total_notes = 0
nb_mangas = 0
for titre in ma_coll.keys():
# Trouver le manga dans le catalogue
for manga in mangas:
if manga["titre"] == titre:
total_notes = total_notes + manga["note"]
nb_mangas = nb_mangas + 1
break
if nb_mangas == 0:
return 0
return round(total_notes / nb_mangas, 2)
```
---
## Exercice 3 (Bonus)
### 3.1 - Recommandation
```python
def recommander(ma_coll, mangas):
# Collecter les genres de ma collection
mes_genres = []
for titre in ma_coll.keys():
for manga in mangas:
if manga["titre"] == titre:
for g in manga["genres"]:
if g not in mes_genres:
mes_genres.append(g)
# Chercher le meilleur manga non possede
meilleur = None
meilleur_score = 0
for manga in mangas:
if manga["titre"] not in ma_coll:
# Compter les genres en commun
genres_communs = 0
for g in manga["genres"]:
if g in mes_genres:
genres_communs = genres_communs + 1
score = genres_communs + manga["note"]
if score > meilleur_score:
meilleur = manga
meilleur_score = score
return meilleur
```
### 3.2 - Auteurs uniques
```python
def auteurs_uniques(mangas):
auteurs = []
for manga in mangas:
auteur = manga["auteur"]
if auteur not in auteurs:
auteurs.append(auteur)
auteurs.sort()
return auteurs
```
### 3.3 - Statistiques par genre
```python
def stats_par_genre(mangas):
# Collecter les donnees par genre
donnees = {}
for manga in mangas:
for genre in manga["genres"]:
if genre not in donnees:
donnees[genre] = {"nb": 0, "total_notes": 0}
donnees[genre]["nb"] = donnees[genre]["nb"] + 1
donnees[genre]["total_notes"] = donnees[genre]["total_notes"] + manga["note"]
# Calculer les moyennes
stats = {}
for genre, data in donnees.items():
moyenne = round(data["total_notes"] / data["nb"], 2)
stats[genre] = {"nombre": data["nb"], "note_moyenne": moyenne}
return stats
```
---
## Pieges a eviter
1. **Genres en liste** : les genres sont une liste `["Action", "Aventure"]`, utilisez `in` pour verifier
2. **Collection vs catalogue** : `ma_collection` contient les titres possedes, `mangas` contient les infos completes
3. **Division par zero** : verifiez que le diviseur est > 0 avant de calculer une moyenne
4. **Tomes manquants** : n'oubliez pas que les tomes sont numerotes de 1 a total_tomes

View File

@@ -1,518 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# TP Évaluation - Système de commande McDonald's\n",
"\n",
"**Durée : 1h30**\n",
"\n",
"**Nom :** \n",
"\n",
"**Prénom :**\n",
"\n",
"---\n",
"\n",
"Dans ce TP, vous allez créer un système de gestion de commandes pour un fast-food.\n",
"\n",
"**Compétences évaluées :**\n",
"- Manipulation de dictionnaires imbriqués\n",
"- Calculs sur des structures de données\n",
"- Algorithmes de traitement de commandes"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Données initiales\n",
"\n",
"**Exécutez cette cellule avant de commencer.**"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Menu du restaurant\n",
"menu = {\n",
" \"burgers\": {\n",
" \"Big Mac\": {\"prix\": 5.50, \"calories\": 540},\n",
" \"McChicken\": {\"prix\": 4.90, \"calories\": 400},\n",
" \"Royal Deluxe\": {\"prix\": 6.20, \"calories\": 580},\n",
" \"Double Cheese\": {\"prix\": 4.50, \"calories\": 450},\n",
" \"Filet-O-Fish\": {\"prix\": 4.80, \"calories\": 380},\n",
" \"McFirst\": {\"prix\": 2.50, \"calories\": 260}\n",
" },\n",
" \"accompagnements\": {\n",
" \"Frites (P)\": {\"prix\": 2.00, \"calories\": 230},\n",
" \"Frites (M)\": {\"prix\": 2.50, \"calories\": 340},\n",
" \"Frites (G)\": {\"prix\": 3.00, \"calories\": 450},\n",
" \"Potatoes\": {\"prix\": 3.20, \"calories\": 290},\n",
" \"Salade\": {\"prix\": 3.50, \"calories\": 80},\n",
" \"Nuggets x6\": {\"prix\": 4.50, \"calories\": 260},\n",
" \"Nuggets x9\": {\"prix\": 5.90, \"calories\": 390}\n",
" },\n",
" \"boissons\": {\n",
" \"Coca-Cola (M)\": {\"prix\": 2.50, \"calories\": 140},\n",
" \"Coca-Cola (G)\": {\"prix\": 3.00, \"calories\": 200},\n",
" \"Sprite (M)\": {\"prix\": 2.50, \"calories\": 130},\n",
" \"Eau\": {\"prix\": 1.50, \"calories\": 0},\n",
" \"Cafe\": {\"prix\": 1.80, \"calories\": 5}\n",
" },\n",
" \"desserts\": {\n",
" \"Sundae Caramel\": {\"prix\": 2.80, \"calories\": 340},\n",
" \"Sundae Chocolat\": {\"prix\": 2.80, \"calories\": 350},\n",
" \"McFlurry Oreo\": {\"prix\": 3.50, \"calories\": 380},\n",
" \"Cookie\": {\"prix\": 1.50, \"calories\": 180}\n",
" }\n",
"}\n",
"\n",
"# Menus Best-Of (formules)\n",
"menus_bestof = {\n",
" \"Best-Of Big Mac\": {\"burger\": \"Big Mac\", \"frites\": \"Frites (M)\", \"boisson\": \"Coca-Cola (M)\", \"prix\": 8.90},\n",
" \"Best-Of McChicken\": {\"burger\": \"McChicken\", \"frites\": \"Frites (M)\", \"boisson\": \"Coca-Cola (M)\", \"prix\": 8.50},\n",
" \"Best-Of Royal\": {\"burger\": \"Royal Deluxe\", \"frites\": \"Frites (M)\", \"boisson\": \"Coca-Cola (M)\", \"prix\": 9.50}\n",
"}\n",
"\n",
"# File de commandes en cours\n",
"# Chaque commande : {\"id\": numero, \"items\": [(article, quantite), ...], \"heure\": \"HH:MM\"}\n",
"commandes_en_cours = [\n",
" {\"id\": 101, \"items\": [(\"Big Mac\", 2), (\"Frites (G)\", 2), (\"Coca-Cola (G)\", 2)], \"heure\": \"12:05\"},\n",
" {\"id\": 102, \"items\": [(\"Best-Of McChicken\", 1), (\"McFlurry Oreo\", 1)], \"heure\": \"12:07\"},\n",
" {\"id\": 103, \"items\": [(\"Nuggets x9\", 2), (\"Frites (M)\", 2), (\"Sprite (M)\", 2)], \"heure\": \"12:08\"},\n",
" {\"id\": 104, \"items\": [(\"Best-Of Royal\", 1), (\"Salade\", 1), (\"Eau\", 1)], \"heure\": \"12:10\"},\n",
" {\"id\": 105, \"items\": [(\"Double Cheese\", 3), (\"Frites (G)\", 3), (\"Sundae Chocolat\", 3)], \"heure\": \"12:12\"}\n",
"]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 1 - Exploration du menu (25 min)\n",
"\n",
"### 1.1 Affichage d'une catégorie (4 pts)\n",
"\n",
"Écrivez une fonction `afficher_categorie(menu, categorie)` qui affiche les articles d'une catégorie.\n",
"\n",
"Exemple :\n",
"```\n",
"=== BURGERS ===\n",
"Big Mac : 5.50 euros (540 cal)\n",
"McChicken : 4.90 euros (400 cal)\n",
"...\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def afficher_categorie(menu, categorie):\n",
" if categorie not in menu:\n",
" print(\"Categorie inconnue\")\n",
" return\n",
" \n",
" print(\"===\", categorie.upper(), \"===\")\n",
" \n",
" articles = menu[categorie]\n",
" for nom, infos in articles.items():\n",
" # Votre code ici : afficher le nom, prix et calories\n",
" pass\n",
"\n",
"# Test\n",
"afficher_categorie(menu, \"burgers\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 1.2 Rechercher un article (4 pts)\n",
"\n",
"Écrivez une fonction `rechercher_article(menu, nom)` qui cherche un article par son nom.\n",
"\n",
"Renvoie un dictionnaire `{\"nom\": ..., \"categorie\": ..., \"prix\": ..., \"calories\": ...}` ou `None` si non trouvé."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def rechercher_article(menu, nom):\n",
" for categorie, articles in menu.items():\n",
" if nom in articles:\n",
" infos = articles[nom]\n",
" # Votre code ici : renvoyer le dictionnaire avec nom, categorie, prix, calories\n",
" pass\n",
" return None\n",
"\n",
"# Tests\n",
"article = rechercher_article(menu, \"Big Mac\")\n",
"if article:\n",
" print(article[\"nom\"], \"trouve dans\", article[\"categorie\"])\n",
" print(\"Prix :\", article[\"prix\"], \"euros\")\n",
"\n",
"print()\n",
"print(\"Pizza :\", rechercher_article(menu, \"Pizza\"))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 1.3 Article le moins calorique (4 pts)\n",
"\n",
"Écrivez une fonction `moins_calorique(menu, categorie)` qui renvoie l'article le moins calorique d'une catégorie.\n",
"\n",
"Si `categorie` est `None`, chercher dans tout le menu.\n",
"\n",
"Renvoie un tuple `(nom, calories)`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def moins_calorique(menu, categorie):\n",
" meilleur_nom = None\n",
" meilleur_cal = 99999\n",
" \n",
" if categorie != None:\n",
" # Chercher dans une seule categorie\n",
" articles = menu[categorie]\n",
" for nom, infos in articles.items():\n",
" # Votre code ici\n",
" pass\n",
" else:\n",
" # Chercher dans tout le menu\n",
" for cat, articles in menu.items():\n",
" for nom, infos in articles.items():\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return (meilleur_nom, meilleur_cal)\n",
"\n",
"# Tests\n",
"print(\"Moins calorique (burgers) :\", moins_calorique(menu, \"burgers\"))\n",
"print(\"Moins calorique (tout) :\", moins_calorique(menu, None))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 2 - Gestion des commandes (35 min)\n",
"\n",
"### 2.1 Calculer le prix d'une commande (6 pts)\n",
"\n",
"Écrivez une fonction `calculer_prix(commande, menu, menus_bestof)` qui calcule le prix total d'une commande.\n",
"\n",
"Attention : les articles peuvent être des Best-Of ou des articles individuels.\n",
"\n",
"*Aide : utilisez `rechercher_article()` pour trouver le prix d'un article dans le menu.*"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def calculer_prix(commande, menu, menus_bestof):\n",
" total = 0\n",
" \n",
" for item in commande[\"items\"]:\n",
" nom_article = item[0]\n",
" quantite = item[1]\n",
" \n",
" # Verifier si c'est un Best-Of\n",
" if nom_article in menus_bestof:\n",
" # Votre code ici : ajouter le prix du Best-Of * quantite\n",
" pass\n",
" else:\n",
" # Chercher dans le menu normal avec rechercher_article\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return round(total, 2)\n",
"\n",
"# Test\n",
"for cmd in commandes_en_cours:\n",
" prix = calculer_prix(cmd, menu, menus_bestof)\n",
" print(\"Commande\", cmd[\"id\"], \":\", prix, \"euros\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.2 Calculer les calories d'une commande (5 pts)\n",
"\n",
"Écrivez une fonction `calculer_calories(commande, menu, menus_bestof)` qui calcule le total des calories.\n",
"\n",
"Pour un Best-Of, additionner les calories du burger, des frites et de la boisson."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def calculer_calories(commande, menu, menus_bestof):\n",
" total_cal = 0\n",
" \n",
" for item in commande[\"items\"]:\n",
" nom_article = item[0]\n",
" quantite = item[1]\n",
" \n",
" # Verifier si c'est un Best-Of\n",
" if nom_article in menus_bestof:\n",
" bestof = menus_bestof[nom_article]\n",
" # Votre code ici : additionner les calories du burger, frites et boisson\n",
" pass\n",
" else:\n",
" # Chercher dans le menu normal\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return total_cal\n",
"\n",
"# Test\n",
"for cmd in commandes_en_cours:\n",
" cal = calculer_calories(cmd, menu, menus_bestof)\n",
" print(\"Commande\", cmd[\"id\"], \":\", cal, \"calories\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.3 Ticket de caisse (6 pts)\n",
"\n",
"Écrivez une fonction `generer_ticket(commande, menu, menus_bestof)` qui génère un ticket de caisse sous forme de chaîne de caractères."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def generer_ticket(commande, menu, menus_bestof):\n",
" lignes = []\n",
" lignes.append(\"=\" * 30)\n",
" lignes.append(\"COMMANDE #\" + str(commande[\"id\"]))\n",
" lignes.append(\"Heure : \" + commande[\"heure\"])\n",
" lignes.append(\"-\" * 30)\n",
" \n",
" for item in commande[\"items\"]:\n",
" nom_article = item[0]\n",
" quantite = item[1]\n",
" \n",
" # Trouver le prix de l'article\n",
" # Votre code ici\n",
" prix = 0\n",
" \n",
" sous_total = prix * quantite\n",
" ligne = str(quantite) + \"x \" + nom_article + \" - \" + str(sous_total) + \" euros\"\n",
" lignes.append(ligne)\n",
" \n",
" lignes.append(\"-\" * 30)\n",
" total = calculer_prix(commande, menu, menus_bestof)\n",
" lignes.append(\"TOTAL : \" + str(total) + \" euros\")\n",
" lignes.append(\"=\" * 30)\n",
" \n",
" return \"\\n\".join(lignes)\n",
"\n",
"# Test\n",
"print(generer_ticket(commandes_en_cours[0], menu, menus_bestof))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.4 Chiffre d'affaires (5 pts)\n",
"\n",
"Écrivez une fonction `chiffre_affaires(commandes, menu, menus_bestof)` qui calcule le chiffre d'affaires total de toutes les commandes."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def chiffre_affaires(commandes, menu, menus_bestof):\n",
" total = 0\n",
" \n",
" for commande in commandes:\n",
" # Votre code ici : utiliser calculer_prix\n",
" pass\n",
" \n",
" return round(total, 2)\n",
"\n",
"# Test\n",
"ca = chiffre_affaires(commandes_en_cours, menu, menus_bestof)\n",
"print(\"Chiffre d'affaires :\", ca, \"euros\")\n",
"print(\"Nombre de commandes :\", len(commandes_en_cours))\n",
"print(\"Panier moyen :\", round(ca / len(commandes_en_cours), 2), \"euros\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 3 - Bonus (20 min)\n",
"\n",
"### 3.1 Article le plus commandé (5 pts)\n",
"\n",
"Écrivez une fonction `article_plus_commande(commandes)` qui renvoie l'article le plus commandé (en nombre total).\n",
"\n",
"Renvoie un tuple `(nom_article, nombre_total)`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def article_plus_commande(commandes):\n",
" compteur = {}\n",
" \n",
" for commande in commandes:\n",
" for item in commande[\"items\"]:\n",
" nom = item[0]\n",
" quantite = item[1]\n",
" # Votre code ici : incrementer le compteur\n",
" pass\n",
" \n",
" # Trouver le maximum\n",
" meilleur = None\n",
" meilleur_nb = 0\n",
" \n",
" for article, nb in compteur.items():\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return (meilleur, meilleur_nb)\n",
"\n",
"# Test\n",
"art, nb = article_plus_commande(commandes_en_cours)\n",
"print(\"Article le plus commande :\", art, \"(\", nb, \"fois)\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3.2 Économie Best-Of (5 pts)\n",
"\n",
"Écrivez une fonction `economie_bestof(nom_bestof, menu, menus_bestof)` qui calcule l'économie réalisée en prenant un Best-Of par rapport aux articles séparés."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def economie_bestof(nom_bestof, menu, menus_bestof):\n",
" if nom_bestof not in menus_bestof:\n",
" return 0\n",
" \n",
" bestof = menus_bestof[nom_bestof]\n",
" prix_bestof = bestof[\"prix\"]\n",
" \n",
" # Calculer le prix des articles separes (burger + frites + boisson)\n",
" # Votre code ici\n",
" prix_separe = 0\n",
" \n",
" economie = prix_separe - prix_bestof\n",
" \n",
" return round(economie, 2)\n",
"\n",
"# Test\n",
"for nom in menus_bestof.keys():\n",
" eco = economie_bestof(nom, menu, menus_bestof)\n",
" print(nom, \": economie de\", eco, \"euros\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3.3 Statistiques par catégorie (4 pts)\n",
"\n",
"Écrivez une fonction `stats_menu(menu)` qui renvoie des statistiques pour chaque catégorie : nombre d'articles, prix moyen, calories moyennes."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def stats_menu(menu):\n",
" stats = {}\n",
" \n",
" for categorie, articles in menu.items():\n",
" nb = len(articles)\n",
" total_prix = 0\n",
" total_cal = 0\n",
" \n",
" for nom, infos in articles.items():\n",
" # Votre code ici : cumuler prix et calories\n",
" pass\n",
" \n",
" stats[categorie] = {\n",
" \"nb_articles\": nb,\n",
" \"prix_moyen\": round(total_prix / nb, 2),\n",
" \"calories_moyennes\": round(total_cal / nb)\n",
" }\n",
" \n",
" return stats\n",
"\n",
"# Test\n",
"print(\"Statistiques du menu :\")\n",
"for cat, data in stats_menu(menu).items():\n",
" print(\" \", cat, \":\")\n",
" print(\" Articles :\", data[\"nb_articles\"])\n",
" print(\" Prix moyen :\", data[\"prix_moyen\"], \"euros\")\n",
" print(\" Calories moyennes :\", data[\"calories_moyennes\"])"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.9.0"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

View File

@@ -1,282 +0,0 @@
# Aide - TP08 McDonald's
## Rappels utiles
### Structure du menu (dictionnaire imbrique)
```python
# menu = {categorie: {article: {infos}}}
menu = {
"burgers": {
"Big Mac": {"prix": 5.50, "calories": 540, "temps_prep": 3},
"McChicken": {"prix": 4.90, "calories": 420, "temps_prep": 3}
},
"accompagnements": {...},
"boissons": {...}
}
# Acceder au prix du Big Mac
prix = menu["burgers"]["Big Mac"]["prix"]
# Parcourir toutes les categories
for categorie, articles in menu.items():
for nom_article, infos in articles.items():
print(nom_article, ":", infos["prix"], "euros")
```
### Structure des commandes
```python
commande = {
"id": 101,
"items": [("Big Mac", 2), ("Frites (G)", 2)], # (article, quantite)
"heure": "12:05"
}
# Parcourir les items
for article, quantite in commande["items"]:
print(quantite, "x", article)
```
### Trouver un article dans le menu
```python
def trouver_article(menu, nom):
for categorie, articles in menu.items():
if nom in articles:
return articles[nom]
return None
```
---
## Exercice 1
### 1.1 - Affichage du menu
```python
def afficher_menu(menu, categorie):
if categorie in menu:
print("===", categorie.upper(), "===")
for nom, infos in menu[categorie].items():
print(" ", nom, ":", infos["prix"], "euros (", infos["calories"], "cal)")
```
### 1.2 - Recherche d'articles
```python
def rechercher_article(menu, nom_recherche):
resultats = []
nom_lower = nom_recherche.lower()
for categorie, articles in menu.items():
for nom_article, infos in articles.items():
if nom_lower in nom_article.lower():
resultats.append({
"nom": nom_article,
"categorie": categorie,
"prix": infos["prix"],
"calories": infos["calories"]
})
return resultats
```
### 1.3 - Statistiques du menu
```python
def stats_menu(menu):
tous_articles = []
for categorie, articles in menu.items():
for nom, infos in articles.items():
tous_articles.append({"nom": nom, "infos": infos})
# Prix moyen
total_prix = 0
for article in tous_articles:
total_prix = total_prix + article["infos"]["prix"]
prix_moyen = total_prix / len(tous_articles)
# Article le moins calorique
min_cal = tous_articles[0]
for article in tous_articles:
if article["infos"]["calories"] < min_cal["infos"]["calories"]:
min_cal = article
return {
"prix_moyen": round(prix_moyen, 2),
"article_moins_calorique": min_cal["nom"]
}
```
---
## Exercice 2
### 2.1 - Calculer le prix
```python
def calculer_prix(commande, menu, menus_bestof):
total = 0
for article, qte in commande["items"]:
# Verifier si c'est un Best-Of
if article in menus_bestof:
total = total + menus_bestof[article]["prix"] * qte
else:
# Chercher dans le menu normal
for categorie, articles in menu.items():
if article in articles:
total = total + articles[article]["prix"] * qte
break
return total
```
### 2.2 - Temps de preparation
```python
def temps_preparation(commande, menu, menus_bestof):
temps_par_categorie = {}
for article, qte in commande["items"]:
if article in menus_bestof:
# Best-Of = burger + frites + boisson
# Ajouter le temps du burger (le plus long)
temps_par_categorie["burgers"] = max(
temps_par_categorie.get("burgers", 0), 3
)
else:
# Trouver la categorie et le temps
for categorie, articles in menu.items():
if article in articles:
temps = articles[article]["temps_prep"]
# Garder le max par categorie (preparation parallele)
temps_par_categorie[categorie] = max(
temps_par_categorie.get(categorie, 0), temps
)
break
# Additionner les temps des differentes categories
total = 0
for temps in temps_par_categorie.values():
total = total + temps
return total
```
### 2.3 - Calories totales
```python
def calories_commande(commande, menu, menus_bestof):
total_calories = 0
for article, qte in commande["items"]:
if article in menus_bestof:
total_calories = total_calories + menus_bestof[article]["calories"] * qte
else:
for categorie, articles in menu.items():
if article in articles:
total_calories = total_calories + articles[article]["calories"] * qte
break
return total_calories
```
---
## Exercice 3 (Bonus)
### 3.1 - Ticket de caisse
```python
def generer_ticket(commande, menu, menus_bestof):
lignes = []
lignes.append("=" * 30)
lignes.append("COMMANDE #" + str(commande["id"]))
lignes.append("Heure: " + commande["heure"])
lignes.append("-" * 30)
total = 0
for article, qte in commande["items"]:
# Trouver le prix
prix = 0
if article in menus_bestof:
prix = menus_bestof[article]["prix"]
else:
for cat, articles in menu.items():
if article in articles:
prix = articles[article]["prix"]
break
sous_total = prix * qte
total = total + sous_total
lignes.append(str(qte) + "x " + article + " : " + str(sous_total) + " euros")
lignes.append("-" * 30)
lignes.append("TOTAL: " + str(total) + " euros")
lignes.append("=" * 30)
return "\n".join(lignes)
```
### 3.2 - Repas optimal
```python
def repas_optimal(menu, budget, calories_max):
meilleur_repas = None
meilleur_score = -1
for burger_nom, burger in menu["burgers"].items():
for accomp_nom, accomp in menu["accompagnements"].items():
for boisson_nom, boisson in menu["boissons"].items():
prix = burger["prix"] + accomp["prix"] + boisson["prix"]
calories = burger["calories"] + accomp["calories"] + boisson["calories"]
if prix <= budget and calories <= calories_max:
# Score = satisfaction / prix
satisfaction = 100 - calories / 10
score = satisfaction / prix
if score > meilleur_score:
meilleur_score = score
meilleur_repas = {
"burger": burger_nom,
"accompagnement": accomp_nom,
"boisson": boisson_nom,
"prix_total": prix,
"calories_total": calories
}
return meilleur_repas
```
### 3.3 - Analyse de la file
```python
def analyser_file(commandes, menu, menus_bestof):
chiffre_affaires = 0
# Compter les articles
compteur_articles = {}
for cmd in commandes:
chiffre_affaires = chiffre_affaires + calculer_prix(cmd, menu, menus_bestof)
for article, qte in cmd["items"]:
if article not in compteur_articles:
compteur_articles[article] = 0
compteur_articles[article] = compteur_articles[article] + qte
# Trouver l'article le plus commande
article_star = None
max_qte = 0
for article, qte in compteur_articles.items():
if qte > max_qte:
article_star = article
max_qte = qte
return {
"nb_commandes": len(commandes),
"chiffre_affaires": chiffre_affaires,
"article_plus_commande": article_star
}
```
---
## Pieges a eviter
1. **Best-Of vs articles individuels** : verifiez d'abord si l'article est un Best-Of avant de chercher dans le menu
2. **Temps de preparation** : meme categorie = parallele (max), categories differentes = sequentiel (somme)
3. **Prix avec decimales** : utilisez round() pour arrondir
4. **Quantites** : n'oubliez pas de multiplier par la quantite !
5. **Articles avec tailles** : "Frites (M)" et "Frites (G)" sont des articles differents

View File

@@ -1,559 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# TP Évaluation - Statistiques Fortnite\n",
"\n",
"**Durée : 1h30**\n",
"\n",
"**Nom :** \n",
"\n",
"**Prénom :**\n",
"\n",
"---\n",
"\n",
"Dans ce TP, vous allez analyser des statistiques de joueurs Fortnite.\n",
"\n",
"**Compétences évaluées :**\n",
"- Dictionnaires imbriqués\n",
"- Algorithmes de calcul statistique\n",
"- Filtrage et tri de données"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Données initiales\n",
"\n",
"**Exécutez cette cellule avant de commencer.**"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Statistiques des joueurs\n",
"joueurs = {\n",
" \"NinjaMaster\": {\n",
" \"niveau\": 250,\n",
" \"vbucks\": 3500,\n",
" \"stats\": {\n",
" \"solo\": {\"parties\": 450, \"victoires\": 89, \"kills\": 2340},\n",
" \"duo\": {\"parties\": 320, \"victoires\": 65, \"kills\": 1890},\n",
" \"squad\": {\"parties\": 280, \"victoires\": 72, \"kills\": 1650}\n",
" },\n",
" \"inventaire\": [\"Pioche Spectrale\", \"Planeur Dragon\", \"Skin Raven\"]\n",
" },\n",
" \"BuilderPro\": {\n",
" \"niveau\": 180,\n",
" \"vbucks\": 1200,\n",
" \"stats\": {\n",
" \"solo\": {\"parties\": 280, \"victoires\": 42, \"kills\": 1120},\n",
" \"duo\": {\"parties\": 450, \"victoires\": 98, \"kills\": 2450},\n",
" \"squad\": {\"parties\": 380, \"victoires\": 110, \"kills\": 2100}\n",
" },\n",
" \"inventaire\": [\"Pioche Arc-en-ciel\", \"Skin Drift\"]\n",
" },\n",
" \"SniperElite\": {\n",
" \"niveau\": 320,\n",
" \"vbucks\": 8900,\n",
" \"stats\": {\n",
" \"solo\": {\"parties\": 680, \"victoires\": 156, \"kills\": 4200},\n",
" \"duo\": {\"parties\": 220, \"victoires\": 45, \"kills\": 980},\n",
" \"squad\": {\"parties\": 150, \"victoires\": 28, \"kills\": 620}\n",
" },\n",
" \"inventaire\": [\"Pioche Galaxy\", \"Planeur Meteore\", \"Skin Black Knight\", \"Skin Omega\"]\n",
" },\n",
" \"CasualGamer\": {\n",
" \"niveau\": 85,\n",
" \"vbucks\": 500,\n",
" \"stats\": {\n",
" \"solo\": {\"parties\": 120, \"victoires\": 8, \"kills\": 180},\n",
" \"duo\": {\"parties\": 200, \"victoires\": 22, \"kills\": 420},\n",
" \"squad\": {\"parties\": 350, \"victoires\": 45, \"kills\": 680}\n",
" },\n",
" \"inventaire\": [\"Skin Default\", \"Pioche Standard\"]\n",
" },\n",
" \"StreamerKing\": {\n",
" \"niveau\": 450,\n",
" \"vbucks\": 25000,\n",
" \"stats\": {\n",
" \"solo\": {\"parties\": 1200, \"victoires\": 312, \"kills\": 8900},\n",
" \"duo\": {\"parties\": 800, \"victoires\": 245, \"kills\": 5600},\n",
" \"squad\": {\"parties\": 600, \"victoires\": 198, \"kills\": 4200}\n",
" },\n",
" \"inventaire\": [\"Pioche Galaxy\", \"Skin Skull Trooper\", \"Skin Ghoul Trooper\", \"Planeur Dragon\", \"Skin Renegade Raider\"]\n",
" }\n",
"}\n",
"\n",
"# Boutique du jour\n",
"boutique = [\n",
" {\"nom\": \"Skin Crystal\", \"type\": \"skin\", \"rarete\": \"rare\", \"prix\": 1200},\n",
" {\"nom\": \"Skin Aura\", \"type\": \"skin\", \"rarete\": \"uncommon\", \"prix\": 800},\n",
" {\"nom\": \"Skin Raptor\", \"type\": \"skin\", \"rarete\": \"legendary\", \"prix\": 2000},\n",
" {\"nom\": \"Pioche Laser\", \"type\": \"pioche\", \"rarete\": \"rare\", \"prix\": 800},\n",
" {\"nom\": \"Pioche Feu\", \"type\": \"pioche\", \"rarete\": \"uncommon\", \"prix\": 500},\n",
" {\"nom\": \"Planeur Etoile\", \"type\": \"planeur\", \"rarete\": \"epic\", \"prix\": 1200},\n",
" {\"nom\": \"Emote Dance\", \"type\": \"emote\", \"rarete\": \"rare\", \"prix\": 500}\n",
"]\n",
"\n",
"# Historique des parties recentes\n",
"parties_recentes = [\n",
" {\"joueur\": \"NinjaMaster\", \"mode\": \"solo\", \"placement\": 1, \"kills\": 8},\n",
" {\"joueur\": \"NinjaMaster\", \"mode\": \"solo\", \"placement\": 15, \"kills\": 3},\n",
" {\"joueur\": \"BuilderPro\", \"mode\": \"duo\", \"placement\": 1, \"kills\": 6},\n",
" {\"joueur\": \"SniperElite\", \"mode\": \"solo\", \"placement\": 1, \"kills\": 12},\n",
" {\"joueur\": \"SniperElite\", \"mode\": \"solo\", \"placement\": 3, \"kills\": 7},\n",
" {\"joueur\": \"CasualGamer\", \"mode\": \"squad\", \"placement\": 8, \"kills\": 2},\n",
" {\"joueur\": \"StreamerKing\", \"mode\": \"solo\", \"placement\": 1, \"kills\": 15},\n",
" {\"joueur\": \"StreamerKing\", \"mode\": \"duo\", \"placement\": 1, \"kills\": 9},\n",
" {\"joueur\": \"BuilderPro\", \"mode\": \"squad\", \"placement\": 2, \"kills\": 5}\n",
"]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 1 - Analyse des profils (25 min)\n",
"\n",
"### 1.1 Affichage de profil (4 pts)\n",
"\n",
"Écrivez une fonction `afficher_profil(pseudo, joueurs)` qui affiche le profil d'un joueur.\n",
"\n",
"Exemple :\n",
"```\n",
"=== NinjaMaster ===\n",
"Niveau : 250 | V-Bucks : 3500\n",
"Inventaire : 3 items\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def afficher_profil(pseudo, joueurs):\n",
" if pseudo not in joueurs:\n",
" print(\"Joueur non trouve\")\n",
" return\n",
" \n",
" profil = joueurs[pseudo]\n",
" \n",
" # Votre code ici : afficher le pseudo, niveau, vbucks et nb d'items\n",
" pass\n",
"\n",
"# Test\n",
"afficher_profil(\"NinjaMaster\", joueurs)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 1.2 Statistiques globales (4 pts)\n",
"\n",
"Écrivez une fonction `stats_globales(pseudo, joueurs)` qui calcule pour un joueur :\n",
"- `parties_totales` : somme de toutes les parties\n",
"- `victoires_totales` : somme de toutes les victoires\n",
"- `kills_totaux` : somme de tous les kills\n",
"- `winrate` : pourcentage de victoires (arrondi à 2 décimales)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def stats_globales(pseudo, joueurs):\n",
" profil = joueurs[pseudo]\n",
" stats = profil[\"stats\"]\n",
" \n",
" parties_totales = 0\n",
" victoires_totales = 0\n",
" kills_totaux = 0\n",
" \n",
" for mode, data in stats.items():\n",
" # Votre code ici : cumuler parties, victoires et kills\n",
" pass\n",
" \n",
" # Calculer le winrate\n",
" # Votre code ici\n",
" winrate = 0\n",
" \n",
" return {\n",
" \"parties_totales\": parties_totales,\n",
" \"victoires_totales\": victoires_totales,\n",
" \"kills_totaux\": kills_totaux,\n",
" \"winrate\": winrate\n",
" }\n",
"\n",
"# Test\n",
"stats = stats_globales(\"SniperElite\", joueurs)\n",
"print(\"Stats de SniperElite :\")\n",
"print(\" Parties :\", stats[\"parties_totales\"])\n",
"print(\" Victoires :\", stats[\"victoires_totales\"])\n",
"print(\" Kills :\", stats[\"kills_totaux\"])\n",
"print(\" Winrate :\", stats[\"winrate\"], \"%\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 1.3 Mode préféré (4 pts)\n",
"\n",
"Écrivez une fonction `mode_prefere(pseudo, joueurs)` qui renvoie le mode de jeu (solo, duo, squad) où le joueur a joué le plus de parties."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def mode_prefere(pseudo, joueurs):\n",
" profil = joueurs[pseudo]\n",
" stats = profil[\"stats\"]\n",
" \n",
" meilleur_mode = None\n",
" max_parties = 0\n",
" \n",
" for mode, data in stats.items():\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return meilleur_mode\n",
"\n",
"# Test\n",
"for pseudo in joueurs:\n",
" print(pseudo, \"prefere le mode\", mode_prefere(pseudo, joueurs))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 2 - Classements et boutique (35 min)\n",
"\n",
"### 2.1 Classement par critère (6 pts)\n",
"\n",
"Écrivez une fonction `classement(joueurs, critere)` qui renvoie la liste des pseudos triés selon le critère.\n",
"\n",
"Critères possibles : `\"niveau\"`, `\"victoires\"`, `\"kills\"`, `\"winrate\"`\n",
"\n",
"*Aide : créez d'abord une liste de tuples (pseudo, valeur), triez-la, puis extrayez les pseudos.*"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def classement(joueurs, critere):\n",
" # Creer une liste de tuples (pseudo, valeur)\n",
" liste = []\n",
" \n",
" for pseudo in joueurs:\n",
" if critere == \"niveau\":\n",
" valeur = joueurs[pseudo][\"niveau\"]\n",
" elif critere == \"victoires\":\n",
" stats = stats_globales(pseudo, joueurs)\n",
" valeur = stats[\"victoires_totales\"]\n",
" elif critere == \"kills\":\n",
" stats = stats_globales(pseudo, joueurs)\n",
" valeur = stats[\"kills_totaux\"]\n",
" elif critere == \"winrate\":\n",
" stats = stats_globales(pseudo, joueurs)\n",
" valeur = stats[\"winrate\"]\n",
" else:\n",
" valeur = 0\n",
" \n",
" liste.append((pseudo, valeur))\n",
" \n",
" # Trier par valeur decroissante\n",
" # Votre code ici\n",
" pass\n",
" \n",
" # Extraire les pseudos\n",
" resultat = []\n",
" for item in liste:\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return resultat\n",
"\n",
"# Tests\n",
"print(\"Par niveau :\", classement(joueurs, \"niveau\"))\n",
"print(\"Par victoires :\", classement(joueurs, \"victoires\"))\n",
"print(\"Par winrate :\", classement(joueurs, \"winrate\"))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.2 Articles achetables (5 pts)\n",
"\n",
"Écrivez une fonction `articles_achetables(pseudo, joueurs, boutique)` qui renvoie la liste des articles que le joueur peut acheter avec ses V-Bucks.\n",
"\n",
"Exclure les articles déjà possédés dans l'inventaire."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def articles_achetables(pseudo, joueurs, boutique):\n",
" profil = joueurs[pseudo]\n",
" vbucks = profil[\"vbucks\"]\n",
" inventaire = profil[\"inventaire\"]\n",
" \n",
" achetables = []\n",
" \n",
" for article in boutique:\n",
" # Verifier le prix et si pas deja possede\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return achetables\n",
"\n",
"# Test\n",
"print(\"Articles achetables pour BuilderPro :\")\n",
"for art in articles_achetables(\"BuilderPro\", joueurs, boutique):\n",
" print(\" \", art[\"nom\"], \"-\", art[\"prix\"], \"V-Bucks\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.3 Comparaison de joueurs (6 pts)\n",
"\n",
"Écrivez une fonction `comparer_joueurs(pseudo1, pseudo2, joueurs)` qui compare deux joueurs.\n",
"\n",
"Renvoie un dictionnaire indiquant pour chaque critère (niveau, victoires, kills, winrate) quel joueur est meilleur."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def comparer_joueurs(pseudo1, pseudo2, joueurs):\n",
" stats1 = stats_globales(pseudo1, joueurs)\n",
" stats2 = stats_globales(pseudo2, joueurs)\n",
" \n",
" comparaison = {}\n",
" \n",
" # Comparer le niveau\n",
" # Votre code ici\n",
" pass\n",
" \n",
" # Comparer les victoires\n",
" # Votre code ici\n",
" pass\n",
" \n",
" # Comparer les kills\n",
" # Votre code ici\n",
" pass\n",
" \n",
" # Comparer le winrate\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return comparaison\n",
"\n",
"# Test\n",
"comp = comparer_joueurs(\"NinjaMaster\", \"SniperElite\", joueurs)\n",
"print(\"Comparaison NinjaMaster vs SniperElite :\")\n",
"for critere, gagnant in comp.items():\n",
" print(\" \", critere, \":\", gagnant)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.4 Joueur le plus riche (5 pts)\n",
"\n",
"Écrivez une fonction `plus_riche(joueurs)` qui renvoie le pseudo du joueur ayant le plus de V-Bucks."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def plus_riche(joueurs):\n",
" meilleur = None\n",
" max_vbucks = 0\n",
" \n",
" for pseudo, profil in joueurs.items():\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return meilleur\n",
"\n",
"# Test\n",
"riche = plus_riche(joueurs)\n",
"print(\"Joueur le plus riche :\", riche)\n",
"if riche:\n",
" print(\"V-Bucks :\", joueurs[riche][\"vbucks\"])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 3 - Bonus (20 min)\n",
"\n",
"### 3.1 Performances récentes (5 pts)\n",
"\n",
"Écrivez une fonction `performances_recentes(pseudo, parties)` qui analyse les parties récentes d'un joueur.\n",
"\n",
"Renvoie : `nb_parties`, `victoires`, `kills_moyen` (arrondi à 1 décimale)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def performances_recentes(pseudo, parties):\n",
" nb_parties = 0\n",
" victoires = 0\n",
" total_kills = 0\n",
" \n",
" for partie in parties:\n",
" if partie[\"joueur\"] == pseudo:\n",
" # Votre code ici\n",
" pass\n",
" \n",
" if nb_parties > 0:\n",
" kills_moyen = round(total_kills / nb_parties, 1)\n",
" else:\n",
" kills_moyen = 0\n",
" \n",
" return {\n",
" \"nb_parties\": nb_parties,\n",
" \"victoires\": victoires,\n",
" \"kills_moyen\": kills_moyen\n",
" }\n",
"\n",
"# Test\n",
"for pseudo in [\"NinjaMaster\", \"SniperElite\", \"StreamerKing\"]:\n",
" perf = performances_recentes(pseudo, parties_recentes)\n",
" print(pseudo, \":\", perf[\"victoires\"], \"/\", perf[\"nb_parties\"], \"victoires, \", perf[\"kills_moyen\"], \"kills/partie\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3.2 K/D Ratio (4 pts)\n",
"\n",
"Écrivez une fonction `kd_ratio(pseudo, joueurs)` qui calcule le ratio kills/deaths.\n",
"\n",
"Deaths = parties - victoires (on meurt une fois par partie perdue)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def kd_ratio(pseudo, joueurs):\n",
" stats = stats_globales(pseudo, joueurs)\n",
" \n",
" kills = stats[\"kills_totaux\"]\n",
" deaths = stats[\"parties_totales\"] - stats[\"victoires_totales\"]\n",
" \n",
" # Votre code ici : calculer le ratio (attention division par zero)\n",
" ratio = 0\n",
" \n",
" return ratio\n",
"\n",
"# Test\n",
"print(\"K/D Ratio :\")\n",
"for pseudo in joueurs:\n",
" print(\" \", pseudo, \":\", kd_ratio(pseudo, joueurs))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3.3 Items les plus possédés (5 pts)\n",
"\n",
"Écrivez une fonction `items_populaires(joueurs)` qui compte combien de joueurs possèdent chaque item et renvoie la liste triée par popularité décroissante.\n",
"\n",
"Renvoie une liste de tuples `(nom_item, nb_joueurs)`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def items_populaires(joueurs):\n",
" compteur = {}\n",
" \n",
" for pseudo, profil in joueurs.items():\n",
" for item in profil[\"inventaire\"]:\n",
" # Votre code ici : incrementer le compteur\n",
" pass\n",
" \n",
" # Convertir en liste de tuples et trier\n",
" liste = []\n",
" for item, nb in compteur.items():\n",
" liste.append((item, nb))\n",
" \n",
" # Votre code ici : trier par nb decroissant\n",
" pass\n",
" \n",
" return liste\n",
"\n",
"# Test\n",
"print(\"Items les plus possedes :\")\n",
"for item, nb in items_populaires(joueurs):\n",
" print(\" \", item, \":\", nb, \"joueur(s)\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.9.0"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

View File

@@ -1,339 +0,0 @@
# Aide - TP09 Fortnite
## Rappels utiles
### Structure des joueurs (dictionnaire imbrique)
```python
joueurs = {
"NinjaMaster": {
"niveau": 250,
"vbucks": 3500,
"stats": {
"solo": {"parties": 450, "victoires": 89, "kills": 2340, "top10": 180},
"duo": {"parties": 320, "victoires": 65, "kills": 1890, "top5": 110},
"squad": {"parties": 280, "victoires": 72, "kills": 1650, "top3": 95}
},
"inventaire": ["Pioche Spectrale", "Planeur Dragon"]
}
}
# Acceder aux stats solo d'un joueur
solo = joueurs["NinjaMaster"]["stats"]["solo"]
victoires_solo = solo["victoires"]
# Parcourir tous les joueurs
for pseudo, profil in joueurs.items():
print(pseudo, ": niveau", profil["niveau"])
```
### Structure de la boutique
```python
boutique = {
"skins": [
{"nom": "Skin Crystal", "rarete": "rare", "prix": 1200},
{"nom": "Skin Phoenix", "rarete": "epique", "prix": 1500}
],
"pioches": [...],
"planeurs": [...]
}
# Parcourir toutes les categories
for categorie, articles in boutique.items():
for article in articles:
print(article["nom"], ":", article["prix"], "V-Bucks")
```
---
## Exercice 1
### 1.1 - Affichage de profil
```python
def afficher_profil(pseudo, joueurs):
if pseudo not in joueurs:
print("Joueur non trouve")
return
profil = joueurs[pseudo]
print("===", pseudo, "===")
print("Niveau:", profil["niveau"])
print("V-Bucks:", profil["vbucks"])
print()
print("Statistiques:")
for mode, stats in profil["stats"].items():
print(" ", mode, ":", stats["victoires"], "victoires /", stats["parties"], "parties")
```
### 1.2 - Statistiques globales
```python
def stats_globales(pseudo, joueurs):
profil = joueurs[pseudo]
stats = profil["stats"]
# Calculer les totaux
parties = 0
victoires = 0
kills = 0
for mode, s in stats.items():
parties = parties + s["parties"]
victoires = victoires + s["victoires"]
kills = kills + s["kills"]
# Winrate
if parties > 0:
winrate = round(victoires * 100 / parties, 2)
else:
winrate = 0
# KD = kills / morts, morts = parties - victoires
morts = parties - victoires
if morts > 0:
kd = round(kills / morts, 2)
else:
kd = kills
# Mode prefere = celui avec le plus de parties
mode_prefere = None
max_parties = 0
for mode, s in stats.items():
if s["parties"] > max_parties:
mode_prefere = mode
max_parties = s["parties"]
return {
"parties_totales": parties,
"victoires_totales": victoires,
"kills_totaux": kills,
"winrate": winrate,
"kd_ratio": kd,
"mode_prefere": mode_prefere
}
```
### 1.3 - Classement des joueurs
```python
def classement(joueurs, critere):
liste_joueurs = []
if critere == "niveau":
for pseudo, profil in joueurs.items():
liste_joueurs.append((pseudo, profil["niveau"]))
liste_joueurs = sorted(liste_joueurs, key=lambda x: x[1], reverse=True)
elif critere == "victoires":
for pseudo, profil in joueurs.items():
total_victoires = 0
for mode, s in profil["stats"].items():
total_victoires = total_victoires + s["victoires"]
liste_joueurs.append((pseudo, total_victoires))
liste_joueurs = sorted(liste_joueurs, key=lambda x: x[1], reverse=True)
# Renvoyer juste les pseudos
pseudos = []
for pseudo, valeur in liste_joueurs:
pseudos.append(pseudo)
return pseudos
```
---
## Exercice 2
### 2.1 - Articles achetables
```python
def articles_achetables(pseudo, joueurs, boutique):
budget = joueurs[pseudo]["vbucks"]
inventaire = joueurs[pseudo]["inventaire"]
achetables = []
for categorie, articles in boutique.items():
for article in articles:
if article["prix"] <= budget and article["nom"] not in inventaire:
achetables.append(article)
return achetables
```
### 2.2 - Panier optimise
```python
def panier_optimal(pseudo, joueurs, boutique, priorites):
budget = joueurs[pseudo]["vbucks"]
inventaire = joueurs[pseudo]["inventaire"]
panier = []
for categorie in priorites:
if categorie not in boutique:
continue
# Trier par prix croissant pour maximiser le nombre d'achats
articles = sorted(boutique[categorie], key=lambda a: a["prix"])
for article in articles:
if article["nom"] not in inventaire and article["prix"] <= budget:
panier.append(article)
budget = budget - article["prix"]
return panier, budget
```
### 2.3 - Analyse des inventaires
```python
def analyser_inventaires(joueurs):
# Compter les occurrences de chaque item
compteur = {}
for pseudo, profil in joueurs.items():
for item in profil["inventaire"]:
if item not in compteur:
compteur[item] = 0
compteur[item] = compteur[item] + 1
# Items communs (possedes par plusieurs joueurs)
items_communs = []
for item, count in compteur.items():
if count >= 2:
items_communs.append(item)
# Items rares (possedes par un seul joueur)
items_rares = []
for item, count in compteur.items():
if count == 1:
items_rares.append(item)
# Collectionneur (le plus d'items)
collectionneur = None
max_items = 0
for pseudo, profil in joueurs.items():
if len(profil["inventaire"]) > max_items:
collectionneur = pseudo
max_items = len(profil["inventaire"])
return {
"items_communs": items_communs,
"items_rares": items_rares,
"joueur_collectionneur": collectionneur
}
```
---
## Exercice 3 (Bonus)
### 3.1 - Performances recentes
```python
def performances_recentes(pseudo, parties):
# Filtrer les parties du joueur
mes_parties = []
for p in parties:
if p["joueur"] == pseudo:
mes_parties.append(p)
if len(mes_parties) == 0:
return None
# Calculer les statistiques
victoires = 0
total_kills = 0
total_degats = 0
total_duree = 0
for p in mes_parties:
if p["placement"] == 1:
victoires = victoires + 1
total_kills = total_kills + p["kills"]
total_degats = total_degats + p["degats"]
total_duree = total_duree + p["duree"]
kills_moyen = round(total_kills / len(mes_parties), 1)
degats_moyens = round(total_degats / len(mes_parties))
duree_moyenne = round(total_duree / len(mes_parties))
# Meilleure partie
meilleure = mes_parties[0]
for p in mes_parties:
if p["kills"] > meilleure["kills"]:
meilleure = p
return {
"nb_parties": len(mes_parties),
"victoires": victoires,
"kills_moyen": kills_moyen,
"degats_moyens": degats_moyens,
"duree_moyenne": duree_moyenne,
"meilleure_partie": meilleure
}
```
### 3.2 - Comparaison de joueurs
```python
def comparer_joueurs(pseudo1, pseudo2, joueurs):
stats1 = stats_globales(pseudo1, joueurs)
stats2 = stats_globales(pseudo2, joueurs)
comparaison = {}
# Comparer les stats
if stats1["kills_totaux"] > stats2["kills_totaux"]:
comparaison["kills"] = pseudo1
else:
comparaison["kills"] = pseudo2
if stats1["winrate"] > stats2["winrate"]:
comparaison["winrate"] = pseudo1
else:
comparaison["winrate"] = pseudo2
if stats1["kd_ratio"] > stats2["kd_ratio"]:
comparaison["kd"] = pseudo1
else:
comparaison["kd"] = pseudo2
return comparaison
```
### 3.3 - Prediction de rang
```python
def calculer_rang(pseudo, joueurs):
stats = stats_globales(pseudo, joueurs)
profil = joueurs[pseudo]
# Winrate solo
solo = profil["stats"]["solo"]
if solo["parties"] > 0:
winrate_solo = solo["victoires"] * 100 / solo["parties"]
else:
winrate_solo = 0
# Calcul des points
points = 0
points = points + winrate_solo * 3
points = points + stats["kd_ratio"] * 50
points = points + stats["victoires_totales"] * 0.1
points = points + profil["niveau"] * 0.05
# Attribution du rang
if points >= 100:
rang = "Champion"
elif points >= 70:
rang = "Diamond"
elif points >= 50:
rang = "Platinum"
elif points >= 30:
rang = "Gold"
elif points >= 15:
rang = "Silver"
else:
rang = "Bronze"
return rang, round(points)
```
---
## Pieges a eviter
1. **KD ratio** : attention a la division par zero ! `morts = parties - victoires` peut etre 0
2. **Stats par mode** : solo a "top10", duo a "top5", squad a "top3"
3. **Inventaire = liste de strings** : utilisez `in` pour verifier si un item est possede
4. **V-Bucks** : ne pas oublier de soustraire apres chaque achat
5. **Parties recentes** : filtrer d'abord par joueur avant de calculer les stats

View File

@@ -1,541 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# TP Évaluation - Planification de Voyage\n",
"\n",
"**Durée : 1h30**\n",
"\n",
"**Nom :** \n",
"\n",
"**Prénom :**\n",
"\n",
"---\n",
"\n",
"Dans ce TP de synthèse, vous allez créer un système de planification de voyage.\n",
"\n",
"**Compétences évaluées :**\n",
"- Listes de tuples et dictionnaires\n",
"- Filtrage et tri de données\n",
"- Algorithmes de recherche"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Données initiales\n",
"\n",
"**Exécutez cette cellule avant de commencer.**"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Base de donnees des villes\n",
"# Chaque ville : (nom, pays, langue, monnaie, decalage_horaire)\n",
"villes = [\n",
" (\"Paris\", \"France\", \"Francais\", \"EUR\", 0),\n",
" (\"Londres\", \"Royaume-Uni\", \"Anglais\", \"GBP\", 0),\n",
" (\"New York\", \"Etats-Unis\", \"Anglais\", \"USD\", -6),\n",
" (\"Tokyo\", \"Japon\", \"Japonais\", \"JPY\", 8),\n",
" (\"Barcelone\", \"Espagne\", \"Espagnol\", \"EUR\", 0),\n",
" (\"Rome\", \"Italie\", \"Italien\", \"EUR\", 0),\n",
" (\"Amsterdam\", \"Pays-Bas\", \"Neerlandais\", \"EUR\", 0),\n",
" (\"Berlin\", \"Allemagne\", \"Allemand\", \"EUR\", 0),\n",
" (\"Dubai\", \"Emirats Arabes Unis\", \"Arabe\", \"AED\", 3),\n",
" (\"Sydney\", \"Australie\", \"Anglais\", \"AUD\", 9)\n",
"]\n",
"\n",
"# Base de donnees des hotels\n",
"# Chaque hotel est un dictionnaire\n",
"hotels = [\n",
" {\"nom\": \"Le Marais Boutique\", \"ville\": \"Paris\", \"etoiles\": 3, \"prix_nuit\": 120, \"note\": 8.5},\n",
" {\"nom\": \"Paris Luxury Palace\", \"ville\": \"Paris\", \"etoiles\": 5, \"prix_nuit\": 450, \"note\": 9.2},\n",
" {\"nom\": \"Eiffel Budget\", \"ville\": \"Paris\", \"etoiles\": 2, \"prix_nuit\": 65, \"note\": 7.1},\n",
" {\"nom\": \"London Central\", \"ville\": \"Londres\", \"etoiles\": 4, \"prix_nuit\": 180, \"note\": 8.8},\n",
" {\"nom\": \"Westminster Inn\", \"ville\": \"Londres\", \"etoiles\": 3, \"prix_nuit\": 95, \"note\": 7.9},\n",
" {\"nom\": \"Manhattan View\", \"ville\": \"New York\", \"etoiles\": 4, \"prix_nuit\": 220, \"note\": 8.6},\n",
" {\"nom\": \"Times Square Budget\", \"ville\": \"New York\", \"etoiles\": 2, \"prix_nuit\": 89, \"note\": 6.8},\n",
" {\"nom\": \"Tokyo Garden\", \"ville\": \"Tokyo\", \"etoiles\": 4, \"prix_nuit\": 150, \"note\": 9.0},\n",
" {\"nom\": \"Shibuya Capsule\", \"ville\": \"Tokyo\", \"etoiles\": 1, \"prix_nuit\": 35, \"note\": 7.5},\n",
" {\"nom\": \"Barcelona Beach\", \"ville\": \"Barcelone\", \"etoiles\": 4, \"prix_nuit\": 140, \"note\": 8.7},\n",
" {\"nom\": \"Roma Antica\", \"ville\": \"Rome\", \"etoiles\": 3, \"prix_nuit\": 110, \"note\": 8.3},\n",
" {\"nom\": \"Canal House\", \"ville\": \"Amsterdam\", \"etoiles\": 3, \"prix_nuit\": 130, \"note\": 8.4},\n",
" {\"nom\": \"Berlin Modern\", \"ville\": \"Berlin\", \"etoiles\": 3, \"prix_nuit\": 85, \"note\": 8.1},\n",
" {\"nom\": \"Burj Luxury\", \"ville\": \"Dubai\", \"etoiles\": 5, \"prix_nuit\": 380, \"note\": 9.4},\n",
" {\"nom\": \"Sydney Harbour\", \"ville\": \"Sydney\", \"etoiles\": 4, \"prix_nuit\": 200, \"note\": 8.9}\n",
"]\n",
"\n",
"# Base de donnees des vols (depuis Paris)\n",
"# Chaque vol : (compagnie, depart, arrivee, prix, escales)\n",
"vols = [\n",
" (\"Air France\", \"Paris\", \"Londres\", 120, 0),\n",
" (\"EasyJet\", \"Paris\", \"Londres\", 65, 0),\n",
" (\"Air France\", \"Paris\", \"New York\", 480, 0),\n",
" (\"Delta\", \"Paris\", \"New York\", 420, 0),\n",
" (\"United\", \"Paris\", \"New York\", 350, 1),\n",
" (\"JAL\", \"Paris\", \"Tokyo\", 750, 0),\n",
" (\"Air France\", \"Paris\", \"Tokyo\", 680, 0),\n",
" (\"ANA\", \"Paris\", \"Tokyo\", 620, 1),\n",
" (\"Vueling\", \"Paris\", \"Barcelone\", 85, 0),\n",
" (\"Air France\", \"Paris\", \"Barcelone\", 130, 0),\n",
" (\"Alitalia\", \"Paris\", \"Rome\", 110, 0),\n",
" (\"EasyJet\", \"Paris\", \"Rome\", 75, 0),\n",
" (\"KLM\", \"Paris\", \"Amsterdam\", 95, 0),\n",
" (\"Lufthansa\", \"Paris\", \"Berlin\", 110, 0),\n",
" (\"Emirates\", \"Paris\", \"Dubai\", 450, 0),\n",
" (\"Qantas\", \"Paris\", \"Sydney\", 980, 1),\n",
" (\"Emirates\", \"Paris\", \"Sydney\", 1100, 1)\n",
"]\n",
"\n",
"# Activites par ville\n",
"activites = {\n",
" \"Paris\": [\n",
" {\"nom\": \"Tour Eiffel\", \"prix\": 26, \"duree\": 2, \"type\": \"monument\"},\n",
" {\"nom\": \"Louvre\", \"prix\": 17, \"duree\": 4, \"type\": \"musee\"},\n",
" {\"nom\": \"Croisiere Seine\", \"prix\": 15, \"duree\": 1, \"type\": \"excursion\"}\n",
" ],\n",
" \"Londres\": [\n",
" {\"nom\": \"British Museum\", \"prix\": 0, \"duree\": 3, \"type\": \"musee\"},\n",
" {\"nom\": \"London Eye\", \"prix\": 32, \"duree\": 1, \"type\": \"attraction\"},\n",
" {\"nom\": \"Tower of London\", \"prix\": 28, \"duree\": 2, \"type\": \"monument\"}\n",
" ],\n",
" \"New York\": [\n",
" {\"nom\": \"Statue of Liberty\", \"prix\": 24, \"duree\": 4, \"type\": \"monument\"},\n",
" {\"nom\": \"Empire State Building\", \"prix\": 44, \"duree\": 2, \"type\": \"monument\"},\n",
" {\"nom\": \"Broadway Show\", \"prix\": 150, \"duree\": 3, \"type\": \"spectacle\"}\n",
" ],\n",
" \"Tokyo\": [\n",
" {\"nom\": \"Temple Senso-ji\", \"prix\": 0, \"duree\": 2, \"type\": \"monument\"},\n",
" {\"nom\": \"Tokyo Skytree\", \"prix\": 20, \"duree\": 2, \"type\": \"attraction\"},\n",
" {\"nom\": \"Robot Restaurant\", \"prix\": 80, \"duree\": 2, \"type\": \"spectacle\"}\n",
" ],\n",
" \"Barcelone\": [\n",
" {\"nom\": \"Sagrada Familia\", \"prix\": 26, \"duree\": 2, \"type\": \"monument\"},\n",
" {\"nom\": \"Parc Guell\", \"prix\": 10, \"duree\": 2, \"type\": \"parc\"},\n",
" {\"nom\": \"Camp Nou\", \"prix\": 28, \"duree\": 2, \"type\": \"sport\"}\n",
" ],\n",
" \"Rome\": [\n",
" {\"nom\": \"Colisee\", \"prix\": 16, \"duree\": 2, \"type\": \"monument\"},\n",
" {\"nom\": \"Vatican\", \"prix\": 20, \"duree\": 4, \"type\": \"monument\"},\n",
" {\"nom\": \"Fontaine de Trevi\", \"prix\": 0, \"duree\": 1, \"type\": \"monument\"}\n",
" ]\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 1 - Exploration des données (25 min)\n",
"\n",
"### 1.1 Affichage d'une ville (4 pts)\n",
"\n",
"Écrivez une fonction `afficher_ville(ville)` qui affiche les informations d'une ville.\n",
"\n",
"Exemple :\n",
"```\n",
"Tokyo (Japon)\n",
"Langue : Japonais | Monnaie : JPY\n",
"Decalage horaire : +8h\n",
"```\n",
"\n",
"*Rappel : ville[0] = nom, ville[1] = pays, ville[2] = langue, ville[3] = monnaie, ville[4] = decalage*"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def afficher_ville(ville):\n",
" nom = ville[0]\n",
" pays = ville[1]\n",
" langue = ville[2]\n",
" monnaie = ville[3]\n",
" decalage = ville[4]\n",
" \n",
" # Votre code ici : afficher les informations\n",
" pass\n",
"\n",
"# Test\n",
"afficher_ville(villes[3]) # Tokyo"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 1.2 Rechercher une ville (4 pts)\n",
"\n",
"Écrivez une fonction `rechercher_ville(nom, villes)` qui renvoie le tuple de la ville correspondante, ou `None` si non trouvée."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def rechercher_ville(nom, villes):\n",
" for ville in villes:\n",
" # Votre code ici\n",
" pass\n",
" return None\n",
"\n",
"# Test\n",
"v = rechercher_ville(\"Rome\", villes)\n",
"if v:\n",
" afficher_ville(v)\n",
"print()\n",
"print(\"Madrid :\", rechercher_ville(\"Madrid\", villes))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 1.3 Villes par monnaie (4 pts)\n",
"\n",
"Écrivez une fonction `villes_par_monnaie(villes, monnaie)` qui renvoie la liste des noms de villes utilisant cette monnaie."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def villes_par_monnaie(villes, monnaie):\n",
" resultats = []\n",
" \n",
" for ville in villes:\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return resultats\n",
"\n",
"# Test\n",
"print(\"Villes en zone Euro :\", villes_par_monnaie(villes, \"EUR\"))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 2 - Recherche d'hôtels et vols (35 min)\n",
"\n",
"### 2.1 Hôtels dans une ville (5 pts)\n",
"\n",
"Écrivez une fonction `hotels_ville(ville, hotels)` qui renvoie la liste des hôtels d'une ville, triés par note décroissante."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def hotels_ville(ville, hotels):\n",
" resultats = []\n",
" \n",
" for hotel in hotels:\n",
" # Votre code ici\n",
" pass\n",
" \n",
" # Trier par note decroissante\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return resultats\n",
"\n",
"# Test\n",
"print(\"Hotels a Paris :\")\n",
"for h in hotels_ville(\"Paris\", hotels):\n",
" print(\" \", h[\"nom\"], \"-\", h[\"etoiles\"], \"etoiles -\", h[\"prix_nuit\"], \"euros/nuit - Note:\", h[\"note\"])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.2 Vols vers une destination (5 pts)\n",
"\n",
"Écrivez une fonction `vols_vers(destination, vols)` qui renvoie la liste des vols vers cette destination, triés par prix croissant.\n",
"\n",
"*Rappel : vol[2] = arrivee, vol[3] = prix*"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def vols_vers(destination, vols):\n",
" resultats = []\n",
" \n",
" for vol in vols:\n",
" # Votre code ici\n",
" pass\n",
" \n",
" # Trier par prix croissant\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return resultats\n",
"\n",
"# Test\n",
"print(\"Vols vers Tokyo :\")\n",
"for v in vols_vers(\"Tokyo\", vols):\n",
" escales = \"direct\" if v[4] == 0 else str(v[4]) + \" escale(s)\"\n",
" print(\" \", v[0], \":\", v[3], \"euros (\", escales, \")\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.3 Vol le moins cher (5 pts)\n",
"\n",
"Écrivez une fonction `vol_moins_cher(destination, vols, direct_seulement)` qui renvoie le vol le moins cher vers une destination.\n",
"\n",
"Si `direct_seulement` est `True`, ne considérer que les vols sans escale."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def vol_moins_cher(destination, vols, direct_seulement):\n",
" meilleur = None\n",
" meilleur_prix = 999999\n",
" \n",
" for vol in vols:\n",
" if vol[2] == destination:\n",
" # Verifier si on veut que des vols directs\n",
" if direct_seulement and vol[4] > 0:\n",
" continue\n",
" \n",
" # Votre code ici : garder le vol le moins cher\n",
" pass\n",
" \n",
" return meilleur\n",
"\n",
"# Tests\n",
"vol = vol_moins_cher(\"New York\", vols, True)\n",
"if vol:\n",
" print(\"Vol direct le moins cher vers New York :\", vol[0], \"-\", vol[3], \"euros\")\n",
"\n",
"vol = vol_moins_cher(\"New York\", vols, False)\n",
"if vol:\n",
" print(\"Vol le moins cher vers New York (avec escales) :\", vol[0], \"-\", vol[3], \"euros\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2.4 Budget hotel (6 pts)\n",
"\n",
"Écrivez une fonction `hotels_budget(ville, hotels, budget_max, etoiles_min)` qui renvoie les hôtels correspondant aux critères, triés par prix croissant."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def hotels_budget(ville, hotels, budget_max, etoiles_min):\n",
" resultats = []\n",
" \n",
" for hotel in hotels:\n",
" # Verifier ville, budget et etoiles\n",
" # Votre code ici\n",
" pass\n",
" \n",
" # Trier par prix croissant\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return resultats\n",
"\n",
"# Test\n",
"print(\"Hotels a Paris, max 150 euros, min 3 etoiles :\")\n",
"for h in hotels_budget(\"Paris\", hotels, 150, 3):\n",
" print(\" \", h[\"nom\"], \"-\", h[\"prix_nuit\"], \"euros/nuit\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## Exercice 3 - Bonus (20 min)\n",
"\n",
"### 3.1 Calculer le budget voyage (5 pts)\n",
"\n",
"Écrivez une fonction `calculer_budget(destination, nuits, vol, hotel, activites_choisies, activites)` qui calcule le budget total.\n",
"\n",
"Budget = prix vol + (prix hotel × nuits) + somme des activités"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def calculer_budget(destination, nuits, vol, hotel, activites_choisies, activites):\n",
" budget = {}\n",
" \n",
" # Vol\n",
" budget[\"vol\"] = vol[3]\n",
" \n",
" # Hotel\n",
" budget[\"hotel\"] = hotel[\"prix_nuit\"] * nuits\n",
" \n",
" # Activites\n",
" budget[\"activites\"] = 0\n",
" if destination in activites:\n",
" for act in activites[destination]:\n",
" # Votre code ici : ajouter le prix si l'activite est choisie\n",
" pass\n",
" \n",
" budget[\"total\"] = budget[\"vol\"] + budget[\"hotel\"] + budget[\"activites\"]\n",
" \n",
" return budget\n",
"\n",
"# Test\n",
"vol_choisi = vols[6] # Air France Paris-Tokyo\n",
"hotel_choisi = hotels[7] # Tokyo Garden\n",
"acts = [\"Temple Senso-ji\", \"Tokyo Skytree\"]\n",
"\n",
"budget = calculer_budget(\"Tokyo\", 5, vol_choisi, hotel_choisi, acts, activites)\n",
"print(\"Budget voyage Tokyo :\")\n",
"for poste, montant in budget.items():\n",
" print(\" \", poste, \":\", montant, \"euros\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3.2 Activités gratuites (4 pts)\n",
"\n",
"Écrivez une fonction `activites_gratuites(activites)` qui renvoie la liste de toutes les activités gratuites (prix = 0).\n",
"\n",
"Renvoie une liste de dictionnaires `{\"ville\": ..., \"activite\": ...}`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def activites_gratuites(activites):\n",
" gratuites = []\n",
" \n",
" for ville, liste_acts in activites.items():\n",
" for act in liste_acts:\n",
" # Votre code ici\n",
" pass\n",
" \n",
" return gratuites\n",
"\n",
"# Test\n",
"print(\"Activites gratuites :\")\n",
"for a in activites_gratuites(activites):\n",
" print(\" \", a[\"ville\"], \":\", a[\"activite\"])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3.3 Destination la moins chère (5 pts)\n",
"\n",
"Écrivez une fonction `destination_moins_chere(vols, hotels, nuits)` qui trouve la destination la moins chère (vol + hotel × nuits).\n",
"\n",
"Pour chaque destination, prendre le vol le moins cher et l'hotel le moins cher."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def destination_moins_chere(vols, hotels, nuits):\n",
" # Trouver toutes les destinations\n",
" destinations = []\n",
" for vol in vols:\n",
" if vol[2] not in destinations:\n",
" destinations.append(vol[2])\n",
" \n",
" meilleure = None\n",
" meilleur_prix = 999999\n",
" \n",
" for dest in destinations:\n",
" # Trouver le vol le moins cher\n",
" vol = vol_moins_cher(dest, vols, False)\n",
" if vol == None:\n",
" continue\n",
" \n",
" # Trouver l'hotel le moins cher\n",
" hotels_dest = hotels_ville(dest, hotels)\n",
" if len(hotels_dest) == 0:\n",
" continue\n",
" \n",
" hotel_min = hotels_dest[0]\n",
" for h in hotels_dest:\n",
" if h[\"prix_nuit\"] < hotel_min[\"prix_nuit\"]:\n",
" hotel_min = h\n",
" \n",
" # Calculer le prix total\n",
" # Votre code ici : mettre a jour meilleure si prix_total est inferieur\n",
" prix_total = 0\n",
" \n",
" return meilleure\n",
"\n",
"# Test\n",
"dest = destination_moins_chere(vols, hotels, 3)\n",
"if dest:\n",
" print(\"Destination la moins chere pour 3 nuits :\")\n",
" print(\" Destination :\", dest[\"destination\"])\n",
" print(\" Vol :\", dest[\"vol\"], \"-\", dest[\"prix_vol\"], \"euros\")\n",
" print(\" Hotel :\", dest[\"hotel\"], \"-\", dest[\"prix_hotel\"], \"euros/nuit\")\n",
" print(\" Total :\", dest[\"total\"], \"euros\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.9.0"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

View File

@@ -1,336 +0,0 @@
# Aide - TP10 Planification de Voyage
## Rappels utiles
### Structure des villes (tuples)
```python
# Ville = (nom, pays, langue, monnaie, decalage_horaire)
ville = villes[0]
nom = ville[0] # "Paris"
pays = ville[1] # "France"
langue = ville[2] # "Francais"
monnaie = ville[3] # "EUR"
decalage = ville[4] # 0
# Parcourir les villes
for ville in villes:
print(ville[0], "-", ville[1])
```
### Structure des hotels (dictionnaires)
```python
hotels = {
"Paris": [
{"nom": "Hotel Lumiere", "etoiles": 4, "prix_nuit": 150, "services": ["wifi", "spa"], "note": 8.5},
{"nom": "Petit Paris", "etoiles": 2, "prix_nuit": 65, "services": ["wifi"], "note": 7.2}
],
"Londres": [...]
}
# Acceder aux hotels de Paris
hotels_paris = hotels["Paris"]
for h in hotels_paris:
print(h["nom"], "-", h["prix_nuit"], "euros/nuit")
```
### Structure des vols (tuples)
```python
# Vol = (compagnie, depart, arrivee, heure_depart, heure_arrivee, prix, escales)
vol = vols[0]
compagnie = vol[0] # "Air France"
depart = vol[1] # "Paris"
arrivee = vol[2] # "Londres"
heure_dep = vol[3] # "08:00"
heure_arr = vol[4] # "09:15"
prix = vol[5] # 120
escales = vol[6] # 0
```
### Structure des activites (dictionnaires)
```python
activites = {
"Paris": [
{"nom": "Tour Eiffel", "duree": 3, "prix": 25, "type": "monument"},
{"nom": "Louvre", "duree": 4, "prix": 17, "type": "musee"}
]
}
# Acceder aux activites d'une ville
acts_paris = activites.get("Paris", []) # [] si la ville n'existe pas
```
---
## Exercice 1
### 1.1 - Fiche destination
```python
def fiche_destination(nom_ville, villes, hotels, vols):
# Trouver la ville
ville = None
for v in villes:
if v[0] == nom_ville:
ville = v
break
if ville == None:
return "Ville non trouvee"
print("===", ville[0], "-", ville[1], "===")
print("Langue:", ville[2])
print("Monnaie:", ville[3])
print("Decalage horaire:", ville[4], "h")
# Compter les hotels
if nom_ville in hotels:
nb_hotels = len(hotels[nom_ville])
else:
nb_hotels = 0
print("Hotels disponibles:", nb_hotels)
# Compter les vols
nb_vols = 0
for vol in vols:
if vol[2] == nom_ville: # arrivee
nb_vols = nb_vols + 1
print("Vols disponibles:", nb_vols)
```
### 1.2 - Recherche de destinations
```python
def rechercher_destinations(villes, monnaie, decalage_max):
resultats = []
for ville in villes:
# Verifier la monnaie
if monnaie is not None and ville[3] != monnaie:
continue
# Verifier le decalage horaire
if decalage_max is not None and abs(ville[4]) > decalage_max:
continue
resultats.append(ville)
return resultats
```
### 1.3 - Statistiques
```python
def stats_base(villes, hotels, vols):
# Prix moyen des hotels
total_prix_hotels = 0
nb_hotels = 0
for ville, liste_hotels in hotels.items():
for h in liste_hotels:
total_prix_hotels = total_prix_hotels + h["prix_nuit"]
nb_hotels = nb_hotels + 1
if nb_hotels > 0:
prix_hotel_moyen = total_prix_hotels / nb_hotels
else:
prix_hotel_moyen = 0
# Prix moyen des vols
total_prix_vols = 0
for vol in vols:
total_prix_vols = total_prix_vols + vol[5]
if len(vols) > 0:
prix_vol_moyen = total_prix_vols / len(vols)
else:
prix_vol_moyen = 0
return {
"nb_destinations": len(villes),
"nb_hotels": nb_hotels,
"nb_vols": len(vols),
"prix_hotel_moyen": round(prix_hotel_moyen, 2),
"prix_vol_moyen": round(prix_vol_moyen, 2)
}
```
---
## Exercice 2
### 2.1 - Trouver les meilleurs vols
```python
def trouver_vols(vols, destination, critere):
# Filtrer les vols vers la destination
vols_dest = []
for v in vols:
if v[2] == destination:
vols_dest.append(v)
if critere == "prix":
vols_dest = sorted(vols_dest, key=lambda v: v[5])
elif critere == "direct":
# Direct d'abord (escales = 0), puis par prix
vols_dest = sorted(vols_dest, key=lambda v: (v[6], v[5]))
return vols_dest
```
### 2.2 - Trouver l'hotel ideal
```python
def trouver_hotel(hotels, ville, budget_nuit, services_requis, etoiles_min):
if ville not in hotels:
return []
resultats = []
for h in hotels[ville]:
# Verifier le budget
if budget_nuit is not None and h["prix_nuit"] > budget_nuit:
continue
# Verifier les etoiles
if etoiles_min is not None and h["etoiles"] < etoiles_min:
continue
# Verifier les services
if services_requis is not None:
a_tous_services = True
for service in services_requis:
if service not in h["services"]:
a_tous_services = False
break
if not a_tous_services:
continue
resultats.append(h)
# Trier par note decroissante
resultats = sorted(resultats, key=lambda h: h["note"], reverse=True)
return resultats
```
### 2.3 - Planifier les activites
```python
def planifier_activites(ville, activites, jours, budget_max):
if ville not in activites:
return {"planning": [], "budget_utilise": 0}
acts_ville = activites[ville]
# Trier par note ou popularite (ici par prix croissant comme exemple)
acts_triees = sorted(acts_ville, key=lambda a: a["prix"])
planning = []
budget_utilise = 0
for act in acts_triees:
if budget_utilise + act["prix"] <= budget_max:
planning.append(act)
budget_utilise = budget_utilise + act["prix"]
return {
"planning": planning,
"budget_utilise": budget_utilise
}
```
---
## Exercice 3 (Bonus)
### 3.1 - Calculer le budget total
```python
def calculer_budget(vol, hotel, nuits, activites_choisies, activites, ville):
budget = {
"vol": vol[5],
"hotel": hotel["prix_nuit"] * nuits,
"activites": 0
}
if ville in activites:
for act in activites[ville]:
if act["nom"] in activites_choisies:
budget["activites"] = budget["activites"] + act["prix"]
budget["total"] = budget["vol"] + budget["hotel"] + budget["activites"]
return budget
```
### 3.2 - Voyage optimal
```python
def voyage_optimal(destination, budget_max, nuits, villes, hotels, vols):
# Trouver les vols
vols_dest = []
for v in vols:
if v[2] == destination:
vols_dest.append(v)
if len(vols_dest) == 0:
return None
# Trouver les hotels
if destination not in hotels:
return None
hotels_dest = hotels[destination]
# Trier par prix
vols_dest = sorted(vols_dest, key=lambda v: v[5])
hotels_dest = sorted(hotels_dest, key=lambda h: h["prix_nuit"])
# Essayer les combinaisons
for vol in vols_dest:
for hotel in hotels_dest:
cout_base = vol[5] + hotel["prix_nuit"] * nuits
if cout_base <= budget_max:
return {
"destination": destination,
"vol": vol,
"hotel": hotel,
"budget_total": cout_base
}
return None
```
### 3.3 - Comparateur de destinations
```python
def comparer_destinations(destinations, budget, nuits, villes, hotels, vols, activites):
comparaison = []
for dest in destinations:
voyage = voyage_optimal(dest, budget, nuits, villes, hotels, vols)
if voyage != None:
# Compter les activites possibles
budget_restant = budget - voyage["budget_total"]
nb_acts = 0
if dest in activites:
for act in activites[dest]:
if act["prix"] <= budget_restant:
nb_acts = nb_acts + 1
# Score = note hotel + nb activites possibles
score = voyage["hotel"]["note"] + nb_acts * 0.5
comparaison.append({
"ville": dest,
"budget": voyage["budget_total"],
"note_hotel": voyage["hotel"]["note"],
"nb_activites": nb_acts,
"score": score
})
# Trier par score decroissant
comparaison = sorted(comparaison, key=lambda x: x["score"], reverse=True)
return comparaison
```
---
## Pieges a eviter
1. **Tuples immutables** : impossible de modifier `vol[5] = 100`
2. **Services = liste** : utilisez `in` pour verifier si un service est disponible
3. **Escales** : 0 = vol direct, > 0 = avec escale(s)
4. **Decalage horaire** : peut etre negatif (New York = -6)
5. **Activites par ville** : utilisez `.get(ville, [])` pour eviter KeyError si ville sans activites
6. **Budget** : vol + (hotel x nuits) + activites
7. **Acces par indice pour les tuples** : ville[0]=nom, ville[1]=pays, vol[5]=prix, etc.