Structures linéaires : nouveau chapitre avec listes chaînées + déplacement Pile_File
This commit is contained in:
BIN
Structures_lineaires/Pile_File/Images/File.png
Normal file
BIN
Structures_lineaires/Pile_File/Images/File.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.6 KiB |
BIN
Structures_lineaires/Pile_File/Images/File_td.png
Normal file
BIN
Structures_lineaires/Pile_File/Images/File_td.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.5 KiB |
BIN
Structures_lineaires/Pile_File/Images/Pile.odg
Normal file
BIN
Structures_lineaires/Pile_File/Images/Pile.odg
Normal file
Binary file not shown.
BIN
Structures_lineaires/Pile_File/Images/Pile.png
Normal file
BIN
Structures_lineaires/Pile_File/Images/Pile.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.6 KiB |
BIN
Structures_lineaires/Pile_File/Images/Pile_td.png
Normal file
BIN
Structures_lineaires/Pile_File/Images/Pile_td.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
BIN
Structures_lineaires/Pile_File/Images/bo_1.png
Normal file
BIN
Structures_lineaires/Pile_File/Images/bo_1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 240 KiB |
BIN
Structures_lineaires/Pile_File/Images/bo_2.png
Normal file
BIN
Structures_lineaires/Pile_File/Images/bo_2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 212 KiB |
102
Structures_lineaires/Pile_File/README.md
Normal file
102
Structures_lineaires/Pile_File/README.md
Normal file
@@ -0,0 +1,102 @@
|
||||
# Structure de données : Pile et File
|
||||
|
||||
> Structures essentielles pour résoudre des problèmes où l'ordre de traitement des données est crucial, comme la gestion des processus ou la navigation dans des graphes, les piles et files permettent de stocker et manipuler des données selon des règles spécifiques. La pile suit un principe **LIFO** (Last In, First Out), tandis que la file suit un principe **FIFO** (First In, First Out).
|
||||
|
||||
## Le programme
|
||||
|
||||
<img src="Images/bo_1.png" alt="BO_Pile & File" style="zoom:67%;" />
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<img src="Images/bo_2.png" alt="BO_Pile&File_2" style="zoom:67%;" />
|
||||
|
||||
|
||||
|
||||
|
||||
## 1. Rappel :
|
||||
|
||||
<u>**Structure de données**</u> : Collection d'information dans laquelle il est possible de stocker, traiter, organiser, extraire des données.
|
||||
|
||||
Les structures de données connues à ce jour sont : Les tableaux, les dictionnaires, les chaînes de caractères, les n-uplets. Chacune de ces structures possèdent des caractéristiques propres qui créent des avantages et des inconvénients selon la situation.
|
||||
|
||||
De plus, ces types sont natifs à Python, et aux autres langages selon les cas. Nous n'avons donc ici aucune idée de comment le type *dict* ou *tuple* est créé par exemple.
|
||||
|
||||
Les structures de données Pile et File ne sont pas natives à Python et nous aurons donc besoin de les implémenter.
|
||||
|
||||
## 2. Interface et implémentation :
|
||||
|
||||
Ces deux termes sont particuliers et très importants pour ce chapitre. Alors un petit rappel n'est pas de trop.
|
||||
|
||||
<u>**Interface :**</u> L'interface d'un type est définie par les méthodes qui lui sont associées.
|
||||
|
||||
**<u>Implémentation :</u>** L'implémentation d'un type est la manière dont on va le coder.
|
||||
|
||||
Il faut bien faire la distinction entre les deux termes.
|
||||
|
||||
## 3. Pile
|
||||
|
||||
### 3. 1. Définition
|
||||
|
||||
Une pile est une structure de données dans laquelle les derniers éléments entrant dans la structure seront les premiers à en sortir, nous appelons ce principe **LIFO (Last In First Out)**. Afin d'imager cette structure nous pouvons penser à une pile d'assiettes par exemple.
|
||||
|
||||

|
||||
|
||||
Ici seul le premier élément est accessible.
|
||||
|
||||
### 3. 2. Interface
|
||||
|
||||
Méthodes associées à la pile :
|
||||
|
||||
- Empile : Méthode permettant d'empiler un élément.
|
||||
- L'élément sera positionné au haut de la pile
|
||||
- Depile : Méthode permettant d'enlever un élément.
|
||||
- L'élément enlevé sera celui en haut de la pile.
|
||||
|
||||
- Est_vide : Permet de savoir si la pile est vide ou non
|
||||
|
||||
On peut ajouter d'autres méthodes :
|
||||
|
||||
- Taille : Permet de savoir le nombre d'éléments de la pile
|
||||
- Top : Permet de connaître l'élément au-dessus de la pile.
|
||||
|
||||
## 4. File
|
||||
|
||||
### 4. 1. Définition
|
||||
|
||||
Une file est une structure de données dans laquelle les premiers éléments entrant dans la structure seront les premiers à en sortir, nous appelons ce principe **FIFO (First In First Out)**. Afin d'imager cette structure nous pouvons penser à une file de voitures sur une route par exemple.
|
||||
|
||||

|
||||
|
||||
Ici seul le premier élément peut sortir de la structure.
|
||||
|
||||
### 4. 2. Interface
|
||||
|
||||
Méthodes associées à la file :
|
||||
|
||||
- Enfile : Méthode permettant d'enfiler un élément.
|
||||
- L'élément sera positionné en queue de la file
|
||||
- Defile : Méthode permettant d'enlever un élément.
|
||||
- L'élément enlevé sera celui en tête de la file.
|
||||
|
||||
- Est_vide : Permet de savoir si la file est vide ou non
|
||||
|
||||
On peut ajouter d'autres méthodes :
|
||||
|
||||
- Taille : Permet de savoir le nombre d'éléments de la file
|
||||
- Top : Permet de connaître l'élément en tête de la file.
|
||||
|
||||
## 5. Conclusion
|
||||
|
||||
Les deux structures ont une interface très semblable. Seul le principe FIFO / LIFO peut les différencier.
|
||||
|
||||
La suite du chapitre se concentrera sur l'utilisation de ces structures et leurs implémentations.
|
||||
|
||||
---------
|
||||
|
||||
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
|
||||
|
||||
Licence CC BY NC
|
||||
|
||||
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a> <br />Ce cours est mis à disposition selon les termes de la <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International</a>.
|
||||
181
Structures_lineaires/Pile_File/TD/Corrige_TD_Pile_File.md
Normal file
181
Structures_lineaires/Pile_File/TD/Corrige_TD_Pile_File.md
Normal file
@@ -0,0 +1,181 @@
|
||||
# Corrigé du TD Pile et File
|
||||
|
||||
---
|
||||
|
||||
## 1. Application de cours
|
||||
|
||||
### 1. 1. Pile
|
||||
|
||||
**État initial de la pile :**
|
||||
```
|
||||
5 ← sommet
|
||||
4
|
||||
3
|
||||
2
|
||||
1 ← fond
|
||||
```
|
||||
|
||||
**Question 1** : État après `Depile(), Depile(), Empile(7), Empile(8), Depile()`
|
||||
|
||||
Exécution pas à pas :
|
||||
|
||||
| Opération | État de la pile | Élément retourné |
|
||||
|-----------|-----------------|------------------|
|
||||
| Initial | [1, 2, 3, 4, 5] | - |
|
||||
| Depile() | [1, 2, 3, 4] | 5 |
|
||||
| Depile() | [1, 2, 3] | 4 |
|
||||
| Empile(7) | [1, 2, 3, 7] | - |
|
||||
| Empile(8) | [1, 2, 3, 7, 8] | - |
|
||||
| Depile() | [1, 2, 3, 7] | 8 |
|
||||
|
||||
**État final :**
|
||||
```
|
||||
7 ← sommet
|
||||
3
|
||||
2
|
||||
1 ← fond
|
||||
```
|
||||
|
||||
**`top()` renvoie : 7**
|
||||
|
||||
---
|
||||
|
||||
**Question 2** : Pour que `Est_vide()` soit vrai, il faut dépiler tous les éléments.
|
||||
|
||||
```
|
||||
Depile() → renvoie 5
|
||||
Depile() → renvoie 4
|
||||
Depile() → renvoie 3
|
||||
Depile() → renvoie 2
|
||||
Depile() → renvoie 1
|
||||
Est_vide() → True
|
||||
```
|
||||
|
||||
**Réponse : 5 appels à Depile()**
|
||||
|
||||
---
|
||||
|
||||
**Question 3** : Créer une pile contenant 19982018 (1 en bas de pile)
|
||||
|
||||
La pile doit ressembler à :
|
||||
```
|
||||
8 ← sommet
|
||||
1
|
||||
0
|
||||
2
|
||||
8
|
||||
9
|
||||
9
|
||||
1 ← fond
|
||||
```
|
||||
|
||||
**Séquence de méthodes :**
|
||||
```
|
||||
Empile(1)
|
||||
Empile(9)
|
||||
Empile(9)
|
||||
Empile(8)
|
||||
Empile(2)
|
||||
Empile(0)
|
||||
Empile(1)
|
||||
Empile(8)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 1. 2. File
|
||||
|
||||
**État initial de la file :**
|
||||
```
|
||||
Entrée → 5 | 4 | 3 | 2 | 1 → Sortie
|
||||
↑ ↑
|
||||
queue tête
|
||||
```
|
||||
|
||||
**Question 1** : État après `Defile(), Defile(), Enfile(7), Enfile(8), Defile()`
|
||||
|
||||
Exécution pas à pas :
|
||||
|
||||
| Opération | État de la file | Élément retourné |
|
||||
|-----------|-----------------|------------------|
|
||||
| Initial | [5, 4, 3, 2, 1] | - |
|
||||
| Defile() | [5, 4, 3, 2] | 1 |
|
||||
| Defile() | [5, 4, 3] | 2 |
|
||||
| Enfile(7) | [7, 5, 4, 3] | - |
|
||||
| Enfile(8) | [8, 7, 5, 4, 3] | - |
|
||||
| Defile() | [8, 7, 5, 4] | 3 |
|
||||
|
||||
**État final :**
|
||||
```
|
||||
Entrée → 8 | 7 | 5 | 4 → Sortie
|
||||
```
|
||||
|
||||
**`top()` renvoie : 4** (élément en tête, prêt à sortir)
|
||||
|
||||
---
|
||||
|
||||
**Question 2** : Pour que `Est_vide()` soit vrai, il faut défiler tous les éléments.
|
||||
|
||||
```
|
||||
Defile() → renvoie 1
|
||||
Defile() → renvoie 2
|
||||
Defile() → renvoie 3
|
||||
Defile() → renvoie 4
|
||||
Defile() → renvoie 5
|
||||
Est_vide() → True
|
||||
```
|
||||
|
||||
**Réponse : 5 appels à Defile()**
|
||||
|
||||
---
|
||||
|
||||
**Question 3** : Créer une file contenant 19982018 (1 en tête de file)
|
||||
|
||||
La file doit ressembler à :
|
||||
```
|
||||
Entrée → 8 | 1 | 0 | 2 | 8 | 9 | 9 | 1 → Sortie
|
||||
↑
|
||||
tête
|
||||
```
|
||||
|
||||
Pour que 1 soit en tête (premier à sortir), il faut l'enfiler en premier :
|
||||
|
||||
**Séquence de méthodes :**
|
||||
```
|
||||
Enfile(1)
|
||||
Enfile(9)
|
||||
Enfile(9)
|
||||
Enfile(8)
|
||||
Enfile(2)
|
||||
Enfile(0)
|
||||
Enfile(1)
|
||||
Enfile(8)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tableau récapitulatif
|
||||
|
||||
| Structure | Principe | Ajout | Retrait | Accès |
|
||||
|-----------|----------|-------|---------|-------|
|
||||
| **Pile** | LIFO (Last In First Out) | Empile (sommet) | Depile (sommet) | Top (sommet) |
|
||||
| **File** | FIFO (First In First Out) | Enfile (queue) | Defile (tête) | Top (tête) |
|
||||
|
||||
---
|
||||
|
||||
## Analogies pour mémoriser
|
||||
|
||||
| Structure | Analogie | Explication |
|
||||
|-----------|----------|-------------|
|
||||
| **Pile** | Pile d'assiettes | On pose et on prend toujours par le dessus |
|
||||
| **File** | File d'attente | Le premier arrivé est le premier servi |
|
||||
| **Pile** | Historique du navigateur | Le bouton "retour" revient à la page précédente (la dernière visitée) |
|
||||
| **File** | Imprimante | Les documents sont imprimés dans l'ordre d'envoi |
|
||||
|
||||
---
|
||||
|
||||
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
|
||||
|
||||
Licence CC BY NC
|
||||
|
||||
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a> <br />Ce cours est mis à disposition selon les termes de la <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International</a>.
|
||||
39
Structures_lineaires/Pile_File/TD/TD_Pile_File.md
Normal file
39
Structures_lineaires/Pile_File/TD/TD_Pile_File.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# TD Pile et File
|
||||
|
||||
------
|
||||
|
||||
Le but du TD est de manipuler des piles et des files sans avoir d'implémentation.
|
||||
|
||||
## 1 Application de cours
|
||||
|
||||
### 1. 1. Pile
|
||||
|
||||
<u>Voici une pile :</u>
|
||||
|
||||

