Aller au contenu

Bibliothèque standard de Python

Les exercices illustrant ce chapitre peuvent se retrouver sur la page correspondante

La bibliothèque standard de Python est particulièrement fournie, en comparaison d'autres langages, comme le C++. Explorons quelques-un de ses modules.

random : l'aléatoire

Nous avons déjà vu une petite partie du module random, qui permet de générer des nombres aléatoires (ou plutôt pseudo-aléatoires, qui ressemblent à une génération aléatoires, et qui est suffisante dans la plupart des cas.).

La fonction randint prends deux paramètres a et b et renvoie un nombre aléatoire entre a et b inclus.

from random import randint

print(randint(5, 20))
Pourra produire comme sortie :
11

Implantez le corps de la fonction suivante :

def tirer_des(a, b, n): 
    """a, b, n des entiers >= 1,
    génère n entiers compris entre a et b inclus, et affiche les résultats. 
    """
N'oubliez pas d'importer les modules et fonctions dont vous aurez besoin !

Affichage possible (1):

tirer_des(1, 6, 2)
Peut produire :
5
6

Autre affichage possible (2):

tirer_des(1, 6, 2)
Peut produire :
5 6

vous aurez besoin de la fonction randint du module random.

Nous avons déjà abordé ce module dans le chapitre précédent, à la section des modules et des bibliothèques.

Vous aurez aussi sans doute besoin d'une boucle while

from random import randint

def tirer_des(a, b, n): 
    """a, b, n des entiers >= 1,
    génère n entiers compris entre a et b inclus, et affiche les résultats. 
    """

    i = 0
    while i < n: 
        print(randint(a,b))
        i = i + 1        
from random import randint

def tirer_des(a, b, n): 
    """a, b, n des entiers >= 1,
    génère n entiers compris entre a et b inclus, et affiche les résultats. 
    """

    r = ""
    i = 0
    while i < n:
        r = r + str(randint(a, b)) + " "
        i = i + 1        
    print(r)

L'aléatoire a de nombreuses applications en informatique, entre autres :

  • Dans les jeux vidéos, l'aléatoire permet d'introduire des variations qui créent suspens et aventure, forçant le joueur à s'adapter ou à essayer d'anticiper: La génération d'environnements dans Minecraft1, la progression dans les roguelikes comme Dead Cells, ou encore les effets des capacités dans Dofus3.
  • Certains problèmes informatiques sont très difficiles à résoudre sans un algorithme utilisant l'aléatoire. Un exemple est le PageRank4 de Google.
  • Dans la création artistique, laisser la responsabilité de l'aléatoire à l'ordinateur peut alléger considérablement la charge de travail de l'artiste.
  • De nombreuses application scientifiques modèlisent des phénomènes aléatoires.

Toutefois, l'aléatoire pose aussi un problème de reproducibilité : deux appels similaires à une même fonction peuvent donc produire des résultats différents. Celà rends plus difficile le débuggage et l'étude des résultats produit par un programme.

Le module random nous fournis une aide pour pallier à ce problème : la fonction seed (graine), qui prends un entier ou une chaîne de caractères en paramètre, et l'utilise comme base pour générer des nombres aléatoires. Les nombres générés à partir d'une même graine sont toujours les même dans une version de Python donnée.

from random import randint, seed

def tirer_des(a, b, n): 
    """a, b, n des entiers >= 1,
    génère n entiers compris entre a et b inclus, et affiche les résultats. 
    """

    r = ""
    i = 0
    while i < n:
        r = r + str(randint(a, b)) + " "
        i = i + 1        
    print(r)

if __name__=="__main__":
    seed(10)
    tirer_des(1, 6, 10)
    seed(10)
    tirer_des(1, 6, 10)
    seed(12)
    tirer_des(1, 6, 10)

Affiche :

5 1 4 4 5 1 2 4 4 3 
5 1 4 4 5 1 2 4 4 3 
4 3 6 5 6 3 2 4 1 3

