NSI Cours Terminale : File


Ce cours a été écrit grâce à une collaboration entre Pierre Brun, professeur de mathématiques et moi, Jared Asuncion. Il s'agit d'un cours de spécialité NSI pour des terminales générales.

Elles ont été initialement rédigées sous forme de notebooks Jupyter, mais nous les avons converties en HTML pour une meilleure lisibilité dans les browsers.

C'est un travail en cours de réalisation. N'hésitez pas à nous contacter à l'adresse mail nsi arobase guissmo point com pour tout commentaires, questions ou suggestions.

Auparavant

  • On a rencontrer des listes, un type d’objet qui peut être modifier par des fonctions comme .append() ou .pop().

Files

Une structure de file (penser à une file d’attente) est associée à la méthode First In, First Out (FIFO; premier arrivé, premier sorti).

Les éléments sont enfilés les uns à la suite des autres, et on ne peut toujours défiler que l’élément du haut de la file. Le premier élément à être arrivé est donc le premier à en sortir. Sinon ça râle dans la file d’attente.

Exemples de données stockées sous forme de file

Dans une file d’attente pour entrer dans un festival de musique, les festivaliers sont admis dans l’ordre d’arrivée. Le premier à arriver est le premier à entrer (« First In, First Out »). Les nouveaux arrivants se placent à la fin de la file et attendent leur tour pour entrer.

Dans une playlist musicale en mode lecture continue, les chansons sont jouées dans l’ordre où elles ont été ajoutées. La première chanson ajoutée sera jouée en premier (« First In, First Out »). Chaque nouvelle chanson ajoutée est placée à la fin de la liste et attend son tour pour être jouée.

Implémentation avec une liste

Dans cette partie, nous allons implémenter une classe File.

Exécuter l’instruction File() doit renvoyer un objet de la classe File qui représente une file vide.

En plus de sa méthode __init__, on va implémenter :

  • une méthode est_vide qui ne prend aucun argument et qui renvoie True si la file est vide. Sinon, elle renvoie False.

  • une méthode enfiler qui prend un argument x. Elle ajoute l’élément x au bout de la file.

  • une méthode defiler qui ne prend aucun argument. Elle enlève l’élément au début de la file et le renvoie.
    S’il n’existe pas, renvoie None.

  • sa méthode __str__ qui renvoie les éléments de la file du premier au dernier élément, séparés par des espaces.

  • sa méthode __len__ qui renvoie le nombre d’éléments dans la file.

class File:
    
    def __init__(self):
        self.contenu = ❓❓❓
        
    def est_vide(self):
        return ❓❓❓
    
    def enfiler(self, x):
        ❓❓❓
        
    def defiler(self):
        if self.est_vide():
            return None
        return self.contenu.pop(❓❓❓)
    
    def __str__(self):
        resultat = ❓❓❓
        for element in ❓❓❓:
            resultat = resultat + " " + ❓❓❓
        return resultat[1:]
    
    def __len__(self):
        return ❓❓❓
ma_file = File()
print( ma_file.defiler() ) # None
ma_file.enfiler(33)
ma_file.enfiler(44)
ma_file.enfiler('+')
print(ma_file) # 33 44 +
print(ma_file.defiler()) # 33
print(ma_file) # 44 +
print(len(ma_file)) # 2

Exercices

Gru dévoile son plan de voler la lune dans une scène de Moi, Moche et Méchant.

Dans cet exercice, nous allons explorer ce plan bien pensé en utilisant de files en Python.

Instanciez un objet de classe File et affectez-le à une variable appelée plan_gru.

Enfilez les quatre chaînes de caractères suivantes dans l’objet plan_gru :

  • Je m'empare de la lune.
  • Je rétrécis la lune.
  • Je pose la lune sur les toilettes.
  • Je vole jusqu'à la lune.

tel que si nous défilons les étapes de la file plan_gru, la première étape défilée serait Je vole jusqu'à la lune. puis Je rétrécis la lune. et ensuite Je m'empare de la lune. et enfin Je pose la lune sur les toilettes..

# ⚠️ Exécutez toujours les deux cellules précédentes avant de lancer ce test. ⚠️
print( plan_gru.defiler() ) # Je vole jusqu'à la lune.
print( plan_gru.defiler() ) # Je rétrécis la lune.
print( plan_gru.defiler() ) # Je m'empare de la lune.
print( plan_gru.defiler() ) # Je pose la lune sur les toilettes.

Rappelez-vous qu’une liste possède parmi ses méthodes .append() et .pop(). Nous pourrions représenter une file avec une liste sans écrire toute une classe.

Par exemple, nous pouvons initialiser file comme une liste vide.

file = []
  • Quelle méthode d’une liste pouvons-nous utiliser pour « enfiler » une valeur ?
  • Enfilez la valeur 1 puis 2 puis 3 à file.
  • Complétez les phrases suivantes en disant « tête » ou « queue » :
    • Le premier élément file[0] de la liste file représente la ❓❓❓ de la file qu’elle représente.
    • Le dernier élément file[-1] de la liste file représente la ❓❓❓ de la file qu’elle représente.
  • Quelle méthode d’une liste pouvons-nous utiliser pour « defiler » une valeur ?
  • Défilez un élément de file.
