# TP n°15 - Manipulation de piles

CGRAS  = '\033[1m'
CEND   = '\x1b[0m'
CGREEN = "\x1b[36m"
CRED   = "\x1b[35m"

## Question 01 - Fonction empiler

def empiler(P,x):
    """ Spécifications de la fonction empiler
    Entrée: - P de type list représentant une pile
            - x un objet de type quelconque
    Sortie: - None
    Rôle  : - ajoute l'élément x au sommet de la pile P
    """
    P.append(x)

# Exemples question 01
print(CGRAS+CGREEN+"-"*60+CEND)
print(CGRAS+CGREEN+"Exemples question 01 :"+CEND)
P = []
print("Création de la pile vide P =",P)
empiler(P,3); empiler(P,12)
print(CRED+"Exécution de >>> empiler(P,3); empiler(P,12)"+CEND)
print("P =",P)
empiler(P,31)
print(CRED+"Exécution de >>> empiler(P,31)"+CEND)
print("P =",P)
print(CGRAS+CGREEN+"-"*60+CEND)


## Question 02 - Fonction estVide

def estVide(P):
    """
    Entrée: - P de type list représentant une pile
    Sortie: - booléen indiquant si la liste P est vide (True) ou non (False)
    """
    return P == []

## Exemples question 02

print(CGRAS+CGREEN+"-"*60+CEND)
print(CGRAS+CGREEN+"Exemples question 02 :"+CEND)
Q = []
print("Création de la pile vide Q =",Q)
print(CRED+"Exécution de >>> estVide(P)"+CEND)
print(estVide(P))
print(CRED+"Exécution de >>> estVide(Q)"+CEND)
print(estVide(Q))
print(CGRAS+CGREEN+"-"*60+CEND)


## Question 03 - Fonction depiler

def depiler(P):
    """
    Entrée: - P de type list représentant une pile
    Sortie: - x un objet de type quelconque
    Rôle  : - supprime en renvoie l'élément x au sommet de la pile P
    """
    assert not estVide(P), "Votre pile est vide, impossible de dépiler !"
    return P.pop()

## Exemples question 03

print(CGRAS+CGREEN+"-"*60+CEND)
print(CGRAS+CGREEN+"Exemples question 03 :"+CEND)

print("Suppression de l'élément au sommet de P =",P)
depiler(P)
print(CRED+"Exécution de >>> x = depiler(P)"+CEND)
print("P =",P)

print("Suppression de l'élément au sommet de Q =",Q)
print(CGRAS+"DOIT PROVOQUER UNE erreur : commenter la ligne suivante !!"+CEND)
print(CRED+"Exécution de >>> depiler(Q)"+CEND)
#depiler(Q)
print(CGRAS+CGREEN+"-"*60+CEND)

## Question 04 - Fonction copier

def copier(P):
    """
    Entrée: - P de type list représentant une pile
    Sortie: - la pile Q copie de la pile P
    """
    T = []  # Pile de transitoire
    Q = []  # Doit contenir une copie de P

    while not estVide(P):
        x = depiler(P)
        empiler(T,x)

    while not estVide(T):
        x = depiler(T)
        empiler(P,x)
        empiler(Q,x)

    return Q

## Exemples question 04

print(CGRAS+CGREEN+"-"*60+CEND)
print(CGRAS+CGREEN+"Exemples question 04 :"+CEND)

P = [12,33,1,4,8,19,20]
print("Création d'une copie de P =",P)
print("Identifiant de P :",id(P))

print(CRED+"Exécution de >>> Q = copier(P)"+CEND)
Q = copier(P)
print("Q =",Q)
print("Identifiant de Q :",id(Q))
print("P =",P)
print("Identifiant de P :",id(P))
print(CGRAS+CGREEN+"-"*60+CEND)


## Question 05  - Fonction inverser

def inverser(P):
    """
    Entrée: - P de type list représentant une pile
    Sortie: - la pile Q contenant les éléments de la pile P en ordre inverse
    """
    Pprime = copier(P)  # copie de P
    Q = []

    while not estVide(Pprime):
        x = depiler(Pprime)
        empiler(Q,x)

    return Q

## Exemples question 05

