Files
1ereNSI/representation_construits/evaluation/TP04_Netflix.ipynb
Florian Mathieu 1290ccf453 ajout exercices, corrections diverses, glossaire
- Ajout des 10 TPs d'évaluation (sans PDF)
- Création GLOSSAIRE.md et AMELIORATIONS.md
- Corrections f-strings, eval(), sommaires

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 23:37:26 +01:00

501 lines
15 KiB
Plaintext

{
"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
}