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