print(CGRAS+CGREEN+"-"*60+CEND)
print(CGRAS+CGREEN+"Exemples question 05 :"+CEND)

P = [12,33,1,4,8,19,20]
print("Inverser la pile P =",P)
print("Identifiant de P :",id(P))

print(CRED+"Exécution de >>> Q = inverser(P)"+CEND)
Q = inverser(P)
print("Q =",Q)
print("Identifiant de Q :",id(Q))
print("P =",P)
print("Identifiant de P :",id(P))
print(CGRAS+CGREEN+"-"*60+CEND)

## Question 06  - Fonction tourner

def tourner(P):
    """
    Entrée: - P de type list représentant une pile
    Sortie: - la pile Q obtenue paar permutation circulaire des éléments de la pile
    """
    Pprime = copier(P)  # copie de P
    T = []              # pile transitoire
    Q = []              # doit contenir la permutation circulaire de P

    x = depiler(Pprime)
    empiler(Q,x)

    while not estVide(Pprime):
        x = depiler(Pprime)
        empiler(T,x)

    while not estVide(T):
        x = depiler(T)
        empiler(Q,x)

    return Q

## Exemples question 06

print(CGRAS+CGREEN+"-"*60+CEND)
print(CGRAS+CGREEN+"Exemples question 06 :"+CEND)

P = [12,33,1,4,8,19,20]
print("permutation circulaire de la pile P =",P)
print("Identifiant de P :",id(P))

print(CRED+"Exécution de >>> Q = tourner(P)"+CEND)
Q = tourner(P)
print("Q =",Q)
print("Identifiant de Q :",id(Q))
print("P =",P)
print("Identifiant de P :",id(P))
print(CGRAS+CGREEN+"-"*60+CEND)

## Question 07  - Fonction lastBeFirst

## Question 07  - Fonction lastBeFirst

def lastBeFirst(P):
    """
    Entrée: - P de type list représentant une pile
    Sortie: - Le premier (sommet) sera le dernier (base) et inversement
    """
    Pprime = copier(P)  # copie de P
    T = []              # pile transitoire
    Q = []              # doit contenir la pile obtenue en échangeant le sommet et la base de P

    y = depiler(Pprime)
    empiler(Q,y)        # devient la base de Q

    while not estVide(Pprime):
        x = depiler(Pprime)
        empiler(T,x)

    y = depiler(T)      # la base de P

    while not estVide(T):
        x = depiler(T)
        empiler(Q,x)

    empiler(Q,y)        # devient le sommet de Q

    return Q

## Exemples question 07

print(CGRAS+CGREEN+"-"*60+CEND)
print(CGRAS+CGREEN+"Exemples question 07 :"+CEND)

P = [12,33,1,4,8,19,20]
print("Echange sommet<-->base de la pile P =",P)
print("Identifiant de P :",id(P))

print(CRED+"Exécution de >>> Q = lastBeFirst(P)"+CEND)
Q = lastBeFirst(P)
print("Q =",Q)
print("Identifiant de Q :",id(Q))
print("P =",P)
print("Identifiant de P :",id(P))
print(CGRAS+CGREEN+"-"*60+CEND)

## Question 08 - Vérification de parenthésage

dicPFermantes = {  }


def verifPar(expression:str):
    pilePar    # Pile des parenthèses ouvrantes



    return True

## Exemples question 08

