diff --git a/TD02/INF-TC1-td02.ipynb b/TD02/INF-TC1-td02.ipynb
deleted file mode 100644
index 02477689ac7145d8203ba223bc378c9cd93db8b7..0000000000000000000000000000000000000000
--- a/TD02/INF-TC1-td02.ipynb
+++ /dev/null
@@ -1,1271 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "markdown",
-   "id": "6e217066",
-   "metadata": {},
-   "source": [
-    "NAME:"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "4079279c",
-   "metadata": {},
-   "source": [
-    "# INF TC1 - TD2 (2h) - Structures de données"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "74d75def",
-   "metadata": {},
-   "source": [
-    "---"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "42890ec6-251a-404c-a6f6-39c138db8650",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "### IMPORTANT A LIRE (SUR L'UTILISATION DE CE NOTEBOOK)\n",
-    "\n",
-    "Le but de votre travail est de répondre aux questions des exercices en **remplissant certaines cellules de ce notebook avec votre solution**. Ces cellules, une foit remplies et lancées au fur et à mesure de vos avancées, permettront de valider des tests écrits dans d'autres cellules de ce notebook. **Il est donc important de bien suivre les instructions et répondre aux questions dans l'ordre**, et ne pas changer le nom des fonctions et/ou les cellules. En particulier :\n",
-    "    \n",
-    "1) Répondez aux questions dans les cellules en dessous des questions.\n",
-    "\n",
-    "2) Votre code devra remplacer le texte suivant : \n",
-    "erge\n",
-    "```python\n",
-    "# YOUR CODE HERE\n",
-    "raise NotImplementedError()\n",
-    "```\n",
-    "\n",
-    "(vous pouvez effacer ces deux lignes quand vous les rencontrez mais ne modifiez pas les noms de fonctions sinon les tests ne marchent plus).\n",
-    "\n",
-    "3) Exécuter enfin les cellules dans leur ordre d'apparition, de haut en bas et si votre code est correct alors les tests (sous forme d'`assert` seront validés (ils ne lanceront pas d'exception du type `AssertionError` ). Vous pouvez lancer plusieurs fois la même cellule, cela ne pose pas de soucis.\n",
-    "    \n",
-    "4) Vous pouvez créer de nouvelles cellules comme bon vous semble.\n",
-    "\n",
-    "**En cas de problème, une solution est de relancer les cellules depuis le début du notebook une par une.** Pensez à bien sauvegarder ce notebook et ne pas le remplacer par un notebook qui a le même nom.\n"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "b692d4dd-6dbc-40e9-9c19-0b59e31e5eab",
-   "metadata": {},
-   "source": [
-    "## Objectif du TD\n",
-    "\n",
-    "Ce TD vous fera manipuler plusieurs structures de données standard en Python (listes, dictionnaires) mais également des structures avancées (piles, files tas) que vous allez créer au moyen de classes. Au final nous allons créer une méthode de tri efficace (tri par tas) et la comparer avec d'autres méthodes de tri de Python."
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "b6221ad1-379e-4e50-8c22-220994439b6d",
-   "metadata": {},
-   "source": [
-    "## Exercice 1 - Chargement et tri d'une liste\n",
-    "\n",
-    "Le but de cet exercice est de charger une liste de dictionnaires et réaliser des méthodes de tri. Vous disposez pour cela d'un fichier appelé [`etudiants.txt`](etudiants.txt) où chaque ligne contient des informations sur des étudiants d'un cour. Pour commencer nous allons réaliser des tris simples et les rendre de plus en plus complexes."
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "985e2dd2-dc05-437c-b3f0-60696fe27e3f",
-   "metadata": {},
-   "source": [
-    "### Rappel : Tri de listes\n",
-    "\n",
-    "Avant de commencer quelques rappels sur les structures de données de listes et leurs tris. Voici une liste en Python :"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "327780ed-4331-43ad-921b-9e42d762f2aa",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "L = [3, 2 , 4]"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "01263b26-3983-4073-aaff-1a30d69ff914",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "Pour la trier vous pouvez utiliser ```.sort()``` [(doc)](https://docs.python.org/3/howto/sorting.html) qui modifie la liste actuelle :"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "79f084ad-942d-46c6-bfe7-2722eeeda426",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "L = [3, 2 , 4]\n",
-    "L.sort()\n",
-    "L"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "f04dbfe7-c000-4c2e-a2c4-e6187fe17ba7",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "Soit vous créez une nouvelle liste triée qui ne modifie pas la liste actuelle en utilisant ```sorted``` [(doc)](https://docs.python.org/3/howto/sorting.html) :"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "c9b79862-a7b6-4b74-af5c-3d36f85f7b67",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "L = [3, 2 , 4]\n",
-    "print(sorted(L))\n",
-    "L"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "4affcb3d-d8ae-4c5e-a7f5-fbc59b1fff76",
-   "metadata": {},
-   "source": [
-    "Enfin les fonctions de tri peuvent prendre un paramètre `key` afin d'indiquer sur quel attribut de la liste réaliser le tri. Ci dessous le tri sera fait sur le premier élément d'une liste de listes à trier :"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "76f37b8b-69f5-4df0-91ae-b221a372e519",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "L = [[3, \"C\"], [1, \"A\"], [2, \"B\"]]\n",
-    "L.sort(key=lambda x: x[0])\n",
-    "L"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "c815465f",
-   "metadata": {},
-   "source": [
-    "### Chargement d'un fichier en dictionnaire\n",
-    "\n",
-    "Le code ci-dessous permet de charger ce fichier dans la variable `students_list`."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "fe36de75-c9c4-49b7-ad79-de78c4f5b3ca",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "students_list = []\n",
-    "\n",
-    "with open(\"etudiants.txt\") as f:\n",
-    "    keys = None\n",
-    "    for line in f:\n",
-    "        l = [w.strip() for w in line.split(';')]\n",
-    "        if keys is None:\n",
-    "            keys = l\n",
-    "        else:\n",
-    "            students_list.append({k:v for k, v in zip(keys, l)})"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "cfb09dcd-d8eb-474d-9f01-bff6de7b114a",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "Un echantillon du jeu de données vous est donné comme suit, il s'agit une liste de dictionnaires [(doc)](https://docs.python.org/3/tutorial/datastructures.html#dictionaries) :"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "a0ab86a7-ed2a-4265-be05-fabd7a7b7fe5",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "students_list[0:2]"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "d54fe400",
-   "metadata": {},
-   "source": [
-    "**Question 1.1 -** Calculez la moyenne de tous les étudiants disponibles dans la liste d'étudiants `students_list`. Vous nommerez votre fonction `average_grade` et lui donnerez en paramètre la variable `L` qui contient la liste d'étudiant. Conseil : pensez à convertir les variables au bon type de données (par ex. en utilisant `int()`ou `float()`)."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "084ca248-e638-4416-9fed-32dde916fb5b",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "91158fa1e745aa0e8763ed62e53c76f7",
-     "grade": false,
-     "grade_id": "cell-0aa9f72deedd3eb2",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def average_grade(L: list)-> int:\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "66486e51-46fa-4475-a990-9764f1206f21",
-   "metadata": {},
-   "source": [
-    "La moyenne attendue de votre fonction est :"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "e6086d5b-1a84-4cee-8bd3-b3acf46d68d3",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "average_grade(students_list)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "65b4a7d1-d0d6-4ec4-a609-b7eb42157cea",
-   "metadata": {},
-   "source": [
-    "Le test ci-dessous doit donc être validé (autrement dit aucune `Exception` ne doit être lancée) :"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "836938d8-a4c7-44e2-b17b-2159acd11aad",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert average_grade(students_list) == 16.6"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "2f986196-2afa-4baf-96a3-3d22280e6c22",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "**Question 1.2 -** Trouver la note maximale de manière _récursive_ et comparez avec la fonction `max` (qui peut prendre un argument `key` afin de trier par note) donnée ci-dessous. Attention aux types des données."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "45624183-f5e7-43ae-9e41-ab8b456d9360",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "cd1544ebc215b597758489fe050ce11e",
-     "grade": false,
-     "grade_id": "cell-103fc5f998c99492",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def find_maximum_recursive(L: list)-> str:\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "59684c44-83db-47c3-a192-781041fc3b59",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert find_maximum_recursive(students_list) == int(max(students_list, key=lambda x: int(x[\"note\"]))[\"note\"])"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "a9bca555-e31a-4294-bdac-d9e2ff5fa950",
-   "metadata": {},
-   "source": [
-    "**Question 1.3 -** Trouver deux étudiants qui ont la même note, et renvoyez leurs noms sous forme de `Tuple`. Conseil : \n",
-    "\n",
-    "- parcourez la liste et mémoriser les notes que vous parcourrez;\n",
-    "- si une note a déjà été parcourue alors renvoyer l'indice du dictionnaire;\n",
-    "- enfin renvoyez les noms des étudiants"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "1dd770ee-1c63-4fcc-b564-158803c665e9",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "089205cb93f662ef5a024c55dc88359a",
-     "grade": false,
-     "grade_id": "cell-01928f10678cd675",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def find_same_grade(L: list)-> tuple:\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "dbfbaf85-01b6-4bbc-ae1e-b9e7cc47489e",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "find_same_grade(students_list)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "5ef24de8-ed61-40e1-ad9a-26f118223c17",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert find_same_grade(students_list) == ('Dupond', 'Dupont')"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "0f948f2e",
-   "metadata": {},
-   "source": [
-    "**Question 1.4 -** Trier la liste de données par ordre croissant en implémentant un _tri par sélection_ fourni dans le pseudo-code ci-dessous (issu de [cette page](https://fr.wikipedia.org/wiki/Tri_par_s%C3%A9lection)). L'argument `key` permet d'indiquer sur quel attribut réaliser le tri (ici ce sera la note). Voir l'usage de cet attribut dans la cellule de test suivante.\n",
-    "\n",
-    "```\n",
-    "   procédure tri_selection(tableau t)\n",
-    "       n ← longueur(t) \n",
-    "       pour i de 0 à n - 2\n",
-    "           min ← i       \n",
-    "           pour j de i + 1 à n - 1\n",
-    "               si t[j] < t[min], alors min ← j\n",
-    "           fin pour\n",
-    "           si min ≠ i, alors échanger t[i] et t[min]\n",
-    "       fin pour\n",
-    "   fin procédure\n",
-    "```"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "03e651d7-1143-4a9f-b453-3469d5b75e52",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "461842f0bd10a79d92c3adb61e9e70fe",
-     "grade": false,
-     "grade_id": "cell-3ee4eefc84f634bc",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def sort_selection(L: list, key=lambda x: x) -> list:\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "d95d2146-847a-4c21-9a9a-af277d236aea",
-   "metadata": {},
-   "source": [
-    "Comparer votre tri avec la méthode `sorted` de Python."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "e27a7071-e10b-4801-8d16-aa611f0866f6",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "768c025dd7d7b842b6ac47a7a2b8e107",
-     "grade": false,
-     "grade_id": "cell-4deb9caaaa6d474f",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "# YOUR CODE HERE\n",
-    "raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "dae866db",
-   "metadata": {},
-   "source": [
-    "## Exercice 2 : Piles et files\n",
-    "\n",
-    "Désormais nous allons implémenter de nouvelles structures de manipulation de listes : les Piles et les Files. Et à terme réaliser un tri de plus en plus efficace (avec un Tas). Nous allons commencer avec la Pile dont nous vous fournissons la structure de données, nommée `Stack` et disponible ci-desous:"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "c4f1b0a9",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "class Stack:\n",
-    "    def __init__(self):\n",
-    "        self.items = []\n",
-    "\n",
-    "    def push(self, item):\n",
-    "        self.items.append(item)\n",
-    "\n",
-    "    def pop(self):\n",
-    "        if not self.is_empty():\n",
-    "            return self.items.pop()\n",
-    "\n",
-    "    def peek(self):\n",
-    "        if not self.is_empty():\n",
-    "            return self.items[-1]\n",
-    "\n",
-    "    def is_empty(self):\n",
-    "        return len(self.items) == 0"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "5ee3c79e-be53-4d98-a2fb-3b0e9adadeb8",
-   "metadata": {},
-   "source": [
-    "La pile ci-dessus a son équivalent avec la méthode `LifoQueue` du module `queue` de pile défini ci-dessous [(doc)](https://docs.python.org/3/library/queue.html). Nous voyons bien que le dépilement renvoie les données dans l'ordre inverse de leur empillement."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "77dee078-c30f-40a0-bd29-f64c978b3e0b",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "import queue\n",
-    "pile = queue.LifoQueue()\n",
-    "for i in range (5): \n",
-    "    pile.put(i)\n",
-    "while not pile.empty():\n",
-    "    print(pile.get(), end=\" \")"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "bfaae7f4",
-   "metadata": {},
-   "source": [
-    "**Question 2.1 -** Utiliser la pile `Stack` afin d'empiler les données de la liste `students_list`. Maintenant dépilez cette pile et comparer les résultats avec la méthode `LifoQueue` afin de vérifier que vous obtenez les mêmes résultats (avec le `while` fourni dans le code ci-dessous) :"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "3ad4b923-5f23-4921-b02e-f8b9fd22dd55",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "b710d25ada58e842e7bcd7333d141cc3",
-     "grade": false,
-     "grade_id": "cell-63bc7e329d9959d4",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "pile = queue.LifoQueue()\n",
-    "s = Stack()\n",
-    "# YOUR CODE HERE\n",
-    "raise NotImplementedError()\n",
-    "\n",
-    "while not s.is_empty() and not pile.empty():\n",
-    "    assert s.pop() == pile.get()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "78b1b0fb-41fb-4e2e-8c2b-3a040fbcc5e0",
-   "metadata": {},
-   "source": [
-    "**Question 2.2 -** Transformer la structure de Pile `Stack` en une File (que vous nommerez `Queue`) et vérifiez que vous obtenez les mêmes résultats en récupérant les données qu'avec le module `Queue()` de Python."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "7ac004cd-f59e-4aa8-a31d-961e24acba69",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "084870f7cbddd7dc85c2b1c02c8648d3",
-     "grade": false,
-     "grade_id": "cell-a9eea459cf78c621",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "class Queue():\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "9b588c0e-d8b8-4a57-b54f-6aef316bb5c5",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "414f416a2a624101edaa0bdeb57fee51",
-     "grade": false,
-     "grade_id": "cell-a259250b447e39e2",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "file = queue.Queue()\n",
-    "f = Queue()\n",
-    "# YOUR CODE HERE\n",
-    "raise NotImplementedError()\n",
-    "\n",
-    "while not f.is_empty() and not file.empty():\n",
-    "    assert f.pop() == file.get()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "5a8722ae-500d-4956-9b8c-18e664e5b09f",
-   "metadata": {},
-   "source": [
-    "Nous voyons bien que le défilement renvoie les données dans l'ordre de leur empillement afin de respecter le principe de File."
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "e1f0a957-2c18-4edd-b37b-d766ac1e8557",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "**Question 2.3** - Mettez à jour votre File afin de ne pas générer d'exception `IndexError`. On peut par exemple renvoyer une valeur de type `None` si aucune valeur n'est disponible."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "49a596f0-fc7c-4158-bab1-e715e1cf6a57",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "file = Queue()\n",
-    "try:\n",
-    "    assert file.pop() == None # si on renvoie None pour une file vide, pas d'Exception !\n",
-    "except IndexError:\n",
-    "    print(\"On ne doit pas générer d'exception IndexError !\")"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "9ebbd490-abcd-45e4-8296-c311e34ddf2d",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "**Question 2.4** - Enfin, transformer la file (classe `Queue`) pour en faire une file de priorité `FilePriorite`. Pour rappel, une file de priorité renvoie les éléments selon un critère particulier (par exemple la note minimale des valeurs contenues dans la file). \n",
-    "\n",
-    "Conseil \n",
-    "\n",
-    "- garder la liste des valeurs internes constamment triée lors de l'ajout;\n",
-    "- pour cela inclure la nouvelle valeur avec la méthode `ajoute()` à la bonne place (en conservant l'ordre de la liste interne) avec `.insert(index, valeur)`\n",
-    "\n",
-    "Nous vous fournissons aussi le module `PriorityQueue` qui est une file de priorité existante [(doc)](https://docs.python.org/3/library/queue.html) afin de comparer votre code."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "fa163d01-ed34-447e-8b55-6198140c349b",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "from queue import PriorityQueue \n",
-    "import random\n",
-    "    \n",
-    "filep = PriorityQueue()\n",
-    "list_random = [random.randint(1, 10) for _ in range(5)] # Liste aléatoire\n",
-    "\n",
-    "for i in list_random: filep.put(i)\n",
-    "\n",
-    "while not filep.empty(): \n",
-    "  print(filep.get(), end=\" \")"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "738fe9f0-7885-40b6-a8cf-eb0c7cd8f3aa",
-   "metadata": {},
-   "source": [
-    "Remplir le code ci-dessous basé sur la file afin d'en faire une file de priorité. "
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "3b0a1122-5d8f-4f5f-8ef4-460f9896f4b6",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "69949417a33fbf1bbe25be57237c60e8",
-     "grade": false,
-     "grade_id": "cell-f5186a99d30ca43e",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "class FilePriorite():\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "4e608d6b-458b-4836-8ab2-4371d96ae54b",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "a56011d08cd37ac3315bef7a813524ce",
-     "grade": false,
-     "grade_id": "cell-76cf4fdc1a271293",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "filep = PriorityQueue()\n",
-    "f = FilePriorite()\n",
-    "\n",
-    "note_list = [student[\"note\"] for student in students_list]\n",
-    "# YOUR CODE HERE\n",
-    "raise NotImplementedError()\n",
-    "\n",
-    "while not f.is_empty() and not filep.empty():\n",
-    "    assert f.pop() == filep.get()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "77038e6d-0b73-434c-910d-c7da733b643a",
-   "metadata": {},
-   "source": [
-    "## Exercice 3 : Arbre binaire complet sous forme de liste"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "5f3fc128-2a2e-42bd-924a-d691c09150d6",
-   "metadata": {},
-   "source": [
-    "Nous allons maintenant implémenter **arbre binaire complet**. Cet arbre sera utile pour l'exercice suivant et la création d'un Tas. Cet arbre binaire sera implémenté en utilisant un tableau (car il s'agit d'un arbre _complet_ où tous les niveaux sont remplis, sauf éventuellement le dernier). L'arbre binaire possède des noeuds ayant un index $i$, avec un fils gauche et un fils droit. Le tableau et l'arbre sont reliés de la façon suivante : \n",
-    "\n",
-    "- La racine a la position $i = 0$ (cette valeur sera renvoyée par la fonction `get_racine`)\n",
-    "- Le parent a la position $\\lfloor (i - 1)/ 2 \\rfloor$ (fonction `get_parent`)\n",
-    "- Le fils gauche a la position $2 \\times i + 1$ (fonction `get_fils_gauche`)\n",
-    "- Le fils droit a la position  $2 \\times i + 2$ (fonction `get_fils_droit`)\n",
-    "\n",
-    "```\n",
-    "        1\n",
-    "       / \\\n",
-    "      2   5\n",
-    "     / \\  /\n",
-    "    3  4 6 \n",
-    "          \n",
-    "\n",
-    "La liste correspondante :\n",
-    "[1, 2, 5, 3, 4, 6]\n",
-    "```\n"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "ea502a0e-faa7-4bb2-9627-35cd128521a4",
-   "metadata": {},
-   "source": [
-    "**Exercice 3.1** - Implémentez un arbre binaire sous forme de classe appellée `BinaryTree` (basée sur la file de priorité) avec les fonctions ci-dessus (`get_racine`, `get_parent`, `get_fils_gauche`, `get_fils_droit`). Vous rajouterez une méthode `taille`qui renvoie la taille de l'arbre binaire (longueur de la liste interne)."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "d6648668-c0e3-47d5-bd83-a49785939877",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "c91ff069482e113d672ed13d2baa8f4b",
-     "grade": false,
-     "grade_id": "cell-528191aadbf86414",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "class BinaryTree():\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "d0dd4680-92db-4dad-8647-951269330870",
-   "metadata": {},
-   "source": [
-    "**Exercice 3.2** - Assurez vous que tous les tests ci-dessous sont validés."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "ac65be98-9649-4753-8ead-c0deb89f5f0c",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "# test arbre vide\n",
-    "tree_empty = BinaryTree()\n",
-    "assert tree_empty.taille() == 0\n",
-    "assert tree_empty.get_racine() == None\n",
-    "assert tree_empty.get_fils_gauche()[0] == None  \n",
-    "assert tree_empty.get_fils_droit()[0] == None  "
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "f548b21a-b2f5-4de5-9261-38d23035e25d",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "L = [1, 2, 5, 3, 4, 6]\n",
-    "tree_values = BinaryTree(L)\n",
-    "assert tree_values.taille() == len(L) # 6\n",
-    "assert tree_values.get_racine() == L[0] # 3\n",
-    "assert tree_values.get_fils_gauche()[0] == L[2*0+1] # 2\n",
-    "assert tree_values.get_fils_droit()[0] == L[2*0+2] # 5"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "25213313-5058-415a-a3bc-7948c3d98588",
-   "metadata": {},
-   "source": [
-    "Cette structure de donnée sera utile pour la question suivante afin de créer un `Tas`."
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "5f35e9de-025f-4c89-a004-a24af997474a",
-   "metadata": {},
-   "source": [
-    "**Exercice 3.3** - L'abre que vous venez de créer sera utilisé dans l'exercice suivant afin de créer un tas. Pour cela nous devrons nous assurer que l'arbre atisfait la propriété suivante : la valeur de tout noeud est inférieure à celle de ses enfant. Ecrire une fonction de parcours de l'arbre qui renvoie `True` si cette propriété est vérifée, sinon `False`. Conseil : \n",
-    "\n",
-    "1. Proposez une approche récursive\n",
-    "2. Le cas d'arrêt est un noeud vide\n",
-    "3. L'appel récursif est déclanché en fonction de la valeur du noeud en cours et celle de ses enfants"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "11065fbe-7209-4e87-8b9c-04d19d14fcee",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "fc1f2a4ce40504acecf986a88152ab86",
-     "grade": false,
-     "grade_id": "cell-f45461f84548c912",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def check_min_tree(T, i=0):\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "da01b2ab-4633-443f-97ea-b1022bc714ef",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "assert check_min_tree(tree_values) == True"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "d9f0166d-d12f-42a1-989a-b7014117e73d",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "## Exercice 4 (Bonus) : Création d'un tas et tri par tas\n",
-    "\n",
-    "Nous allons désormais créer une nouvelle structure de donnée : le `Tas`. Celle-ci permettra à termes de réduire la complexité de manipulation d'une file de priorité, en répartissant le coût de la recherche du plus petit élément (qui sera renvoyé) entre l'ajout et la suppression.\n",
-    "\n",
-    "Nous nous baserons pour cela sur l'arbre binaire de la question précédente, qui est dit dans une configuration [min-heap](https://en.wikipedia.org/wiki/Min-max_heaphttps://en.wikipedia.org/wiki/Min-max_heap), où les données sont renvoyées par ordre croissant."
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "6061d866-51fb-48bc-9f1a-46b1b57a0ec0",
-   "metadata": {},
-   "source": [
-    "**Question 4.1 -** Implémentez une structure de `Tas`comme suit :\n",
-    "\n",
-    "- Créez une structure de données de `Tas` similaire au `BinaryTree`\n",
-    " \n",
-    "- Créez une méthode `inserer` (que l'on utilisera à la place d'`ajoute`) dont le principe est le suivant :\n",
-    "\n",
-    "    - Chaque nouveau noeud est rajouté comme dernier élément du tableau (à la fin donc)\n",
-    "\n",
-    "    - Comparez ce noeud à son parent et si il est plus grand que ce parent inversez-le\n",
-    "\n",
-    "    - Répétez tant que la condition ci-dessus est vraie et que la racine n'est pas atteinte\n",
-    "    \n",
-    "\n",
-    "- Créez une méthode `enlever` dont le principe est le suivant :\n",
-    "\n",
-    "    - Enlever l'élément racine de l'arbre (premier élément du tableau)\n",
-    "\n",
-    "    - Déplacer le dernier noeud de l'arbre (dernier élément du tableau) à la place de la racine de l'arbre\n",
-    "\n",
-    "    - Vérifier que la racine conserve la propriété de Tas (qu'elle est inférieur à ses enfants); si ce n'est pas le cas alors implémenter une méthode `descendre` définie par la suite.\n",
-    "\n",
-    "- Créez une méthode `descendre` qui : \n",
-    "\n",
-    "    - Prend le plus petit des enfants\n",
-    "    - Echange sa place avec lui si il est plus petit\n",
-    "    - Répéte cela tant qu'il existe des enfants\n",
-    "    \n",
-    "Attention : pensez à tester si il existe un fils droit et un fils gauche lors des opération de descente lors de l'insertion."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "301e69f3-4035-4b10-9c85-f4427d92e03b",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "1527573490f338be2ecd33a9df08ceb7",
-     "grade": false,
-     "grade_id": "cell-1f833c3f451e29d9",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "class Tas():\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "0b467f58-c800-4ae3-b066-8717732a1095",
-   "metadata": {},
-   "source": [
-    "Votre tas doit valider les tests suivants :"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "3c41d4a7-5971-497b-b484-4a42a2480b06",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "# test tas vide\n",
-    "tas_vide = Tas()\n",
-    "assert tas_vide.taille() == 0\n",
-    "assert tas_vide.get_racine() == None\n",
-    "assert tas_vide.get_fils_droit()[0] == None  \n",
-    "assert tas_vide.get_fils_droit()[0] == None  \n",
-    "\n",
-    "# test tas simple\n",
-    "tas_simple = Tas()\n",
-    "tas_simple.inserer(1)\n",
-    "tas_simple.inserer(2)\n",
-    "assert tas_simple.taille() == 2\n",
-    "\n",
-    "# test tas un peu plus complexe\n",
-    "tas = Tas()\n",
-    "liste = [1, 4, 10000, 2, 29, .2, 13, .5, 14, .1, 100]\n",
-    "liste_triee = sorted(liste)\n",
-    "for l in liste:\n",
-    "    tas.inserer(l)\n",
-    "\n",
-    "assert tas.taille() == len(liste)    \n",
-    "assert tas.get_racine() == liste_triee[0]\n",
-    "assert tas.get_fils_gauche(0) == (liste_triee[1], 1)\n",
-    "assert tas.get_fils_droit(0) == (liste_triee[2], 2)\n",
-    "\n",
-    "while not tas.est_vide():\n",
-    "    assert tas.enlever(0) == liste_triee.pop(0)\n",
-    "    assert tas.taille() == len(liste_triee)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "ec678229-485e-4f3b-8c24-56febe7bd69e",
-   "metadata": {},
-   "source": [
-    "**Question 4.2 -** Implémentez un tri par tas en utilisant la structure de données de `Tas` que vous avez réalisé précédemment."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "1d483588-4153-4614-b969-854846b08f4e",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "812a12d8443aeaac357684ff5a590f6f",
-     "grade": false,
-     "grade_id": "cell-3a78d4e48e46d4d9",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "def triTas(l: list = []) -> list:\n",
-    "    t = Tas()\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "e7ab0b07-f13c-4b95-b5fa-c38aea9b6ead",
-   "metadata": {},
-   "source": [
-    "Comparez à la méthode de tri `sorted`."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "4e9fd04a-910a-4d32-b0dc-0a1502599901",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "liste = [54,26,93,17,77,31,44,55,20]\n",
-    "l2 = triTas(liste.copy())\n",
-    "\n",
-    "assert(l2 == sorted(liste))\n",
-    "assert([] == triTas([]))\n",
-    "assert([1] == triTas([1]))\n",
-    "assert([1, 1] == triTas([1, 1]))"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "49bae650-a23a-41f7-8896-8ac502cd71e8",
-   "metadata": {},
-   "source": [
-    "Pour information, le module `heapq` contient l'implémentation d'un tas en Python et s'utilise comme les Piles, Files, etc."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "5bcc3ebf-749e-4a10-8b90-37cfd2488171",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "import heapq\n",
-    "tas = []\n",
-    "\n",
-    "for i in range(5): heapq.heappush(tas, i)\n",
-    "\n",
-    "while not len(tas) == 0: \n",
-    "  print(heapq.heappop(tas), end=\" \")\n",
-    "\n",
-    "# 0 1 2 3 4"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "7f774fa4-c586-4d5c-9cf3-5f9bb899f725",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "**Question 4.2 -** Comparez la performance (en temps) des méthodes de tri que vous avez implémenté dans les questions précentes."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "56e72b68-1d5c-4cea-8e9a-6d9f5f9ae34d",
-   "metadata": {
-    "deletable": false,
-    "nbgrader": {
-     "cell_type": "code",
-     "checksum": "4c8bbe5f3d1599e3ca6db336ae4e3603",
-     "grade": false,
-     "grade_id": "cell-ca3b537d9dcc8790",
-     "locked": false,
-     "schema_version": 3,
-     "solution": true,
-     "task": false
-    },
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "import time\n",
-    "import random\n",
-    "import matplotlib.pyplot as plt\n",
-    "\n",
-    "nvalues = [100, 500, 1500, 2000, 2500, 3000]\n",
-    "\n",
-    "timesSorted = []\n",
-    "timesSort = []\n",
-    "timesSelection = []\n",
-    "timesHeap = []\n",
-    "\n",
-    "for i in nvalues:\n",
-    "\n",
-    "    random.seed()\n",
-    "    p = 12**2\n",
-    "    liste = []\n",
-    "    \n",
-    "    for x in range(i): liste.append(random.randint(0, p))\n",
-    "\n",
-    "    # tri sorted\n",
-    "    c = liste.copy()\n",
-    "    a=time.perf_counter()\n",
-    "    triSorted = sorted(c)\n",
-    "    b=time.perf_counter()\n",
-    "    timesSorted.append(b-a)\n",
-    "\n",
-    "    # tri .sort()\n",
-    "    c = liste.copy()\n",
-    "    a=time.perf_counter()\n",
-    "    triSort = c\n",
-    "    triSort.sort()\n",
-    "    b=time.perf_counter()\n",
-    "    timesSort.append(b-a)\n",
-    "\n",
-    "    # YOUR CODE HERE\n",
-    "    raise NotImplementedError()\n",
-    "    \n",
-    "plt.plot(nvalues, timesSorted, \"g-\", label=\"Tri Sorted\")\n",
-    "plt.plot(nvalues, timesSort, \"b-\", label=\"Tri .sort()\")\n",
-    "plt.plot(nvalues, timesSelection, \"r-\", label=\"Tri Selection\")\n",
-    "plt.plot(nvalues, timesHeap, \"r-\", label=\"Tri Heap\")\n",
-    "plt.xlabel(\"Taille du jeu de données\")\n",
-    "plt.ylabel(\"Temps\")\n",
-    "plt.legend(loc=\"upper left\")\n",
-    "plt.title(\"Comparaison des performances des algorithmes de tri\")\n",
-    "plt.show()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "04456b1e-92fd-4433-b230-8ea4374595a0",
-   "metadata": {},
-   "source": [
-    "Pour en savoir plus comment Python réalise le tri, lire la documentation du `TimSort` (doc)[https://en.wikipedia.org/wiki/Timsort] qui est l'algorithme de tri utilisé."
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "3e925273-2161-4c10-8e79-dabcc9bb38cb",
-   "metadata": {},
-   "source": [
-    "## Pour aller plus loin\n",
-    "\n",
-    "- Mettez à jour votre file afin de renvoyer [une exception](https://docs.python.org/3/tutorial/errors.html) si on demande une valeur qui n'est pas dans la structure de données (pile, file, etc.)\n",
-    "- Utilisez un [grand jeu de donnée](https://generatedata.com/) d'étudiants pour les premières questions."
-   ]
-  }
- ],
- "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.10.9"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/TD02/etudiants.txt b/TD02/etudiants.txt
index 12151c39224809a6186b94c0d80b33cf9d929d21..2a4798d7b6364616036f3b7887756c725e24a445 100644
--- a/TD02/etudiants.txt
+++ b/TD02/etudiants.txt
@@ -1,6 +1,6 @@
 nom;prenom;filiere;note;absences
 Dupond;Pierre;MP;19;7
-Dupond;Jeanne;MP;19;5
+Dupont;Jeanne;MP;19;5
 Clavier;Christian;PSI;14;1
 Gilles;Eric;PC;16;3
 Arthaud;Nathalie;MP;15;0
\ No newline at end of file
diff --git a/TD03/INF-TC1-td03.ipynb b/TD03/INF-TC1-td03.ipynb
index 44d251d30d9b0218ac32c4d4bd34761f5b6e9292..8b6f6bff9d3b1725bb4c36e2d59a8344352a9323 100644
--- a/TD03/INF-TC1-td03.ipynb
+++ b/TD03/INF-TC1-td03.ipynb
@@ -2,7 +2,7 @@
  "cells": [
   {
    "cell_type": "markdown",
-   "id": "c71aca63",
+   "id": "4770edbf",
    "metadata": {},
    "source": [
     "NAME:"
@@ -57,39 +57,6 @@
     "</details>"
    ]
   },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "818565ab-9088-4729-94f9-601ca50de254",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "import graphviz\n",
-    "from graphviz import Digraph\n",
-    "from IPython.display import display\n",
-    "def visualize_oop(root):\n",
-    "    def build(node, dot=None):\n",
-    "        if dot is None:\n",
-    "            dot = graphviz.Digraph(format='png')\n",
-    "\n",
-    "        if node is not None:\n",
-    "            dot.node(str(node.value))\n",
-    "\n",
-    "            if node.left is not None:\n",
-    "                dot.edge(str(node.value), str(node.left.value))\n",
-    "                build(node.left, dot)\n",
-    "\n",
-    "            if node.right is not None:\n",
-    "                dot.edge(str(node.value), str(node.right.value))\n",
-    "                build(node.right, dot)\n",
-    "\n",
-    "        return dot\n",
-    "\n",
-    "    return build(root)"
-   ]
-  },
   {
    "cell_type": "markdown",
    "id": "de645c99-52cf-4cff-9c6b-b156101ad47c",
@@ -97,7 +64,7 @@
    "source": [
     "## Objectif du TD\n",
     "\n",
-    "Ce TD vous fera manipuler les arbres binaires, qui sont une structure de donnée efficace afin de trier des listes mais aussi de réaliser des opérations plus avancées grace à des méthodes de parcours en largeur et en profondeur."
+    "Ce TD vous fera manipuler les Arbres Binaires, qui sont une structure de données permettant de stocker des informations de manière hierarchique, et de les récupérer grace à des méthodes de parcours."
    ]
   },
   {
@@ -105,15 +72,15 @@
    "id": "abde77ea-e21d-434e-b72e-a62ac464c793",
    "metadata": {},
    "source": [
-    "## Exercice 1 : Introduction aux arbres binaires\n",
+    "## Exercice 1 : Introduction aux Arbres Binaires\n",
     "\n",
-    "Dans ce exercice nous allons créer et parcourir un arbre binaire. Un arbre binaire est un arbre qui a les propriétés suivantes : \n",
+    "Dans ce exercice nous allons créer et parcourir un Arbre Binaire. Un Arbre Binaire est un Arbre qui a les propriétés suivantes : \n",
     "\n",
     "- il comporte des noeuds ayant au _maximum deux enfants_\n",
-    "- il est _complet_ si tous les noeuds de tous les niveaux ont deux enfants\n",
-    "- il est _équilibré_ si l'arbre est complet sauf pour le dernier niveau. \n",
+    "- il est dit _complet_ si tous les niveaux de l'arbre sont remplis (sauf éventuellement le dernier), et dans lequel les feuilles sont alignées à gauche\n",
+    "- il est dit _équilibré_ si la différence de hauteur entre les sous-arbres gauche et droit de chaque nœud est au plus 1\n",
     "\n",
-    "Voici un exemple d'arbre binaire :\n",
+    "Voici un exemple d'Arbre Binaire :\n",
     "\n",
     "```\n",
     "      1\n",
@@ -121,7 +88,7 @@
     "    2   3\n",
     "```\n",
     "\n",
-    "Dans cet exercice nous stockeront l'arbre avec une structure de donnée _explicite_ en POO (comme ci-dessous) qui contient des valeurs entières (et uniques, à savoir deux noeuds n'auront pas la même valeur `value`) dans chaque noeud :"
+    "Dans cet exercice nous stockeront l'Arbre Binaire avec une structure de donnée _explicite_ en POO (comme ci-dessous) qui contient des valeurs entières (et uniques, à savoir deux noeuds n'auront pas la même valeur `value`) dans chaque noeud :"
    ]
   },
   {
@@ -195,39 +162,17 @@
     "assert root.right.value == 3"
    ]
   },
-  {
-   "cell_type": "markdown",
-   "id": "2fc5d004-bed5-4e6f-adf9-649d8f1543fb",
-   "metadata": {
-    "tags": []
-   },
-   "source": [
-    "Vous pouvez visualiser et comparer votre résultat avec la méthode `visualize_oop` comme ci-dessous:"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "1edd4902-6ce9-4ffa-90c9-2d5ce45052be",
-   "metadata": {
-    "tags": []
-   },
-   "outputs": [],
-   "source": [
-    "visualize_oop(root)"
-   ]
-  },
   {
    "cell_type": "markdown",
    "id": "24670502-ecd5-4d86-a32c-1d7d43eb04fe",
    "metadata": {},
    "source": [
-    "**Question 1.2.** Proposer une méthode `bfs` de _parcours en largeur_ de l'arbre afin d'afficher la valeur des noeuds dans l'ordre croissant. Pour cela vous utiliserez une structure de données de File (sous forme de liste, cela sera suffisant). Une méthode possible pour mener cela à bien consiste à :\n",
+    "**Question 1.2.** Proposer une méthode `bfs` de _parcours en largeur_ de l'Arbre afin d'afficher la valeur des noeuds dans l'ordre croissant. Pour cela vous utiliserez une structure de données de File (sous forme de liste, cela sera suffisant). Une méthode possible pour mener cela à bien consiste à :\n",
     "\n",
-    "1. Intialiser la file avec la racine de l'arbre\n",
+    "1. Intialiser la File avec la racine de l'Arbre\n",
     "2. Dé-filer une valeur et la stocker dans une liste de résultat\n",
-    "3. En-filer ses enfants (si il y en a) dans la file\n",
-    "4. Répéter l'étape 2 jusqu'à ce que la file soit vide, renvoyer le résultat"
+    "3. En-filer ses enfants (si il y en a) dans la File\n",
+    "4. Répéter l'étape 2 jusqu'à ce que la File soit vide, renvoyer le résultat"
    ]
   },
   {
@@ -274,9 +219,12 @@
     "tags": []
    },
    "source": [
-    "**Question 1.3** - Écrire une fonction `depth` de calcul de la _profondeur_ d'un noeud d'un arbre. La profondeur est défini comme la distance entre ce noeud et la racine (celle-ci aura une profondeur de `0`). Cette fonction prendra la racine de l'arbre `root`en paramètre, ainsi que le noeud dont on veut calculer la profondeur avec le paramètre `target_value`.\n",
+    "**Question 1.3** - Écrire une fonction `depth` de calcul de la _profondeur_ d'un noeud d'un Arbre. La profondeur est défini comme la distance entre ce noeud et la racine (celle-ci aura une profondeur de `0`) ou autrement dit le nombre d'arête entre le noeud et la racine. Cette fonction prendra en paramètre la racine de l'arbre `root`, ainsi que le noeud dont on veut calculer la profondeur avec le paramètre `target_value`.\n",
     "\n",
-    "Conseil : s'inspirer de la fonction précédente en incluant la profondeur de chaque noeud parcouru lors de son ajout dans la file (autrement dit rajouter un tuple `(noeud, profondeur)` au lieu du noeud parcouru seulement."
+    "Conseils : \n",
+    "\n",
+    "- s'inspirer de la fonction précédente en incluant la profondeur de chaque noeud parcouru lors de son ajout dans la file;\n",
+    "- autrement dit rajouter un tuple `(noeud, profondeur)` au lieu du simple noeud parcouru."
    ]
   },
   {
@@ -323,7 +271,7 @@
    "id": "f8abb2f4-24dc-4346-9081-4400df30e3af",
    "metadata": {},
    "source": [
-    "**Question 1.4** - Écrire une fonction `height` de calcul de la _hauteur_ d'un arbre définie comme la prodondeur maximale possible dans un arbe. Vous pouvez l'implémenter comme la profondeur maximale des noeuds de l'arbre, ou bien de manière récursive."
+    "**Question 1.4** - Écrire une fonction `height` de calcul de la _hauteur_ d'un Arbre définie comme la prodondeur maximale possible dans un Arbe. Vous pouvez l'implémenter comme la profondeur maximale des noeuds de l'Arbre, ou bien de manière récursive."
    ]
   },
   {
@@ -368,7 +316,7 @@
    "id": "29fca7e0-aaf9-495b-822d-f20e1a672092",
    "metadata": {},
    "source": [
-    "**Question 1.5** - Valider si l'arbre est bien équilibré, autrement dit si il n'y a pas de différence de profondeur suppérieur à 1 entre les feuilles d'un arbre."
+    "**Question 1.5** - Valider si l'Arbre est bien équilibré, autrement dit si il n'y a pas de différence de profondeur suppérieur à 1 entre les feuilles d'un arbre."
    ]
   },
   {
@@ -415,9 +363,9 @@
    "source": [
     "## Exercice 2 : Arbres syntaxiques\n",
     "\n",
-    "Un arbre _syntaxique_ permet le stockage d'une expression structurée, par exemple une équation. Dans cet exercice nous allons modéliser un tel arbre sous forme d'arbre binaire (exemple ci-dessous à gauche) afin de réaliser un calcul arithmétique simple à partir de l'expression fournie de manière textuelle :\n",
+    "Un Arbre _syntaxique_ permet le stockage d'une expression structurée, par exemple une équation. Dans cet exercice nous allons modéliser un tel arbre sous forme d'arbre binaire (exemple ci-dessous à gauche) afin de réaliser un calcul arithmétique simple à partir de l'expression fournie de manière textuelle :\n",
     "\n",
-    "Expression : `(3-2) * (7+(10/2)`\n",
+    "Expression : `(3-2) * (7+(10/2))`\n",
     "\n",
     "Résultat : `12.0`\n",
     "\n",
@@ -455,7 +403,7 @@
    "id": "88fbc62f-ae5a-4765-bf8f-bb127f5d5a13",
    "metadata": {},
    "source": [
-    "**Question 2.1** - Utilisez la structure de données d'arbre ci-dessus afin de stocker l'arbre syntaxique donné en exemple.\n"
+    "**Question 2.1** - Utilisez la structure de données d'Arbre ci-dessus afin de stocker l'Arbre syntaxique donné en exemple.\n"
    ]
   },
   {
@@ -505,8 +453,8 @@
     "**Question 2.2** - Implémenter désormais une méthode d'évaluation (autrement dit de calcul) automatique d'un arbre syntaxique tel que vous l'avez stocké dans la variable `arbre` ci-dessus. \n",
     "\n",
     "Conseil : proposer une solution récursive avec un cas d'arrêt et des appels récursifs comme suit :\n",
-    "- Si la valeur du noeud en cours est un opérateur, l'appliquer sur les deux sous-branches\n",
-    "- Si c'est une valeur numérique, renvoyer cette valeur (cas d'arrêt car c'est une feuille de l'arbre)"
+    "- si la valeur du noeud en cours est un opérateur, l'appliquer sur les deux sous-branches;\n",
+    "- si c'est une valeur numérique, renvoyer cette valeur (cas d'arrêt car c'est une feuille de l'arbre)"
    ]
   },
   {
@@ -551,11 +499,16 @@
    "id": "de5c394d-df35-4d7b-b057-164620b0b38d",
    "metadata": {},
    "source": [
-    "**Question 2.3** - Écrire une méthode permettant de construire l'arbre à partir d'une expression fournie sous forme de chaîne de caractère en entrée comme `( ( 3 - 2 ) * ( 7 + ( 10 / 2 ) ) )\"`. Les espaces sont nécessaires et vous permettront de faire un `.split(\" \")}`. \n",
+    "**Question 2.3** - Écrire une méthode permettant de construire l'Arbre à partir d'une expression fournie sous forme de chaîne de caractère en entrée comme `( ( 3 - 2 ) * ( 7 + ( 10 / 2 ) ) )\"`. Les espaces sont nécessaires et vous permettront de faire un `.split(\" \")}`. \n",
     "\n",
     "Conseil : \n",
-    "- Parcourez caractère par caractère l'expression textuelle\n",
-    "- Et utilisez une Pile permettant la bonne construction de l'arbre au fur et à mesure de son parcours"
+    "- parcourez caractère par caractère l'expression textuelle transformée en liste;\n",
+    "- créez au fur et à mesure l'arbre initialisé par une racine et une variable stockage le noeud courant en cours de construction\n",
+    "- identifiez les 4 cas possibles : début d'une expression, valeurs numériques, opérateur, fin d'une expression\n",
+    "    - si une expression commence, créer un nouveau fils gauche au noeud courant et stockez le noeud courant dans une Pile\n",
+    "    - si une expression finie, considérez comme noeud courant l'élément que vous dé-Pilerez\n",
+    "    - si un opérateur, stocker sa valeur dans le noeud courant, empiliez ce noeud mais avant lui rajoute un fils droit qui devient le noeud courant\n",
+    "    - si une valeur numérique, la stocker dans le noeud courant et considérez comme noeud courant l'élément que vous dé-Pilerez"
    ]
   },
   {
@@ -620,7 +573,7 @@
    "id": "012a5378-a2b7-498f-8115-e35f55c529ce",
    "metadata": {},
    "source": [
-    "**Question 2.4 (Bonus) -** - Ecrire une fonction qui renvoie `True` ou `False` si l'arbre est bien un arbre syntaxique tel que défini en introduction. Autrement dit qu'il est binaire, et comporte des opérateurs partout sauf aux feuilles.\n",
+    "**Question 2.4 (Bonus) -** - Ecrire une fonction qui renvoie `True` ou `False` si l'Arbre est bien un arbre syntaxique tel que défini en introduction. Autrement dit qu'il est binaire, et comporte des opérateurs partout sauf aux feuilles.\n",
     "\n",
     "Proposez une méthode itérative :"
    ]
@@ -718,7 +671,126 @@
     "\n",
     "- Rajouter des tests dans les exemples ci-dessus avec des arbres plus complexes, des cas particuliers, etc.\n",
     "- Inclure des Exceptions dans votre code afin de gérer par exemple l'accès à un index de liste inexistant, etc.\n",
-    "- Créer une table de hachage afin de mémoriser les opérations déja réalisées pour l'arbre syntaxique"
+    "- Créer une table de hachage afin de mémoriser les opérations déja réalisées pour l'Arbre syntaxique\n",
+    "- Modulariser votre code afin de créer des fonctions auxiliaires (par exemple pour vérifier la valeur des noeuds de l'Arbre syntaxique)."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "08c48261",
+   "metadata": {},
+   "source": [
+    "## Visualiser avec Graphviz\n",
+    "\n",
+    "Graphviz est une bibliothèque de visualisation de graphe. Elle peut être très pratique afin de comprendre la structure de votre instance de graphe. \n",
+    "\n",
+    "Cependant, la bibliothèque pose quelques soucis d'installation en Python, voici des étapes éventuellement à suivre.\n",
+    "\n",
+    "Tout d'abord vérifiez que le module est bien installé :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "c8c95b89",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "!pip install graphviz"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "5a9ebd95",
+   "metadata": {},
+   "source": [
+    "Si oui (vous avez le message du type `Requirement already satisfied:`) testez l'import du module :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "e897987f",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import graphviz\n",
+    "from graphviz import Digraph"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "2bf9b677",
+   "metadata": {},
+   "source": [
+    "Si vous avez des erreurs, essayer l'installation du module à partir des exécutables"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "bd3cfb66",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "https://graphviz.org/"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "9373f3bc",
+   "metadata": {},
+   "source": [
+    "Un autre source d'erreur est l'installation à partir de la mauvaise version de Python qu'il faut utiliser avec pip."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "504eff4a",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "!python --version"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "5eb4ab77",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from IPython.display import display\n",
+    "def visualize_oop(root):\n",
+    "    def build(node, dot=None):\n",
+    "        if dot is None:\n",
+    "            dot = graphviz.Digraph(format='png')\n",
+    "\n",
+    "        if node is not None:\n",
+    "            dot.node(str(node.value))\n",
+    "\n",
+    "            if node.left is not None:\n",
+    "                dot.edge(str(node.value), str(node.left.value))\n",
+    "                build(node.left, dot)\n",
+    "\n",
+    "            if node.right is not None:\n",
+    "                dot.edge(str(node.value), str(node.right.value))\n",
+    "                build(node.right, dot)\n",
+    "\n",
+    "        return dot\n",
+    "\n",
+    "    return build(root)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "ded5b1fe",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "visualize_oop(root)"
    ]
   }
  ],