- 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>
477 lines
15 KiB
Plaintext
477 lines
15 KiB
Plaintext
{
|
|
"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
|
|
}
|