file.pop(❓❓❓)
print(file) # [2, 3]

Modifiez le code suivant afin qu’il renvoie la tête actuel de la file.

file[❓❓❓]

La fonction suivante prend un objet de la classe File.

def mystere(file):
    n = len(file)
    for i in range(n):
        x = file.defile()
        file.enfile(x)

Supposons qu’on appelle mystere(file) pour une file qui contient (du haut vers le bas) 111, 222 et 333 :

  • Que renverra mystere(file) ?
  • La taille de notre file originale change-t-elle ? Si oui, pourquoi ?
  • La fonction modifie-t-elle la file ? Si oui, de quelle manière la modifie-t-elle ?

Corrigez la fonction diviser suivante qui prend comme argument un objet File appelé file.

Elle distribue la file file dans deux files différentes : file1 et file2, de manière alternée. Par exemple, le premier élément de file va dans file1, le second élément va dans file2, le troisième dans file1, etc.

La fonction diviser retourne ensuite le tuple (file1, file2) après avoir vidé file.

def diviser(file):
    file_vide = File()
    file1 = file_vide
    file2 = file_vide
    count = 0
    while not file.est_vide():
        if count%2 == 0:
            file1.enfiler(file.defiler())
        else:
            file2.enfiler(file.defiler())
        count += 1
    return file1, file2
ma_file = File()
ma_file.enfiler(111)
ma_file.enfiler(222)
ma_file.enfiler(333)
ma_file.enfiler(444)
ma_file.enfiler(555)
print( ma_file ) # 111 222 333 444 555 
print( len(ma_file) ) # 5
ma_file1, ma_file2 = diviser(ma_file)
print( len(ma_file) ) # 0
print( ma_file1 ) # 111 333 555 
print( ma_file2 ) # 222 444 

Recopiez et modifiez File de sorte que __init__ ait un argument initiale, qui est une liste.

La file qu’on initialise doit alors contenir les éléments de initiale. Le premier élément de initiale sera la tête et son dernier élément sera la queue.

ma_file = File([66, 77, 88, 99])
print(ma_file) # 66 77 88 99 
ma_file.enfiler(100)
print(ma_file) # 66 77 88 99 100
ma_file.defiler()
ma_file.defiler()
print(ma_file.defiler()) # 88

Un robot a appris à griller de la viande pendant un barbecue.

Le robot recevra un ensemble d’instructions sous forme de file de tuples. Chaque élément de cette file est un tuple (a,b)(a, b) avec l’une des valeurs suivantes :

  • ('GRILLER', 'poulet'), ce qui signifie qu’il place un morceau de poulet sur le grill pour le cuire.
  • ('GRILLER', 'boeuf'), ce qui signifie qu’il place un morceau de boeuf sur le grill pour le cuire.
  • ('PRENDRE', 'poulet'), ce qui signifie qu’il retire un morceau de poulet du grill. S’il n’y a pas de poulet actuellement sur le grill, cette instruction est ignorée.
  • ('PRENDRE', 'boeuf'), ce qui signifie qu’il retire un morceau de boeuf du grill. S’il n’y a pas de boeuf actuellement sur le grill, cette instruction est ignorée.

Votre tâche dans cet exercice est d’écrire une fonction combien_sont_cuits, qui prend comme argument une file qui contient des instructions au format décrit ci-dessus. Elle doit traiter (et donc vider) la file et renvoyer un dictionnaire sous la forme {'boeuf': b, 'poulet': p}, où b représente le nombre de morceaux de boeuf et p le nombre de morceaux de poulet que le robot a cuits (c’est-à-dire retirés du grill), en suivant les instructions de la liste.

Vous pouvez vous référer aux exemples ci-dessous pour plus de clarté.

instructions = File()
instructions.enfiler(('GRILLER', 'boeuf'))
instructions.enfiler(('GRILLER', 'poulet'))
instructions.enfiler(('PRENDRE', 'boeuf'))
instructions.enfiler(('PRENDRE', 'poulet'))
print( combien_sont_cuits(instructions) ) # {'boeuf': 1, 'poulet': 1}
print( len(instructions) ) # 0
instructions.enfiler(('PRENDRE', 'boeuf'))
instructions.enfiler(('GRILLER', 'boeuf'))
instructions.enfiler(('GRILLER', 'poulet'))
instructions.enfiler(('PRENDRE', 'poulet'))
instructions.enfiler(('PRENDRE', 'poulet'))
instructions.enfiler(('GRILLER', 'boeuf'))
instructions.enfiler(('PRENDRE', 'boeuf'))
instructions.enfiler(('PRENDRE', 'boeuf'))
print( combien_sont_cuits(instructions) ) # {'boeuf': 2, 'poulet': 1}
print( combien_sont_cuits(instructions) ) # {'boeuf': 0, 'poulet': 0}