Structures linéaires : nouveau chapitre avec listes chaînées + déplacement Pile_File

This commit is contained in:
2026-06-16 09:38:57 +02:00
parent b7847e19d3
commit 5e050b384f
23 changed files with 444 additions and 1 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

View 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.
![image-20220729234146926](Images/Pile.png)
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.
![File](Images/File.png)
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>.

View 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>.

View 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>
![Pile_td](../Images/Pile_td.png)
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>
![image-20220730000106940](../Images/File_td.png)
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>.

View 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()

View 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()

View 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]

View 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>.

View 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>.

View 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>.

View 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)

View 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)