{ "metadata": { "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.3-final" }, "orig_nbformat": 2, "kernelspec": { "name": "python37364bit201329ed7ee849b4a43ad7bb610f5989", "display_name": "Python 3.7.3 64-bit" } }, "nbformat": 4, "nbformat_minor": 2, "cells": [ { "source": [ "# Les dictionnaires en Python : exercices d'application\n", "\n", "Pour réaliser ce notebook il est impératif :\n", "\n", " - d'avoir réalisé et compris les exemples donnés dans le cours **Types construits\"** paragraphe **3- Les dictionnaires**\n", "\n", " - d'avoir fait le notebook **1nsi_8_recherche_tableau.ipynb** (cours d'algorithmique)\n", "\n", "## Ce qui est important à retenir :\n", "\n", "Pour une liste, chaque élément est implicitement lié à sa position par un index :\n", "\n", "Si notes = \\[12, 14, 8, 13, 9] alors notes\\[3] renvoie la valeur 13 et notes\\[3] = 15 remplace la valeur 13 par 15\n", "\n", "Si on reprend l'exemple des notes de Fifi, Riri et Loulou :\n", "\n", "matieres = \\['Math', 'Français', 'NSI', 'Hist-Géo', 'Anglais', 'Pêche']\n", "\n", "Riri = \\[12, 14, 17, 8, 15, 7]\n", "\n", "... pour associer la note 17 de Riri à NSI il faut travailler sur ces deux listes pour lesquelles les indices sont parfaitement \"raccord\". Cette façon de procéder est **très dangereuse** car il suffit (pour une raison quelconque) que le nombre d'éléments soit différent dans les deux listes pour perdre la cohérence de l'ensemble. Par exemple :\n", "\n", "matieres = \\['Math', 'Français', 'NSI', 'Hist-Géo', 'Anglais', 'Pêche']\n", "\n", "Riri = \\[12, 14, 17, 15, 7]\n", "\n", "Dans quelle matière manque-t-il une note ????\n", "\n", "Pour éviter ce genre de problème, on utilise les **dictionnaires** qui fonctionnent avec un système de **clé:valeur**. Sur l'exemple des notes cela donnerait :\n", "\n", "Riri = \\{'Math':12, 'Français':14, 'NSI':17, 'Hist-Géo':8, 'Anglais':15, 'Pêche':7}\n", "\n", "les **clés** (**keys** en anglais) sont les différentes matières, tandis que les **valeurs** (**values** en anglais) sont les notes correspondantes.\n", "\n", "Si une note n'est pas présente, cela devient par exemple :\n", "\n", "Riri = \\{'Math':12, 'Français':14, 'NSI':17, 'Anglais':15, 'Pêche':7} : on voit que la cohérence des données n'est pas rompue.\n", "\n", "Ce qui est important à comprendre maintenant c'est que dans un dictionnaire ce n'est pas l'association valeur <-> position dans le dictionnaire qui compte (et d'ailleurs pour cette raison **il n'y a pas d'index dans un dictionnaire**), mais c'est l'association **clé <-> valeur**.\n", "\n", "Pour connaître la note de Riri en NSI : Riri\\['NSI'] va renvoyer la valeur 17\n", "\n", "Pour modifier la note d'Histoire-Géo de Riri : Riri\\['Hist-Géo'] = 11\n", "\n" ], "cell_type": "markdown", "metadata": {} }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# On donne :\n", "Riri = {'Math':12, 'Français':14, 'NSI':17, 'Hist-Géo':8, 'Anglais':15, 'Pêche':7}\n", "\n", "# Afficher la note de Riri en Français :\n", "print(???)\n", "\n", "# Modifier la note de Riri en Mathématiques car il lui manque un point :\n", "???\n", "\n", "# Vérifier que le dictionnaire a bien été modifié :\n", "print(???)\n", "\n", "# Voici sous forme de liste les notes de Fifi : [7, 11, 10, 12, 9, 15]. Les réécrire (\"à la main\") dans un dictionnaire :\n", "Fifi = {???}\n", "\n", "# Comparer la note obtenue en Anglais par Riri et Fifi :\n", "???" ] }, { "source": [ "### Itérer sur un dictionnaire :\n", "\n", "Python propose trois méthodes pour récupérer :\n", " - tous les items présents dans le dictionnaire (= toutes les paires clé:valeur)\n", " - uniquement les clés présentes dans le dictionnaire\n", " - uniquement les valeurs présentes dans le dictionnaire\n", "\n", "Les tester dans la cellule ci-dessous :" ], "cell_type": "markdown", "metadata": {} }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Voici un dictionnaire :\n", "Riri = {'Math':12, 'Français':14, 'NSI':17, 'Hist-Géo':8, 'Anglais':15, 'Pêche':7}\n", "\n", "# 1 : pour lister tous les éléments (items) du dictionnaire Riri :\n", "print(\"Voici tous les items du dictionnaire : \", Riri.items(), '\\n')\n", "\n", "\n", "# 2 : pour lister toutes les clés présentes dans le dictionnaire Riri :\n", "print(\"Voici toutes les clés du dictionnaire : \",Riri.keys(), '\\n')\n", "\n", "# 3 : lister toutes les valeurs présentes dans le dictionnaire Riri :\n", "print(\"Voici toutes les valeurs du dictionnaire : \", Riri.values())" ] }, { "source": [ "## 1- Dénombrer chacun des caractères présents dans une chaîne de caractères.\n", "\n", "On souhaite écrire une fonction **compte_caracteres(chaine)** qui renvoie un dictionnaire dont les items sont constitués de paires clé/valeur définies ainsi : \n", "\n", " - la clé est un caractère présent dans chaine\n", " - la valeur est le nombre de fois que le caractère est rencontré\n", "\n", "Par exemple : \n", ">>> compte_caracteres(\"NSI\")\n", "\n", "renvoie {'N': 1, 'S': 1, 'I': 1} # car chacune des lettres de NSI n'est rencontrée qu'une fois\n", "\n", "alors que :\n", "\n", ">>> compte_caracteres(\"SOS\")\n", "\n", "renvoie {'S': 2, 'O': 1} # car la lettre 'S' est rencontrée deux fois el la lettre 'O' une fois\n", "\n" ], "cell_type": "markdown", "metadata": {} }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def compte_caracteres(chaine):\n", " \"\"\" fonction qui range et comptabilise dans un dictionnaire\n", " chacun des caractères présents dans 'chaine'\n", " :param chaine: (str) la chaîne de caractères à analyser\n", " :return: (dict) le dictionnaire construit : clé:valeur = caractere:nombre\n", " Exemples :\n", " >>> compte_caracteres(\"NSI\")\n", " {'N': 1, 'S': 1, 'I': 1}\n", " >>> compte_caracteres(\"SOS\")\n", " {'S': 2, 'O': 1}\n", " \"\"\" \n", " carac = {} # dictionnaire temporaire qui sera renvoyé à la fin\n", "\n", " for elt in chaine: # 'elt' représentera successivement chacun des caractères de 'chaine'\n", " if ??? not in carac.??? : # si le caractère n'est pas dans la liste des clés\n", " carac[???] = ???? # alors on ajoute ce nouveau caractère dans le dictionnaire 'carac'\n", " # en lui attribuant la valeur 1 puisque c'est la première fois qu'on le # rencontre dans 'chaine'\n", " else: # sinon, c'est que le caractère avait déjà été repéré une ou plusieurs fois\n", " carac[???] = ??? # il faut donc incrémenter la valeur\n", " return carac # on renvoie le dictionnaire\n", "\n", "\n", "# Tester la fonction sur différentes chaînes de caractères :\n", "print(compte_caracteres(\"BONJOUR A TOUS !!!\"))\n", "\n", "# Proposer un autre test :" ] }, { "source": [ "## 2 - Le jeu du Scrabble\n", "\n", "Dans le jeu du Scabble (marque déposée) on doit constituer des mots à partir des lettres que l'on a dans \"sa main\" et de celles déjà déposées sur le plateau et formant elles aussi des mots :\n", "\n", "![title](images/scrabble.jpg)\n", "\n", "Dans ce jeu, on cumule des points à chaque fois que l'on pose un mot : pour cela, chaque lettre a une valeur spécifique. \n", "\n", "Remarque : la valeur d'une lettre et le nombre de jetons d'une même lettre disponibles dépent de la version linguistique du jeu.\n", "\n", "Pour la version française du jeu il y a 102 jetons dont 100 lettres (les deux autres jetons sont des jokers) :\n", "\n", "- 0 point : Joker ×2 (appelés en français jokers ou lettres blanches)\n", "- 1 point : E ×15, A ×9, I ×8, N ×6, O ×6, R ×6, S ×6, T ×6, U ×6, L ×5\n", "- 2 points : D ×3, M ×3, G ×2\n", "- 3 points : B ×2, C ×2, P ×2\n", "- 4 points : F ×2, H ×2, V ×2\n", "- 8 points : J ×1, Q ×1\n", "- 10 points : K ×1, W ×1, X ×1, Y ×1, Z ×1\n", "\n", "Interprétation :\n", "\n", "il y a 15 jetons portant la lettre 'E' ; leur valeur est de 1 point\n", "il y a 2 jetons portant la lettre 'F' ; leur valeur est de 4 points\n", "\n", "A l'aide de ces informations, on a écrit un dictionnaire **scrabble_fr** pour lequel :\n", "\n", "une clé est une lettre de l'alphabet (en majuscule)\n", "une valeur est un tuple (nombre_de_jetons, valeur_lettre)\n", "\n", "On a de même écrit le dictionnaire **scrabble_en** pour le jeu anglais :\n", "\n" ], "cell_type": "markdown", "metadata": {} }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "scrabble_fr = {'A':(9, 1), 'B':(2, 3), 'C':(2, 3), 'D':(3, 2), 'E':(15, 1), 'F':(2, 4), 'G':(2, 2),\n", " 'H':(2, 4), 'I':(8, 1), 'J':(1, 8), 'K':(1, 10), 'L':(5, 1), 'M':(3, 2), 'N':(6, 1),\n", " 'O':(6, 1), 'P':(2, 3), 'Q':(1, 8), 'R':(6, 1), 'S':(6, 1), 'T':(6, 1), 'U':(6, 1),\n", " 'V':(2, 4), 'W':(1, 10), 'X':(1, 10), 'Y':(1, 10), 'Z':(1, 10)}\n", "\n", "scrabble_en = {'A':(9, 1), 'B':(2, 3), 'C':(2, 3), 'D':(4, 2), 'E':(12, 1), 'F':(2, 4), 'G':(2, 2),\n", " 'H':(2, 4), 'I':(9, 1), 'J':(1, 8), 'K':(1, 5), 'L':(4, 1), 'M':(3, 2), 'N':(6, 1),\n", " 'O':(8, 1), 'P':(2, 3), 'Q':(1, 10), 'R':(6, 1), 'S':(4, 1), 'T':(6, 1), 'U':(4, 1),\n", " 'V':(2, 4), 'W':(2, 4), 'X':(1, 8), 'Y':(2, 4), 'Z':(1, 10)}\n", "\n", "# IMPORTANT : Travail préliminaire à savoir faire sur le dictionnaire scrabble_fr :\n", "# afficher le nombre de jetons disponibles pour la lettre 'P' :\n", "???\n", "\n", "# afficher la valeur de la lettre 'J' :\n", "???\n", "\n", "# afficher toutes les clés du dictionnaire scrabble_fr :\n", "???\n" ] }, { "source": [ "## 2.1 - Vérification :\n", "\n", " 1- Ecrire le code permettant de vérifier que **scrabble_fr** comporte effectivement 100 jetons représentant des lettres \n", "\n", " 2- Le scrabble anglais comporte-t-il autant de jetons de type lettres que le scrabble français ?\n", "\n", " (Si nécessaire, relire le paragraphe **\"Itérer sur un dictionnaire\"** fourni en introduction)\n", "\n" ], "cell_type": "markdown", "metadata": {} }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# écrire ici le code de vérification.\n", "# coup de pouce : les valeurs dans ces dictionnaires sont des tuples constitués de 2 éléments (nombre_de_jetons, valeur) \n", "???\n", "...\n", "???" ] }, { "source": [ "## 2.2 - Compter les points au Scrabble :\n", "\n", "Remarque : lorsque l'on pose une lettre sur le plateau la valeur d'une lettre, voire du mot peut changer grâce aux cases comme \"Lettre compte double\" ou \"Mot compte triple\". \n", "Pour simplifier le problème on ne tiendra pas compte de ces modifications possibles.\n", "\n", "On demande :\n", "\n", " - d'écrire une fonction **compte_points(mot, scrabble_xy)** qui calcule le nombre de points que rapporterait 'mot' dans une version linguistique donnée 'scrabble_xy' du Scrabble.\n", " - de faire calculer ce que rapporte le mot **\"PYTHON\"** écrit dans un Scrabble français puis dans un Scrabble anglais.\n" ], "cell_type": "markdown", "metadata": {} }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def compte_points(mot, scrabble_xy = scrabble_fr):\n", " \"\"\" fonction qui calcule le nombre de points que rapporterait 'mot' au Scrabble\n", " :param mot: (str) le mot dont on cherche la valeur\n", " :param scrabble_xy: (dict) dictionnaire 'lettre':(nombre, valeur) pour une version linguistique donnée\n", " :return: (int) la valeur calculé pour 'mot'\n", " Exemple:\n", " >>> compte_points('BONJOUR')\n", " 16\n", " >>> compte_points('HELLO', scrabble_en)\n", " 8\n", " \"\"\"\n", " ???\n", "\n", "# tests de la fonction sur le mot 'PYTHON'\n", "# dans le scrabble français :\n", "\n", "\n", "# dans le scrabble anglais :\n", "\n" ] }, { "source": [ "## 2.3 - Initialisation du jeu :\n", "\n", "On envisage un début de partie à deux joueurs :\n", "\n", "1- Ecrire une fonction **genere_pioche()** qui produit, à partir d'un dictionnaire scrabble_xy, une liste de tous les jetons disponibles. Cette liste sera appelée **pioche** et ne prendra pas en compte les jokers.\n", "\n", "2- Ecrire une fonction **distribue()**qui distribue aléatoirement à un joueur, un nombre n de jetons qui seront alors retirés de la pioche. Lorsque cette fonction sera appelée elle devra ajouter autant de jetons que nécessaire pour atteindre un nombre total de jetons égal à 7. Ainsi au début du jeu un joueur recevra 7 jetons. Au cours du jeu, s'il pose le mot 'PYTHON' il devra recevoir 6 jetons.\n", "\n", "(pour commencer la partie chaque joueur reçoit 7 jetons)\n", "\n", "3- Ecrire une fonction **coup()** qui demande à un joueur de proposer un mot et qui retire les jetons correspondants de la main du joueur\n", "\n", "4- Initialisation du jeu : distribuer 7 jetons à chacun des deux joueurs\n", "\n", "5- Début de partie : \n", "\n", " - Avec tout ou partie des jetons dont dispose le joueur1, proposer un mot qui serait le premier mot posé sur le plateau\n", "\n", " - Calculer et afficher le nombre de points obtenus par le joueur1 avec ce mot posé\n", "\n", " - Recharger la 'main' du joueur pour avoir de nouveau 7 jetons, et l'afficher\n", "\n", "Exemple d'affichage (entre parenthèses les commentaires explicatifs): \n", "\n", "**joueur1 = \\['E', 'G', 'N', 'I', 'E', 'M', 'X']** *(la main initiale du joueur1)*\n", "\n", "**\\['M', 'X']** *(Le joueur1 a proposé le mot GENIE)*\n", "\n", "**Avec ce mot posé : GENIE vous gagnez 6 points** *(calcul des points obtenus par joueur1)*\n", "\n", "**Et voici votre nouvelle main : \\['M', 'X', 'E', 'W', 'Z', 'H', 'U']** *(la main du joueur suite au rechargement)*\n", "\n", "\n" ], "cell_type": "markdown", "metadata": {} }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import random\n", "\n", "def genere_pioche(scrabble_xy = scrabble_fr):\n", " \"\"\" fonction qui génére une pioche initiale\n", " :param scrabble_xy: (dict) \n", " :return: (list) renvoie la liste représentant la pioche initiale\n", " Exemple la génération de la liste de jetons pour le jeu français doit donner ceci :\n", " ['A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'C', 'C', 'D', 'D', 'D', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'F', 'F', 'G', 'G', 'H', 'H', 'I', 'I', 'I', 'I', 'I', 'I', 'I', 'I', 'J', 'K', 'L', 'L', 'L', 'L', 'L', 'M', 'M', 'M', 'N', 'N', 'N', 'N', 'N', 'N', 'O', 'O', 'O', 'O', 'O', 'O', 'P', 'P', 'Q', 'R', 'R', 'R', 'R', 'R', 'R', 'S', 'S', 'S', 'S', 'S', 'S', 'T', 'T', 'T', 'T', 'T', 'T', 'U', 'U', 'U', 'U', 'U', 'U', 'V', 'V', 'W', 'X', 'Y', 'Z']\n", " \"\"\"\n", " liste_jetons = []\n", " for elt in scrabble_xy.keys(): # que va représenter ici 'elt' ?\n", " for i in range(scrabble_xy[???][???]): # autant de fois qu'il n'y a de jetons pour une lettre donnée,\n", " ???.append(???) # ajouter cette lettre à la liste de jetons qui représentera la pioche\n", " return ???\n", "\n", "\n", "def distribue(joueur, de_pioche):\n", " \"\"\" fonction qui distribue à un 'joueur' un nombre de jetons suffisant pour avoir une main de 7 jetons\n", " (ces jetons seront retirés de la pioche)\n", " :param joueur: (list) un joueur\n", " :param de_pioche: (list) la liste de laquelle on doit retirer les jetons\n", " :return: (list) la main du joueur après distribution des jetons nécessaires\n", " \"\"\"\n", " random.shuffle(de_pioche)\n", " for i in range(???): # on doit distribuer des jetons pour arriver à un total de 7 \n", " joueur.append(???) # ajouter à la liste joueur ce que l'on retire de la pioche \n", " return ???\n", "\n", "def coup(joueur):\n", " \"\"\" fonction qui demande à un joueur de proposer un mot et qui retire les \n", " jetons correspondants de la main du joueur\n", " :param joueur: (list) un joueur\n", " :return: (str) le mot joué sinon renvoyer '!' comme code d'erreur (si le joueur ne dispose pas de toutes les lettres du mot)\n", " \"\"\"\n", " mot = input(' : Proposer un mot valide avec les jetons en main : ' )\n", " # code pour retirer les lettres de 'mot' de la main du joueur. En cas d'erreur, renvoyer le caractère '!'\n", " ???\n", " ...\n", " ???\n", " return mot\n", "\n", "# ne pas oublier de recopier ici le code de la fonction de comptage des points :\n", "\n", "\n", "\n", "#initialisation du jeu :\n", "\n", "scrabble_fr = {'A':(9, 1), 'B':(2, 3), 'C':(2, 3), 'D':(3, 2), 'E':(15, 1), 'F':(2, 4), 'G':(2, 2),\n", " 'H':(2, 4), 'I':(8, 1), 'J':(1, 8), 'K':(1, 10), 'L':(5, 1), 'M':(3, 2), 'N':(6, 1),\n", " 'O':(6, 1), 'P':(2, 3), 'Q':(1, 8), 'R':(6, 1), 'S':(6, 1), 'T':(6, 1), 'U':(6, 1),\n", " 'V':(2, 4), 'W':(1, 10), 'X':(1, 10), 'Y':(1, 10), 'Z':(1, 10)}\n", "\n", "???\n", "...\n", "???\n", "\n", "# début de partie :\n", "???\n", "...\n", "???" ] } ] }