{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Université d’Orléans - Licence 1 semestre 1 - 2025-26  <br> Programmation et Algorithmique 1      \n",
    "<h3 align=\"center\">TP 04 (enseignant)</h3>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Exercice 1 - Championnat de football\n",
    "\n",
    "On souhaite modéliser un championnat de football à 4 équipes. Le championnat se déroule en 6 journées (chaque équipe joue contre les 3 autres, en 2 matchs : un à domicile, l'autre à l'extérieur).\n",
    "\n",
    "Les équipes sont regroupées en une liste. \n",
    "\n",
    "Chaque équipe est un dictionnaire comprenant son nom, son nombre de points, le nombre de buts marqués et le nombre de buts encaissés, ainsi que la différence de buts (nombre de buts marqués - nombre de buts encaissés).\n",
    "\n",
    "Une victoire rapporte 3 points, un match nul 1 point et une défaite 0 point.\n",
    "\n",
    "Pour le championnat, on utilise diverses variables python : \n",
    "\n",
    "- 4 dictionnaires représentant chacun une équipe ;\n",
    "- 1 liste regroupant ces 4 équipes ;\n",
    "- 6 tuples journee1, ..., journee6. Ces tuples contiennent chacun deux éléments qui sont eux aussi des tuples. \n",
    "\n",
    "Par exemple, journee1 = ((0, 1), (2, 3)) signifie que la journée 1 se joue en 2 matchs (il y a 4 équipes). Le premier match oppose l'équipe d'indice 0 à celle d'indice 1 et le second, celle d'indice 2 à celle d'indice 3.\n",
    "- 1 tuple calendrier dont les 6 éléments sont les 6 journées de championnat.\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## question 1\n",
    "Dans le code suivant, complétez la fonction *saisir_equipes()* qui permet de compléter le nom de chaque équipe. Cette fonction pourra agir directement sur les équipes, qui sont déclarées en dehors de la fonction et qui sont donc des variables globales. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import random\n",
    "\n",
    "# les équipes dont les noms n'ont pas encore été renseignés\n",
    "equipe1 = {'nom' : '', 'pts' : 0, 'bp' : 0, 'bc' : 0, 'diff' : 0} # bp= buts marqués\n",
    "equipe2 = {'nom' : '', 'pts' : 0, 'bp' : 0, 'bc' : 0, 'diff' : 0} # bc= buts encaissés\n",
    "equipe3 = {'nom' : '', 'pts' : 0, 'bp' : 0, 'bc' : 0, 'diff' : 0} #  diff = bp - bc\n",
    "equipe4 = {'nom' : '', 'pts' : 0, 'bp' : 0, 'bc' : 0, 'diff' : 0}\n",
    "\n",
    "# la liste des équipes\n",
    "equipes = [equipe1, equipe2, equipe3, equipe4]\n",
    "\n",
    "# les 6 journées du championnat\n",
    "journee1 = ((0, 1), (2, 3))    # equipe_indice0 contre equipe_indice1 (et 2 contre 3)\n",
    "journee2 = ((0, 2), (1, 3))\n",
    "journee3 = ((3, 0), (2, 1))\n",
    "journee4 = ((1, 0), (3, 2))\n",
    "journee5 = ((2, 0), (3, 1))\n",
    "journee6 = ((0, 3), (1, 2))\n",
    "\n",
    "# le calendrier, tuple contenant les 6 journées\n",
    "calendrier = (journee1, journee2, journee3, journee4, journee5, journee6) \n",
    "\n",
    "def saisir_equipes() :\n",
    "    for equipe in equipes :\n",
    "        nom = input(\"entrez le nom de l'équipe : \")\n",
    "        equipe[\"nom\"] = nom\n",
    "\n",
    "# test de la fonction        \n",
    "saisir_equipes()\n",
    "print(equipes)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## question 2\n",
    "Ecrivez une fonction *jouer_match(equipe1, equipe2)* qui prend en paramètres deux dictionnaires représentant chacun une équipe. Cette fonction :\n",
    "- tire au hasard deux entiers (par exemple entre 0 et 4) qui correspondent au nombre de buts marqués par les deux équipes ;\n",
    "- affiche le résultat du match. Par exemple \"PSG 2 - 1 ASM\" pour une victoire 2 à 1 du PSG sur l'ASM ;\n",
    "- met à jour le nombre de buts marqués et encaissés de chaque équipe ;\n",
    "- met à jour leur différence de buts ;\n",
    "- met à jour leur nombre de points.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def jouer_match(equipe1, equipe2) :\n",
    "    res1 = random.randint(0, 4) # nb buts marqués par equipe1\n",
    "    res2 = random.randint(0, 4) # nb buts marqués par equipe2\n",
    "    print(\"{0} {1} - {2} {3}\".format(equipe1['nom'], res1, res2, equipe2['nom']))\n",
    "    \n",
    "    # mise à jour des points après le match\n",
    "    if res1 > res2 :         # equipe1 a gagné : 3 points ajoutés \n",
    "        equipe1['pts'] += 3\n",
    "    elif res1 == res2 :      # égalité : chacun 1 point ajouté\n",
    "        equipe1['pts'] += 1\n",
    "        equipe2['pts'] += 1\n",
    "    else :                   # equipe2 a gagné : 3 points ajoutés\n",
    "        equipe2['pts'] += 3\n",
    "    \n",
    "    equipe1['bp'] += res1 # marqué\n",
    "    equipe1['bc'] += res2 # encaissé (concédé)\n",
    "    equipe2['bp'] += res2 \n",
    "    equipe2['bc'] += res1\n",
    "    equipe1['diff'] = equipe1['bp'] - equipe1['bc'] # écart \n",
    "    equipe2['diff'] = equipe2['bp'] - equipe2['bc']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## question 3\n",
    "Ecrivez une fonction *jouer_journee(i)* qui permet de jouer la journée d'indice *i* (*i* entre 0 et 5). Jouer la journée *i* signifie jouer les deux matchs de la journée."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def jouer_journee(i) :\n",
    "    jouer_match(equipes[calendrier[i][0][0]], equipes[calendrier[i][0][1]])\n",
    "    jouer_match(equipes[calendrier[i][1][0]], equipes[calendrier[i][1][1]])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## question 4\n",
    "Ecrivez le programme principal qui, pour *i* entre 0 et 5 :\n",
    "- annonce la journée à jouer par un message adapté (on affichera plutôt journée 1 que journée 0, c'est plus naturel pour le lecteur) ;\n",
    "- fait jouer la journée *i*\n",
    "- ensuite, affiche toutes les équipes pour pouvoir les comparer."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(6) :\n",
    "    print(\"============= journée {0} ===============\".format(i+1))\n",
    "    jouer_journee(i)\n",
    "    for equipe in equipes :\n",
    "        print(equipe)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Exercice 2 - Dictionnaire français - anglais\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "On va travailler avec un dictionnaire français-anglais, matérialisé par un fichier externe **dico.txt** :\n",
    "\n",
    "- téléchargez le fichier dico.txt sur Celene ;\n",
    "- placez le fichier au même endroit que le fichier notebook TP04_etu.ipynb ;\n",
    "- examinez ce fichier pour voir comment il est conçu."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## question 1\n",
    "La fonction *charger_dictionnaire(nomFichier)* est partiellement codée. Elle permet pour le moment de :\n",
    "\n",
    "1. ouvrir le fichier dico.txt en mode lecture ;\n",
    "2. récupérer toutes les lignes du fichier dans une liste nommée \"lignes\";\n",
    "3. afficher cette liste.\n",
    "\n",
    "Testez cette fonction pour voir l'affichage.\n",
    "\n",
    "Il vous reste maintenant à produire quelques lignes de code pour cette fonction, qui vont **remplacer l'affichage** de la liste. \n",
    "\n",
    "Il faut :\n",
    "\n",
    "4. supprimer l'affichage de la liste **lignes** ;\n",
    "5. créer un dictionnaire vide ;\n",
    "6. parcourir les items de la liste **lignes**, en récupérer dans 2 variables les deux mots séparés par un point-virgule ;\n",
    "7. alimenter le dictionnaire en créant une paire clé / valeur construite sur les deux mots. **Ne pas oublier de retirer le \"\\n\" des valeurs** ;\n",
    "8. à la fin, retourner ce dictionnaire."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'écran': 'screen', 'souris': 'mouse', 'clavier': 'keyboard', 'imprimante': 'printer', 'ordinateur': 'computer'}\n"
     ]
    }
   ],
   "source": [
    "def charger_dictionnaire(nomFichier) :\n",
    "    dico = {}\n",
    "    with open(nomFichier, \"r\") as f : # ouverture en lecture et fermeture automatique \n",
    "        lignes = f.readlines()\n",
    "    for ligne in lignes :\n",
    "        liste = ligne.split(\";\")\n",
    "        dico[liste[0]] = liste[1][0:-1] # 0:-1 exclu pour retirer le \\n de la str\n",
    "    return dico\n",
    "\n",
    "# test \n",
    "mon_dico = charger_dictionnaire(\"dico.txt\")\n",
    "print(mon_dico)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## question 2\n",
    "Ecrivez une fonction *afficher(dictionnaire)* qui affiche les items du dictionnaire sous la forme clé : valeur\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "écran:screen\n",
      "souris:mouse\n",
      "clavier:keyboard\n",
      "imprimante:printer\n",
      "ordinateur:computer\n"
     ]
    }
   ],
   "source": [
    "def afficher(dictionnaire) :\n",
    "    for mot, traduction in dictionnaire.items() :\n",
    "        print(mot + \":\" + traduction)\n",
    "\n",
    "# test \n",
    "afficher(mon_dico)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## question 3\n",
    "Ecrivez une fonction *est_une_cle(dictionnaire, mot)* qui retourne un booléen qui dit si oui ou non la chaîne de caractères *mot* est une clé du dictionnaire python *dictionnaire*.\n",
    "\n",
    "Ecrivez aussi une fonction *est_une_valeur(dictionnaire, mot)* qui retourne un booléen qui dit si oui ou non la chaîne de caractères *mot* est une valeur du dictionnaire python *dictionnaire*."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def est_une_cle(dictionnaire, mot) :\n",
    "    return mot in dictionnaire.keys()\n",
    "\n",
    "def est_une_valeur(dictionnaire, mot) :\n",
    "    return mot in dictionnaire.values()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## question 4\n",
    "Ecrivez une fonction *ajouter_dans(dictionnaire, mot, traduction)* qui vérifie si le dictionnaire python *dictionnaire* contient déjà une clé égale à la chaîne de caractères *mot*. \n",
    "- Si c'est le cas, la fonction affiche un message présentant la traduction actuelle du mot, demande si oui ou non on procède à la mise à jour de la traduction et, si la réponse de l'utilisateur est positive, alors on met à jour la valeur de la traduction ;\n",
    "- Sinon (clé non présente dans le dictionnaire), on ajoute tout simplement l'item *mot* / *traduction* au dictionnaire python.\n",
    "La fonction ne retourne rien."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "le mot imprimante est déjà présent dans le dictionnaire, sa traduction est printer.\n",
      "doit-on mettre à jour la traduction ? (o/n)n\n",
      "le mot ordinateur est déjà présent dans le dictionnaire, sa traduction est computer.\n",
      "doit-on mettre à jour la traduction ? (o/n)n\n",
      "écran:screen\n",
      "souris:mouse\n",
      "clavier:keyboard\n",
      "imprimante:printer\n",
      "ordinateur:computer\n"
     ]
    }
   ],
   "source": [
    "def ajouter_dans(dictionnaire, mot, traduction) :\n",
    "    if est_une_cle(dictionnaire, mot) :\n",
    "        print(\"le mot {0} est déjà présent dans le dictionnaire, sa traduction est {1}.\".format(mot, dictionnaire[mot]))\n",
    "        reponse = input(\"doit-on mettre à jour la traduction ? (o/n)\")\n",
    "        if reponse == 'o' :\n",
    "            dictionnaire[mot] = traduction\n",
    "    else :\n",
    "        dictionnaire[mot] = traduction\n",
    "\n",
    "# test\n",
    "ajouter_dans(mon_dico, 'imprimante', 'printer')\n",
    "ajouter_dans(mon_dico, 'ordinateur', 'computer')\n",
    "afficher(mon_dico)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## question 5\n",
    "Ecrivez une fonction *supprimer_mot(dictionnaire, mot)* qui supprime, si elle existe, l'item du dictionnaire python *dictionnaire* dont la clé est la chaîne de caractères *mot*."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def supprimer_mot(dictionnaire, mot) :\n",
    "    if mot in dictionnaire.keys() :\n",
    "        del dictionnaire[mot]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## question 6\n",
    "Voci une fonction *exporter_dictionnaire(dictionnaire, nomFichier)* partiellement codée, qui exporte toutes les entrées du dictionnaire python *dictionnaire* dans un fichier de nom *nomFichier*. Vous n'avez qu'à compléter les lignes de code qui, à partir d'un item du dictionnaire, construisent une ligne du futur fichier. Cet export respectera le format donné initialement, à savoir *clé;valeur* pour chaque ligne. \n",
    "\n",
    "Cet export se fera en mode 'w', donc il écrasera le précédent fichier. Pour plus de détails, voir le CM sur les fichiers."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "def exporter_dictionnaire(dictionnaire, nomFichier) :\n",
    "    with open(nomFichier, 'w') as f :\n",
    "        for item in dictionnaire.items() :\n",
    "            # à compléter\n",
    "            mot_francais = item[0]\n",
    "            mot_anglais = item[1]\n",
    "            ligne_fichier = mot_francais + \";\" + mot_anglais\n",
    "            # fin de votre code\n",
    "            f.write(ligne_fichier + \"\\n\")\n",
    "\n",
    "# Test \n",
    "exporter_dictionnaire(mon_dico, \"dico.txt\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## question 7\n",
    "Ecrivez une fonction *menu()* qui affiche les 3 options suivantes :\n",
    "\n",
    "1. afficher le dictionnaire ;\n",
    "2. ajouter un mot et sa traduction dans le dictionnaire, ou le modifier ;\n",
    "3. supprimer un mot du dictionnaire ;\n",
    "4. exporter le dictionnaire ;\n",
    "5. arrêter le programme.\n",
    "\n",
    "La fonction demande de saisir, autant de fois que nécessaire, un numéro d'option valide, puis retourne ce numéro d'option, comme ci-dessous :\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "![menu.png](./menu.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def menu() :\n",
    "    print(\"#====================== MENU ======================#\")\n",
    "    print(\"# afficher le dictionnaire                     : 1 #\")\n",
    "    print(\"# ajouter (modifier) un mot et sa traduction   : 2 #\")\n",
    "    print(\"# supprimer un mot et sa traduction            : 3 #\")\n",
    "    print(\"# exporter le dictionnaire                     : 4 #\")\n",
    "    print(\"# arrêter le programme                         : 5 #\")\n",
    "    print(\"#==================================================#\")\n",
    "    option = 0\n",
    "    while not(1 <= option <= 5) :\n",
    "        option = int(input(\"entrez une option valide : \"))\n",
    "    return option\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## question 8\n",
    "Ecrivez le programme principal : \n",
    "1. le programme charge le dictionnaire correspondant à *dico.txt* ;\n",
    "2. dans une boucle \"while True\", le programme affiche le menu, récupère l'option retournée et, en fonction de cette option, accomplit ce qu'il faut accomplir. \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "#====================== MENU ======================#\n",
      "# afficher le dictionnaire                     : 1 #\n",
      "# ajouter (modifier) un mot et sa traduction   : 2 #\n",
      "# supprimer un mot et sa traduction            : 3 #\n",
      "# exporter le dictionnaire                     : 4 #\n",
      "# arrêter le programme                         : 5 #\n",
      "#==================================================#\n"
     ]
    }
   ],
   "source": [
    "nomFichier = \"dico.txt\"\n",
    "mon_dico = charger_dictionnaire(nomFichier)\n",
    "while True :\n",
    "    option = menu()\n",
    "    if option == 1 :\n",
    "        afficher(mon_dico)\n",
    "    elif option == 2 :\n",
    "        mot = input(\"votre mot  : \")\n",
    "        traduction = input(\"traduction : \")\n",
    "        ajouter_dans(mon_dico, mot, traduction)\n",
    "    elif option == 3 :\n",
    "        mot = input(\"votre mot  : \")\n",
    "        supprimer_mot(mon_dico, mot)\n",
    "    elif option == 4 :\n",
    "        exporter_dictionnaire(mon_dico, nomFichier)\n",
    "    elif option == 5 :\n",
    "        print(\"bye !\")\n",
    "        break"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "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.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
