Pour chaque question, une seule réponse est correcte.
Question 1. On dispose d’un fichier outils.py contenant une fonction carre(n). Pour utiliser cette fonction depuis un autre fichier Python situé dans le même répertoire, on écrit :
include outilsimport outils puis outils.carre(5)import carre from outilsoutils.carre(5) directement, sans importCorrection publiée après la séance.
Question 2. Une docstring est :
#Correction publiée après la séance.
Question 3. Le module doctest permet de :
Correction publiée après la séance.
Question 4. Quelle est la différence entre import math et from math import sqrt ?
import math, on écrit math.sqrt(4) ; avec from math import sqrt, on écrit sqrt(4)from math import sqrt est plus lent car il charge tout le moduleimport math n’importe que la fonction math, pas le module entierCorrection publiée après la séance.
Question 5. Un paquet (package) Python est :
.py contenant plusieurs fonctions__init__.py et un ou plusieurs modules.zip contenant du code PythonpipCorrection publiée après la séance.
On dispose du module geometrie.py vu en cours, contenant les fonctions aire_cercle(rayon), perimetre_cercle(rayon) et aire_rectangle(longueur, largeur).
Écrire un programme qui importe le module geometrie et affiche l’aire et le périmètre d’un cercle de rayon 7.
Après import geometrie, chaque fonction du module s’appelle avec le nom du module devant, en notation pointée.
Réécrire le même programme en n’important que les fonctions aire_cercle et perimetre_cercle. Quelle syntaxe faut-il utiliser ?
Relire dans le cours la seconde forme d’importation, celle qui nomme les fonctions à importer : comment s’appellent-elles ensuite ?
Que se passe-t-il si on écrit from geometrie import * ? Pourquoi cette pratique est-elle déconseillée ?
Que se passerait-il si le programme, ou un autre module importé de la même façon, définissait déjà une fonction du même nom ? En lisant le code, sait-on encore d’où vient chaque fonction ?
Écrire l’instruction permettant d’afficher la documentation de la fonction aire_cercle depuis l’interpréteur Python.
La fonction help affiche la docstring de ce qu’on lui passe : un module, ou l’une de ses fonctions en notation pointée.
Correction publiée après la séance.
doctest :def est_palindrome(mot):
"""
___________________________________
>>> est_palindrome("kayak")
____
>>> est_palindrome("python")
____
"""
return mot == mot[::-1]
La description dit en une phrase ce que renvoie la fonction. Sous chaque ligne >>>, écrire exactement ce que Python afficherait pour cet appel : ici un booléen.
Écrire une fonction pgcd(a, b) qui calcule le PGCD de deux entiers par l’algorithme d’Euclide. Ajouter une docstring complète avec au moins trois exemples, dont un cas limite (par exemple pgcd(0, 5)).
Algorithme d’Euclide : tant que b n’est pas nul, remplacer le couple (a, b) par (b, a % b) ; le PGCD est alors la valeur de a. Pour les exemples, choisir des couples dont on connaît le PGCD, comme 48 et 18.
Écrire le code permettant de lancer les tests doctest sur ces deux fonctions.
Le module doctest fournit la fonction testmod, qui exécute tous les exemples des docstrings du fichier : importer le module, puis appeler cette fonction.
Correction publiée après la séance.
On souhaite créer un module stats.py contenant les fonctions suivantes, chacune documentée avec une docstring et des exemples doctest :
moyenne(liste) : retourne la moyenne arithmétique d’une liste de nombres.
sum(liste) donne la somme des éléments et len(liste) leur nombre. Pour les exemples, choisir une liste dont on connaît la moyenne de tête, comme [10, 20, 30].
variance(liste) : retourne la variance de la liste, définie par $\frac{1}{n}\sum_{i=1}^{n}(x_i - \bar{x})^2$ où $\bar{x}$ est la moyenne.
Calculer d’abord la moyenne m avec la fonction précédente, puis la moyenne des carrés des écarts (x - m) ** 2.
def variance(liste):
"""Renvoie la variance de la liste.
>>> variance([5, 5, 5])
0.0
"""
m = moyenne(liste)
total = 0
for x in liste:
total = total + ...
return ...
ecart_type(liste) : retourne l’écart type (racine carrée de la variance).
Réutiliser variance ; la racine carrée s’obtient avec math.sqrt, après import math en tête du module.
mediane(liste) : retourne la médiane d’une liste triée. Si la liste a un nombre pair d’éléments, la médiane est la moyenne des deux éléments centraux.
Trier d’abord une copie de la liste avec sorted. Si sa longueur n est impaire, un seul élément est au milieu ; si elle est paire, il y en a deux. Tester sur [1, 2, 3] et [1, 2, 3, 4] pour trouver leurs indices en fonction de n.
def mediane(liste):
tri = sorted(liste)
n = len(tri)
if n % 2 == 1:
return ...
else:
return (... + ...) / 2
Ajouter en fin de fichier le bloc suivant et expliquer son rôle :
if __name__ == "__main__":
import doctest
doctest.testmod()
Ajouter print(__name__) dans le module, puis exécuter le fichier directement, et enfin l’importer depuis un autre fichier : quelle valeur prend __name__ dans chaque cas ?
Correction publiée après la séance.
On souhaite organiser un petit projet de gestion de notes en trois modules, regroupés dans un paquet gestion_notes/.
Proposer une structure de fichiers pour ce paquet, avec les modules suivants :
eleve.py : contient une classe Eleve avec un nom et une liste de notes ;calculs.py : contient les fonctions moyenne(notes) et meilleure_note(notes) ;affichage.py : contient une fonction bulletin(eleve) qui affiche le nom, la moyenne et la meilleure note.Un paquet est un répertoire qui contient un fichier __init__.py, éventuellement vide, et les modules du projet.
Écrire le contenu du fichier eleve.py avec une classe Eleve dotée d’un constructeur (__init__), d’une méthode ajouter_note(note) et d’une méthode __repr__. Documenter chaque méthode.
Le constructeur crée les attributs nom et notes, la liste de notes étant vide au départ. __repr__ renvoie une chaîne, par exemple Eleve('Alice', notes=[15, 12]), que Python affiche quand on évalue l’objet dans la console.
"""Module de gestion des élèves."""
class Eleve:
"""Représente un élève avec son nom et ses notes."""
def __init__(self, nom):
"""Initialise un élève avec un nom et une liste de notes vide."""
self.nom = ...
self.notes = ...
def ajouter_note(self, note):
"""Ajoute une note à la liste de l'élève."""
...
def __repr__(self):
"""Renvoie une représentation lisible de l'élève."""
return f"Eleve('{...}', notes={...})"
Écrire le contenu du fichier calculs.py avec les deux fonctions documentées.
Ces deux fonctions ne dépendent pas de la classe : elles reçoivent une simple liste de nombres. sum, len et max suffisent.
Écrire le contenu du fichier affichage.py. Ce module devra importer les fonctions moyenne et meilleure_note de calculs.py.
Le programme est lancé depuis main.py, en dehors du paquet : l’import doit donc nommer le paquet, from gestion_notes.calculs import .... La fonction bulletin lit les attributs nom et notes de l’objet reçu.
Écrire un fichier main.py (en dehors du paquet) qui crée deux élèves, leur ajoute des notes, puis affiche leur bulletin.
Importer la classe Eleve depuis gestion_notes.eleve et la fonction bulletin depuis gestion_notes.affichage, puis créer chaque élève avec Eleve("Alice") et appeler ajouter_note plusieurs fois.
Correction publiée après la séance.