En général, on donne une valeur à la graine avant une grande séquence de traitements aléatoires dans le programme :

  • Au début du programme
  • Au lancement d'une partie de jeu
  • Au moment la génération d'un monde dans le jeu
  • Au début d'une simulation scientifique
  • ...

Remarque

Dans Minecraft, quand on crée un nouveau monde, dans l'interface il y a un champs "graine de génération du monde" ou "seed". Celà corresponds à la graine de génération aléatoire que nous avons vu ici !

Le module random fournis de nombreuses autres fonctions, comme la fonction random pour générer des flottants. Vous pouvez aller voir sa documentation pour plus d'information.

string et str : les chaînes

La plupart des opérations sur les chaînes de caractères dites natives en Python: elles sont automatiquement importées par Python, et on n'a pas besoin de les importer sous forme d'un module.

Les opérations sur les chaînes sont en majorité sous forme de méthodes, c'est à dire des fonctions qui font partie d'un type, ici le type str. On appelle une méthode en utilisant l'opérateur .. Ici un exemple pour la méthode upper, qui retourne une copie de la chaîne où les lettres sont toutes en majuscules :

minuscules = "une chaine"
majuscules = minuscules.upper()
print(majuscules)

produit :

UNE CHAINE

On peut appeler une méthode directement sur une valeur :

majuscules = "une chaine".upper()
print(majuscules)

produit :

UNE CHAINE

Voici quelques exemples de transformations de chaîne :

méthode description Exemple d'appel exemple de résultat
upper Tout en majuscule "une chaine".upper() "UNE CHAINE"
lower Tout en minuscule UnE ChAiNe".lower() "une chaine"
capitalize Première lettre en majuscule "une chaine".capitalize() "Une chaine"
title Chaque groupe de lettres commence en majuscule "il s'arrete".title() "Il S'Arrete"
capwords Chaque mot commence en majuscule "il s'arrete".capwords() "Il S'arrete"

La méthode replace prends deux chaînes a et b en paramètres, et remplace toutes les occurrences de a dans la chaîne par des occurrences de b.

chaine_chats = "Les chats sont très mignons. Les chats sont très doux. Les chats aiment jouer."
chaine_lapins = chaine_chats.replace("chats", "lapins")
print(chaine_lapins)

produit :

Les lapins sont très mignons. Les lapins sont très doux. Les lapins aiment jouer.

La méthode isdecimal renvoie un booléen qui vaut True si la chaine est composée de chiffres de 0 à 9, False sinon.

"010404".isdecimal() ## retourne True
"10.2".isdecimal() ## retourne False
"mot".isdecimal() ## retourne False

Il existe de nombreuses autres méthodes de manipulations des chaines. Elles peuvent être trouvées dans la documentation du type str.

les fichiers

Voici un exemple de programme en Python qui ouvre un fichier texte exemple_fichier.txt et en affiche le contenu :

exemple_fichier.py
1
2
3
4
fichier = open("exemple_fichier.txt")
contenu = fichier.read()
fichier.close()
print(contenu)
exemple_fichier.txt
je suis un fichier d'exemple, 
qui sera affiché par le programme

Créez ces deux fichiers dans le même dossier. Executez ensuite le fichier Python. Vous devriez obtenir la sortie suivante :

je suis un fichier d'exemple, 
qui sera affiché par le programme

Attention

Il se peut que vous obteniez une erreur de ce style :

Traceback (most recent call last):
File "/home/felix/exemple_fichier.py", line 1, in <module>
    fichier = open("exemple_fichier.txt")
FileNotFoundError: [Errno 2] No such file or directory: 'exemple_fichier.txt'

Dans ce cas-là, ne restez pas bloqué et demandez de l'aide au professeur !

Etudions un peu ce programme.

Fonction open

En Python, la manipulation de fichiers est en parti assurée par une fonction native : open5 (ligne 1).

Cette fonction prends 2 arguments :

  • une chaîne de caractères qui représente le chemin vers un fichier
  • une chaîne de caractères qui représente le mode d'ouverture du fichier, c'est à dire si on veut lire ('r') ou écrire ('w') dans le fichier. On peut ne pas fournir cet argument, et le fichier sera alors ouvert en lecture par défaut.

