# -------------------------------------------------
# Implémentation du type de données abstrait : pile
# -------------------------------------------------

from collections import deque


class Pile:
    """
    Classe pile implémentée avec les listes doublement chainées
    du module deque.
    """

    def __init__(self):
        """
        Création d'une pile vide
        """
        self.item = deque()


    def __str__(self):
        """
        Modification de l'affichage par défaut avec print
        """
        if self.est_vide():
            return("Pile vide")
        else:
            str_pile = 'bas'
            for e in self.item:
                str_pile = str_pile + ' | ' + str(e)
            str_pile = str_pile + ' | haut'
            return str_pile


    def est_vide(self):
        """
        Renvoie True si la pile est vide, False sinon
        """
        return not(self.item)


    def empiler(self, x):
        """
        Ajoute l'élément x au sommet de la pile
        """
        self.item.append(x)


    def depiler(self):
        """
        Dépile en renvoyant l'objet
        """
        if self.est_vide():
            print("Erreur : tentative de dépilement d'une pile vide")
        else:
            return self.item.pop()

    def sommet(self):
        """
        Renvoie le sommet d'une pile sans la modifier
        """
        if self.est_vide():
            print("Erreur : tentative d'accès au sommet d'une pile vide")
        else:
            return self.item[-1]


# -----------------------------------------------
if __name__ == "__main__":

    a = Pile()
    assert a.est_vide() == True
    a.empiler(1)
    a.empiler(2)
    a.empiler(3)
    assert a.est_vide() == False
    x = a.depiler()
    assert x == 3
    assert a.sommet() == 2
    x = a.depiler()
    assert x == 2
    a.empiler(a.depiler())
    assert a.sommet() == 1
    a.depiler()
    assert a.est_vide() == True




# -------------------------------------------------
# Implémentation du type de données abstrait : file
# -------------------------------------------------

from collections import deque


class File:
    """
    Classe file implémentée avec les listes doublement chainées
    du module deque.
    """

    def __init__(self):
        """
        Création d'une file vide
        """
        self.item = deque()


    def __str__(self):
        """
        Modification de l'affichage par défaut avec print
        """
        if self.est_vide():
            return("File vide")
        else:
            str_file = 'entrée'
            for e in self.item:
                str_file = str_file + ' | ' + str(e)
            str_file = str_file + ' | sortie'
            return str_file


    def est_vide(self):
        """
        Renvoie True si la file est vide, False sinon
        """
        return not(self.item)


    def enfiler(self, x):
        """
        Enfile l'élément x dans la file
        """
        self.item.appendleft(x)


    def defiler(self):
        """
        Dépile en renvoyant l'objet
        """
        if self.est_vide():
            print("Erreur : tentative de défilement d'une file vide")
        else:
            return self.item.pop()


# -----------------------------------------------
if __name__ == "__main__":

    a = File()
    assert a.est_vide() == True
    a.enfiler(1)
    a.enfiler(2)
    a.enfiler(3)
    assert a.est_vide() == False
    x = a.defiler()
    assert x == 1
    x = a.defiler()
    assert x == 2

