Accueil

Traduction

Tutoriel Python - sommaire

Tutoriel Python - recherche

L'auteur : Patrick Darcheville

Vous pouvez me contacter via Facebook pour questions & suggestions : Page Facebook relative à mon site

Python : fonctions complexes & modules personnels

Retour sur les fonctions

J'ai déjà évoqué les fonctions dans le chapitre 4 mais je n'ai pas tout dit ...

Que se passe t-il si on ne passe pas le nombre correct d'arguments ?

>>> pow(10,5)
100000
>>> pow(10)
...
TypeError: pow() missing required argument 'exp' (pos 2)

La fonction native pow() exige deux arguments lors de son appel. Donc si n'en passe qu'un il y a plantage !

Fonction avec argument optionnel

Je vous montre maintenant que l'on peut donner une valeur par défaut à certains paramètres. lors de l'appel de la fonction je ne suis pas obligé de saisir un argument correspondant au paramètre ayant une valeur par défaut. On dit que l'argument est optionnel.

>>> def puissance(x, p =2) :
...     return pow(x,p)
...
>>> puissance(5)
25  # 5 à la puissance 2
>>> puissance(5,3)
125
>>>

J'ai créé une fonction perso. puissance() basée sur la fonction native pow() afin d'améliorer cette dernière.
Notez la syntaxe : def puissance(x, p =2).
Donc lors de l'appel de la fonction je peux passer un seul argument ; le paramètre "p" prendra alors la valeur 2 : élever à la puissance 2.
Mais bien sûr je peux aussi passer deux arguments si je veux une puissance différente de 2.

Fonction flexible

Avec Python, c'est possible de définir une fonction acceptant un nombre variable d'arguments lors de son appel.

 
>>> def somme(*args):
...     s=0
...     for i in args:
...             s = s+i
...     return s
...
>>> somme(10,20)
30
>>> somme(10,20,15,25)
70
>>>

