268 lines
14 KiB
Plaintext
268 lines
14 KiB
Plaintext
|
|
{
|
||
|
|
"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
|
||
|
|
}
|