diff --git a/TD02/INF-TC1-td02.ipynb b/TD02/INF-TC1-td02.ipynb
index d8e75a594f09649683ced71f88bb5e191ad22dbe..9f0a7ce517207949fa0009b1a5cdca0254ccdb78 100644
--- a/TD02/INF-TC1-td02.ipynb
+++ b/TD02/INF-TC1-td02.ipynb
@@ -2,7 +2,7 @@
  "cells": [
   {
    "cell_type": "markdown",
-   "id": "8d6e8e15",
+   "id": "c8809a88",
    "metadata": {},
    "source": [
     "NAME:"
@@ -33,20 +33,18 @@
    "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",
+    "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 des 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",
+    "2) Votre code devra remplacer le texte suivant (que vous pouvez effacer) : \n",
+    "\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",
+    "3) Exécutez enfin les cellules dans leur ordre d'apparition, de haut en bas et si votre code est correct. Ainsi les tests (sous forme d'`assert` seront validés et 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",
@@ -60,7 +58,7 @@
    "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."
+    "Ce TD vous fera manipuler plusieurs structures de données standard en Python (listes `list`, dictionnaires `dict`) 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."
    ]
   },
   {
@@ -92,7 +90,7 @@
    },
    "outputs": [],
    "source": [
-    "L = [3, 2 , 4]"
+    "L1 = [3, 2 , 4]"
    ]
   },
   {
@@ -114,9 +112,9 @@
    },
    "outputs": [],
    "source": [
-    "L = [3, 2 , 4]\n",
-    "L.sort()\n",
-    "L"
+    "L1 = [3, 2 , 4]\n",
+    "L1.sort()\n",
+    "L1"
    ]
   },
   {
@@ -138,9 +136,29 @@
    },
    "outputs": [],
    "source": [
-    "L = [3, 2 , 4]\n",
-    "print(sorted(L))\n",
-    "L"
+    "L2 = [3, 2 , 4]\n",
+    "L2 = sorted(L2)\n",
+    "L2"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "f06e9236-898c-460e-bb23-3a4fed30ad1a",
+   "metadata": {},
+   "source": [
+    "..Et les deux tris sont identiques :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "45b395c0-192f-47db-833d-4087d8244dea",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "L1 == L2"
    ]
   },
   {
@@ -148,7 +166,7 @@
    "id": "4affcb3d-d8ae-4c5e-a7f5-fbc59b1fff76",
    "metadata": {},
    "source": [
-    "Enfin les fonctions de tri peuvent prendre un [paramètre nommé](https://docs.python.org/3/glossary.html#term-parameter) `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 :"
+    "Enfin les fonctions de tri peuvent prendre un [paramètre nommé](https://docs.python.org/3/glossary.html#term-parameter) `key` afin d'indiquer sur quel attribut de la liste réaliser le tri. Ci-dessous le tri sera appliqué sur le premier élément d'une liste de listes à trier :"
    ]
   },
   {
@@ -203,7 +221,7 @@
     "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) :"
+    "Un échantillon 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) :"
    ]
   },
   {
@@ -223,7 +241,7 @@
    "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()`)."
+    "**Question 1.1 -** Calculez la moyenne des dans la liste `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()`)."
    ]
   },
   {
@@ -298,7 +316,7 @@
     "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."
+    "**Question 1.2 -** Trouvez 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 encore au type des données."
    ]
   },
   {
@@ -330,7 +348,9 @@
    "cell_type": "code",
    "execution_count": null,
    "id": "ef350eab",
-   "metadata": {},
+   "metadata": {
+    "tags": []
+   },
    "outputs": [],
    "source": [
     "find_maximum_recursive(students_list)"
@@ -353,11 +373,11 @@
    "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",
+    "**Question 1.3 -** Ecrivez une fonction de recherche d'une pair d'é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"
+    "- si une note a déjà été visitée alors renvoyer l'indice du dictionnaire;\n",
+    "- enfin renvoyez les noms des étudiants."
    ]
   },
   {
@@ -414,7 +434,7 @@
    "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",
+    "**Question 1.4 (BONUS si vous avez du temps) -** Triez la liste d'étudiants 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` permettra d'indiquer sur quel attribut réaliser le tri (par exemple la note). Voir l'usage de cet attribut dans la cellule de test suivante.\n",
     "\n",
     "```\n",
     "   procédure tri_selection(tableau t)\n",
@@ -530,7 +550,7 @@
    "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 empilement."
+    "La Pile ci-dessus a son équivalent avec la méthode `LifoQueue` du module `queue` de Python 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 empilement."
    ]
   },
   {
@@ -555,7 +575,7 @@
    "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` (avec le `while` fourni dans le code ci-dessous) :"
+    "**Question 2.1 -** Utilisez 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` (avec le `while` fourni dans le code ci-dessous) :"
    ]
   },
   {
@@ -592,7 +612,7 @@
    "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."
+    "**Question 2.2 -** Transformer la structure de Pile `Stack` en une **File** (que vous nommerez `File`) 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."
    ]
   },
   {
@@ -603,7 +623,7 @@
     "deletable": false,
     "nbgrader": {
      "cell_type": "code",
-     "checksum": "084870f7cbddd7dc85c2b1c02c8648d3",
+     "checksum": "d2be858817d2925e39e826b8ae208a2f",
      "grade": false,
      "grade_id": "cell-a9eea459cf78c621",
      "locked": false,
@@ -615,7 +635,7 @@
    },
    "outputs": [],
    "source": [
-    "class Queue():\n",
+    "class File():\n",
     "    # YOUR CODE HERE\n",
     "    raise NotImplementedError()"
    ]
@@ -628,7 +648,7 @@
     "deletable": false,
     "nbgrader": {
      "cell_type": "code",
-     "checksum": "414f416a2a624101edaa0bdeb57fee51",
+     "checksum": "789f8b36c6e74a35fbbbce020fc87f83",
      "grade": false,
      "grade_id": "cell-a259250b447e39e2",
      "locked": false,
@@ -641,7 +661,7 @@
    "outputs": [],
    "source": [
     "file = queue.Queue()\n",
-    "f = Queue()\n",
+    "f = File()\n",
     "# YOUR CODE HERE\n",
     "raise NotImplementedError()\n",
     "\n",
@@ -664,7 +684,7 @@
     "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."
+    "**Question 2.3** - Mettez à jour votre File afin de ne pas générer d'[exception](https://docs.python.org/3/tutorial/errors.html) `IndexError`. On peut par exemple renvoyer une valeur de type `None` si aucune valeur n'est disponible. Ci-dessous un exemple de capture d'exception en Python sur lequel vous pouvez vous baser :"
    ]
   },
   {
@@ -676,7 +696,7 @@
    },
    "outputs": [],
    "source": [
-    "file = Queue()\n",
+    "file = File()\n",
     "try:\n",
     "    assert file.pop() == None # si on renvoie None pour une file vide, pas d'Exception !\n",
     "except IndexError:\n",
@@ -690,14 +710,14 @@
     "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",
+    "**Question 2.4** - Enfin, transformez la File (classe `Queue`) pour en faire une file de Priorité nommée `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",
     "Conseils :\n",
     "\n",
-    "- garder la liste des valeurs internes constamment triée lors de l'ajout;\n",
+    "- garderzla liste des valeurs internes constamment triée lors de l'ajout de nouvelles valeurs;\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."
+    "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 le comportement de votre code."
    ]
   },
   {
@@ -785,6 +805,14 @@
     "    assert f.pop() == filep.get()"
    ]
   },