|
||||
|
||||
1. Quel sera l'état de la pile après l'utilisation des méthodes suivantes :
|
||||
- Depile(), Depile(), Empile(7), Empile(8),Depile()
|
||||
- Que renvoie la méthode top() ?
|
||||
2. Reprenons la pile de l'image, que faut-il faire comme méthode pour que Est_vide() soit vrai ?
|
||||
3. En partant de 0, écrire les méthodes permettant de créer une pile contenant les numéros dans cet ordre : 19982018. (1 est en bas de pile)
|
||||
|
||||
### 1. 2. File
|
||||
|
||||
<u>Voici une file :</u>
|
||||
|
||||

|
||||
|
||||
1. Quel sera l'état de la file après l'utilisation des méthodes suivantes :
|
||||
- Defile(), Defile(), Enfile(7), Enfile(8),Defile()
|
||||
- Que renvoie la méthode top() ?
|
||||
2. Reprenons la file de l'image, que faut-il faire comme méthode pour que Est_vide() soit vrai ?
|
||||
3. En partant de 0, écrire les méthodes permettant de créer une file contenant les numéros dans cet ordre : 19982018. (1 est en tête de file)
|
||||
|
||||
---
|
||||
|
||||
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
|
||||
|
||||
Licence CC BY NC
|
||||
|
||||
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a> <br />Ce cours est mis à disposition selon les termes de la <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International</a>.
|
||||
155
Structures_lineaires/Pile_File/TP/Bataille_correction.py
Normal file
155
Structures_lineaires/Pile_File/TP/Bataille_correction.py
Normal file
@@ -0,0 +1,155 @@
|
||||
from File import *
|
||||
import random
|
||||
|
||||
VAL_CARTE = ['1','2','3','4','5','6','7','8','9','10','V','D','R','AS']
|
||||
COL_CARTE = ['P','T','C','H']
|
||||
|
||||
|
||||
def in_file(x,f):
|
||||
"""
|
||||
Fonction qui revoie True si x est dans la file f
|
||||
param x (): element present ou non dans f
|
||||
param f (File1/File2) : File contenant ou non x
|
||||
return (bool) : Renvoie True si x est dans f, False sinon
|
||||
"""
|
||||
if type(f) == File1 :
|
||||
if x in f.file :
|
||||
return True
|
||||
else :
|
||||
return False
|
||||
elif type(f) == File2 :
|
||||
if f.tete == x :
|
||||
return True
|
||||
elif f.queue != None :
|
||||
return in_file(x,f.queue)
|
||||
else :
|
||||
return False
|
||||
else :
|
||||
return False
|
||||
|
||||
def comp(c1,c2) :
|
||||
"""
|
||||
Fonction de comparaison entre deux cartes
|
||||
param c1 : (tuple) Carte 1
|
||||
param c2 : (tuple) Carte 2
|
||||
return : Renvoie
|
||||
-1 si => c1 < c2
|
||||
1 si => c1 > <2
|
||||
0 si => c1 == c2
|
||||
|
||||
"""
|
||||
if VAL_CARTE.index(c1[0]) < VAL_CARTE.index(c2[0]) :
|
||||
return -1
|
||||
elif VAL_CARTE.index(c1[0]) > VAL_CARTE.index(c2[0]) :
|
||||
return 1
|
||||
else :
|
||||
return 0
|
||||
|
||||
def creer_jeu():
|
||||
"""
|
||||
Fonction qui crée un jeu aléatoire
|
||||
return a,b (File) Deux files contenant 26 cartes chacunes
|
||||
"""
|
||||
i = 0
|
||||
val_carte = ['1','2','3','4','5','6','7','8','9','10','V','D','R','AS']
|
||||
col_carte = ['P','T','C','H']
|
||||
f1 = File1()
|
||||
f2 = File1()
|
||||
while i < 52 :
|
||||
val = random.randint(0,len(val_carte)-1)
|
||||
col = random.randint(0,len(col_carte)-1)
|
||||
carte = (val_carte[val],col_carte[col])
|
||||
if in_file(carte,f1) == False or in_file(carte,f2) == False :
|
||||
if i%2 == 0 :
|
||||
f1.enfile(carte)
|
||||
else :
|
||||
f2.enfile(carte)
|
||||
i+=1
|
||||
return f1,f2
|
||||
|
||||
def tour(f1,f2) :
|
||||
"""
|
||||
Foncton qui simule un tour de bataille
|
||||
param f1: (File) File contenant le jeu n°1
|
||||
param f2: (File) File contenant le jeu n°2
|
||||
"""
|
||||
i = f1.defile()
|
||||
j = f2.defile()
|
||||
res = comp(i,j)
|
||||
if res == -1 :
|
||||
f2.enfile(i)
|
||||
f2.enfile(j)
|
||||
print('f2')
|
||||
elif res == 1 :
|
||||
f1.enfile(i)
|
||||
f1.enfile(j)
|
||||
print('f1')
|
||||
else :
|
||||
print('bataille')
|
||||
if f1.taille()>=3 and f2.taille()>=3 :
|
||||
bataille(i,j,f1,f2)
|
||||
else :
|
||||
# Si un des deux paquet ne peut pas faire la bataille alors on le vide pour faire gagner l'autre joueur
|
||||
if f1.taille() < 3 :
|
||||
while not f1.est_vide() :
|
||||
f1.defile()
|
||||
else :
|
||||
while not f2.est_vide() :
|
||||
f2.defile()
|
||||
|
||||
def bataille(c1,c2,f1,f2) :
|
||||
"""
|
||||
Fonction simulant un tour de bataille
|
||||
param c1 : (tuple) Carte n°1 égale a c2
|
||||
param c2 : (tuple) Carte n°1 égale a c1
|
||||
param f1: (File) File contenant le jeu n°1
|
||||
param f2: (File) File contenant le jeu n°2
|
||||
"""
|
||||
bataille_tab= []
|
||||
while comp(c1,c2) == 0:
|
||||
bataille_tab.append(c1)
|
||||
bataille_tab.append(c2)
|
||||
bataille_tab.append(f1.defile())
|
||||
bataille_tab.append(f2.defile())
|
||||
c1 = f1.defile()
|
||||
c2 = f2.defile()
|
||||
if comp(c1,c2) == 1 :
|
||||
for carte in bataille_tab :
|
||||
f1.enfile(carte)
|
||||
f1.enfile(c1)
|
||||
f1.enfile(c2)
|
||||
if comp(c1,c2) == -1 :
|
||||
for carte in bataille_tab :
|
||||
f2.enfile(carte)
|
||||
f2.enfile(c1)
|
||||
f2.enfile(c2)
|
||||
|
||||
|
||||
|
||||
def est_fini(f1,f2):
|
||||
"""
|
||||
Fonction qui détermine si le jeu est fini
|
||||
param f1: (File) File contenant le jeu n°1
|
||||
param f2: (File) File contenant le jeu n°2
|
||||
return (bool): renvoie True si le jeu est fini, False sinon.
|
||||
"""
|
||||
if f1.taille() == 0 :
|
||||
print("JOUEUR 2 A GAGNE")
|
||||
return True
|
||||
elif f2.taille() ==0:
|
||||
print("JOUEUR 1 A GAGNE")
|
||||
return True
|
||||
else :
|
||||
return False
|
||||
|
||||
def game(f1,f2):
|
||||
"""
|
||||
Fonction simulant le jeu de la bataille
|
||||
param f1: (File) File contenant le jeu n°1
|
||||
param f2: (File) File contenant le jeu n°2
|
||||
"""
|
||||
while not est_fini(f1,f2) :
|
||||
tour(f1,f2)
|
||||
|
||||
|
||||
a,b = creer_jeu()
|
||||
494
Structures_lineaires/Pile_File/TP/Corrige_TP_Navigateur.py
Normal file
494
Structures_lineaires/Pile_File/TP/Corrige_TP_Navigateur.py
Normal file
@@ -0,0 +1,494 @@
|
||||
"""
|
||||
Corrigé du TP Navigateur — Piles et Files en action
|
||||
"""
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# PARTIE 1 : Implémentation des structures
|
||||
# =============================================================================
|
||||
|
||||
class Pile:
|
||||
"""Structure de données LIFO (Last In First Out)."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialise une pile vide."""
|
||||
self.elements = []
|
||||
|
||||
def empile(self, element):
|
||||
"""Ajoute un élément au sommet de la pile."""
|
||||
self.elements.append(element)
|
||||
|
||||
def depile(self):
|
||||
"""
|
||||
Retire et renvoie l'élément au sommet.
|
||||
Renvoie None si la pile est vide.
|
||||
"""
|
||||
if self.est_vide():
|
||||
return None
|
||||
return self.elements.pop()
|
||||
|
||||
def est_vide(self):
|
||||
"""Renvoie True si la pile est vide."""
|
||||
return len(self.elements) == 0
|
||||
|
||||
def sommet(self):
|
||||
"""
|
||||
Renvoie l'élément au sommet sans le retirer.
|
||||
Renvoie None si la pile est vide.
|
||||
"""
|
||||
if self.est_vide():
|
||||
return None
|
||||
return self.elements[-1]
|
||||
|
||||
def taille(self):
|
||||
"""Renvoie le nombre d'éléments dans la pile."""
|
||||
return len(self.elements)
|
||||
|
||||
def __repr__(self):
|
||||
"""Affichage de la pile."""
|
||||
if self.est_vide():
|
||||
return "Pile vide"
|
||||
result = "Sommet\n"
|
||||
for i in range(len(self.elements) - 1, -1, -1):
|
||||
result += f" | {self.elements[i]} |\n"
|
||||
result += "Fond"
|
||||
return result
|
||||
|
||||
|
||||
class File:
|
||||
"""Structure de données FIFO (First In First Out)."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialise une file vide."""
|
||||
self.elements = []
|
||||
|
||||
def enfile(self, element):
|
||||
"""Ajoute un élément en queue de file."""
|
||||
self.elements.append(element)
|
||||
|
||||
def defile(self):
|
||||
"""
|
||||
Retire et renvoie l'élément en tête de file.
|
||||
Renvoie None si la file est vide.
|
||||
"""
|
||||
if self.est_vide():
|
||||
return None
|
||||
return self.elements.pop(0)
|
||||
|
||||
def est_vide(self):
|
||||
"""Renvoie True si la file est vide."""
|
||||
return len(self.elements) == 0
|
||||
|
||||
def tete(self):
|
||||
"""
|
||||
Renvoie l'élément en tête sans le retirer.
|
||||
Renvoie None si la file est vide.
|
||||
"""
|
||||
if self.est_vide():
|
||||
return None
|
||||
return self.elements[0]
|
||||
|
||||
def taille(self):
|
||||
"""Renvoie le nombre d'éléments dans la file."""
|
||||
return len(self.elements)
|
||||
|
||||
def __repr__(self):
|
||||
"""Affichage de la file."""
|
||||
if self.est_vide():
|
||||
return "File vide"
|
||||
result = "Tête → "
|
||||
result += " → ".join(str(e) for e in self.elements)
|
||||
result += " → Queue"
|
||||
return result
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# PARTIE 2 : Simulateur de navigateur web
|
||||
# =============================================================================
|
||||
|
||||
class Navigateur:
|
||||
"""Simulateur de navigateur web avec historique."""
|
||||
|
||||
def __init__(self, page_accueil="https://www.google.com"):
|
||||
"""
|
||||
Initialise le navigateur avec une page d'accueil.
|
||||
|
||||
:param page_accueil: (str) URL de la page d'accueil
|
||||
"""
|
||||
self.historique = Pile()
|
||||
self.suivant = Pile()
|
||||
self.historique.empile(page_accueil)
|
||||
|
||||
def page_actuelle(self):
|
||||
"""
|
||||
Renvoie l'URL de la page actuellement affichée.
|
||||
|
||||
:return: (str) URL de la page actuelle ou None
|
||||
"""
|
||||
return self.historique.sommet()
|
||||
|
||||
def visiter(self, url):
|
||||
"""
|
||||
Visite une nouvelle page.
|
||||
- Empile l'URL dans l'historique
|
||||
- Vide la pile 'suivant' (on ne peut plus avancer)
|
||||
|
||||
:param url: (str) URL de la page à visiter
|
||||
"""
|
||||
self.historique.empile(url)
|
||||
# Vider la pile suivant
|
||||
while not self.suivant.est_vide():
|
||||
self.suivant.depile()
|
||||
|
||||
def retour(self):
|
||||
"""
|
||||
Revient à la page précédente (bouton ←).
|
||||
- Dépile l'historique
|
||||
- Empile la page actuelle dans 'suivant'
|
||||
|
||||
:return: (str) URL de la nouvelle page actuelle ou None si impossible
|
||||
"""
|
||||
if not self.peut_reculer():
|
||||
return None
|
||||
|
||||
page_actuelle = self.historique.depile()
|
||||
self.suivant.empile(page_actuelle)
|
||||
return self.page_actuelle()
|
||||
|
||||
def avancer(self):
|
||||
"""
|
||||
Avance à la page suivante (bouton →).
|
||||
- Dépile 'suivant'
|
||||
- Empile dans l'historique
|
||||
|
||||
:return: (str) URL de la nouvelle page actuelle ou None si impossible
|
||||
"""
|
||||
if not self.peut_avancer():
|
||||
return None
|
||||
|
||||
page_suivante = self.suivant.depile()
|
||||
self.historique.empile(page_suivante)
|
||||
return self.page_actuelle()
|
||||
|
||||
def peut_reculer(self):
|
||||
"""Renvoie True si le bouton Retour est actif."""
|
||||
return self.historique.taille() > 1
|
||||
|
||||
def peut_avancer(self):
|
||||
"""Renvoie True si le bouton Suivant est actif."""
|
||||
return not self.suivant.est_vide()
|
||||
|
||||
def afficher_etat(self):
|
||||
"""Affiche l'état actuel du navigateur."""
|
||||
retour = "←" if self.peut_reculer() else "✗"
|
||||
avancer = "→" if self.peut_avancer() else "✗"
|
||||
print(f"[{retour}] [{avancer}] | {self.page_actuelle()}")
|
||||
|
||||
def afficher_historique(self):
|
||||
"""
|
||||
Affiche l'historique complet de navigation.
|
||||
La page actuelle est marquée d'une flèche.
|
||||
"""
|
||||
print("Historique de navigation :")
|
||||
# Copier la pile pour l'afficher sans la modifier
|
||||
temp = Pile()
|
||||
pages = []
|
||||
|
||||
while not self.historique.est_vide():
|
||||
page = self.historique.depile()
|
||||
pages.append(page)
|
||||
temp.empile(page)
|
||||
|
||||
# Restaurer la pile
|
||||
while not temp.est_vide():
|
||||
self.historique.empile(temp.depile())
|
||||
|
||||
# Afficher (inverser pour avoir l'ordre chronologique)
|
||||
pages.reverse()
|
||||
for i, page in enumerate(pages, 1):
|
||||
if i == len(pages):
|
||||
print(f"→ {i}. {page} (page actuelle)")
|
||||
else:
|
||||
print(f" {i}. {page}")
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# PARTIE 3 : File d'attente Netflix
|
||||
# =============================================================================
|
||||
|
||||
class ListeVisionnage:
|
||||
"""Gestionnaire de file d'attente de visionnage."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialise une liste de visionnage vide."""
|
||||
self.file_attente = File()
|
||||
self.historique = Pile()
|
||||
|
||||
def ajouter(self, titre):
|
||||
"""
|
||||
Ajoute un film/série à la file d'attente.
|
||||
|
||||
:param titre: (str) Titre du contenu à ajouter
|
||||
"""
|
||||
self.file_attente.enfile(titre)
|
||||
|
||||
def regarder_suivant(self):
|
||||
"""
|
||||
Regarde le prochain élément de la file.
|
||||
- Défile le contenu
|
||||
- L'ajoute à l'historique
|
||||
|
||||
:return: (str) Titre du contenu regardé ou None
|
||||
"""
|
||||
if self.file_attente.est_vide():
|
||||
return None
|
||||
|
||||
contenu = self.file_attente.defile()
|
||||
self.historique.empile(contenu)
|
||||
return contenu
|
||||
|
||||
def prochain(self):
|
||||
"""
|
||||
Renvoie le prochain contenu sans le retirer.
|
||||
|
||||
:return: (str) Titre du prochain contenu ou None
|
||||
"""
|
||||
return self.file_attente.tete()
|
||||
|
||||
def revoir_dernier(self):
|
||||
"""
|
||||
Remet le dernier contenu regardé dans la file (en tête).
|
||||
Utile pour revoir un épisode.
|
||||
|
||||
:return: (str) Titre du contenu remis en file ou None
|
||||
"""
|
||||
if self.historique.est_vide():
|
||||
return None
|
||||
|
||||
contenu = self.historique.depile()
|
||||
# Créer une nouvelle file avec ce contenu en tête
|
||||
nouvelle_file = File()
|
||||
nouvelle_file.enfile(contenu)
|
||||
|
||||
# Transvaser l'ancienne file
|
||||
while not self.file_attente.est_vide():
|
||||
nouvelle_file.enfile(self.file_attente.defile())
|
||||
|
||||
self.file_attente = nouvelle_file
|
||||
return contenu
|
||||
|
||||
def ajouter_prioritaire(self, titre):
|
||||
"""
|
||||
Ajoute un contenu en tête de file (sera regardé en premier).
|
||||
|
||||
:param titre: (str) Titre du contenu prioritaire
|
||||
"""
|
||||
nouvelle_file = File()
|
||||
nouvelle_file.enfile(titre)
|
||||
|
||||
while not self.file_attente.est_vide():
|
||||
nouvelle_file.enfile(self.file_attente.defile())
|
||||
|
||||
self.file_attente = nouvelle_file
|
||||
|
||||
def afficher(self):
|
||||
"""Affiche l'état de la liste de visionnage."""
|
||||
print("=== Ma Liste Netflix ===")
|
||||
print(f"À regarder : {self.file_attente.taille()} élément(s)")
|
||||
print(f"Déjà vus : {self.historique.taille()} élément(s)")
|
||||
if not self.file_attente.est_vide():
|
||||
print(f"Prochain : {self.prochain()}")
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# PARTIE 4 : Système Undo/Redo
|
||||
# =============================================================================
|
||||
|
||||
class EditeurTexte:
|
||||
"""Éditeur de texte avec Undo/Redo."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialise l'éditeur."""
|
||||
self.texte = ""
|
||||
self.historique_undo = Pile()
|
||||
self.historique_redo = Pile()
|
||||
|
||||
def ecrire(self, texte_ajoute):
|
||||
"""
|
||||
Ajoute du texte.
|
||||
Sauvegarde l'état actuel dans l'historique.
|
||||
|
||||
:param texte_ajoute: (str) Texte à ajouter
|
||||
"""
|
||||
self.historique_undo.empile(self.texte)
|
||||
self.texte += texte_ajoute
|
||||
# Vider l'historique redo car nouvelle action
|
||||
while not self.historique_redo.est_vide():
|
||||
self.historique_redo.depile()
|
||||
|
||||
def effacer(self, n=1):
|
||||
"""
|
||||
Efface les n derniers caractères.
|
||||
|
||||
:param n: (int) Nombre de caractères à effacer
|
||||
"""
|
||||
if n > len(self.texte):
|
||||
n = len(self.texte)
|
||||
|
||||
self.historique_undo.empile(self.texte)
|
||||
self.texte = self.texte[:-n] if n > 0 else self.texte
|
||||
# Vider l'historique redo
|
||||
while not self.historique_redo.est_vide():
|
||||
self.historique_redo.depile()
|
||||
|
||||
def undo(self):
|
||||
"""
|
||||
Annule la dernière action (Ctrl+Z).
|
||||
|
||||
:return: (bool) True si l'annulation a réussi
|
||||
"""
|
||||
if self.historique_undo.est_vide():
|
||||
return False
|
||||
|
||||
self.historique_redo.empile(self.texte)
|
||||
self.texte = self.historique_undo.depile()
|
||||
return True
|
||||
|
||||
def redo(self):
|
||||
"""
|
||||
Refait la dernière action annulée (Ctrl+Y).
|
||||
|
||||
:return: (bool) True si le redo a réussi
|
||||
"""
|
||||
if self.historique_redo.est_vide():
|
||||
return False
|
||||
|
||||
self.historique_undo.empile(self.texte)
|
||||
self.texte = self.historique_redo.depile()
|
||||
return True
|
||||
|
||||
def afficher(self):
|
||||
"""Affiche le texte actuel."""
|
||||
undo_dispo = "Ctrl+Z" if not self.historique_undo.est_vide() else "-----"
|
||||
redo_dispo = "Ctrl+Y" if not self.historique_redo.est_vide() else "-----"
|
||||
print(f"[{undo_dispo}] [{redo_dispo}]")
|
||||
print(f'Texte : "{self.texte}"')
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# BONUS : File avec deux piles (complexité amortie O(1))
|
||||
# =============================================================================
|
||||
|
||||
class FileDeuxPiles:
|
||||
"""
|
||||
Implémentation efficace d'une file avec deux piles.
|
||||
Complexité amortie O(1) pour toutes les opérations.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialise une file vide."""
|
||||
self.pile_entree = Pile() # Pour les enfilements
|
||||
self.pile_sortie = Pile() # Pour les défilements
|
||||
|
||||
def enfile(self, element):
|
||||
"""Ajoute un élément en queue de file. O(1)"""
|
||||
self.pile_entree.empile(element)
|
||||
|
||||
def _transferer(self):
|
||||
"""Transfère pile_entree vers pile_sortie si nécessaire."""
|
||||
if self.pile_sortie.est_vide():
|
||||
while not self.pile_entree.est_vide():
|
||||
self.pile_sortie.empile(self.pile_entree.depile())
|
||||
|
||||
def defile(self):
|
||||
"""Retire et renvoie l'élément en tête. O(1) amorti."""
|
||||
self._transferer()
|
||||
return self.pile_sortie.depile()
|
||||
|
||||
def tete(self):
|
||||
"""Renvoie l'élément en tête sans le retirer. O(1) amorti."""
|
||||
self._transferer()
|
||||
return self.pile_sortie.sommet()
|
||||
|
||||
def est_vide(self):
|
||||
"""Renvoie True si la file est vide. O(1)"""
|
||||
return self.pile_entree.est_vide() and self.pile_sortie.est_vide()
|
||||
|
||||
def taille(self):
|
||||
"""Renvoie le nombre d'éléments. O(1)"""
|
||||
return self.pile_entree.taille() + self.pile_sortie.taille()
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# TESTS
|
||||
# =============================================================================
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("=" * 60)
|
||||
print("TEST DU NAVIGATEUR")
|
||||
print("=" * 60)
|
||||
|
||||
nav = Navigateur()
|
||||
nav.afficher_etat()
|
||||
|
||||
nav.visiter("https://www.wikipedia.org")
|
||||
nav.visiter("https://www.youtube.com")
|
||||
nav.visiter("https://www.github.com")
|
||||
nav.afficher_etat()
|
||||
|
||||
print("\nRetour...")
|
||||
nav.retour()
|
||||
nav.afficher_etat()
|
||||
|
||||
print("\nRetour...")
|
||||
nav.retour()
|
||||
nav.afficher_etat()
|
||||
|
||||
print("\nAvancer...")
|
||||
nav.avancer()
|
||||
nav.afficher_etat()
|
||||
|
||||
print("\nVisite nouvelle page...")
|
||||
nav.visiter("https://www.python.org")
|
||||
nav.afficher_etat()
|
||||
|
||||
print("\n")
|
||||
nav.afficher_historique()
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("TEST DE NETFLIX")
|
||||
print("=" * 60)
|
||||
|
||||
netflix = ListeVisionnage()
|
||||
netflix.ajouter("Stranger Things S5")
|
||||
netflix.ajouter("Wednesday S2")
|
||||
netflix.ajouter("Squid Game S3")
|
||||
netflix.afficher()
|
||||
|
||||
print(f"\nRegardé : {netflix.regarder_suivant()}")
|
||||
print(f"Regardé : {netflix.regarder_suivant()}")
|
||||
netflix.afficher()
|
||||
|
||||
print(f"\nRevoir dernier : {netflix.revoir_dernier()}")
|
||||
netflix.afficher()
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("TEST DE L'EDITEUR")
|
||||
print("=" * 60)
|
||||
|
||||
editeur = EditeurTexte()
|
||||
editeur.ecrire("Bonjour")
|
||||
editeur.ecrire(" le monde")
|
||||
editeur.afficher()
|
||||
|
||||
print("\nUndo...")
|
||||
editeur.undo()
|
||||
editeur.afficher()
|
||||
|
||||
print("\nRedo...")
|
||||
editeur.redo()
|
||||
editeur.afficher()
|
||||
|
||||
print("\nEffacer 6 caractères...")
|
||||
editeur.effacer(6)
|
||||
editeur.afficher()
|
||||
139
Structures_lineaires/Pile_File/TP/File.py
Normal file
139
Structures_lineaires/Pile_File/TP/File.py
Normal file
@@ -0,0 +1,139 @@
|
||||
#PARTIE
|
||||
class File1 :
|
||||
|
||||
def __init__(self,liste = []) :
|
||||
"""
|
||||
Méthode d'initialisation
|
||||
param liste : (List) Liste d'élément à enfiler dès l'initialisation
|
||||
"""
|
||||
self.file = liste
|
||||
|
||||
def enfile(self,x) :
|
||||
"""
|
||||
Méthode qui enfile un élément x
|
||||
param x : () Elément x à enfiler
|
||||
"""
|
||||
self.file = [x] + self.file
|
||||
|
||||
def defile(self) :
|
||||
"""
|
||||
Méthode qui defile un élément de la file
|
||||
return : (bool/ ) False si impossible de retirer l'élément / Elément sinon
|
||||
"""
|
||||
if not self.est_vide() :
|
||||
return self.file.pop()
|
||||
else :
|
||||
return False
|
||||
|
||||
def est_vide(self):
|
||||
"""
|
||||
Méthode testant la longueur de la file
|
||||
return : (bool) True si la file est vide, False sinon
|
||||
"""
|
||||
return len(self.file) == 0
|
||||
|
||||
def taille(self):
|
||||
"""
|
||||
Méthode retournant la taille de la file
|
||||
return : (int) taille de la file
|
||||
"""
|
||||
return len(self.file)
|
||||
|
||||
def get_file(self):
|
||||
"""
|
||||
Méthode retournant la file sous forme de liste pour en avoir un aperçu
|
||||
return : (list) file sous forme de list
|
||||
"""
|
||||
return self.file
|
||||
|
||||
# EXERCICE 2
|
||||
|
||||
def ajout_element(self,element):
|
||||
"""
|
||||
Fonction qui ajoute un élément, si la taille le permet.
|
||||
return (bool): Renvoie True si l'ajout de l'élément a eu lieu, False sinon
|
||||
"""
|
||||
if self.taille() < 7 :
|
||||
self.enfile(element)
|
||||
return True
|
||||
else :
|
||||
return False
|
||||
|
||||
def vide_file(self):
|
||||
"""
|
||||
Fonction qui vide une file et affiche ces éléments
|
||||
"""
|
||||
while self.est_vide() == False :
|
||||
e = self.defile()
|
||||
print(e)
|
||||
|
||||
# PARTIE 3 :
|
||||
|
||||
class File2 :
|
||||
|
||||
def __init__(self,tete = None,queue = None):
|
||||
"""
|
||||
Méthode d'initialisation
|
||||
param tete : () Element a mettre en tete de file
|
||||
param queue : (File) queue de la file (élements suivants)
|
||||
"""
|
||||
self.tete = tete
|
||||
self.queue = queue
|
||||
|
||||
def enfile(self,x) :
|
||||
"""
|
||||
Méthode qui enfile un élément x
|
||||
param x : () Elément x à enfiler
|
||||
"""
|
||||
self.queue = File2(self.tete,self.queue)
|
||||
self.tete = x
|
||||
|
||||
def defile(self) :
|
||||
"""
|
||||
Méthode qui defile un élément de la file
|
||||
return : (bool/ ) False si impossible de retirer l'élément / Elément sinon
|
||||
"""
|
||||
if self.est_vide() :
|
||||
return False
|
||||
if self.queue == None :
|
||||
val = self.tete
|
||||
self.tete = None
|
||||
return val
|
||||
elif self.queue.queue == None :
|
||||
val = self.queue.tete
|
||||
self.queue = None
|
||||
return val
|
||||
else :
|
||||
return self.queue.defile()
|
||||
|
||||
def est_vide(self) :
|
||||
"""
|
||||
Méthode testant la longueur de la file
|
||||
return : (bool) True si la file est vide, False sinon
|
||||
"""
|
||||
return self.queue == None and self.tete == None
|
||||
|
||||
def taille(self):
|
||||
"""
|
||||
Méthode retournant la taille de la file
|
||||
return : (int) taille de la file
|
||||
"""
|
||||
if self.queue == None :
|
||||
return 1
|
||||
else :
|
||||
return 1 + self.queue.taille()
|
||||
|
||||
def get_file(self):
|
||||
"""
|
||||
Méthode retournant la file sous forme de liste pour en avoir un aperçu
|
||||
return : (list) file sous forme de list
|
||||
"""
|
||||
if self.queue != None :
|
||||
return [self.tete] + self.queue.get_file()
|
||||
else :
|
||||
return [self.tete]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
80
Structures_lineaires/Pile_File/TP/TP_File.md
Normal file
80
Structures_lineaires/Pile_File/TP/TP_File.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# TP File
|
||||
|
||||
------
|
||||
|
||||
## 1. Première implémentation
|
||||
|
||||
Pour cette implémentation, le constructeur de la classe utilisera un tableau pour stocker les données.
|
||||
|
||||
1. Créez cette classe File contenant les méthodes suivantes :
|
||||
|
||||
* **enfile( )**
|
||||
|
||||
* **defile( )**
|
||||
|
||||
* **top( )**
|
||||
|
||||
* **est_vide( )**
|
||||
|
||||
* **taille( )**
|
||||
|
||||
## 2. File à taille fixe :
|
||||
|
||||
Supposons que notre file à une taille fixe, disons 7 éléments maximum.
|
||||
|
||||
1. Ecrire une méthode ajout_element( ) qui ajoute un élément dans la file seulement si il n'y a pas trop d'éléments dans la file.
|
||||
2. Ecrire une méthode vide_file( ) qui enlève tous les éléments de la file.
|
||||
|
||||
## 3. Deuxième implémentation
|
||||
|
||||
Ici nous allons implémenter la file de manière récursive. Elle possèdera deux attributs, le premier sera un élément de la file nommé tête, le second sera une autre File. Cette seconde file possèdera elle aura un élément et une autre file en attribut. Ainsi de suite.
|
||||
|
||||
1. Programmez cette classe nommée File2 avec les méthodes suivantes
|
||||
* **enfile( )**
|
||||
* **defile( )**
|
||||
* **top( )**
|
||||
* **est_vide( )**
|
||||
* **taille( )**
|
||||
|
||||
## 4. Implémentation d'un jeu de bataille :
|
||||
|
||||
La bataille : règles du jeu
|
||||
|
||||
Chacun tire la carte du dessus de son paquet et la pose sur la table. Celui qui a la carte la plus forte ramasse les autres cartes. L'as est la plus forte carte, puis roi, dame, valet, 10, etc. Lorsque deux joueurs posent en même temps deux cartes de même valeur il y a "bataille".
|
||||
|
||||
Lorsqu'il y a "bataille" les joueurs tirent la carte suivante et la posent, face cachée, sur la carte précédente. Puis ils tirent une deuxième carte qu'ils posent cette fois-ci face découverte et c'est cette dernière qui départagera les joueurs.
|
||||
|
||||
Lorsqu'il y a bataille et qu'un des deux joueurs a moins de 3 cartes alors il a perdu.
|
||||
|
||||
Le gagnant est celui qui remporte toutes les cartes.
|
||||
|
||||
Le jeu de la bataille peut être facilement codé avec des Files.
|
||||
|
||||
Un fichier carte.py contient la classe carte et les fonctions suivantes :
|
||||
|
||||
- comp
|
||||
- game
|
||||
|
||||
- creer_jeu
|
||||
|
||||
1. Pour ce travail vous allez devoir compléter les fonctions :
|
||||
|
||||
- tour
|
||||
|
||||
- bataille
|
||||
|
||||
- jeu_fini
|
||||
|
||||
Ces fonctions se trouvent dans un fichier nommé carte_eleve.py
|
||||
|
||||
## Pour aller plus loin :
|
||||
|
||||
Écrire une nouvelle implémentation d'une file, cette fois-ci il faut manipuler la file avec deux piles.
|
||||
|
||||
---
|
||||
|
||||
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
|
||||
|
||||
Licence CC BY NC
|
||||
|
||||
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a> <br />Ce cours est mis à disposition selon les termes de la <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International</a>.
|
||||
530
Structures_lineaires/Pile_File/TP/TP_Navigateur.md
Normal file
530
Structures_lineaires/Pile_File/TP/TP_Navigateur.md
Normal file
@@ -0,0 +1,530 @@
|
||||
# TP : Simulateur de Navigateur Web — Piles et Files en action
|
||||
|
||||
> **Thème** : Structures de données linéaires (Pile, File)
|
||||
|
||||
---
|
||||
|
||||
## Contexte
|
||||
|
||||
Chaque jour, vous utilisez un navigateur web (Chrome, Firefox, Safari...). Avez-vous déjà remarqué comment fonctionnent les boutons **← Retour** et **→ Suivant** ? Et comment Netflix gère votre file d'attente "**À regarder ensuite**" ?
|
||||
|
||||
Dans ce TP, vous allez recréer ces mécanismes en utilisant les structures **Pile** et **File**.
|
||||
|
||||
---
|
||||
|
||||
## Partie 1 : Implémentation des structures
|
||||
|
||||
### Exercice 1 : La classe Pile
|
||||
|
||||
Implémentez une classe `Pile` avec les méthodes suivantes :
|
||||
|
||||
```python
|
||||
class Pile:
|
||||
"""Structure de données LIFO (Last In First Out)."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialise une pile vide."""
|
||||
pass
|
||||
|
||||
def empile(self, element):
|
||||
"""Ajoute un élément au sommet de la pile."""
|
||||
pass
|
||||
|
||||
def depile(self):
|
||||
"""
|
||||
Retire et renvoie l'élément au sommet.
|
||||
Renvoie None si la pile est vide.
|
||||
"""
|
||||
pass
|
||||
|
||||
def est_vide(self):
|
||||
"""Renvoie True si la pile est vide."""
|
||||
pass
|
||||
|
||||
def sommet(self):
|
||||
"""
|
||||
Renvoie l'élément au sommet sans le retirer.
|
||||
Renvoie None si la pile est vide.
|
||||
"""
|
||||
pass
|
||||
|
||||
def taille(self):
|
||||
"""Renvoie le nombre d'éléments dans la pile."""
|
||||
pass
|
||||
|
||||
def __repr__(self):
|
||||
"""Affichage de la pile."""
|
||||
pass
|
||||
```
|
||||
|
||||
**Tests à effectuer :**
|
||||
```python
|
||||
>>> p = Pile()
|
||||
>>> p.est_vide()
|
||||
True
|
||||
>>> p.empile("A")
|
||||
>>> p.empile("B")
|
||||
>>> p.empile("C")
|
||||
>>> p.sommet()
|
||||
'C'
|
||||
>>> p.depile()
|
||||
'C'
|
||||
>>> p.taille()
|
||||
2
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Exercice 2 : La classe File
|
||||
|
||||
Implémentez une classe `File` avec les méthodes suivantes :
|
||||
|
||||
```python
|
||||
class File:
|
||||
"""Structure de données FIFO (First In First Out)."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialise une file vide."""
|
||||
pass
|
||||
|
||||
def enfile(self, element):
|
||||
"""Ajoute un élément en queue de file."""
|
||||
pass
|
||||
|
||||
def defile(self):
|
||||
"""
|
||||
Retire et renvoie l'élément en tête de file.
|
||||
Renvoie None si la file est vide.
|
||||
"""
|
||||
pass
|
||||
|
||||
def est_vide(self):
|
||||
"""Renvoie True si la file est vide."""
|
||||
pass
|
||||
|
||||
def tete(self):
|
||||
"""
|
||||
Renvoie l'élément en tête sans le retirer.
|
||||
Renvoie None si la file est vide.
|
||||
"""
|
||||
pass
|
||||
|
||||
def taille(self):
|
||||
"""Renvoie le nombre d'éléments dans la file."""
|
||||
pass
|
||||
|
||||
def __repr__(self):
|
||||
"""Affichage de la file."""
|
||||
pass
|
||||
```
|
||||
|
||||
**Tests à effectuer :**
|
||||
```python
|
||||
>>> f = File()
|
||||
>>> f.est_vide()
|
||||
True
|
||||
>>> f.enfile("Premier")
|
||||
>>> f.enfile("Deuxième")
|
||||
>>> f.enfile("Troisième")
|
||||
>>> f.tete()
|
||||
'Premier'
|
||||
>>> f.defile()
|
||||
'Premier'
|
||||
>>> f.taille()
|
||||
2
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Partie 2 : Simulateur de navigateur web
|
||||
|
||||
### Principe de fonctionnement
|
||||
|
||||
Un navigateur utilise **deux piles** pour gérer l'historique :
|
||||
|
||||
- **Pile `historique`** : contient les pages visitées (la page actuelle est au sommet)
|
||||
- **Pile `suivant`** : contient les pages "en avant" (après avoir cliqué sur Retour)
|
||||
|
||||
| Action | Effet |
|
||||
|--------|-------|
|
||||
| Visiter une page | Empile dans `historique`, vide `suivant` |
|
||||
| Clic sur ← Retour | Dépile `historique` → empile dans `suivant` |
|
||||
| Clic sur → Suivant | Dépile `suivant` → empile dans `historique` |
|
||||
|
||||
---
|
||||
|
||||
### Exercice 3 : La classe Navigateur
|
||||
|
||||
```python
|
||||
class Navigateur:
|
||||
"""Simulateur de navigateur web avec historique."""
|
||||
|
||||
def __init__(self, page_accueil="https://www.google.com"):
|
||||
"""
|
||||
Initialise le navigateur avec une page d'accueil.
|
||||
|
||||
:param page_accueil: (str) URL de la page d'accueil
|
||||
"""
|
||||
self.historique = Pile()
|
||||
self.suivant = Pile()
|
||||
# À compléter : empiler la page d'accueil
|
||||
|
||||
def page_actuelle(self):
|
||||
"""
|
||||
Renvoie l'URL de la page actuellement affichée.
|
||||
|
||||
:return: (str) URL de la page actuelle ou None
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
def visiter(self, url):
|
||||
"""
|
||||
Visite une nouvelle page.
|
||||
- Empile l'URL dans l'historique
|
||||
- Vide la pile 'suivant' (on ne peut plus avancer)
|
||||
|
||||
:param url: (str) URL de la page à visiter
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
def retour(self):
|
||||
"""
|
||||
Revient à la page précédente (bouton ←).
|
||||
- Dépile l'historique
|
||||
- Empile la page actuelle dans 'suivant'
|
||||
|
||||
:return: (str) URL de la nouvelle page actuelle ou None si impossible
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
def avancer(self):
|
||||
"""
|
||||
Avance à la page suivante (bouton →).
|
||||
- Dépile 'suivant'
|
||||
- Empile dans l'historique
|
||||
|
||||
:return: (str) URL de la nouvelle page actuelle ou None si impossible
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
def peut_reculer(self):
|
||||
"""Renvoie True si le bouton Retour est actif."""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
def peut_avancer(self):
|
||||
"""Renvoie True si le bouton Suivant est actif."""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
def afficher_etat(self):
|
||||
"""Affiche l'état actuel du navigateur."""
|
||||
retour = "←" if self.peut_reculer() else "✗"
|
||||
avancer = "→" if self.peut_avancer() else "✗"
|
||||
print(f"[{retour}] [{avancer}] | {self.page_actuelle()}")
|
||||
```
|
||||
|
||||
**Tests à effectuer :**
|
||||
```python
|
||||
>>> nav = Navigateur()
|
||||
>>> nav.afficher_etat()
|
||||
[✗] [✗] | https://www.google.com
|
||||
|
||||
>>> nav.visiter("https://www.wikipedia.org")
|
||||
>>> nav.visiter("https://www.youtube.com")
|
||||
>>> nav.visiter("https://www.github.com")
|
||||
>>> nav.afficher_etat()
|
||||
[←] [✗] | https://www.github.com
|
||||
|
||||
>>> nav.retour()
|
||||
'https://www.youtube.com'
|
||||
>>> nav.afficher_etat()
|
||||
[←] [→] | https://www.youtube.com
|
||||
|
||||
>>> nav.retour()
|
||||
'https://www.wikipedia.org'
|
||||
>>> nav.avancer()
|
||||
'https://www.youtube.com'
|
||||
|
||||
>>> nav.visiter("https://www.python.org")
|
||||
>>> nav.afficher_etat()
|
||||
[←] [✗] | https://www.python.org
|
||||
>>> nav.peut_avancer()
|
||||
False # La pile 'suivant' a été vidée
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Exercice 4 : Historique complet
|
||||
|
||||
Ajoutez une méthode pour afficher tout l'historique de navigation :
|
||||
|
||||
```python
|
||||
def afficher_historique(self):
|
||||
"""
|
||||
Affiche l'historique complet de navigation.
|
||||
La page actuelle est marquée d'une flèche.
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
```
|
||||
|
||||
**Exemple de sortie :**
|
||||
```
|
||||
Historique de navigation :
|
||||
1. https://www.google.com
|
||||
2. https://www.wikipedia.org
|
||||
3. https://www.youtube.com
|
||||
→ 4. https://www.github.com (page actuelle)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Partie 3 : File d'attente Netflix
|
||||
|
||||
### Contexte
|
||||
|
||||
Sur Netflix, vous pouvez ajouter des films à votre liste "**À regarder**". Les films sont regardés dans l'ordre d'ajout (FIFO), mais vous pouvez aussi mettre un film en priorité.
|
||||
|
||||
---
|
||||
|
||||
### Exercice 5 : La classe ListeVisionnage
|
||||
|
||||
```python
|
||||
class ListeVisionnage:
|
||||
"""Gestionnaire de file d'attente de visionnage."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialise une liste de visionnage vide."""
|
||||
self.file_attente = File()
|
||||
self.historique = Pile() # Films déjà regardés
|
||||
|
||||
def ajouter(self, titre):
|
||||
"""
|
||||
Ajoute un film/série à la file d'attente.
|
||||
|
||||
:param titre: (str) Titre du contenu à ajouter
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
def regarder_suivant(self):
|
||||
"""
|
||||
Regarde le prochain élément de la file.
|
||||
- Défile le contenu
|
||||
- L'ajoute à l'historique
|
||||
|
||||
:return: (str) Titre du contenu regardé ou None
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
def prochain(self):
|
||||
"""
|
||||
Renvoie le prochain contenu sans le retirer.
|
||||
|
||||
:return: (str) Titre du prochain contenu ou None
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
def revoir_dernier(self):
|
||||
"""
|
||||
Remet le dernier contenu regardé dans la file (en tête).
|
||||
Utile pour revoir un épisode.
|
||||
|
||||
:return: (str) Titre du contenu remis en file ou None
|
||||
"""
|
||||
# À compléter (utiliser une file temporaire ou une autre approche)
|
||||
pass
|
||||
|
||||
def afficher(self):
|
||||
"""Affiche l'état de la liste de visionnage."""
|
||||
print("=== Ma Liste Netflix ===")
|
||||
print(f"À regarder : {self.file_attente.taille()} élément(s)")
|
||||
print(f"Déjà vus : {self.historique.taille()} élément(s)")
|
||||
if not self.file_attente.est_vide():
|
||||
print(f"Prochain : {self.prochain()}")
|
||||
```
|
||||
|
||||
**Tests à effectuer :**
|
||||
```python
|
||||
>>> netflix = ListeVisionnage()
|
||||
>>> netflix.ajouter("Stranger Things S5")
|
||||
>>> netflix.ajouter("Wednesday S2")
|
||||
>>> netflix.ajouter("Squid Game S3")
|
||||
>>> netflix.afficher()
|
||||
=== Ma Liste Netflix ===
|
||||
À regarder : 3 élément(s)
|
||||
Déjà vus : 0 élément(s)
|
||||
Prochain : Stranger Things S5
|
||||
|
||||
>>> netflix.regarder_suivant()
|
||||
'Stranger Things S5'
|
||||
>>> netflix.regarder_suivant()
|
||||
'Wednesday S2'
|
||||
>>> netflix.afficher()
|
||||
=== Ma Liste Netflix ===
|
||||
À regarder : 1 élément(s)
|
||||
Déjà vus : 2 élément(s)
|
||||
Prochain : Squid Game S3
|
||||
|
||||
>>> netflix.revoir_dernier()
|
||||
'Wednesday S2'
|
||||
>>> netflix.prochain()
|
||||
'Wednesday S2'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Exercice 6 : File avec priorité
|
||||
|
||||
Netflix permet aussi de mettre un contenu "en haut de la liste". Ajoutez cette fonctionnalité :
|
||||
|
||||
```python
|
||||
def ajouter_prioritaire(self, titre):
|
||||
"""
|
||||
Ajoute un contenu en tête de file (sera regardé en premier).
|
||||
Nécessite de reconstruire la file.
|
||||
|
||||
:param titre: (str) Titre du contenu prioritaire
|
||||
"""
|
||||
# Indice : créer une nouvelle file, enfiler le titre prioritaire,
|
||||
# puis transvaser l'ancienne file
|
||||
pass
|
||||
```
|
||||
|
||||
**Test :**
|
||||
```python
|
||||
>>> netflix.ajouter("Film 1")
|
||||
>>> netflix.ajouter("Film 2")
|
||||
>>> netflix.ajouter_prioritaire("Film URGENT")
|
||||
>>> netflix.prochain()
|
||||
'Film URGENT'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Partie 4 : Système Undo/Redo
|
||||
|
||||
### Exercice 7 : Éditeur de texte simplifié
|
||||
|
||||
Créez un éditeur qui permet d'annuler (Ctrl+Z) et de refaire (Ctrl+Y) des actions.
|
||||
|
||||
```python
|
||||
class EditeurTexte:
|
||||
"""Éditeur de texte avec Undo/Redo."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialise l'éditeur."""
|
||||
self.texte = ""
|
||||
self.historique_undo = Pile() # États précédents
|
||||
self.historique_redo = Pile() # États annulés
|
||||
|
||||
def ecrire(self, texte_ajoute):
|
||||
"""
|
||||
Ajoute du texte.
|
||||
Sauvegarde l'état actuel dans l'historique.
|
||||
|
||||
:param texte_ajoute: (str) Texte à ajouter
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
def effacer(self, n=1):
|
||||
"""
|
||||
Efface les n derniers caractères.
|
||||
|
||||
:param n: (int) Nombre de caractères à effacer
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
def undo(self):
|
||||
"""
|
||||
Annule la dernière action (Ctrl+Z).
|
||||
|
||||
:return: (bool) True si l'annulation a réussi
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
def redo(self):
|
||||
"""
|
||||
Refait la dernière action annulée (Ctrl+Y).
|
||||
|
||||
:return: (bool) True si le redo a réussi
|
||||
"""
|
||||
# À compléter
|
||||
pass
|
||||
|
||||
def afficher(self):
|
||||
"""Affiche le texte actuel."""
|
||||
undo_dispo = "Ctrl+Z" if not self.historique_undo.est_vide() else "-----"
|
||||
redo_dispo = "Ctrl+Y" if not self.historique_redo.est_vide() else "-----"
|
||||
print(f"[{undo_dispo}] [{redo_dispo}]")
|
||||
print(f"Texte : \"{self.texte}\"")
|
||||
```
|
||||
|
||||
**Tests :**
|
||||
```python
|
||||
>>> editeur = EditeurTexte()
|
||||
>>> editeur.ecrire("Bonjour")
|
||||
>>> editeur.ecrire(" le monde")
|
||||
>>> editeur.afficher()
|
||||
[Ctrl+Z] [-----]
|
||||
Texte : "Bonjour le monde"
|
||||
|
||||
>>> editeur.undo()
|
||||
True
|
||||
>>> editeur.afficher()
|
||||
[Ctrl+Z] [Ctrl+Y]
|
||||
Texte : "Bonjour"
|
||||
|
||||
>>> editeur.redo()
|
||||
True
|
||||
>>> editeur.afficher()
|
||||
[Ctrl+Z] [-----]
|
||||
Texte : "Bonjour le monde"
|
||||
|
||||
>>> editeur.effacer(6)
|
||||
>>> editeur.afficher()
|
||||
[Ctrl+Z] [-----]
|
||||
Texte : "Bonjour le"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Bonus : Comparaison des complexités
|
||||
|
||||
| Opération | Pile (liste Python) | File (liste Python) | File (deux piles) |
|
||||
|-----------|---------------------|---------------------|-------------------|
|
||||
| Empile/Enfile | O(1) | O(n)* | O(1) amorti |
|
||||
| Dépile/Défile | O(1) | O(1) | O(1) amorti |
|
||||
| Sommet/Tête | O(1) | O(1) | O(1) |
|
||||
| Est_vide | O(1) | O(1) | O(1) |
|
||||
|
||||
*L'insertion en début de liste Python est en O(n).
|
||||
|
||||
**Exercice bonus** : Implémentez une file efficace en utilisant deux piles.
|
||||
|
||||
---
|
||||
|
||||
## Résumé des notions
|
||||
|
||||
| Structure | Principe | Analogie | Cas d'usage |
|
||||
|-----------|----------|----------|-------------|
|
||||
| **Pile** | LIFO | Pile d'assiettes | Historique, Undo, Appels de fonctions |
|
||||
| **File** | FIFO | File d'attente | Impression, Streaming, BFS |
|
||||
|
||||
---
|
||||
|
||||
Auteurs : Florian Mathieu
|
||||
|
||||
Licence CC BY NC
|
||||
|
||||
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a> <br />Ce cours est mis à disposition selon les termes de la <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International</a>.
|
||||
107
Structures_lineaires/Pile_File/TP/TP_Pile.md
Normal file
107
Structures_lineaires/Pile_File/TP/TP_Pile.md
Normal file
@@ -0,0 +1,107 @@
|
||||
# TP Pile
|
||||
|
||||
------
|
||||
|
||||
## 1. Implémentation de la pile :
|
||||
|
||||
Afin d'implémenter la pile il nous faut utiliser une structure de données permettant de stocker des informations.
|
||||
|
||||
1. Trouver une structure de données adéquate permettant de réaliser les méthodes liées à la Pile
|
||||
|
||||
2. Implémenter la Pile (Constructeur et méthodes associées)
|
||||
|
||||
3. Implémenter la méthode *\_\_repr\_\_( )* permettant d'afficher la Pile crée
|
||||
|
||||
*Exemple :*
|
||||
|
||||
```python
|
||||
>>> p = Pile()
|
||||
>>> p
|
||||
[ ]
|
||||
>>> p.empile(7)
|
||||
>>> p.empile(9)
|
||||
>>> p
|
||||
9
|
||||
7
|
||||
```
|
||||
|
||||
## 2. Exercices :
|
||||
|
||||
### 2. 1. Bon parenthésage
|
||||
|
||||
1. Ecrire une fonction *bien_parenthese*( ) vérifiant si une chaîne de caractère est bien parenthésée ou non. La valeur de retour sera un booléen. On vérifie les parenthèses '( )' ainsi que les crochets '[ ]'
|
||||
|
||||
```python
|
||||
>>> bien_parenthese("(oui)")
|
||||
True
|
||||
>>> bien_parenthese("(ou(i)")
|
||||
False
|
||||
>>> bien_parenthese("(o[u]i)")
|
||||
True
|
||||
>>> bien_parenthese("(ou][i)")
|
||||
False
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 2. 2. Calculatrice polonaise inverse
|
||||
|
||||
La calculatrice polonaise inverse permet de faire des calculs simple mais pose l'opérateur après les deux opérandes.
|
||||
|
||||
<u>Par exemple :</u>
|
||||
|
||||
5 + 8 + 9 => 5 8 + 9 +
|
||||
|
||||
7 * 8 + 9 * 2 => 7 8 * 9 2 * +
|
||||
|
||||
1. Ecrire une fonction calculatrice( ) prenant une chaîne de caractère en paramètre qui sera un calcul en polonais inverse et le résout.
|
||||
|
||||
```python
|
||||
>>> calculatrice("5 8 + 9 + ")
|
||||
22
|
||||
>>> calculatrice("7 8 * 9 2 * + ")
|
||||
74
|
||||
>>> calculatrice("11 4 +")
|
||||
15
|
||||
```
|
||||
|
||||
> Ici il y a plusieurs points important.
|
||||
> Il faut pouvoir découper la chaîne de caractères en plusieurs données. (split())
|
||||
>
|
||||
> Les éléments traités sont des chaînes de caractères => '11' '+' '4' ne veut rien dire
|
||||
> De la même manière => '11' + '4' => '114'
|
||||
|
||||
## 2. 3. Tri d'une pile
|
||||
|
||||
Le but ici est de trier une pile. Pour cela nous utiliserons une autre pile temporaire permettant de stocker les éléments.
|
||||
|
||||
1. Écrire une fonction tri_pile( ) prenant en paramètre une pile et renvoyant la pile triée.
|
||||
|
||||
> L'idée ici est d'utiliser seulement deux piles. Afin de comprendre le fonctionnement il faut faire quelques essais à la main.
|
||||
|
||||
```python
|
||||
>>> >>> p = Pile()
|
||||
>>> p
|
||||
>>> p.empile(7)
|
||||
>>> p.empile(1)
|
||||
>>> p.empile(3)
|
||||
>>> p.empile(9)
|
||||
>>> p
|
||||
9
|
||||
3
|
||||
1
|
||||
7
|
||||
>>> tri_pile(p)
|
||||
1
|
||||
3
|
||||
7
|
||||
9
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Auteurs : Florian Mathieu, Enzo Frémeaux, Thimothée Decooster
|
||||
|
||||
Licence CC BY NC
|
||||
|
||||
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Licence Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a> <br />Ce cours est mis à disposition selon les termes de la <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International</a>.
|
||||
64
Structures_lineaires/Pile_File/TP/TP_Pile_correction.py
Normal file
64
Structures_lineaires/Pile_File/TP/TP_Pile_correction.py
Normal file
@@ -0,0 +1,64 @@
|
||||
class Pile :
|
||||
|
||||
def __init__(self) :
|
||||
"""
|
||||
Méthode constructeur
|
||||
"""
|
||||
self.pile = []
|
||||
|
||||
def empile(self,x) :
|
||||
"""
|
||||
Méthode qui empile un élément
|
||||
param x : () Elément x à empiler
|
||||
"""
|
||||
self.pile.append(x)
|
||||
|
||||
def depile(self) :
|
||||
"""
|
||||
Méthode qui defile un élément de la pile
|
||||
return : (bool/ ) False si impossible de retirer l'élément / Elément sinon
|
||||
"""
|
||||
if self.est_vide() :
|
||||
return False
|
||||
else :
|
||||
return self.pile.pop()
|
||||
|
||||
|
||||
def est_vide(self):
|
||||
"""Méthode calculant la longueur de la pile"""
|
||||
return self.pile == []
|
||||
|
||||
def top(self):
|
||||
"""Méthode renvoyant l'élément au dessus de la pile"""
|
||||
return self.pile[-1]
|
||||
|
||||
def __repr__(self):
|
||||
long = len(self.pile)-1
|
||||
s = ''
|
||||
while long >= 0 :
|
||||
s+=str(self.pile[long])+'\n'
|
||||
long-=1
|
||||
return s
|
||||
|
||||
def taille(self):
|
||||
"""Méthode permettant de connaître la taille de la pile"""
|
||||
return len(self.pile)
|
||||
|
||||
def sort_stack(self):
|
||||
"""Méthode qui renvoie la pile trié"""
|
||||
pile_tmp = Pile()
|
||||
while not self.est_vide() :
|
||||
val_tmp = self.depile()
|
||||
while pile_tmp.taille() != 0 and pile_tmp.top() < val_tmp:
|
||||
self.empile(pile_tmp.depile())
|
||||
pile_tmp.empile(val_tmp)
|
||||
self.pile = pile_tmp.pile
|
||||
return self
|
||||
|
||||
|
||||
p = Pile()
|
||||
p.empile(7)
|
||||
p.empile(1)
|
||||
p.empile(3)
|
||||
p.empile(9)
|
||||
|
||||
129
Structures_lineaires/Pile_File/TP/carte_eleve.py
Normal file
129
Structures_lineaires/Pile_File/TP/carte_eleve.py
Normal file
@@ -0,0 +1,129 @@
|
||||
import File
|
||||
import random
|
||||
|
||||
VAL_CARTE = ['1','2','3','4','5','6','7','8','9','10','V','D','R','AS']
|
||||
COL_CARTE = ['P','T','C','H']
|
||||
|
||||
def in_file(x,f):
|
||||
"""
|
||||
Fonction qui revoie True si x est dans la file f
|
||||
param x (): element present ou non dans f
|
||||
param f (File1/File2) : File contenant ou non x
|
||||
return (bool) : Renvoie True si x est dans f, False sinon
|
||||
"""
|
||||
if type(f) == File1 :
|
||||
if x in f.file :
|
||||
return True
|
||||
else :
|
||||
return False
|
||||
elif type(f) == File2 :
|
||||
if f.tete == x :
|
||||
return True
|
||||
elif f.queue != None :
|
||||
return in_file(x,f.queue)
|
||||
else :
|
||||
return False
|
||||
else :
|
||||
return False
|
||||
|
||||
def comp(c1,c2) :
|
||||
"""
|
||||
Fonction de comparaison entre deux cartes
|
||||
param c1 : (tuple) Carte 1
|
||||
param c2 : (tuple) Carte 2
|
||||
return : Renvoie
|
||||
-1 si => c1 < c2
|
||||
1 si => c1 > <2
|
||||
0 si => c1 == c2
|
||||
|
||||
"""
|
||||
if VAL_CARTE.index(c1[0]) < VAL_CARTE.index(c2[0]) :
|
||||
return -1
|
||||
elif VAL_CARTE.index(c1[0]) > VAL_CARTE.index(c2[0]) :
|
||||
return 1
|
||||
else :
|
||||
return 0
|
||||
|
||||
def creer_jeu():
|
||||
"""
|
||||
Fonction qui crée un jeu aléatoire
|
||||
return a,b (File) Deux files contenant 26 cartes chacunes
|
||||
"""
|
||||
i = 0
|
||||
val_carte = ['1','2','3','4','5','6','7','8','9','10','V','D','R','AS']
|
||||
col_carte = ['P','T','C','H']
|
||||
f1 = File1()
|
||||
f2 = File1()
|
||||
while i < 52 :
|
||||
val = random.randint(0,len(val_carte)-1)
|
||||
col = random.randint(0,len(col_carte)-1)
|
||||
carte = (val_carte[val],col_carte[col])
|
||||
if in_file(carte,f1) == False or in_file(carte,f2) == False :
|
||||
if i%2 == 0 :
|
||||
f1.enfile(carte)
|
||||
else :
|
||||
f2.enfile(carte)
|
||||
i+=1
|
||||
return f1,f2
|
||||
|
||||
def tour(f1,f2) :
|
||||
"""
|
||||
Foncton qui simule un tour de bataille
|
||||
param f1: (File) File contenant le jeu n°1
|
||||
param f2: (File) File contenant le jeu n°2
|
||||
"""
|
||||
i = f1.defile()
|
||||
j = f2.defile()
|
||||
res = comp(i,j)
|
||||
if # A compléter
|
||||
elif # A compléter
|
||||
else :
|
||||
print('bataille')
|
||||
if # A compléter :
|
||||
bataille(i,j,f1,f2)
|
||||
else :
|
||||
# Si un des deux paquet ne peut pas faire la bataille alors on le vide pour faire gagner l'autre joueur
|
||||
if # A compléter :
|
||||
# A compléter
|
||||
else :
|
||||
# A compléter
|
||||
|
||||
def bataille(c1,c2,f1,f2) :
|
||||
"""
|
||||
Fonction simulant un tour de bataille
|
||||
param c1 : (tuple) Carte n°1 égale a c2
|
||||
param c2 : (tuple) Carte n°1 égale a c1
|
||||
param f1: (File) File contenant le jeu n°1
|
||||
param f2: (File) File contenant le jeu n°2
|
||||
"""
|
||||
bataille_tab= []
|
||||
while comp(c1,c2) == 0:
|
||||
# A compléter
|
||||
if comp(c1,c2) == 1 :
|
||||
# A compléter
|
||||
if comp(c1,c2) == -1 :
|
||||
# A compléter
|
||||
|
||||
|
||||
|
||||
def est_fini(f1,f2):
|
||||
"""
|
||||
Fonction qui détermine si le jeu est fini
|
||||
param f1: (File) File contenant le jeu n°1
|
||||
param f2: (File) File contenant le jeu n°2
|
||||
return (bool): renvoie True si le jeu est fini, False sinon.
|
||||
"""
|
||||
if # A compléter
|
||||
elif # A compléter
|
||||
else :
|
||||
# A compléter
|
||||
|
||||
|
||||
def game(f1,f2):
|
||||
"""
|
||||
Fonction simulant le jeu de la bataille
|
||||
param f1: (File) File contenant le jeu n°1
|
||||
param f2: (File) File contenant le jeu n°2
|
||||
"""
|
||||
while not est_fini(f1,f2) :
|
||||
tour(f1,f2)
|
||||
Reference in New Issue
Block a user