Aller au contenu

Chapitre 3 : Fonctions⚓︎

Partie A - Appel et définition d'une fonction⚓︎

Appel d'une fonction⚓︎

Activité 3-01 : Départements de la région Île-de-France

Objectif : Comprendre comment faire appel à une fonction.

Carnet Jupyter à télécharger ici

Carnet Jupyter accessible sur CAPYTALE

Corrigé disponible ici

L'activité introductive nous fait utiliser deux fonctions :

  • La première, nom_departement, renvoie le nom d'un département de la région Île-de-France à partir de son numéro.
  • La seconde, prefecture, renvoie le nom du chef lieu d'un département de la région Île-de-France à partir de son numéro.

Les appels nom_departement(94) et prefecture(94) sont des expressions dont la valeur est déterminée et renvoyée par la fonction. Ces expressions peuvent bien entendu être affectées à des variables.

La valeur 94 écrite entre parenthèses après le nom des deux fonctions s'appelle un argument. En changeant l'argument d'une fonction, son appel peut produire un résultat différent.

1
2
3
4
numero = 94
nom = nom_departement(numero)
ville = prefecture(numero)
print("Le département", numero, "s'appelle", nom, "et sa préfecture est", ville)

Par exemple, l'exécution du programme ci-dessus entraîne l'affichage de la phrase Le département 94 s'appelle Val-de-Marne et sa préfecture est Créteil.

1
2
3
4
numero = 93
nom = nom_departement(numero)
ville = prefecture(numero)
print("Le département", numero, "s'appelle", nom, "et sa préfecture est", ville)

Par contre, l'exécution du programme ci-dessus entraîne l'affichage de la phrase Le département 93 s'appelle Seine Saint Denis et sa préfecture est Bobigny.

Définition d'une fonction⚓︎

Nous souhaitons maintenant définir une fonction nom_academie, qui renvoie le nom de l'académie dont fait partie un département désigné par son numéro. On rappelle que les trois académies d'Île-de-France sont composées de la façon suivante :

Académie de Créteil Académie de Paris Académie de Versailles
77 - 93 - 94 75 78 - 91 - 92 - 95
1
2
3
4
5
6
7
8
def nom_academie(num):
    if num == 75:
        ac = "Académie de Paris"
    elif num == 77 or num == 93 or num == 94:
        ac = "Académie de Créteil"
    else:
        ac = "Académie de Versailles"
    return ac

Lors qu'on définit une fonction, la première ligne commence toujours par le mot clé def, suivi du nom de la fonction, et se termine par un couple de parenthèses suivi de deux points.

À l'intérieur des parenthèses, on fait apparaître le ou les éventuel(s) paramètre(s) d'entrée de la fonction. Il s'agit de variables locales, qui n'existent dans la mémoire que pendant l'exécution de la fonction, et qui ont pour valeur un argument fixé au moment de l'appel de la fonction. Par exemple, pour la fonction nom_academie, il y a un seul paramètre d'entrée num, qui correspond à un numéro de département.

Sous la première ligne figure la séquence d'instructions qui est exécutée lors de l'appel de la fonction. Cette séquence s'exécute soit jusqu'à la fin, soit jusqu'à l'instruction return variable_ou_expression (qui stoppe toujours l'exécution de la fonction dans laquelle elle se trouve). C'est cette instruction qui permet de renvoyer une valeur, appelée paramètre de sortie, qui est conservée dans la mémoire pour la suite de l'exécution du programme. Par exemple, pour la fonction nom_academie, il y a un paramètre de sortie ac, qui correspond au nom de l'académie dans laquelle se trouve le département numéro num.

Attention à ne pas confondre définition et appel de fonction

Lorsqu'on se contente d'écrire la définition d'une fonction, aucune exécution de la fonction n'est réalisée. C'est seulement lors d'un appel à la fonction que les instructions correspondantes sont exécutées.

Exercice 3-02 : Définition de fonctions simples

Objectif : Définir et tester des fonctions simples tout en retravaillant les instructions conditionnelles et les boucles.

Carnet Jupyter à télécharger ici

Carnet Jupyter accessible sur CAPYTALE

Corrigé disponible ici

Activité 3-03 : Retour sur la suite de Syracuse

Objectif : Poursuivre l'étude de la suite de Syracuse, vue au chapitre précédent, dans le but d'écrire et de tester des fonctions.

Carnet Jupyter à télécharger ici

Carnet Jupyter accessible sur CAPYTALE

Corrigé disponible ici

Cas particulier des procédures⚓︎

Une procédure est une fonction qui ne renvoie aucune valeur, et ne possède donc pas de paramètre de sortie. Elle peut, en revanche, posséder un ou plusieurs paramètres d'entrée.

Exercice 3-04 : Jeu du retournement

Objectif : Identifier dans un programme quelles sont les fonctions et quelles sont les procédures.

Carnet Jupyter à télécharger ici

Partie B - Spécification d'une fonction⚓︎

La spécification d'une fonction permet de connaître son rôle et ses éventuels paramètres d'entrée, paramètre de sortie et effets de bord.

Cela permet de savoir à quoi sert une fonction, comment l'utiliser (quelles entrées ? quelle sortie ?) et quels sont ses effets secondaires éventuels sur la machine (par exemple la modification d'une variable globale en mémoire, un affichage à l'écran, l'écriture dans un fichier, ...).