+  {
+   "cell_type": "markdown",
+   "id": "014b7c3e-cfaf-4e80-9aa8-aff4e2ca821d",
+   "metadata": {},
+   "source": [
+    "La complexité de la structure de données de file de priorité est $O(n)$ en ajout et de $O(1)$ en lecture."
+   ]
+  },
   {
    "cell_type": "markdown",
    "id": "77038e6d-0b73-434c-910d-c7da733b643a",
@@ -798,7 +826,7 @@
    "id": "5f3fc128-2a2e-42bd-924a-d691c09150d6",
    "metadata": {},
    "source": [
-    "Nous allons maintenant implémenter un **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",
+    "Nous allons maintenant implémenter un **arbre binaire complet**. Cet arbre sera utile pour l'exercice suivant et la création d'une nouvelle structure de données : le 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",
@@ -823,7 +851,7 @@
    "id": "ea502a0e-faa7-4bb2-9627-35cd128521a4",
    "metadata": {},
    "source": [
-    "**Exercice 3.1** - Implémentez un Arbre Binaire sous forme de classe appellée `BinaryTree` (vous pouvez vous inspirer de la File de Priorité) avec les fonctions ci-dessus. En particulier les méthodes `get_parent`, `get_fils_gauche`, `get_fils_droit` renvoient un `Tuple` (valeur, indice). Vous rajouterez une méthode `taille`qui renvoie la taille de l'arbre binaire (longueur de la liste interne)."
+    "**Exercice 3.1** - Implémentez un arbre binaire sous forme de classe appellée `BinaryTree` (vous pouvez vous inspirer de la classe de File de Priorité). En particulier les méthodes `get_parent`, `get_fils_gauche`, `get_fils_droit` renvoient un `Tuple` (valeur, indice). Vous rajouterez une méthode `taille`qui renvoie la taille de l'arbre binaire (longueur de la liste interne)."
    ]
   },
   {
@@ -900,7 +928,7 @@
    "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`."
+    "Cette structure de donnée sera utile pour la question suivante afin de créer un tas."
    ]
   },
   {
@@ -908,7 +936,7 @@
    "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 satisfait 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",
+    "**Exercice 3.3** - Ecrivez une fonction de parcours de l'arbre qui renvoie `True` si un noeud est inférieur à ses enfants, sinon `False`. Conseil : \n",
     "\n",
     "1. Proposez une approche récursive\n",
     "2. Le cas d'arrêt est un noeud vide\n",
@@ -978,9 +1006,9 @@
    "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."
+    "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. Pour rappel la file créée précédemment avant une complexité de $O(n)$ en ajout et de $O(1)$ en lecture. \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. Cette structure de données sera plus efficace en $O(log(n)$ pour l'ajout d'une nouvelle valeur (mais aussi pour le retrait)."
    ]
   },
   {
@@ -990,26 +1018,21 @@
    "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",
+    "1. 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",
+    "2. 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",
+    "3. 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",
+    "4. 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",
@@ -1303,7 +1326,7 @@
     "tags": []
    },
    "source": [
-    "- Utilisez un [grand jeu de donnée](https://generatedata.com/) d'étudiants pour les premières questions."
+    "- Utilisez un [grand jeu de donnée](https://generatedata.com/) d'étudiants pour les premières questions. Réaliser une analyse de complexité avec ce jeu de données."
    ]
   },
   {
diff --git a/TD03/INF-TC1-td03.ipynb b/TD03/INF-TC1-td03.ipynb
index 8b6f6bff9d3b1725bb4c36e2d59a8344352a9323..e81aafd8f9368ac9322c5a9a7d2a3a2fc5ae346f 100644
--- a/TD03/INF-TC1-td03.ipynb
+++ b/TD03/INF-TC1-td03.ipynb
@@ -2,7 +2,7 @@
  "cells": [
   {
    "cell_type": "markdown",
-   "id": "4770edbf",
+   "id": "39a8f123",
    "metadata": {},
    "source": [
     "NAME:"
@@ -74,9 +74,9 @@
    "source": [
     "## 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 vous allez 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 dit _binaire_ car il comporte des noeuds ayant au _maximum_ deux enfants\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",
@@ -88,7 +88,7 @@
     "    2   3\n",
     "```\n",
     "\n",
-    "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 :"
+    "Dans cet exercice nous stockeront l'Arbre Binaire avec une structure de donnée _explicite_ (en POO comme ci-dessous, et non plus dans un tableau comme pour le tas dans le TD 2) qui contient des valeurs entières (et uniques, à savoir deux noeuds n'auront pas la même valeur `value`) dans chaque noeud :"
    ]
   },
   {
@@ -145,7 +145,7 @@
    "id": "0a4461c4-09b8-4f9f-ad70-6b953dc4b7e6",
    "metadata": {},
    "source": [
-    "Les tests suivant doivent être validés (vous pouvez rajouter d'autres tests) :"
+    "Les tests suivant doivent être validés (rajoutez d'autres tests) :"
    ]
   },
   {
@@ -167,12 +167,12 @@
    "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.** Proposez 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",
-    "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"
+    "1. intialiser la File avec la racine de l'Arbre;\n",
+    "2. dé-filer une valeur et la stocker dans une liste de résultats;\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."
    ]
   },
   {
@@ -219,12 +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`) 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",
+    "**Question 1.3** - Écrivez 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`). Autrement dit la profondeur correspond au nombre d'arêtes entre un noeud et la racine de l'arbre. 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",
     "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."
+    "- s'inspirer de la fonction précédente de parcours en largeur 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 afin de mémoriser la profondeur des noeuds parcourus."
    ]
   },
   {
@@ -271,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** - Écrivez 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."
    ]
   },
   {
@@ -316,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** - Ecrivez une fonction de validation afin de déterminer si un 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. Conseil : utilisez une approche récursive."
    ]
   },
   {
@@ -381,14 +381,16 @@
     "           10  2\n",
     "```\n",
     "\n",
-    "Vous utiliserez la structure d'arbre binaire ci-dessous afin de le stocker :"
+    "Vous utiliserez la structure d'arbre binaire ci-dessous afin de stocker l'arbre comme pour l'abre binaire précédent :"
    ]
   },
   {
    "cell_type": "code",
    "execution_count": null,
    "id": "e78ec913-cd5f-4304-8c8a-438758d909f4",
-   "metadata": {},
+   "metadata": {
+    "tags": []
+   },
    "outputs": [],
    "source": [
     "class Noeud:\n",
@@ -403,7 +405,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** - Stockez l'Arbre syntaxique donné en exemple graphique en utilisant la structure de données d'arbre binaire ci-dessus (il s'agit d'écrire une instance d'arbre dans la variable `arbre`, et non une fonction)."
    ]
   },
   {
@@ -450,11 +452,11 @@
    "id": "0be8aab9-1aba-4340-9235-eb3d1cc7fd29",
    "metadata": {},
    "source": [
-    "**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",
+    "**Question 2.2** - Implémentez 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",
+    "Conseil : proposez 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 il s'agit d'une valeur numérique, renvoyez cette valeur (cas d'arrêt car c'est une feuille de l'arbre)."
    ]
   },
   {
@@ -499,15 +501,15 @@
    "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** - Écrivez 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 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",
+    "- 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éez 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 un opérateur, stockez sa valeur dans le noeud courant, empilez 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"
    ]
   },
