Skip to content
Snippets Groups Projects
Commit 59809971 authored by Romain Vuillemot's avatar Romain Vuillemot
Browse files

corrections mineures

parent 8f324ea0
No related branches found
No related tags found
No related merge requests found
%% Cell type:markdown id:fab957ee tags: %% Cell type:markdown id:6e217066 tags:
NAME: NAME:
%% Cell type:markdown id:4079279c tags: %% Cell type:markdown id:4079279c tags:
# INF TC1 - TD2 (2h) - Structures de données # INF TC1 - TD2 (2h) - Structures de données
%% Cell type:markdown id:74d75def tags: %% Cell type:markdown id:74d75def tags:
--- ---
%% Cell type:markdown id:42890ec6-251a-404c-a6f6-39c138db8650 tags: %% Cell type:markdown id:42890ec6-251a-404c-a6f6-39c138db8650 tags:
### IMPORTANT A LIRE (SUR L'UTILISATION DE CE NOTEBOOK) ### IMPORTANT A LIRE (SUR L'UTILISATION DE CE NOTEBOOK)
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 : 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 :
1) Répondez aux questions dans les cellules en dessous des questions. 1) Répondez aux questions dans les cellules en dessous des questions.
2) Votre code devra remplacer le texte suivant : 2) Votre code devra remplacer le texte suivant :
erge
```python ```python
# YOUR CODE HERE # YOUR CODE HERE
raise NotImplementedError() raise NotImplementedError()
``` ```
(vous pouvez effacer ces deux lignes quand vous les rencontrez mais ne modifiez pas les noms de fonctions sinon les tests ne marchent plus). (vous pouvez effacer ces deux lignes quand vous les rencontrez mais ne modifiez pas les noms de fonctions sinon les tests ne marchent plus).
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. 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.
4) Vous pouvez créer de nouvelles cellules comme bon vous semble. 4) Vous pouvez créer de nouvelles cellules comme bon vous semble.
**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. **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.
%% Cell type:markdown id:b692d4dd-6dbc-40e9-9c19-0b59e31e5eab tags: %% Cell type:markdown id:b692d4dd-6dbc-40e9-9c19-0b59e31e5eab tags:
## Objectif du TD ## Objectif du TD
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, 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 tags: %% Cell type:markdown id:b6221ad1-379e-4e50-8c22-220994439b6d tags:
## Exercice 1 - Chargement et tri d'une liste ## Exercice 1 - Chargement et tri d'une liste
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. 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 tags: %% Cell type:markdown id:985e2dd2-dc05-437c-b3f0-60696fe27e3f tags:
### Rappel : Tri de listes ### Rappel : Tri de listes
Avant de commencer quelques rappels sur les structures de données de listes et leurs tris. Voici une liste en Python : Avant de commencer quelques rappels sur les structures de données de listes et leurs tris. Voici une liste en Python :
%% Cell type:code id:327780ed-4331-43ad-921b-9e42d762f2aa tags: %% Cell type:code id:327780ed-4331-43ad-921b-9e42d762f2aa tags:
``` python ``` python
L = [3, 2 , 4] L = [3, 2 , 4]
``` ```
%% Cell type:markdown id:01263b26-3983-4073-aaff-1a30d69ff914 tags: %% Cell type:markdown id:01263b26-3983-4073-aaff-1a30d69ff914 tags:
Pour la trier vous pouvez utiliser ```.sort()``` [(doc)](https://docs.python.org/3/howto/sorting.html) qui modifie la liste actuelle : Pour la trier vous pouvez utiliser ```.sort()``` [(doc)](https://docs.python.org/3/howto/sorting.html) qui modifie la liste actuelle :
%% Cell type:code id:79f084ad-942d-46c6-bfe7-2722eeeda426 tags: %% Cell type:code id:79f084ad-942d-46c6-bfe7-2722eeeda426 tags:
``` python ``` python
L = [3, 2 , 4] L = [3, 2 , 4]
L.sort() L.sort()
L L
``` ```
%% Cell type:markdown id:f04dbfe7-c000-4c2e-a2c4-e6187fe17ba7 tags: %% Cell type:markdown id:f04dbfe7-c000-4c2e-a2c4-e6187fe17ba7 tags:
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) : 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 id:c9b79862-a7b6-4b74-af5c-3d36f85f7b67 tags: %% Cell type:code id:c9b79862-a7b6-4b74-af5c-3d36f85f7b67 tags:
``` python ``` python
L = [3, 2 , 4] L = [3, 2 , 4]
print(sorted(L)) print(sorted(L))
L L
``` ```
%% Cell type:markdown id:4affcb3d-d8ae-4c5e-a7f5-fbc59b1fff76 tags: %% Cell type:markdown id:4affcb3d-d8ae-4c5e-a7f5-fbc59b1fff76 tags:
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 : 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 id:76f37b8b-69f5-4df0-91ae-b221a372e519 tags: %% Cell type:code id:76f37b8b-69f5-4df0-91ae-b221a372e519 tags:
``` python ``` python
L = [[3, "C"], [1, "A"], [2, "B"]] L = [[3, "C"], [1, "A"], [2, "B"]]
L.sort(key=lambda x: x[0]) L.sort(key=lambda x: x[0])
L L
``` ```
%% Cell type:markdown id:c815465f tags: %% Cell type:markdown id:c815465f tags:
### Chargement d'un fichier en dictionnaire ### Chargement d'un fichier en dictionnaire
Le code ci-dessous permet de charger ce fichier dans la variable `students_list`. Le code ci-dessous permet de charger ce fichier dans la variable `students_list`.
%% Cell type:code id:fe36de75-c9c4-49b7-ad79-de78c4f5b3ca tags: %% Cell type:code id:fe36de75-c9c4-49b7-ad79-de78c4f5b3ca tags:
``` python ``` python
students_list = [] students_list = []
with open("etudiants.txt") as f: with open("etudiants.txt") as f:
keys = None keys = None
for line in f: for line in f:
l = [w.strip() for w in line.split(';')] l = [w.strip() for w in line.split(';')]
if keys is None: if keys is None:
keys = l keys = l
else: else:
students_list.append({k:v for k, v in zip(keys, l)}) students_list.append({k:v for k, v in zip(keys, l)})
``` ```
%% Cell type:markdown id:cfb09dcd-d8eb-474d-9f01-bff6de7b114a tags: %% Cell type:markdown id:cfb09dcd-d8eb-474d-9f01-bff6de7b114a tags:
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 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 id:a0ab86a7-ed2a-4265-be05-fabd7a7b7fe5 tags: %% Cell type:code id:a0ab86a7-ed2a-4265-be05-fabd7a7b7fe5 tags:
``` python ``` python
students_list[0:2] students_list[0:2]
``` ```
%% Cell type:markdown id:d54fe400 tags: %% Cell type:markdown id:d54fe400 tags:
**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 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 id:084ca248-e638-4416-9fed-32dde916fb5b tags: %% Cell type:code id:084ca248-e638-4416-9fed-32dde916fb5b tags:
``` python ``` python
def average_grade(L: list)-> int: def average_grade(L: list)-> int:
# YOUR CODE HERE # YOUR CODE HERE
raise NotImplementedError() raise NotImplementedError()
``` ```
%% Cell type:markdown id:66486e51-46fa-4475-a990-9764f1206f21 tags: %% Cell type:markdown id:66486e51-46fa-4475-a990-9764f1206f21 tags:
La moyenne attendue de votre fonction est : La moyenne attendue de votre fonction est :
%% Cell type:code id:e6086d5b-1a84-4cee-8bd3-b3acf46d68d3 tags: %% Cell type:code id:e6086d5b-1a84-4cee-8bd3-b3acf46d68d3 tags:
``` python ``` python
average_grade(students_list) average_grade(students_list)
``` ```
%% Cell type:markdown id:65b4a7d1-d0d6-4ec4-a609-b7eb42157cea tags: %% Cell type:markdown id:65b4a7d1-d0d6-4ec4-a609-b7eb42157cea tags:
Le test ci-dessous doit donc être validé (autrement dit aucune `Exception` ne doit être lancée) : Le test ci-dessous doit donc être validé (autrement dit aucune `Exception` ne doit être lancée) :
%% Cell type:code id:836938d8-a4c7-44e2-b17b-2159acd11aad tags: %% Cell type:code id:836938d8-a4c7-44e2-b17b-2159acd11aad tags:
``` python ``` python
assert average_grade(students_list) == 16.6 assert average_grade(students_list) == 16.6
``` ```
%% Cell type:markdown id:2f986196-2afa-4baf-96a3-3d22280e6c22 tags: %% Cell type:markdown id:2f986196-2afa-4baf-96a3-3d22280e6c22 tags:
**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 -** 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 id:45624183-f5e7-43ae-9e41-ab8b456d9360 tags: %% Cell type:code id:45624183-f5e7-43ae-9e41-ab8b456d9360 tags:
``` python ``` python
def find_maximum_recursive(L: list)-> str: def find_maximum_recursive(L: list)-> str:
# YOUR CODE HERE # YOUR CODE HERE
raise NotImplementedError() raise NotImplementedError()
``` ```
%% Cell type:code id:59684c44-83db-47c3-a192-781041fc3b59 tags: %% Cell type:code id:59684c44-83db-47c3-a192-781041fc3b59 tags:
``` python ``` python
assert find_maximum_recursive(students_list) == int(max(students_list, key=lambda x: int(x["note"]))["note"]) 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 tags: %% Cell type:markdown id:a9bca555-e31a-4294-bdac-d9e2ff5fa950 tags:
**Question 1.3 -** Trouver deux étudiants qui ont la même note, et renvoyez leurs noms sous forme de `Tuple`. Conseil : **Question 1.3 -** Trouver deux étudiants qui ont la même note, et renvoyez leurs noms sous forme de `Tuple`. Conseil :
- parcourez la liste et mémoriser les notes que vous parcourrez; - parcourez la liste et mémoriser les notes que vous parcourrez;
- si une note a déjà été parcourue alors renvoyer l'indice du dictionnaire; - si une note a déjà été parcourue alors renvoyer l'indice du dictionnaire;
- enfin renvoyez les noms des étudiants - enfin renvoyez les noms des étudiants
%% Cell type:code id:1dd770ee-1c63-4fcc-b564-158803c665e9 tags: %% Cell type:code id:1dd770ee-1c63-4fcc-b564-158803c665e9 tags:
``` python ``` python
def find_same_grade(L: list)-> tuple: def find_same_grade(L: list)-> tuple:
# YOUR CODE HERE # YOUR CODE HERE
raise NotImplementedError() raise NotImplementedError()
``` ```
%% Cell type:code id:dbfbaf85-01b6-4bbc-ae1e-b9e7cc47489e tags: %% Cell type:code id:dbfbaf85-01b6-4bbc-ae1e-b9e7cc47489e tags:
``` python ``` python
find_same_grade(students_list) find_same_grade(students_list)
``` ```
%% Cell type:code id:5ef24de8-ed61-40e1-ad9a-26f118223c17 tags: %% Cell type:code id:5ef24de8-ed61-40e1-ad9a-26f118223c17 tags:
``` python ``` python
assert find_same_grade(students_list) == ('Dupond', 'Dupont') assert find_same_grade(students_list) == ('Dupond', 'Dupont')
``` ```
%% Cell type:markdown id:0f948f2e tags: %% Cell type:markdown id:0f948f2e tags:
**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. **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.
``` ```
procédure tri_selection(tableau t) procédure tri_selection(tableau t)
n ← longueur(t) n ← longueur(t)
pour i de 0 à n - 2 pour i de 0 à n - 2
min ← i min ← i
pour j de i + 1 à n - 1 pour j de i + 1 à n - 1
si t[j] < t[min], alors min ← j si t[j] < t[min], alors min ← j
fin pour fin pour
si min ≠ i, alors échanger t[i] et t[min] si min ≠ i, alors échanger t[i] et t[min]
fin pour fin pour
fin procédure fin procédure
``` ```
%% Cell type:code id:03e651d7-1143-4a9f-b453-3469d5b75e52 tags: %% Cell type:code id:03e651d7-1143-4a9f-b453-3469d5b75e52 tags:
``` python ``` python
def sort_selection(L: list, key=lambda x: x) -> list: def sort_selection(L: list, key=lambda x: x) -> list:
# YOUR CODE HERE # YOUR CODE HERE
raise NotImplementedError() raise NotImplementedError()
``` ```
%% Cell type:markdown id:d95d2146-847a-4c21-9a9a-af277d236aea tags: %% Cell type:markdown id:d95d2146-847a-4c21-9a9a-af277d236aea tags:
Comparer votre tri avec la méthode `sorted` de Python. Comparer votre tri avec la méthode `sorted` de Python.
%% Cell type:code id:e27a7071-e10b-4801-8d16-aa611f0866f6 tags: %% Cell type:code id:e27a7071-e10b-4801-8d16-aa611f0866f6 tags:
``` python ``` python
# YOUR CODE HERE # YOUR CODE HERE
raise NotImplementedError() raise NotImplementedError()
``` ```
%% Cell type:markdown id:dae866db tags: %% Cell type:markdown id:dae866db tags:
## Exercice 2 : Piles et files ## Exercice 2 : Piles et files
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: 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 id:c4f1b0a9 tags: %% Cell type:code id:c4f1b0a9 tags:
``` python ``` python
class Stack: class Stack:
def __init__(self): def __init__(self):
self.items = [] self.items = []
def push(self, item): def push(self, item):
self.items.append(item) self.items.append(item)
def pop(self): def pop(self):
if not self.is_empty(): if not self.is_empty():
return self.items.pop() return self.items.pop()
def peek(self): def peek(self):
if not self.is_empty(): if not self.is_empty():
return self.items[-1] return self.items[-1]
def is_empty(self): def is_empty(self):
return len(self.items) == 0 return len(self.items) == 0
``` ```
%% Cell type:markdown id:5ee3c79e-be53-4d98-a2fb-3b0e9adadeb8 tags: %% Cell type:markdown id:5ee3c79e-be53-4d98-a2fb-3b0e9adadeb8 tags:
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. 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 id:77dee078-c30f-40a0-bd29-f64c978b3e0b tags: %% Cell type:code id:77dee078-c30f-40a0-bd29-f64c978b3e0b tags:
``` python ``` python
import queue import queue
pile = queue.LifoQueue() pile = queue.LifoQueue()
for i in range (5): for i in range (5):
pile.put(i) pile.put(i)
while not pile.empty(): while not pile.empty():
print(pile.get(), end=" ") print(pile.get(), end=" ")
``` ```
%% Cell type:markdown id:bfaae7f4 tags: %% Cell type:markdown id:bfaae7f4 tags:
**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) : **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 id:3ad4b923-5f23-4921-b02e-f8b9fd22dd55 tags: %% Cell type:code id:3ad4b923-5f23-4921-b02e-f8b9fd22dd55 tags:
``` python ``` python
pile = queue.LifoQueue() pile = queue.LifoQueue()
s = Stack() s = Stack()
# YOUR CODE HERE # YOUR CODE HERE
raise NotImplementedError() raise NotImplementedError()
while not s.is_empty() and not pile.empty(): while not s.is_empty() and not pile.empty():
assert s.pop() == pile.get() assert s.pop() == pile.get()
``` ```
%% Cell type:markdown id:78b1b0fb-41fb-4e2e-8c2b-3a040fbcc5e0 tags: %% Cell type:markdown id:78b1b0fb-41fb-4e2e-8c2b-3a040fbcc5e0 tags:
**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 `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 id:7ac004cd-f59e-4aa8-a31d-961e24acba69 tags: %% Cell type:code id:7ac004cd-f59e-4aa8-a31d-961e24acba69 tags:
``` python ``` python
class Queue(): class Queue():
# YOUR CODE HERE # YOUR CODE HERE
raise NotImplementedError() raise NotImplementedError()
``` ```
%% Cell type:code id:9b588c0e-d8b8-4a57-b54f-6aef316bb5c5 tags: %% Cell type:code id:9b588c0e-d8b8-4a57-b54f-6aef316bb5c5 tags:
``` python ``` python
file = queue.Queue() file = queue.Queue()
f = Queue() f = Queue()
# YOUR CODE HERE # YOUR CODE HERE
raise NotImplementedError() raise NotImplementedError()
while not f.is_empty() and not file.empty(): while not f.is_empty() and not file.empty():
assert f.pop() == file.get() assert f.pop() == file.get()
``` ```
%% Cell type:markdown id:5a8722ae-500d-4956-9b8c-18e664e5b09f tags: %% Cell type:markdown id:5a8722ae-500d-4956-9b8c-18e664e5b09f tags:
Nous voyons bien que le défilement renvoie les données dans l'ordre de leur empillement afin de respecter le principe de File. 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 tags: %% Cell type:markdown id:e1f0a957-2c18-4edd-b37b-d766ac1e8557 tags:
**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 `IndexError`. On peut par exemple renvoyer une valeur de type `None` si aucune valeur n'est disponible.
%% Cell type:code id:49a596f0-fc7c-4158-bab1-e715e1cf6a57 tags: %% Cell type:code id:49a596f0-fc7c-4158-bab1-e715e1cf6a57 tags:
``` python ``` python
file = Queue() file = Queue()
try: try:
assert file.pop() == None # si on renvoie None pour une file vide, pas d'Exception ! assert file.pop() == None # si on renvoie None pour une file vide, pas d'Exception !
except IndexError: except IndexError:
print("On ne doit pas générer d'exception IndexError !") print("On ne doit pas générer d'exception IndexError !")
``` ```
%% Cell type:markdown id:9ebbd490-abcd-45e4-8296-c311e34ddf2d tags: %% Cell type:markdown id:9ebbd490-abcd-45e4-8296-c311e34ddf2d tags:
**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). **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).
Conseil Conseil
- garder la liste des valeurs internes constamment triée lors de l'ajout; - garder la liste des valeurs internes constamment triée lors de l'ajout;
- 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)` - 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)`
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 votre code.
%% Cell type:code id:fa163d01-ed34-447e-8b55-6198140c349b tags: %% Cell type:code id:fa163d01-ed34-447e-8b55-6198140c349b tags:
``` python ``` python
from queue import PriorityQueue from queue import PriorityQueue
import random import random
filep = PriorityQueue() filep = PriorityQueue()
list_random = [random.randint(1, 10) for _ in range(5)] # Liste aléatoire list_random = [random.randint(1, 10) for _ in range(5)] # Liste aléatoire
for i in list_random: filep.put(i) for i in list_random: filep.put(i)
while not filep.empty(): while not filep.empty():
print(filep.get(), end=" ") print(filep.get(), end=" ")
``` ```
%% Cell type:markdown id:738fe9f0-7885-40b6-a8cf-eb0c7cd8f3aa tags: %% Cell type:markdown id:738fe9f0-7885-40b6-a8cf-eb0c7cd8f3aa tags:
Remplir le code ci-dessous basé sur la file afin d'en faire une file de priorité. Remplir le code ci-dessous basé sur la file afin d'en faire une file de priorité.
%% Cell type:code id:3b0a1122-5d8f-4f5f-8ef4-460f9896f4b6 tags: %% Cell type:code id:3b0a1122-5d8f-4f5f-8ef4-460f9896f4b6 tags:
``` python ``` python
class FilePriorite(): class FilePriorite():
# YOUR CODE HERE # YOUR CODE HERE
raise NotImplementedError() raise NotImplementedError()
``` ```
%% Cell type:code id:4e608d6b-458b-4836-8ab2-4371d96ae54b tags: %% Cell type:code id:4e608d6b-458b-4836-8ab2-4371d96ae54b tags:
``` python ``` python
filep = PriorityQueue() filep = PriorityQueue()
f = FilePriorite() f = FilePriorite()
note_list = [student["note"] for student in students_list] note_list = [student["note"] for student in students_list]
# YOUR CODE HERE # YOUR CODE HERE
raise NotImplementedError() raise NotImplementedError()
while not f.is_empty() and not filep.empty(): while not f.is_empty() and not filep.empty():
assert f.pop() == filep.get() assert f.pop() == filep.get()
``` ```
%% Cell type:markdown id:77038e6d-0b73-434c-910d-c7da733b643a tags: %% Cell type:markdown id:77038e6d-0b73-434c-910d-c7da733b643a tags:
## Exercice 3 : Arbre binaire complet sous forme de liste ## Exercice 3 : Arbre binaire complet sous forme de liste
%% Cell type:markdown id:5f3fc128-2a2e-42bd-924a-d691c09150d6 tags: %% Cell type:markdown id:5f3fc128-2a2e-42bd-924a-d691c09150d6 tags:
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 (dans sa 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) satisfait la propriété suivante : la valeur de tout noeud est inférieure à celle de ses enfant. Cet arbre binaire sera de surcroît 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 : 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 :
- La racine a la position $i = 0$ (cette valeur sera renvoyée par la fonction `get_racine`) - La racine a la position $i = 0$ (cette valeur sera renvoyée par la fonction `get_racine`)
- Le parent a la position $\lfloor (i - 1)/ 2 \rfloor$ (fonction `get_parent`) - Le parent a la position $\lfloor (i - 1)/ 2 \rfloor$ (fonction `get_parent`)
- Le fils gauche a la position $2 \times i + 1$ (fonction `get_fils_gauche`) - Le fils gauche a la position $2 \times i + 1$ (fonction `get_fils_gauche`)
- Le fils droit a la position $2 \times i + 2$ (fonction `get_fils_droit`) - Le fils droit a la position $2 \times i + 2$ (fonction `get_fils_droit`)
``` ```
3 1
/ \ / \
2 5 2 5
/ \ / / \ /
1 4 6 3 4 6
La liste correspondante : La liste correspondante :
[3, 2, 5, 1, 4, 6] [1, 2, 5, 3, 4, 6]
``` ```
%% Cell type:markdown id:ea502a0e-faa7-4bb2-9627-35cd128521a4 tags: %% Cell type:markdown id:ea502a0e-faa7-4bb2-9627-35cd128521a4 tags:
**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). **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 id:d6648668-c0e3-47d5-bd83-a49785939877 tags: %% Cell type:code id:d6648668-c0e3-47d5-bd83-a49785939877 tags:
``` python ``` python
class BinaryTree(): class BinaryTree():
# YOUR CODE HERE # YOUR CODE HERE
raise NotImplementedError() raise NotImplementedError()
``` ```
%% Cell type:markdown id:d0dd4680-92db-4dad-8647-951269330870 tags: %% Cell type:markdown id:d0dd4680-92db-4dad-8647-951269330870 tags:
**Exercice 3.2** - Assurez vous que tous les tests ci-dessous sont validés. **Exercice 3.2** - Assurez vous que tous les tests ci-dessous sont validés.
%% Cell type:code id:ac65be98-9649-4753-8ead-c0deb89f5f0c tags: %% Cell type:code id:ac65be98-9649-4753-8ead-c0deb89f5f0c tags:
``` python ``` python
# test arbre vide # test arbre vide
tree_empty = BinaryTree() tree_empty = BinaryTree()
assert tree_empty.taille() == 0 assert tree_empty.taille() == 0
assert tree_empty.get_racine() == None assert tree_empty.get_racine() == None
assert tree_empty.get_fils_gauche()[0] == None assert tree_empty.get_fils_gauche()[0] == None
assert tree_empty.get_fils_droit()[0] == None assert tree_empty.get_fils_droit()[0] == None
``` ```
%% Cell type:code id:f548b21a-b2f5-4de5-9261-38d23035e25d tags: %% Cell type:code id:f548b21a-b2f5-4de5-9261-38d23035e25d tags:
``` python ``` python
L = [3, 2, 5, 1, 4, 6] L = [1, 2, 5, 3, 4, 6]
tree_empty = BinaryTree(L) tree_values = BinaryTree(L)
assert tree_empty.taille() == len(L) # 6 assert tree_values.taille() == len(L) # 6
assert tree_empty.get_racine() == L[0] # 3 assert tree_values.get_racine() == L[0] # 3
assert tree_empty.get_fils_gauche()[0] == L[2*0+1] # 2 assert tree_values.get_fils_gauche()[0] == L[2*0+1] # 2
assert tree_empty.get_fils_droit()[0] == L[2*0+2] # 5 assert tree_values.get_fils_droit()[0] == L[2*0+2] # 5
``` ```
%% Cell type:markdown id:25213313-5058-415a-a3bc-7948c3d98588 tags: %% Cell type:markdown id:25213313-5058-415a-a3bc-7948c3d98588 tags:
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`.
%% Cell type:markdown id:5f35e9de-025f-4c89-a004-a24af997474a tags:
**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 :
1. Proposez une approche récursive
2. Le cas d'arrêt est un noeud vide
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 id:11065fbe-7209-4e87-8b9c-04d19d14fcee tags:
``` python
def check_min_tree(T, i=0):
# YOUR CODE HERE
raise NotImplementedError()
```
%% Cell type:code id:da01b2ab-4633-443f-97ea-b1022bc714ef tags:
``` python
assert check_min_tree(tree_values) == True
```
%% Cell type:markdown id:d9f0166d-d12f-42a1-989a-b7014117e73d tags: %% Cell type:markdown id:d9f0166d-d12f-42a1-989a-b7014117e73d tags:
## Exercice 4 (Bonus) : Création d'un tas et tri par tas ## Exercice 4 (Bonus) : Création d'un tas et tri par tas
Une structure de donnée de `Tas` permet de réduire la complexité de manipulation d'une file de priorité. La particularité de cette méthode est de répartir le coût de la recherche du plus petit élément (qui sera renvoyé) entre l'ajout et la suppression. 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.
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 tags: %% Cell type:markdown id:6061d866-51fb-48bc-9f1a-46b1b57a0ec0 tags:
**Question 4.1 -** Implémentez une structure de `Tas`comme suit : **Question 4.1 -** Implémentez une structure de `Tas`comme suit :
- Créez une structure de données de `Tas` similaire au `BinaryTree` - Créez une structure de données de `Tas` similaire au `BinaryTree`
- Créez une méthode `inserer` (que l'on utilisera à la place d'`ajoute`) dont le principe est le suivant : - Créez une méthode `inserer` (que l'on utilisera à la place d'`ajoute`) dont le principe est le suivant :
- Chaque nouveau noeud est rajouté comme dernier élément du tableau (à la fin donc) - Chaque nouveau noeud est rajouté comme dernier élément du tableau (à la fin donc)
- Comparez ce noeud à son parent et si il est plus grand que ce parent inversez-le - Comparez ce noeud à son parent et si il est plus grand que ce parent inversez-le
- Répétez tant que la condition ci-dessus est vraie et que la racine n'est pas atteinte - Répétez tant que la condition ci-dessus est vraie et que la racine n'est pas atteinte
- Créez une méthode `enlever` dont le principe est le suivant : - Créez une méthode `enlever` dont le principe est le suivant :
- Enlever l'élément racine de l'arbre (premier élément du tableau) - Enlever l'élément racine de l'arbre (premier élément du tableau)
- Déplacer le dernier noeud de l'arbre (dernier élément du tableau) à la place de la racine de l'arbre - Déplacer le dernier noeud de l'arbre (dernier élément du tableau) à la place de la racine de l'arbre
- 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. - 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.
- Créez une méthode `descendre` qui : - Créez une méthode `descendre` qui :
- Prend le plus petit des enfants - Prend le plus petit des enfants
- Echange sa place avec lui si il est plus petit - Echange sa place avec lui si il est plus petit
- Répéte cela tant qu'il existe des enfants - Répéte cela tant qu'il existe des enfants
Attention : pensez à tester si il existe un fils droit et un fils gauche lors des opération de descente lors de l'insertion. 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 id:301e69f3-4035-4b10-9c85-f4427d92e03b tags: %% Cell type:code id:301e69f3-4035-4b10-9c85-f4427d92e03b tags:
``` python ``` python
class Tas(): class Tas():
# YOUR CODE HERE # YOUR CODE HERE
raise NotImplementedError() raise NotImplementedError()
``` ```
%% Cell type:markdown id:0b467f58-c800-4ae3-b066-8717732a1095 tags: %% Cell type:markdown id:0b467f58-c800-4ae3-b066-8717732a1095 tags:
Votre tas doit valider les tests suivants : Votre tas doit valider les tests suivants :
%% Cell type:code id:3c41d4a7-5971-497b-b484-4a42a2480b06 tags: %% Cell type:code id:3c41d4a7-5971-497b-b484-4a42a2480b06 tags:
``` python ``` python
# test tas vide # test tas vide
tas_vide = Tas() tas_vide = Tas()
assert tas_vide.taille() == 0 assert tas_vide.taille() == 0
assert tas_vide.get_racine() == None assert tas_vide.get_racine() == None
assert tas_vide.get_fils_droit()[0] == None assert tas_vide.get_fils_droit()[0] == None
assert tas_vide.get_fils_droit()[0] == None assert tas_vide.get_fils_droit()[0] == None
# test tas simple # test tas simple
tas_simple = Tas() tas_simple = Tas()
tas_simple.inserer(1) tas_simple.inserer(1)
tas_simple.inserer(2) tas_simple.inserer(2)
assert tas_simple.taille() == 2 assert tas_simple.taille() == 2
# test tas un peu plus complexe # test tas un peu plus complexe
tas = Tas() tas = Tas()
liste = [1, 4, 10000, 2, 29, .2, 13, .5, 14, .1, 100] liste = [1, 4, 10000, 2, 29, .2, 13, .5, 14, .1, 100]
liste_triee = sorted(liste) liste_triee = sorted(liste)
for l in liste: for l in liste:
tas.inserer(l) tas.inserer(l)
assert tas.taille() == len(liste) assert tas.taille() == len(liste)
assert tas.get_racine() == liste_triee[0] assert tas.get_racine() == liste_triee[0]
assert tas.get_fils_gauche(0) == (liste_triee[1], 1) assert tas.get_fils_gauche(0) == (liste_triee[1], 1)
assert tas.get_fils_droit(0) == (liste_triee[2], 2) assert tas.get_fils_droit(0) == (liste_triee[2], 2)
while not tas.est_vide(): while not tas.est_vide():
assert tas.enlever(0) == liste_triee.pop(0) assert tas.enlever(0) == liste_triee.pop(0)
assert tas.taille() == len(liste_triee) assert tas.taille() == len(liste_triee)
``` ```
%% Cell type:markdown id:ec678229-485e-4f3b-8c24-56febe7bd69e tags: %% Cell type:markdown id:ec678229-485e-4f3b-8c24-56febe7bd69e tags:
**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. **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 id:1d483588-4153-4614-b969-854846b08f4e tags: %% Cell type:code id:1d483588-4153-4614-b969-854846b08f4e tags:
``` python ``` python
def triTas(l: list = []) -> list: def triTas(l: list = []) -> list:
t = Tas() t = Tas()
# YOUR CODE HERE # YOUR CODE HERE
raise NotImplementedError() raise NotImplementedError()
``` ```
%% Cell type:markdown id:e7ab0b07-f13c-4b95-b5fa-c38aea9b6ead tags: %% Cell type:markdown id:e7ab0b07-f13c-4b95-b5fa-c38aea9b6ead tags:
Comparez à la méthode de tri `sorted`. Comparez à la méthode de tri `sorted`.
%% Cell type:code id:4e9fd04a-910a-4d32-b0dc-0a1502599901 tags: %% Cell type:code id:4e9fd04a-910a-4d32-b0dc-0a1502599901 tags:
``` python ``` python
liste = [54,26,93,17,77,31,44,55,20] liste = [54,26,93,17,77,31,44,55,20]
l2 = triTas(liste.copy()) l2 = triTas(liste.copy())
assert(l2 == sorted(liste)) assert(l2 == sorted(liste))
assert([] == triTas([])) assert([] == triTas([]))
assert([1] == triTas([1])) assert([1] == triTas([1]))
assert([1, 1] == triTas([1, 1])) assert([1, 1] == triTas([1, 1]))
``` ```
%% Cell type:markdown id:49bae650-a23a-41f7-8896-8ac502cd71e8 tags: %% Cell type:markdown id:49bae650-a23a-41f7-8896-8ac502cd71e8 tags:
Pour information, le module `heapq` contient l'implémentation d'un tas en Python et s'utilise comme les Piles, Files, etc. 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 id:5bcc3ebf-749e-4a10-8b90-37cfd2488171 tags: %% Cell type:code id:5bcc3ebf-749e-4a10-8b90-37cfd2488171 tags:
``` python ``` python
import heapq import heapq
tas = [] tas = []
for i in range(5): heapq.heappush(tas, i) for i in range(5): heapq.heappush(tas, i)
while not len(tas) == 0: while not len(tas) == 0:
print(heapq.heappop(tas), end=" ") print(heapq.heappop(tas), end=" ")
# 0 1 2 3 4 # 0 1 2 3 4
``` ```
%% Cell type:markdown id:7f774fa4-c586-4d5c-9cf3-5f9bb899f725 tags: %% Cell type:markdown id:7f774fa4-c586-4d5c-9cf3-5f9bb899f725 tags:
**Question 4.2 -** Comparez la performance (en temps) des méthodes de tri que vous avez implémenté dans les questions précentes. **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 id:56e72b68-1d5c-4cea-8e9a-6d9f5f9ae34d tags: %% Cell type:code id:56e72b68-1d5c-4cea-8e9a-6d9f5f9ae34d tags:
``` python ``` python
import time import time
import random import random
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
nvalues = [100, 500, 1500, 2000, 2500, 3000] nvalues = [100, 500, 1500, 2000, 2500, 3000]
timesSorted = [] timesSorted = []
timesSort = [] timesSort = []
timesSelection = [] timesSelection = []
timesHeap = [] timesHeap = []
for i in nvalues: for i in nvalues:
random.seed() random.seed()
p = 12**2 p = 12**2
liste = [] liste = []
for x in range(i): liste.append(random.randint(0, p)) for x in range(i): liste.append(random.randint(0, p))
# tri sorted # tri sorted
c = liste.copy() c = liste.copy()
a=time.perf_counter() a=time.perf_counter()
triSorted = sorted(c) triSorted = sorted(c)
b=time.perf_counter() b=time.perf_counter()
timesSorted.append(b-a) timesSorted.append(b-a)
# tri .sort() # tri .sort()
c = liste.copy() c = liste.copy()
a=time.perf_counter() a=time.perf_counter()
triSort = c triSort = c
triSort.sort() triSort.sort()
b=time.perf_counter() b=time.perf_counter()
timesSort.append(b-a) timesSort.append(b-a)
# YOUR CODE HERE # YOUR CODE HERE
raise NotImplementedError() raise NotImplementedError()
plt.plot(nvalues, timesSorted, "g-", label="Tri Sorted") plt.plot(nvalues, timesSorted, "g-", label="Tri Sorted")
plt.plot(nvalues, timesSort, "b-", label="Tri .sort()") plt.plot(nvalues, timesSort, "b-", label="Tri .sort()")
plt.plot(nvalues, timesSelection, "r-", label="Tri Selection") plt.plot(nvalues, timesSelection, "r-", label="Tri Selection")
plt.plot(nvalues, timesHeap, "r-", label="Tri Heap") plt.plot(nvalues, timesHeap, "r-", label="Tri Heap")
plt.xlabel("Taille du jeu de données") plt.xlabel("Taille du jeu de données")
plt.ylabel("Temps") plt.ylabel("Temps")
plt.legend(loc="upper left") plt.legend(loc="upper left")
plt.title("Comparaison des performances des algorithmes de tri") plt.title("Comparaison des performances des algorithmes de tri")
plt.show() plt.show()
``` ```
%% Cell type:markdown id:04456b1e-92fd-4433-b230-8ea4374595a0 tags: %% Cell type:markdown id:04456b1e-92fd-4433-b230-8ea4374595a0 tags:
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é. 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 tags: %% Cell type:markdown id:3e925273-2161-4c10-8e79-dabcc9bb38cb tags:
## Pour aller plus loin ## Pour aller plus loin
- 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.) - 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.)
- 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.
......
%% Cell type:markdown id:a4c364d0 tags: %% Cell type:markdown id:c71aca63 tags:
NAME: NAME:
%% Cell type:markdown id:e1098061-ab50-4ba8-aa59-0b76ec1049a2 tags: %% Cell type:markdown id:e1098061-ab50-4ba8-aa59-0b76ec1049a2 tags:
# INF TC1 - TD3 (2h) - Arbres binaires # INF TC1 - TD3 (2h) - Arbres binaires
%% Cell type:markdown id:fc6c7558-96c4-435b-a841-e38c5d14bc9f tags: %% Cell type:markdown id:fc6c7558-96c4-435b-a841-e38c5d14bc9f tags:
--- ---
%% Cell type:markdown id:b0997389-5a87-4e8d-9600-29ed76e01759 tags: %% Cell type:markdown id:b0997389-5a87-4e8d-9600-29ed76e01759 tags:
### IMPORTANT A LIRE (SUR L'UTILISATION DE CE NOTEBOOK) <details style="border: 1px">
<summary> RAPPELS SUR L'UTILISATION DES NOTEBOOKS</summary>
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. Pour résumer : ### Comment utiliser ces notebooks ?
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 :
1) Répondez aux questions dans les cellules en dessous des questions. 1) Répondez aux questions dans les cellules en dessous des questions.
2) Votre code devra remplacer le texte suivant : 2) Votre code devra remplacer le texte suivant :
```python ```python
# YOUR CODE HERE # YOUR CODE HERE
raise NotImplementedError() raise NotImplementedError()
``` ```
(vous pouvez effacer ces deux lignes quand vous les rencontrez mais ne modifiez pas les noms de fonctions sinon les tests ne marchent plus). (vous pouvez effacer ces deux lignes quand vous les rencontrez mais ne modifiez pas les noms de fonctions sinon les tests ne marchent plus).
3) Exécuter enfin les cellules dans l'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. 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.
4) Vous pouvez créer de nouvelles cellules comme bon vous semble. 4) Vous pouvez créer de nouvelles cellules comme bon vous semble.
**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. **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.
</details>
## Chargement de fonctions
_Les fonctions ci-dessous seront nécessaire afin de mener à bien ce TD. Il faut donc les charger en exécutant leur cellulle. Ne pas les modifier._
%% Cell type:code id:818565ab-9088-4729-94f9-601ca50de254 tags: %% Cell type:code id:818565ab-9088-4729-94f9-601ca50de254 tags:
``` python ``` python
import graphviz import graphviz
from graphviz import Digraph from graphviz import Digraph
from IPython.display import display from IPython.display import display
def visualize_oop(root): def visualize_oop(root):
def build(node, dot=None): def build(node, dot=None):
if dot is None: if dot is None:
dot = graphviz.Digraph(format='png') dot = graphviz.Digraph(format='png')
if node is not None: if node is not None:
dot.node(str(node.value)) dot.node(str(node.value))
if node.left is not None: if node.left is not None:
dot.edge(str(node.value), str(node.left.value)) dot.edge(str(node.value), str(node.left.value))
build(node.left, dot) build(node.left, dot)
if node.right is not None: if node.right is not None:
dot.edge(str(node.value), str(node.right.value)) dot.edge(str(node.value), str(node.right.value))
build(node.right, dot) build(node.right, dot)
return dot return dot
return build(root) return build(root)
``` ```
%% Cell type:markdown id:de645c99-52cf-4cff-9c6b-b156101ad47c tags: %% Cell type:markdown id:de645c99-52cf-4cff-9c6b-b156101ad47c tags:
## Objectif du TD ## Objectif du TD
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é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.
%% Cell type:markdown id:abde77ea-e21d-434e-b72e-a62ac464c793 tags: %% Cell type:markdown id:abde77ea-e21d-434e-b72e-a62ac464c793 tags:
## Exercice 1 : Introduction aux arbres binaires ## Exercice 1 : Introduction aux arbres binaires
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 : 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 :
- il comporte des noeuds ayant au _maximum deux enfants_ - il comporte des noeuds ayant au _maximum deux enfants_
- il est _complet_ si tous les noeuds de tous les niveaux ont deux enfants - il est _complet_ si tous les noeuds de tous les niveaux ont deux enfants
- il est _équilibré_ si l'arbre est complet sauf pour le dernier niveau. - il est _équilibré_ si l'arbre est complet sauf pour le dernier niveau.
Voici un exemple d'arbre binaire : Voici un exemple d'arbre binaire :
``` ```
1 1
/ \ / \
2 3 2 3
``` ```
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 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 :
%% Cell type:code id:9318f291-f289-4eb6-a7f7-94cbc4e3f459 tags: %% Cell type:code id:9318f291-f289-4eb6-a7f7-94cbc4e3f459 tags:
``` python ``` python
class Node: class Node:
def __init__(self, value : int, left : Node = None, right : Node = None): def __init__(self, value : int, left = None, right = None):
self.value = value self.value = value
self.left = left self.left = left
self.right = right self.right = right
``` ```
%% Cell type:markdown id:31993aa6-7361-4a58-856d-32f3a3fcec36 tags: %% Cell type:markdown id:31993aa6-7361-4a58-856d-32f3a3fcec36 tags:
**Question 1.1** - Utilisez la structure de donnée `Node` ci-dessus afin d'implémenter l'arbre donné en introduction. Votre arbre sera stocké dans la variable `root`. Vous pouvez rajouter des noeuds supplémentaires à cet arbre (mais il doit rester binaire). **Question 1.1** - Utilisez la structure de donnée `Node` ci-dessus afin d'implémenter l'arbre donné en introduction. Votre arbre sera stocké dans la variable `root`. Vous pouvez rajouter des noeuds supplémentaires à cet arbre (mais il doit rester binaire).
%% Cell type:code id:48a9b647-260e-40a5-a3da-c11ed77a9e62 tags: %% Cell type:code id:48a9b647-260e-40a5-a3da-c11ed77a9e62 tags:
``` python ``` python
root = Node(1) # a modifier root = Node(1) # a modifier
# YOUR CODE HERE # YOUR CODE HERE
raise NotImplementedError() raise NotImplementedError()
``` ```
%% Cell type:markdown id:0a4461c4-09b8-4f9f-ad70-6b953dc4b7e6 tags: %% Cell type:markdown id:0a4461c4-09b8-4f9f-ad70-6b953dc4b7e6 tags:
Les tests suivant doivent être validés (vous pouvez rajouter d'autres tests) : Les tests suivant doivent être validés (vous pouvez rajouter d'autres tests) :
%% Cell type:code id:c08d3050-ccba-4b51-8a01-1d2689455e96 tags: %% Cell type:code id:c08d3050-ccba-4b51-8a01-1d2689455e96 tags:
``` python ``` python
assert root.value == 1 assert root.value == 1
assert root.left.value == 2 assert root.left.value == 2
assert root.right.value == 3 assert root.right.value == 3
``` ```
%% Cell type:markdown id:2fc5d004-bed5-4e6f-adf9-649d8f1543fb tags: %% Cell type:markdown id:2fc5d004-bed5-4e6f-adf9-649d8f1543fb tags:
Vous pouvez visualiser et comparer votre résultat avec la méthode `visualize_oop` comme ci-dessous: Vous pouvez visualiser et comparer votre résultat avec la méthode `visualize_oop` comme ci-dessous:
%% Cell type:code id:1edd4902-6ce9-4ffa-90c9-2d5ce45052be tags: %% Cell type:code id:1edd4902-6ce9-4ffa-90c9-2d5ce45052be tags:
``` python ``` python
visualize_oop(root) visualize_oop(root)
``` ```
%% Cell type:markdown id:24670502-ecd5-4d86-a32c-1d7d43eb04fe tags: %% Cell type:markdown id:24670502-ecd5-4d86-a32c-1d7d43eb04fe tags:
**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 à : **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 à :
1. Intialiser la file avec la racine de l'arbre 1. Intialiser la file avec la racine de l'arbre
2. Dé-filer une valeur et la stocker dans une liste de résultat 2. Dé-filer une valeur et la stocker dans une liste de résultat
3. En-filer ses enfants (si il y en a) dans la file 3. En-filer ses enfants (si il y en a) dans la file
4. Répéter l'étape 2 jusqu'à ce que la file soit vide, renvoyer le résultat 4. Répéter l'étape 2 jusqu'à ce que la file soit vide, renvoyer le résultat
%% Cell type:code id:1f92e83b-ba51-4fa4-a127-2aa970a96a26 tags: %% Cell type:code id:1f92e83b-ba51-4fa4-a127-2aa970a96a26 tags:
``` python ``` python
def bfs(node: Node): def bfs(node: Node):
# YOUR CODE HERE # YOUR CODE HERE
raise NotImplementedError() raise NotImplementedError()
``` ```
%% Cell type:code id:c1b198c7-8387-4552-a163-7a70a70c61a3 tags: %% Cell type:code id:c1b198c7-8387-4552-a163-7a70a70c61a3 tags:
``` python ``` python
assert bfs(root) == [1, 2, 3] assert bfs(root) == [1, 2, 3]
``` ```
%% Cell type:markdown id:675c8c46-ed69-4a2e-a9cf-57301112e3ab tags: %% Cell type:markdown id:675c8c46-ed69-4a2e-a9cf-57301112e3ab tags:
**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`. **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`.
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. 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.
%% Cell type:code id:6c21f3f7-0f21-47ad-a4ce-a2af7b9743d4 tags: %% Cell type:code id:6c21f3f7-0f21-47ad-a4ce-a2af7b9743d4 tags:
``` python ``` python
def depth(root: Node, target_value: int) -> int: def depth(root: Node, target_value: int) -> int:
# YOUR CODE HERE # YOUR CODE HERE
raise NotImplementedError() raise NotImplementedError()
``` ```
%% Cell type:code id:37a27a50-68f4-486b-a0da-b0905b8db8dd tags: %% Cell type:code id:37a27a50-68f4-486b-a0da-b0905b8db8dd tags:
``` python ``` python
assert depth(root, 1) == 0 assert depth(root, 1) == 0
assert depth(root, 2) == 1 assert depth(root, 2) == 1
assert depth(root, 3) == 1 assert depth(root, 3) == 1
``` ```
%% Cell type:markdown id:f8abb2f4-24dc-4346-9081-4400df30e3af tags: %% Cell type:markdown id:f8abb2f4-24dc-4346-9081-4400df30e3af tags:
**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.
%% Cell type:code id:4944b0bb-5f59-41c2-b5d9-052a0d5386dd tags: %% Cell type:code id:4944b0bb-5f59-41c2-b5d9-052a0d5386dd tags:
``` python ``` python
def height(root: Node) -> int: def height(root: Node) -> int:
# YOUR CODE HERE # YOUR CODE HERE
raise NotImplementedError() raise NotImplementedError()
``` ```
%% Cell type:code id:2d11935c-2212-4ec3-ba57-5303ec05b274 tags: %% Cell type:code id:2d11935c-2212-4ec3-ba57-5303ec05b274 tags:
``` python ``` python
assert height(root) == 2 assert height(root) == 2
``` ```
%% Cell type:markdown id:29fca7e0-aaf9-495b-822d-f20e1a672092 tags: %% Cell type:markdown id:29fca7e0-aaf9-495b-822d-f20e1a672092 tags:
**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.
%% Cell type:code id:3b4f56e8-e4bf-4d27-97eb-b24995d741fe tags: %% Cell type:code id:3b4f56e8-e4bf-4d27-97eb-b24995d741fe tags:
``` python ``` python
def est_equlibre(root: Node) -> bool: def est_equlibre(root: Node) -> bool:
# YOUR CODE HERE # YOUR CODE HERE
raise NotImplementedError() raise NotImplementedError()
``` ```
%% Cell type:code id:69b03c9b-2092-4343-b9e4-7d9904a445b0 tags: %% Cell type:code id:69b03c9b-2092-4343-b9e4-7d9904a445b0 tags:
``` python ``` python
assert est_equlibre(root) assert est_equlibre(root)
``` ```
%% Cell type:markdown id:9e29fddc-c249-4b2a-a9d3-26e56f5474ab tags: %% Cell type:markdown id:9e29fddc-c249-4b2a-a9d3-26e56f5474ab tags:
## Exercice 2 : Arbres syntaxiques ## Exercice 2 : Arbres syntaxiques
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 : 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 :
Expression : `(3-2) * (7+(10/2)` Expression : `(3-2) * (7+(10/2)`
Résultat : `12.0` Résultat : `12.0`
Nous ferons l'hypothèse que les opérations sont limitées à `+ - / *`, seront toujours binaires et porteront sur des valeurs numériques entières (mais le résultat peut ne pas être un entier). Nous ferons l'hypothèse que les opérations sont limitées à `+ - / *`, seront toujours binaires et porteront sur des valeurs numériques entières (mais le résultat peut ne pas être un entier).
``` ```
* *
/ \ / \
- + - +
/ \ / \ / \ / \
3 2 7 / 3 2 7 /
/ \ / \
10 2 10 2
``` ```
Vous utiliserez la structure d'arbre binaire ci-dessous afin de le stocker : Vous utiliserez la structure d'arbre binaire ci-dessous afin de le stocker :
%% Cell type:code id:e78ec913-cd5f-4304-8c8a-438758d909f4 tags: %% Cell type:code id:e78ec913-cd5f-4304-8c8a-438758d909f4 tags:
``` python ``` python
class Noeud: class Noeud:
def __init__(self, v = None, g = None, d = None) -> None: def __init__(self, v = None, g = None, d = None) -> None:
self.valeur = v self.valeur = v
self.gauche = g self.gauche = g
self.droit = d self.droit = d
``` ```
%% Cell type:markdown id:88fbc62f-ae5a-4765-bf8f-bb127f5d5a13 tags: %% Cell type:markdown id:88fbc62f-ae5a-4765-bf8f-bb127f5d5a13 tags:
**Question 2.1** - Utilisez la structure de données d'arbre ci-dessus afin de stocker l'arbre syntaxique donné en exemple. **Question 2.1** - Utilisez la structure de données d'arbre ci-dessus afin de stocker l'arbre syntaxique donné en exemple.
%% Cell type:code id:4661ca46-489c-4330-9e72-64fe25e4b49c tags: %% Cell type:code id:4661ca46-489c-4330-9e72-64fe25e4b49c tags:
``` python ``` python
arbre = None # à changer arbre = None # à changer
# YOUR CODE HERE # YOUR CODE HERE
raise NotImplementedError() raise NotImplementedError()
``` ```
%% Cell type:code id:cee8c8d3-f4ab-4dcc-931e-f0b8681b225c tags: %% Cell type:code id:cee8c8d3-f4ab-4dcc-931e-f0b8681b225c tags:
``` python ``` python
assert arbre.valeur == "*" assert arbre.valeur == "*"
assert arbre.gauche.valeur == "-" assert arbre.gauche.valeur == "-"
assert arbre.droit.valeur == "+" assert arbre.droit.valeur == "+"
``` ```
%% Cell type:markdown id:0be8aab9-1aba-4340-9235-eb3d1cc7fd29 tags: %% Cell type:markdown id:0be8aab9-1aba-4340-9235-eb3d1cc7fd29 tags:
**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. **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.
Conseil : proposer une solution récursive avec un cas d'arrêt et des appels récursifs comme suit : Conseil : proposer une solution récursive avec un cas d'arrêt et des appels récursifs comme suit :
- Si la valeur du noeud en cours est un opérateur, l'appliquer sur les deux sous-branches - Si la valeur du noeud en cours est un opérateur, l'appliquer sur les deux sous-branches
- Si c'est une valeur numérique, renvoyer cette valeur (cas d'arrêt car c'est une feuille de l'arbre) - Si c'est une valeur numérique, renvoyer cette valeur (cas d'arrêt car c'est une feuille de l'arbre)
%% Cell type:code id:dc899d17-67fd-4cc9-bf92-f5f32e08f89e tags: %% Cell type:code id:dc899d17-67fd-4cc9-bf92-f5f32e08f89e tags:
``` python ``` python
def eval(r: Noeud) -> float: def eval(r: Noeud) -> float:
# YOUR CODE HERE # YOUR CODE HERE
raise NotImplementedError() raise NotImplementedError()
``` ```
%% Cell type:code id:00eb3e33-64b1-486f-97c8-d87de80f3a1a tags: %% Cell type:code id:00eb3e33-64b1-486f-97c8-d87de80f3a1a tags:
``` python ``` python
eval(arbre) eval(arbre)
``` ```
%% Cell type:markdown id:de5c394d-df35-4d7b-b057-164620b0b38d tags: %% Cell type:markdown id:de5c394d-df35-4d7b-b057-164620b0b38d tags:
**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(" ")}`. **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(" ")}`.
Conseil : Conseil :
- Parcourez caractère par caractère l'expression textuelle - Parcourez caractère par caractère l'expression textuelle
- Et utilisez une Pile permettant la bonne construction de l'arbre au fur et à mesure de son parcours - Et utilisez une Pile permettant la bonne construction de l'arbre au fur et à mesure de son parcours
%% Cell type:code id:1c33faaa-2289-498f-9ef1-5afeb4da4628 tags: %% Cell type:code id:1c33faaa-2289-498f-9ef1-5afeb4da4628 tags:
``` python ``` python
def construit_arbre(exp: str) -> int: def construit_arbre(exp: str) -> int:
# YOUR CODE HERE # YOUR CODE HERE
raise NotImplementedError() raise NotImplementedError()
``` ```
%% Cell type:code id:b56d0304-5d23-4e1c-91fb-09b511465ad5 tags: %% Cell type:code id:b56d0304-5d23-4e1c-91fb-09b511465ad5 tags:
``` python ``` python
r = construit_arbre("( ( 3 - 2 ) * ( 7 + ( 10 / 2 ) )") r = construit_arbre("( ( 3 - 2 ) * ( 7 + ( 10 / 2 ) )")
``` ```
%% Cell type:markdown id:89a9015c-dd4e-409d-91b2-9b64b55288e9 tags: %% Cell type:markdown id:89a9015c-dd4e-409d-91b2-9b64b55288e9 tags:
Enfin vérifiez que vous obtenez la bonne valeur en évaluant l'expression. Enfin vérifiez que vous obtenez la bonne valeur en évaluant l'expression.
%% Cell type:code id:e5c49c1f-75e0-4872-8578-40a532c7cea1 tags: %% Cell type:code id:e5c49c1f-75e0-4872-8578-40a532c7cea1 tags:
``` python ``` python
assert eval(r) == 12.0 assert eval(r) == 12.0
``` ```
%% Cell type:markdown id:012a5378-a2b7-498f-8115-e35f55c529ce tags: %% Cell type:markdown id:012a5378-a2b7-498f-8115-e35f55c529ce tags:
**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. **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.
Proposez une méthode itérative : Proposez une méthode itérative :
%% Cell type:code id:823d29e7-66c3-41a0-bdad-da6862a5e420 tags: %% Cell type:code id:823d29e7-66c3-41a0-bdad-da6862a5e420 tags:
``` python ``` python
def valide_ite(r: Noeud) -> bool: def valide_ite(r: Noeud) -> bool:
# YOUR CODE HERE # YOUR CODE HERE
raise NotImplementedError() raise NotImplementedError()
``` ```
%% Cell type:code id:06e73b57-959a-436f-bd7a-e12c615c805c tags: %% Cell type:code id:06e73b57-959a-436f-bd7a-e12c615c805c tags:
``` python ``` python
assert valide_ite(arbre) assert valide_ite(arbre)
``` ```
%% Cell type:markdown id:dfdf1d42-60bb-4a7e-9cd4-e6cb72b8130a tags: %% Cell type:markdown id:dfdf1d42-60bb-4a7e-9cd4-e6cb72b8130a tags:
Proposez une méthode récursive : Proposez une méthode récursive :
%% Cell type:code id:df0033e9-c076-4cde-ab6f-982a3677ce05 tags: %% Cell type:code id:df0033e9-c076-4cde-ab6f-982a3677ce05 tags:
``` python ``` python
def valide_rec(r: Noeud) -> bool: def valide_rec(r: Noeud) -> bool:
# YOUR CODE HERE # YOUR CODE HERE
raise NotImplementedError() raise NotImplementedError()
``` ```
%% Cell type:code id:9998c852-ec74-4225-9f01-4368899e303f tags: %% Cell type:code id:9998c852-ec74-4225-9f01-4368899e303f tags:
``` python ``` python
assert valide_rec(arbre) assert valide_rec(arbre)
``` ```
%% Cell type:markdown id:85c6a3e6-dea0-4e86-b7d9-b0c5735c3630 tags: %% Cell type:markdown id:85c6a3e6-dea0-4e86-b7d9-b0c5735c3630 tags:
## Pour aller plus loin ## Pour aller plus loin
- Rajouter des tests dans les exemples ci-dessus avec des arbres plus complexes - Rajouter des tests dans les exemples ci-dessus avec des arbres plus complexes, des cas particuliers, etc.
- Inclure des Exceptions dans votre code - Inclure des Exceptions dans votre code afin de gérer par exemple l'accès à un index de liste inexistant, etc.
- 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
%% Cell type:code id:9cbffdb0-7d54-4054-b13d-fd1dc1afd0f2 tags:
``` python
```
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment