first commit

This commit is contained in:
2024-11-23 13:38:17 +01:00
parent 678203b19f
commit fb915042df
99 changed files with 6624 additions and 0 deletions

260
tp6_self/LSC.py Normal file
View File

@@ -0,0 +1,260 @@
"""
Librairie des Listes Simplement Chaînées.
Elle met à distribution cette structure de données et son interface.
@author: L. JOANNIC
"""
# ############################################################################
class Liste_Simplement_Chainee(object):
"""
Classe des Listes Simplement Chainees.
Attributs
- _tete : None si vide, Maillon sinon.
Méthodes
- est_vide
- ajouter_en_tete
- tete
- queue
"""
def __init__(self):
"""
Construire une instance de Liste Simplement Chainee.
Returns
-------
None.
"""
self._tete = None
return None
def est_vide(self):
"""
Tester si l'instance est vide.
Returns
-------
bool
Vrai ssi la liste est vide.
"""
return (self._tete is None)
def ajouter_en_tete(self, element):
"""
Ajouter l'élément en tête de liste.
Parameters
----------
element : type de donnee
Donnnée à ajouter à la liste.
Returns
-------
resultat : Liste_Simplement_Chainee
La liste à abonder.
"""
resultat = Liste_Simplement_Chainee()
resultat._tete = Maillon(element, self)
return resultat
def tete(self):
"""
Renvoyer la donnée stockée en tête de liste.
Returns
-------
type de donnee quelconque
donnee en tete.
"""
assert not(self.est_vide()), "Liste Vide"
return self._tete.donnee
def queue(self):
"""
Renvoyer la sous-liste suivant le maillon de tete.
Returns
-------
Liste_Simplement_Chainee
Queue de la liste.
"""
assert not(self.est_vide()), "Liste Vide"
return self._tete.suite
# ############################################################################
def creer_liste_vide():
"""
Créer une liste simplement chainee vide.
Returns
-------
Liste_Simplement_Chainee
Liste vide.
Effets de bord
--------------
Aucun
"""
return Liste_Simplement_Chainee()
def est_vide(liste):
"""
Tester si la liste simplement chainee est vide.
Parameters
----------
liste : Liste Simplement Chainee
Liste à tester.
Returns
-------
bool
Vrai ssi la liste est vide.
Effets de bord
--------------
Aucun
"""
return liste.est_vide()
def ajouter_en_tete(liste, element):
"""
Inserer un element en tete de liste simplemeent chainee.
Parameters
----------
liste : LSC
Liste à abonder.
element : type de donnee
Donnee à aouter.
Returns
-------
LSC, copie de liste à laquelle element a été ajouté en tete.
Effets de bord
--------------
Aucun
"""
return liste.ajouter_en_tete(element)
def tete(liste):
"""
Consulter la tete de liste.
Parameters
----------
liste : LSC
Liste à consulter.
Returns
-------
type de donnée
valeur de la tete de liste.
Effets de bord
--------------
Aucun
"""
return liste.tete()
def queue(liste):
"""
Renvoyer la liste sans sa tete.
Parameters
----------
liste : LSC
Liste à étêter.
Returns
-------
LSC
Liste sans son maillon de tête.
Effets de bord
--------------
Aucun
"""
return liste.queue()
def afficher_liste(liste, taille=-1):
"""
Afficher la liste en format de présentation.
Parameters
----------
liste : LSC
Liste à énumérer.
Returns
-------
None.
Effets de bord
--------------
Affichage à l'écran.
"""
reste = liste
compteur = 0
print('+-----\n|')
while not(est_vide(reste)) and (taille == -1 or compteur < taille):
print('+- {}\n|'.format(str(tete(reste))))
reste = queue(reste)
compteur += 1
print('+-----')
return None
# ############################################################################
class Maillon(object):
"""
Classe des Maillons d'une Liste Simplement Chainee.
Attributs
- donnee : donnee stockee dans le maillon
- suite : liste simplemement chainee suivant le maillon
"""
def __init__(self, donnee=None, suite=Liste_Simplement_Chainee()):
"""
Construire une instance de la classe des Maillons.
Parameters
----------
donnee : type de donnee, optional
Donnee initiale dans le Maillon. The default is None.
suite : LSC, optional
Sous-liste suivant le Maillon courant.
The default is Liste_Simplement_Chainee().
Returns
-------
None.
"""
self.donnee = donnee
self.suite = suite
return None
# ############################################################################

55
tp6_self/Pile_LSC.py Normal file
View File

@@ -0,0 +1,55 @@
import LSC as lsc
# Chacune des fonctions renvoie et n'ont pas d'effet de bord
def creer_pile_vide():
"""Creer une pile vide.
Returns:
lsc.Liste_Simplement_Chainee: La liste vide
"""
return lsc.creer_liste_vide()
def est_pile_vide(pile: lsc.Liste_Simplement_Chainee):
"""Retourne True si la pile est vide, False sinon.
Args:
pile (lsc.Liste_Simplement_Chainee): La pile à tester
Returns:
bool: True si la pile est vide
"""
return lsc.est_vide(pile)
def sommet(pile: lsc.Liste_Simplement_Chainee):
"""Retourne le sommet de la pile.
Args:
pile (lsc.Liste_Simplement_Chainee): La pile avec le sommet
Returns:
any: Le sommet de la pile
"""
assert not est_pile_vide(pile), "La pile est vide"
return lsc.tete(pile)
def empiler(pile: lsc.Liste_Simplement_Chainee,elt: any):
"""Ajoute un element en tete de la pile
Args:
pile lsc.Liste_Simplement_Chainee: La pile à modifier
elt any: l'element a ajouter
Returns:
lsc.Liste_Simplement_Chainee : La pile avec l'element ajouté
"""
return lsc.ajouter_en_tete(pile, elt)
def depiler(pile: lsc.Liste_Simplement_Chainee):
"""Retire le sommet de la pile
Args:
pile (lsc.Liste_Simplement_Chainee): La pile avec le sommet
Returns:
lsc.Liste_Simplement_Chainee: La pile avec le sommet retiré
"""
assert not est_pile_vide(pile), "La pile est vide"
return lsc.queue(pile)

54
tp6_self/Pile_List.py Normal file
View File

@@ -0,0 +1,54 @@
# Chacune des fonctions renvoie et n'ont pas d'effet de bord
def creer_pile_vide()->list:
"""Créer une pile vide.
Returns:
list: La pile vide
"""
return []
def est_pile_vide(pile: list) -> bool:
"""Retourne True si la pile est vide, False sinon.
Args:
pile (list): La pile à tester
Returns:
bool: True si la pile est vide
"""
return len(pile) == 0
def sommet(pile: list)->int:
"""Retourne le sommet de la pile.
Args:
pile (list): La pile avec le sommet
Returns:
any: le sommet de la pile
"""
assert not est_pile_vide(pile), "La pile est vide"
return pile[-1]
def empiler(pile: list, elt: any)-> list:
"""rajoute elt au sommet de la pile
Args:
pile (list): La pile à modifier
elt (any): l'élement à ajouter
Returns:
list: la pile modifiée
"""
return pile + [elt]
def depiler(pile: list)-> any:
"""retourne la pile sans le sommet
Args:
pile (list): la pile avec le sommet
Returns:
any: la pile sans le sommet
"""
assert not est_pile_vide(pile), "La pile est vide"
return pile[:-1]

54
tp6_self/Pile_Tuple.py Normal file
View File

@@ -0,0 +1,54 @@
# Chacune des fonctions renvoie et n'ont pas d'effet de bord
def creer_pile_vide() -> tuple:
"""Créer une pile vide.
Returns:
Tuple: La pile vide
"""
return ()
def est_pile_vide(pile: tuple) -> bool:
"""Retourne True si la pile est vide, False sinon.
Args:
pile (tuple): La pile à tester
Returns:
bool: True si la pile est vide
"""
return len(pile) == 0
def sommet(pile: tuple) -> any:
"""Renvoie le sommet de la pile.
Args:
pile (tuple): La pile contenant le sommet
Returns:
any: Le sommet de la pile
"""
return pile[-1]
def empiler(pile: tuple, elt: any)-> tuple:
"""ajoute elt au sommet de la pile
Args:
pile (tuple): la pile a modifier
elt (any): l'élement à ajouter
Returns:
tuple: la pile avec l'élement ajouté
"""
return pile + (elt,)
def depiler(pile: tuple) -> tuple:
"""Retire le sommet de la pile
Args:
pile (tuple): La pile avec le sommet
Returns:
tuple: La pile avec le sommet retiré
"""
assert not est_pile_vide(pile), "La pile est vide"
return pile[:-1]

133
tp6_self/README.md Normal file
View File

@@ -0,0 +1,133 @@
# **README - DM Piles et NPI**
## **Comment exécuter le programme :**
1. Verfier que tous les fichiers sont dans le même répertoire :
- `test.py`
- `Pile_Tuple.py`
- `Pile_LSC.py`
- `Pile_Liste.py`
- `npi.py`
2. Ouvrez un terminal dans ce répertoire.
3. Exécutez le programme avec la commande suivante :
```bash
python3 test.py
```
ou executer pour la notation polonaise inverse:
```bash
python3 npi.py
```
---
## **Fonctions disponibles et leur utilisation :**
### 1. **`creer_pile_vide()`**
- **Description** : Crée et renvoie une pile vide.
- **Utilisation** :
```python
pile = creer_pile_vide()
```
---
### 2. **`est_pile_vide(pile)`**
- **Description** : Vérifie si une pile est vide.
- **Paramètre** :
- `pile` : La pile à vérifier.
- **Retour** : Renvoie `True` si la pile est vide, sinon `False`.
- **Utilisation** :
```python
if est_pile_vide(pile):
print("La pile est vide.")
```
---
### 3. **`sommet(pile)`**
- **Description** : Retourne lélément au sommet de la pile sans le retirer.
- **Paramètre** :
- `pile` : La pile à consulter.
- **Retour** : Lélément au sommet de la pile.
- **Utilisation** :
```python
print(sommet(pile))
```
---
### 4. **`empiler(pile, elt)`**
- **Description** : Ajoute un élément au sommet de la pile.
- **Paramètres** :
- `pile` : La pile à modifier.
- `elt` : Lélément à empiler.
- **Retour** : La nouvelle pile avec lélément ajouté.
- **Utilisation** :
```python
pile = empiler(pile, 5)
```
---
### 5. **`depiler(pile)`**
- **Description** : Retire lélément au sommet de la pile.
- **Paramètre** :
- `pile` : La pile à modifier.
- **Retour** : La pile sans lélément au sommet.
- **Utilisation** :
```python
pile = depiler(pile)
```
---
### 6. **`hauteur_pile(pile)`**
- **Description** : Renvoie le nombre d'éléments présents dans la pile sans la modifier.
- **Paramètre** :
- `pile` : La pile à analyser.
- **Retour** : La hauteur de la pile (nombre d'éléments).
- **Utilisation** :
```python
print(hauteur_pile(pile))
```
---
### 7. **`max_pile(pile, i)`**
- **Description** : Trouve le maximum parmi les `i` premiers éléments de la pile.
- **Paramètres** :
- `pile` : La pile à analyser.
- `i` : Le nombre d'éléments à prendre en compte depuis le sommet.
- **Retour** : Le maximum trouvé parmi les `i` éléments.
- **Utilisation** :
```python
print(max_pile(pile, 3))
```
---
### 8. **`retourner(pile, j)`**
- **Description** : Inverse lordre des `j` premiers éléments de la pile.
- **Paramètres** :
- `pile` : La pile à modifier.
- `j` : Le nombre d'éléments à inverser.
- **Retour** : La pile modifiée.
- **Utilisation** :
```python
pile = retourner(pile, 2)
```
---
### 9. **`tri_crepes_recursif(pile)`**
- **Description** : Trie une pile en suivant le tri des crêpes.
- **Paramètre** :
- `pile` : La pile à trier.
- **Retour** : La pile triée.
- **Utilisation** :
```python
pile = tri_crepes_recursif(pile)
```
<hr>
Cela conclut la documentation des fonctions. Pour toute question, consultez le fichier **test.py** pour des exemples plus détaillés.
pour toutes questions: elouan.fare@protonmail.ch

44
tp6_self/npi.py Normal file
View File

@@ -0,0 +1,44 @@
def npi(exp: str) -> float:
"""Calcule une expression arithmétique en NPI (notation polonaise inverse).
Args:
exp (str): L'expression arithmétique à calculer.
Returns:
float: Le résultat de l'expression.
"""
assert exp, "L'expression est vide."
pile = []
for token in exp.split():
if token in "+-*/":
if len(pile) < 2:
print("Erreure : Pas assez d'opérandes.")
return None
b, a = pile.pop(), pile.pop()
match token:
case '+': pile.append(a + b)
case '-': pile.append(a - b)
case '*': pile.append(a * b)
case '/':
if b == 0:
print("Erreur : Division par zéro.")
return None
pile.append(a / b)
elif token.replace('.', '', 1).isdigit(): # isdigit verifie si 'token' est un nombre ou un chiffre
pile.append(float(token))
else:
print(f"erreur : '{token}' n'est pas un opérande valide.")
return None
if len(pile) != 1:
print("erreur : Expression mal formée.")
return None
return pile[0] # On aurait pu mettre pile[-1]
if __name__ == "__main__":
# Test
exp = "3 4 + 5 * 2 /" # correspond a (3+4)(5/2) soit 7 * 2.5 = 17.5
print(npi(exp))

160
tp6_self/test.py Normal file
View File

@@ -0,0 +1,160 @@
#!/usr/bin/python3
import LSC as lsc
import Pile_List as lifo
from random import shuffle
from typing import List, Tuple, Union, TypeVar, Any
T = TypeVar('T')
PileType = Union[List[T], Tuple[T,...], lsc.Liste_Simplement_Chainee]
#----------------------------------------------------------------
# Aucun effet de bord sur les fonctions ajoutés car je n'y suis pas arrivé
#----------------------------------------------------------------
def afficher(pile):
print("|----\n|")
while not(lifo.est_pile_vide(pile)):
print(f"| {lifo.sommet(pile)}\n|")
pile = lifo.depiler(pile)
print("|----")
return None
def hauteur_pile(pile: PileType) -> int:
"""Retourne la taille/ hauteur de la pile
Args:
pile (list/tuple/lsc.Liste_Simplement_Chainee): la pile a mesurer
Returns:
int: la taille de la pile
"""
n = 0
while not(lifo.est_pile_vide(pile)):
n += 1
pile = lifo.depiler(pile)
return n
def copie(pile: PileType) -> PileType:
"""creer une copie de la pile
Args:
pile (PileType): pile a copier
Returns:
PileType: une copie de la pile
"""
pile_copie = lifo.creer_pile_vide()
while not(lifo.est_pile_vide(pile)):
pile_copie = lifo.empiler(pile_copie, lifo.sommet(pile))
pile = lifo.depiler(pile)
return pile_copie
def max_pile(pile: PileType,start: int)-> int:
"""Retourne l'element le plus grand de la pile
Args:
start: int: la position de départ de la recherche
pile: PileType: la pile a analyser
Returns:
int: l'indice de l'element le plus grand de la pile
"""
assert start >=0, "Position de départ invalide"
assert hauteur_pile(pile) >= start, "Position de départ dépasse la taille de la pile"
assert not(lifo.est_pile_vide(pile)), "La pile est vide"
pile2 = copie(copie(pile)) # <--- pas très propre c'est pour renverser la copie qui a été renversé
# J'itère jusqu' a start:
max_n = lifo.sommet(pile)
for _ in range(start):
sommet = lifo.sommet(pile2)
pile2 = lifo.depiler(pile2)
if sommet > max_n:
max_n = sommet
pile2 = copie(copie(pile))
# je cherche l'index du max dans pile2
for i in range(start):
i+=1
if lifo.sommet(pile2) == max_n:
return i
else:
pile2 = lifo.depiler(pile2)
def retourner(pile: PileType, j: int) -> PileType:
"""retourne la pile avec les j premiers éléments renversés.
Args:
pile (PileType): la pile
j (int): l'index a renverser
Returns:
PileType: la pile renversée
"""
pile1 = copie(copie(pile))
pile2 = lifo.creer_pile_vide()
# je déplace les j premiers éléments de pile1 dans pile2
for _ in range(j):
sommet = lifo.sommet(pile1)
pile1 = lifo.depiler(pile1)
pile2 = lifo.empiler(pile2, sommet)
# renverse Pile 2
pile2 = copie(pile2)
#ajoute pile2 a pile1
while not(lifo.est_pile_vide(pile2)):
sommet = lifo.sommet(pile2)
pile1 = lifo.empiler(pile1,sommet)
pile2 = lifo.depiler(pile2)
pile = lifo.creer_pile_vide()
# remplace Pile par Pile1
while not(lifo.est_pile_vide(pile1)):
sommet = lifo.sommet(pile1)
pile = lifo.empiler(pile, sommet)
pile1 = lifo.depiler(pile1)
return copie(pile)
def tri_crepes(pile: PileType) -> PileType:
"""tri la pile en utilisant 'pancakes sort'
Args:
pile (PileType): la pile a trier
Returns:
PileType: la pile triée
"""
n = hauteur_pile(pile)
while n > 1:
index_max = max_pile(pile, n)
pile = retourner(pile,index_max)
pile = retourner(pile,n)
n-=1
return (pile)
if __name__ == "__main__":
ma_liste = [_ for _ in range(10)]
shuffle(ma_liste)
print("Liste de départ : ", ma_liste)
ma_pile = lifo.creer_pile_vide()
print("\nEMPILEMENT\n")
for element in ma_liste:
ma_pile = lifo.empiler(ma_pile, element)
j = 4
print("\nTaille de la pile : ", hauteur_pile(ma_pile))
print(f"Element le plus grand de la pile à partir de l'index {j}: {max_pile(ma_pile,4)}")
pile = retourner(ma_pile, j)
hauteur_pile(ma_pile)
afficher(pile)
print("\nDEPILEMENT\n")
pile_triee = tri_crepes(ma_pile)
afficher(pile_triee)
while not(lifo.est_pile_vide(ma_pile)):
print(f"Sommet : {lifo.sommet(ma_pile)}")
ma_pile = lifo.depiler(ma_pile)
afficher(ma_pile)