@@ -573,9 +575,9 @@
    "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 :"
+    "Proposez d'abord une méthode itérative :"
    ]
   },
   {
@@ -622,7 +624,7 @@
     "tags": []
    },
    "source": [
-    "Proposez une méthode récursive :"
+    "Proposez ensuite une méthode récursive :"
    ]
   },
   {
@@ -662,6 +664,83 @@
     "assert valide_rec(arbre)"
    ]
   },
+  {
+   "cell_type": "markdown",
+   "id": "3503e6a5-2bc1-46d2-bef0-d1f1ceb6827e",
+   "metadata": {},
+   "source": [
+    "Montrez que les deux méthodes ont un comportement identique :"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "81e1b468-5d22-4a25-a2c3-17ab165627e5",
+   "metadata": {
+    "deletable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "31598d4e9ae9c42c9188b472f6ba4fad",
+     "grade": false,
+     "grade_id": "cell-379297f2e2b88a1b",
+     "locked": false,
+     "schema_version": 3,
+     "solution": true,
+     "task": false
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "# YOUR CODE HERE\n",
+    "raise NotImplementedError()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "81842c6c-1784-432b-8322-f3793d633e03",
+   "metadata": {},
+   "source": [
+    "**Question 2.5 (Bonus) -** Créez une table de hachage afin de mémoriser les opérations déja réalisées pour l'Arbre syntaxique. Conseil : utilisez les informations sur le noeud comme clé (valeurs, opérateur)."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "fb91bda6-7076-44be-9014-ceb5507eb01c",
+   "metadata": {
+    "deletable": false,
+    "nbgrader": {
+     "cell_type": "code",
+     "checksum": "e15011947c1d26437561ca41b8e06546",
+     "grade": false,
+     "grade_id": "cell-5e2de1024606fa88",
+     "locked": false,
+     "schema_version": 3,
+     "solution": true,
+     "task": false
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "def eval_hash(r: Noeud, memo=None) -> float:\n",
+    "    # YOUR CODE HERE\n",
+    "    raise NotImplementedError()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "22979a11-3455-4525-b816-a84b2164291c",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "assert eval_hash(arbre) == eval(arbre)"
+   ]
+  },
   {
    "cell_type": "markdown",
    "id": "85c6a3e6-dea0-4e86-b7d9-b0c5735c3630",
@@ -670,8 +749,7 @@
     "## Pour aller plus loin\n",
     "\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\n",
+    "- Inclure des [Exceptions](https://docs.python.org/3/tutorial/errors.html) dans votre code afin de gérer par exemple l'accès à un index de liste inexistant, etc.\n",
     "- Modulariser votre code afin de créer des fonctions auxiliaires (par exemple pour vérifier la valeur des noeuds de l'Arbre syntaxique)."
    ]
   },