Elle retourne une valeur de type file (fichier).

Chemin vers un fichier : os.path

Un chemin (en anglais path) vers un fichier est le nom d'un fichiers et les dossiers successifs dans lesquels il se trouve.

images/chats/trop_mignon.png

Corresponds à une image appelée trop_mignon.png, qui se trouve dans un dossier chats, qui lui-même se trouve dans un dossier images.

Les chemins peuvent être absolus ou relatifs, c'est à dire prendre pour référence la racine du système de fichier (un dossier contenu dans aucun autre dossier), ou le dossier dans lequel le programme est éxécuté.

La manière d'exprimer un chemin varie en fonction du système d'exploitation :

La racine du système se note /.

Les dossiers sont séparés par des slash /.

Exemple de chemin absolu :

/home/felix/images/chats/trop_mignon.png

Exemple de chemin relatif :

images/chats/trop_mignon.png

La racine du système se note avec la lettre d'un disque dur suivie de deux points C:

Les dossiers sont séparés par des antislash \

Exemple de chemin absolu :

C:\Users\felix\images\chats\trop_mignon.png

Exemple de chemin relatif :

images\chats\trop_mignon.png

Pour ne pas avoir de problèmes de compatibilité, quand on manipulera des chemins de fichiers, on le fera par le biais de la fonction normpath du module os.path, qui prends en argument un chemin POSIX (Linux), et retourne le chemin au format Windows si le programme Python s'execute sous Windows.

from os.path import normpath
chemin_posix = "images/chats/trop_mignon.png"
chemin_adapte = normpath(chemin_posix)
print(chemin_adapte) 

Sous Linux, le programme affiche :

images/chats/trop_mignon.png

Sous Windows, le programme affichera probablement :

images\chats\trop_mignon.png

Les chemins relatifs sont exprimés à partir du dossier où le programme Python est exécuté. Par défaut dans Thonny et EduPython, quand vous executez un fichier Python il est exécuté dans le dossier où il se trouve. Dans ce cours, il vous sera demandé, sauf mention contraire, de placer les fichiers à lire dans le même dossier que les fichiers Python qui les traitent, pour plus de simplicité.

Le module os.path contient de nombreuses autres fonction, par exemple pour vérifier si un fichier existe. Elles sont listées dans https://docs.python.org/fr/3/library/os.path.html

Type fichier, structure with

La fonction open retourne une valeur de type file, qui représente un fichier. Le type fichier a de nombreuses méthodes, mais pour l'instant, il n'y en a que deux qui nous intéressent :

read, qui ne prends aucun argument, et retourne le contenu du fichier sous forme d'une chaîne de caractères.

close, qui ne prends aucun argument, et ferme le fichier. Elle est à appeler une fois qu'on a fait toutes les opérations qu'on voulait sur le fichier. Il est crucial de penser à l'appeler, sinon on peut avoir des erreurs d'écritures ou de lecture !

Comme appeler penser à appeler close est compliqué, on va plutôt passer par une structure de contrôle spéciale, le with, qui va s'occuper de fermer automatiquement le fichier quand nous n'en avons plus besoin. Elle se présente comme suit :

with open("cheminverslefichier") as nomvariable :
    ## opérations indentées sur le fichier
    ## a la fin du bloc indenté, le fichier est fermé

Si on veut lire le fichier comme dans l'exemple, on écrira donc :

from os.path import normpath

with open(normpath("exemple_fichier.txt")) as f:
    contenu = f.read()

print(contenu)

Qui produit la même sortie :

je suis un fichier d'exemple, 
qui sera affiché par le programme

  1. Jeu non libre développé par Mojang. Des alternatives libres existent, comme le mod Minetest Mineclone 2 https://content.minetest.net/packages/Wuzzy/mineclone2/ 

  2. Roguelike non libre développé par Motion Twin, un studio indépendant français. 

  3. MMORPG non libre développé par Ankama, un studio français 

  4. https://patents.google.com/patent/US7058628B1/en 

  5. https://docs.python.org/3/library/functions.html#open