"""
print(CGRAS+CGREEN+"-"*60+CEND)
print(CGRAS+CGREEN+"Exemples question 08.a :"+CEND)

chaine1 = "2+3*[4*(1+5*(7+6)+8*{6+4}/5)+12]"
print("Vérification du parenthésage sur chaine1 =",chaine1)
test = verifPar1(chaine1)
assert(test),"Le résultat devrait être True, mais votre fonction renvoie False"
print(CGRAS+"Résultat de votre fonction --->",test,CEND)
print("Bravo, le test est réussi, la chaine est bien parenthésée")
print(CGRAS+CGREEN+"-"*60+CEND)

chaine2 = "aaa(kkk)(kkk)[lll)"
print("Vérification du parenthésage sur chaine2 =",chaine2)
test = verifPar1(chaine2)
assert(not test),"Le résultat devrait être False, mais votre fonction renvoie True"
print(CGRAS+"Résultat de votre fonction --->",test,CEND)
print("Bravo, le test est réussi ! La chaine est mal parenthésée")
print(CGRAS+CGREEN+"-"*60+CEND)

chaine3 = "aaa(kkk)(kkk)[lll"
print("Vérification du parenthésage sur chaine3 =",chaine3)
test = verifPar1(chaine3)
assert(not test),"Le résultat devrait être False, mais votre fonction renvoie True"
print(CGRAS+"Résultat de votre fonction --->",test,CEND)
print("Bravo, le test est réussi ! La chaine est mal parenthésée")
print(CGRAS+CGREEN+"-"*60+CEND)

chaine4 = "ss]ddd["
print("Vérification du parenthésage sur chaine3 =",chaine4)
test = verifPar1(chaine4)
assert(not test),"Le résultat devrait être False, mais votre fonction renvoie True"
print(CGRAS+"Résultat de votre fonction --->",test,CEND)
print("Bravo, le test est réussi ! La chaine est mal parenthésée")
print(CGRAS+CGREEN+"-"*60+CEND)
"""

## Question 09 - Notation polonaise inversée (NPI)

operateurs = ["+","-","*","/","//"]

def evalNPI(commande):
    saisiesClavier = commande.split()   # On transforme la commande saisie au clavier en liste
    pile = []

    # Boucle for

    assert True,"Un problème est survenu : plus d'opérateur"
    depiler(pile)
    assert True,"il reste des opérandes sans opérateur dans la pile : "+ str(pile)
    return 0

## Exemples question 09
"""
print(CGRAS+CGREEN+"-"*60+CEND)

commande1 = "1 4 5 6 + / +"
print(CGRAS+"Application de l'évaluateur en NPI à commande1 =",commande1,CEND)
res = evalNPI(commande1)
assert(res == 3.75),"Le résultat devrait être 3.75, mais votre fonction renvoie"+str(res)
print(CGRAS+CRED+"Résultat de votre fonction evalNPI --->",res,CEND)
print("Bravo, le test est réussi !")
print(CGRAS+CGREEN+"-"*60+CEND)

commande2 = "1 4 5 6 + // +"
print(CGRAS+"Application de l'évaluateur en NPI à commande2 =",commande2,CEND)
res = evalNPI(commande2)
assert(res == 3),"Le résultat devrait être 3, mais votre fonction renvoie "+str(res)
print(CGRAS+CRED+"Résultat de votre fonction evalNPI --->",res,CEND)
print("Bravo, le test est réussi !")
print(CGRAS+CGREEN+"-"*60+CEND)

commande3 = "1 4 + 5 6 + * -2 -"
print(CGRAS+"Application de l'évaluateur en NPI à commande3 = «",commande3,"»"+CEND)
res = evalNPI(commande3)
assert(res == -57),"Le résultat devrait être -57, mais votre fonction renvoie "+str(res)
print(CGRAS+CRED+"Résultat de votre fonction evalNPI --->",res,CEND)
print("Bravo, le test est réussi !")
print(CGRAS+CGREEN+"-"*60+CEND)

## Les lignes suivantes sont à décommenter une à une car elles provoquent des erreurs intentionnelles

commande4 = "1 4 + 5 6 + * -2 - +"
print(CGRAS+"Application de l'évaluateur en NPI à commande4 = «",commande4,"»"+CEND)
print(CRED+CGRAS+"Doit provoquer une erreur !!"+CEND)
#res = evalNPI(commande4)
print(CGRAS+CGREEN+"-"*60+CEND)

commande5 = "4 +"
print(CGRAS+"Application de l'évaluateur en NPI à commande5 = «",commande5,"»"+CEND)
print(CRED+CGRAS+"Doit provoquer une erreur !!"+CEND)
#res = evalNPI(commande5)
print(CGRAS+CGREEN+"-"*60+CEND)

commande6 = "1 2 4 +"
print(CGRAS+"Application de l'évaluateur en NPI à commande6 = «",commande6,"»"+CEND)
print(CRED+CGRAS+"Doit provoquer une erreur !!"+CEND)
#res = evalNPI(commande6)
print(CGRAS+CGREEN+"-"*60+CEND)


"""