Considérons par exemple la fonction suivante, et donnons sa spécification :

1
2
3
4
5
6
7
8
def aire_triangle(a, b, c):
    if a == b and b == c:  # Les trois côtés sont de même longueur
        print("Triangle équilatéral !")
    elif a == b or b == c or c == a:  # Deux des trois côtés sont de même longueur
        print("Triangle isocèle !")
    demi_perimetre = (a + b + c) / 2
    aire = (demi_perimetre * (demi_perimetre - a) * (demi_perimetre - b) * (demi_perimetre - c)) ** 0.5
    return aire
  • Rôle de la fonction : Affiche à l'écran si le triangle est équilatéral ou isocèle, et renvoie son aire.
  • Paramètres d'entrée : a, b, c (nombres), les longueurs des trois côtés du triangle.
  • Paramètre de sortie : aire (nombre), l'aire du triangle (calculée grâce à la formule de Héron).
  • Effets de bord : Affichage à l'écran dans le cas où le triangle est équilatéral ou isocèle.

La spécification d'une fonction s'écrit en Python dans une zone (appelée docstring) délimitée par trois guillemets doubles """ et située juste au dessous de la ligne commençant par def.

On fait apparaître successivement le rôle de la fonction, puis ses paramètres d'entrée, son paramètre de sortie et ses effets de bord s'il y en a.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
def aire_triangle(a, b, c):
    """
    Affiche à l'écran si le triangle est équilatéral ou isocèle, et renvoie son aire.
    - Entrées : a, b, c (nombres)
    - Sortie : aire (nombre)
    Effet de bord : affichage éventuel à l'écran
    """
    if a == b and b == c:  # Les trois côtés sont de même longueur
        print("Triangle équilatéral !")
    elif a == b or b == c or c == a:  # Deux des trois côtés sont de même longueur
        print("Triangle isocèle !")
    demi_perimetre = (a + b + c) / 2
    aire = (demi_perimetre * (demi_perimetre - a) * (demi_perimetre - b) * (demi_perimetre - c)) ** 0.5
    return aire

Attention aux spécifications

Toutes les fonctions et procédures que vous définirez devront désormais avoir leur spécification. Cela permettra de rendre votre code plus clair, en explicitant le rôle de chaque fonction ou procédure et les paramètres qu'elle utilise, mais aussi plus facile à corriger dans le cas où il contiendrait des erreurs.

La fonction help permet d'accéder à la docstring de la fonction dont le nom est passé en paramètre d'entrée.

Exercice 3-05 : Procédure etoile

Objectif : Écrire la spécification d'une procédure après l'avoir testée.

Carnet Jupyter à télécharger ici

Corrigé disponible ici

Partie C - Assertions⚓︎

Lors d'un appel de fonction, il faut souvent s'assurer que les arguments passés en paramètre d'entrée sont acceptables, tant au niveau de leur type que de leur valeur. On utilise pour cela des assertions.

On peut par exemple remarquer que la procédure etoile définie précédemment ne fonctionne correctement que si son paramètre d'entrée nb_branches est un entier impair.

En Python, il existe deux façons de mettre en place une assertion :

  • avec le mot-clé assert, à privilégier pour le débogage des fonctions que vous serez le seul ou la seule à utiliser.
  • avec le mot-clé raise, à privilégier dans le cas où les fonctions seraient mises à la disposition d'autres que vous.

Assertions avec le mot-clé assert⚓︎

La syntaxe est la suivante : assert condition, message_d_erreur.

Si la condition est fausse, l'exécution de la fonction s'interrompt et le message_d_erreur s'affiche.

Pour vérifier que nb_branches est un entier, la condition s'écrit type(nb_branches) == int. C'est une vérification de type.

Pour vérifier que nb_branches est impair, la condition s'écrit nb_branches % 2 != 0. C'est une vérification de valeur.

1
2
3
4
5
6
7
8
def etoile(nb_branches, longueur):
    assert type(nb_branches) == int, "le premier argument doit être un entier"
    assert nb_branches % 2 != 0, "le premier argument doit être impair"
    clear()
    angle = 180 * (1 - 1 / nb_branches)
    for n in range(nb_branches):
        forward(longueur)
        left(angle)

L'appel etoile("bonjour", 300) entraîne l'erreur suivante :

1
AssertionError: le premier argument doit être un entier

L'appel etoile(6, 300) entraîne l'erreur suivante :

1
AssertionError: le premier argument doit être impair

Utilisation de la fonction type

La fonction type renvoie le type de la variable ou de l'expression qui lui est passée en paramètre. Les principaux types que nous utiliserons cette année sont listés dans le tableau suivant :

Notation Python Type Exemples
int Nombre entier 0 -1023 7*9+2 10**9 int(3.1)
float Nombre flottant 0.0 -10.23 6/3 10**-9 float(3)
bool Booléen True False True or False 2 <= 0 bool(1)
function Fonction ou procédure print input nom_departement aire_triangle etoile
str Chaîne de caractères voir chap. 4
list Tableau voir chap. 5
tuple p-uplet voir chap. 6
dict Dictionnaire voir chap. 6
Exercice 3-06 : Assertions avec assert

Objectif : Écrire des assertions avec le mot-clé assert.

Carnet Jupyter à télécharger ici

Carnet Jupyter accessible sur CAPYTALE

Corrigé disponible ici

Assertions avec le mot-clé raise⚓︎

Le mot-clé raise s'utilise à l'intérieur d'une instruction conditionnelle.

La syntaxe est la suivante : raise Exception(message_d_erreur).

Si la commande est exécutée, la fonction s'interrompt et le message_d_erreur s'affiche.

Le mot-clé Exception peut, par exemple, être remplacé :

  • par TypeError dans le cas d'une erreur de type.
  • par ValueError dans le cas d'une erreur de valeur.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
def etoile(nb_branches, longueur):
    if type(nb_branches) != int:
        raise TypeError("le premier argument doit être un entier")
    if nb_branches % 2 == 0:
        raise ValueError("le premier argument doit être impair")
    clear()
    angle = 180 * (1 - 1 / nb_branches)
    for n in range(nb_branches):
        forward(longueur)
        left(angle)

L'appel etoile("bonjour", 300) entraîne l'erreur suivante :

1
TypeError: le premier argument doit être un entier

L'appel etoile(6, 300) entraîne l'erreur suivante :

1
ValueError: le premier argument doit être impair
Exercice 3-07 : Assertions avec raise

Objectif : Écrire des assertions avec le mot-clé raise.

Carnet Jupyter à télécharger ici

Carnet Jupyter accessible sur CAPYTALE

Partie D - Exercices et activités⚓︎

Exercices 3-08 à 3-10

Carnet Jupyter à télécharger ici

Carnet Jupyter accessible sur CAPYTALE

Corrigé disponible ici

Carnet Jupyter à télécharger ici

Carnet Jupyter accessible sur CAPYTALE

Corrigé disponible ici

Carnet Jupyter à télécharger ici

Carnet Jupyter accessible sur CAPYTALE

Activités 3-11 et 3-12

Objectif : Définir des procédures pour réaliser des dessins géométriques.

Carnet Jupyter à télécharger ici

Objectif : Utiliser des fonctions et procédures pour représenter des données sur une carte.

Carnet Jupyter à télécharger ici

Carnet Jupyter accessible sur CAPYTALE

Ce qu'il faut savoir et savoir faire⚓︎

  • Appeler une fonction.
  • Définir une fonction, avec paramètres d'entrée éventuels et paramètre de sortie.
  • Tester une fonction, et vérifier que le résultat obtenu est cohérent.
  • Faire la différence entre variable globale et variable locale associée à une fonction.
  • Faire la différence entre une fonction et une procédure.
  • Écrire ou comprendre la spécification d'une fonction.
  • Écrire une assertion avec le mot-clé assert.
  • Écrire une assertion avec le mot-clé raise.
  • Utiliser la fonction type.
  • Utiliser la fonction help pour obtenir la spécification d'une fonction.
  • Utiliser quelques procédures du module Turtle, dont forward, left, right, goto, up et down.