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