Lors de la déclaration de la fonction le paramètre doit être "* args" (remplacez 'args' par ce que voulez mais surtout n'oubliez pas le caractère "*" devant le mot "args").
Lors de l'appel de la fonction, vous saisissez en guise d'arguments un tuple de valeurs avec 2,3, 4 ou plus éléments.

Fonction récursive

Récursivité, un mot qui fait peur aux apprentis programmeurs.
Vous devez savoir qu’une fonction peut également s’appeler elle même dans son exécution. C’est ce qu’on appelle la récursivité.
L’exemple classique de fonction récursive est celle qui calcule une factorielle.
La factorielle de 4, par exemple, est égale à 1 * 2 * 3 * 4 = 24
La factorielle de 6 = 1 * 2 * 3 * 4 * 5 * 6 = 720

Fonction récursive pour calculer factorielle n

def factorielle(n):
    if n == 0:
        return 1
    else:
        return n  * factorielle(n-1)

Dans la fonction notez la syntaxe : return n * factorielle(n-1) : appel récursif.
Si on argumente avec n > à 1 on retourne cette valeur et on appelle factorielle(n-1).
Si n-1 est toujours > à 1, on retourne cette valeur et on appelle à nouveau notre fonction avec une valeur diminuée de 1 ce jusqu’à ce que la valeur passée à factorielle() soit 1.

Programme sans récursivité

On peut éviter la récursivité à condition d'utiliser range().

# nom_prog : factoriel_range.py
def calcul_factoriel(nbre) : 
    factoriel = 1
    for i in range(1, nbre+1):
        factoriel = factoriel * i
    return factoriel

print(calcul_factoriel(3))
print(calcul_factoriel(4))
nbre = int(input('saisir un entier : '))
print(calcul_factoriel(nbre))

J'intégre ma fonction perso. "calcul_factoriel()" dans une programme car ça serait un peu délicat de saisir toutes ces commandes via la console.
Dans ce programme j'appelle trois fois la fonction.

Le rendu :

6
24
saisir un entier : 5
120
>>> 

Solution ultime

Nous nous serions évités tous ces efforts de programmation si nous avions pris la peine de rechercher dans la documentation Python.
Ce langage est très orienté "mathématiques" (c'est pour cette raison qu'il est enseigné en lycée dans les filières Math sup & Math spé).
Il existe dans le module math la fonction factorial()

>>> import math
>>> math.factorial(4)
24
>>> math.factorial(6)
720
>>>

Une fonction définie en une seule ligne

Une fonction peut être définie en une seule instruction à condition d'utiliser le mot clé "lamda".
Aussi désigne t-on ces fonctions sous l'expression "fonctions lambda".
Dans une fonction lambda on ne retrouve pas les mots clés "def" & "return".

>>> carre = lambda x: x*x
>>> carre(5)
25
>>> carre(10)
100
>>>

La syntaxe d'une fonction lambda : nomFonction = lambda arg1, arg2 : instruction de retour
J'ai défini la fonction "carre".
Concernant l'appel de la fonction il n'y a pas de différence avec une fonction classique : nomFonction(liste des arguments)

Creer ses propres modules

Utiliser un module personnel

>>> import geometrie as geom
>>> geom.cercle(50)
(314.0, 7850.0)
>>> geom.rectangle(30,50)
(160, 1500)
>>>

J'utilise un module que j'ai personnellement créé. Ce module contient deux fonctions perso.
Je sais que la fonction cercle() réclame deux arguments et la fonction rectangle() a besoin de deux arguments.

Pourquoi créer ses propres modules ?

Vous avez du créer une fonction perso car vous n'avez pas trouvé votre bonheur dans le module de base, les modules importables voire les bibliothèques. Avez-vous vraiment bien cherché ?

Si vous créer cette fonction dans le cadre d'un programme, celle-ci ne pourra être appelée qu'à partir de ce programme.
Ce qui est vraiment dommage cette fonction est vraiment innovante et représente un gros investissement personnel.
Par contre une fonction appartenant à un module peut être appelée via la console ou dans n'importe quel programme.

Comment créer un module perso. ?

Je crée un fichier nommé "geometrie.py" (comme un programme).
Contenu de ce fichier :

""" Module geometrie
qui comprend deux fonctions : cercle() et rectangle() : 
- cercle(rayon) -> circonférence, aire
- rectangle(largeur,longueur) -> périmètre, aire
"""

def cercle(rayon):
    circonference = rayon * 2 * 3.14
    aire = rayon* rayon * 3.14
    return circonference, aire

def rectangle(longueur,largeur):
    perimetre = (longueur *2) + (largeur*2)
    aire = longueur*largeur 
    return perimetre, aire

Un module perso. doit débuter par un commentaire multilignes (délimité par une paire de triple guillemets). Cette chaine de commentaire sera affichée via la commande help().
Il faut donc soigner la rédaction de ce texte. Elle est appelée "docstrings" dans la documentation de Python.
Ensuite on trouve la définition des fonctions et c'est tout.

Pour devenir un module à part entière, le fichier "geometrie.py" doit être enregistré dans "c:/Python39" et pas ailleurs.

Commandes dans la console

>>> import geometrie as geom
>>> help(geom)
Help on module geometrie:

NAME
    geometrie

DESCRIPTION
    Module geometrie
    qui comprend deux fonctions : cercle() et rectangle() :
    - cercle(rayon) -> circonfÚrence, aire
    - rectangle(largeur,longueur) -> pÚrimÞtre, aire

FUNCTIONS
    cercle(rayon)

    rectangle(longueur, largeur)

FILE
    c:\python39\geometrie.py

Si vous importez un module en lui attribuant un alias, il faut taper la commande help(alias) pour afficher l'aide relative au module.

Python ne se contente pas d'afficher la chaine multilignes que j'ai rédigée ; Il la structure en différents paragraphes : NAME, DESCRIPTION, FUNCTIONS, FILE.

Exercice

Commandes dans la console

>>> import maintenant as now
>>> help(now)
Help on module maintenant:

NAME
    maintenant

DESCRIPTION
    Module maintenant
    qui comprend deux fonctions :
    - date_courante() -> jour/mois/annee
    - heure_presente() ->H/M/S
    Donc aucun argument à passer !

FUNCTIONS
    date_courante()

    heure_presente()

FILE
    c:\python39\maintenant.py

>>> now.date_courante()
'Nous sommes le : Monday 12 August 2024'
>>> now.heure_presente()
'Il est exactement : 13 : 36 : 24'
>>>

Travail à faire

Afin de vérifier si vous avez compris, essayez de récréer le fichier "maintenant.py" .
Ce module comprend deux fonctions perso. Celles-ci sont construites à partir de la fonction time.strftime(format).
Vous pouvez aussi améliorer la première fonction afin qu'elle affiche la date en français : "lundi 12 aout 2024" !
Je vous invite donc à revoir le chapitre 9 qui porte entre autres sur les modules time,locale,datetime.