Infoforall

Python 21 : Les fonctions et les méthodes (révisions 2)

1 - Les fonctions

Dans les premières leçons sur Python, nous avions vu les fonctions : des bouts de code qu'on peut appeler à l'aide d'un mot-clé (le nom de la fonction) plutôt que de retaper les lignes de code dans leur intégralité.

On doit définir le contenu d'une fonction en début de code à l'aide du mot-clé def puis on pourra y faire appel depuis le "programme principal".

Voici ci-dessous une fonction nommmée test_fonction() qui demande à l'utilisateur de rentrer un entier puis que affiche son carré. ATTENTION : son appel se fait depuis le 'corps du programme principal'.

#!/usr/bin/env python

# -*- coding: utf-8 -*-


#########################################################

# Déclarations des fonctions

#########################################################


def test_fonction():

    a = input("Tapez un nombre entier : ")

    a = int(a)**2

    print("Au carré, on obtient : ",a)


#########################################################

# Corps du programme

#########################################################

test_fonction()

b = input("Tapez sur entrée")

01° Lancer le programme pour vérifier qu'il fonctionne correctement. Supprimer ensuite la ligne test_fonction() sous "CORPS DU PROGRAMME". L'interpréteur Python utilise-t-il les lignes de code de la fonction si on n'y fait pas appel ?

02° Que va faire le programme si on utilise plutôt les lignes ci-dessous dans "CORPS DU PROGRAMME" ? Posez-vous la question puis vérifiez votre réponse.

#########################################################

# Corps du programme

#########################################################

print("Première demande")

test_fonction()

print("Seconde demande")

test_fonction()

b = input("Tapez sur entrée")

Premier intérêt des fonctions : ne pas retaper les lignes de code lorsqu'on veut les reutiliser plusieurs fois.

Continuons les révisions : pourquoi doit-on placer des parenthèses derrière le nom de la fonction ? Première raison : cela permet à Python de savoir qu'il s'agit d'une fonction et donc d'aller chercher dans les définitions pour trouver les lignes de codes à exécuter. La seconde raison est qu'on peut envoyer entre ces parenthèses des arguments. Exemple pratique :

#!/usr/bin/env python

# -*- coding: utf-8 -*-


#########################################################

# Déclarations des fonctions

#########################################################


def test_fonction_2(a):

    print("On teste la fonction en lui ayant transmis a = ",a)

    p2 = int(a)**2

    print("Au carré, on obtient : ",p2)

    p3 = int(a)**3

    print("A la puissance 3, on obtient : ",p3)


#########################################################

# Corps du programme

#########################################################

test_fonction_2(3)

test_fonction_2(4)

b = input("Tapez sur entrée")

03° Tester le code puis rajouter le code permettant d'afficher les puissances pour les entiers 5 et 6.

Conclusion : les fonctions sont des éléments fondamentaux de la programmation : elles permettent d'éviter les copier/coller inutiles ET peuvent recevoir des valeurs qui leurs permettent d'éxécuter des instructions différentes en fonction des arguments transmis.

Paramètres et arguments

Pour ceux qui aiment bien les termes précis, sachez que paramètre est le nom donné à ce qu'on place entre parenthèses lors de la définition de la fonction. Ce sont des "conteneurs" qui ne contiennent rien avant qu'on utilise concrétement la fonction lors d'un appel. On nomme les données fournies lors de l'appel les arguments :

#!/usr/bin/env python

# -*- coding: utf-8 -*-


#########################################################

# Déclarations des fonctions

#########################################################

def fois_trois(x): # x est un paramètre

    print(3*x)


#########################################################

# Corps du programme

#########################################################

fois_trois(10) # 10 est un argument

fois_trois("10") # "10" est un argument

input("Appuyer sur ENTREE pour quitter")

Il ne s'agit que de vocabulaire, mais il permet de comprendre les documentations techniques. Ca donne parameter et argument en anglais.

Il reste à revoir les interactions entre les variables du 'corps du programme' et d'une fonction.

Imaginons qu'on dispose d'une variable nommée x dans le corps du programme et d'une variable x dans la fonction également :

#!/usr/bin/env python

# -*- coding: utf-8 -*-


#########################################################

# Déclarations des fonctions

#########################################################


def test_fonction():

    x = 100

    print("Dans la fonction, x contient ",x)

    print(id(x))

    a = input("Tapez un nombre entier : ")

    a = int(a)*x

    print("On obtient : ",a)


#########################################################

# Corps du programme

#########################################################

x=10

test_fonction()

print("Dans le corps du programme, x contient ",x)

print(id(x))

b = input("Tapez sur entrée")

04° Lorsqu'on utilise x dans la fonction, la fonction utilise-t-elle le x du programme (contenant 10) ou le x de la fonction (contenant 100) ?

05° En vous aidant des valeurs des id de x, peut-on dire que x désigne deux variables différentes ou une seule et unique variable ?

Voilà, nous venons de revoir la notion d'espace des noms que nous avions vu dans l'activité Fonction - Portée des variables. Chaque partie d'un programme possède son propre espace des noms. La variable x du corps du programme est donc différente de la variable x de la fonction. D'ailleurs, on pourrait également définir des variables x dans deux fonctions également. Cela permet l'encapsulation des codes dans les fonctions : vous n'avez pas à vous demander quels sont les noms déjà utilisés dans telle ou telle partie d'un programme. Le x que vous venez d'introduire dans votre fonction ne va pas rentrer en conflit avec un x que vous n'aviez pas vu dans une autre fonction ou dans le programme principal.

06° Supprimer la ligne x=10 puis lancer le programme. Que constatez-vous ?

...CORRECTION...

On définit un x dans la fonction. Elle parvient à fonctionner.

Par contre, le programme principal ne parvient pas à avoir accès à l'espace des noms d'une fonction : x de la fonction n'existe que le temps de l'exécution de la fonction. Python libère immédiatement l'espace mémoire nécessaire pour x car lorsqu'on sort de la fonction, il n'en a plus besoin. Sans cela, la mémoire risquerait d'être rapidement saturée.

06° Remettre x=10 en première ligne du corps du programme. Supprimer la ligne x=100 dans la fonction. Lancer le programme. Que constatez-vous ?

...CORRECTION...

Cette fois, c'est l'inverse : si l'espace des noms de la fonction ne contient pas de variable nommée x, la fonction va aller voir dans l'espace des noms de l'entité qui l'a appelé : elle va donc prendre x=10.

D'ailleurs, vous pouvez remarquer que cette fois l'id de x est le même dans la fonction et dans le corps du programme : on va bien regarder dans la même case mémoire.

C'est l'option par défaut dans Python. Attention, dans la plupart des autres langages, l'option par défaut est l'inverse : une fonction n'a pas accès aux autres espaces des noms. Cela fait partie des différences dont il faut tenir compte lorsqu'on porte un code d'un langage vers un autre.

Bien. Résumons : le corps du programme n'a pas accès aux espaces des noms des fonctions mais les fonctions peuvent accéder à l'espace des noms du corps du programme si on leur demande de travailler avec une variable qu'elle ne connait pas à la base.

Mais peut-on modifier une variable du corps du programme depuis une fonction ?

07° Utiliser le code ci-dessous pour voir si on peut modifier x depuis la fonction.

#!/usr/bin/env python

# -*- coding: utf-8 -*-


#########################################################

# Déclarations des fonctions

#########################################################


def test_fonction():

    print("Dans la fonction, x contient ",x)

    print(id(x))

    print("On augmente x de 10")

    x=x+10

    print("On obtient : ",x)

    print(id(x))


#########################################################

# Corps du programme

#########################################################

x=10

test_fonction()

print("Dans le corps du programme, x contient ",x)

print(id(x))

b = input("Tapez sur entrée")

Et oui : ca ne fonctionne pas, et ça provoque même une erreur. Pourquoi ? Simplement car la fonction a accès en LECTURE à l'espace des noms mais pas en ECRITURE. Si on tape x=x+10, on veut faire de l'écriture. La fonction ne va donc pas voir dans l'espace des noms du corps du programme mais pense qu'il s'agit d'une variable x locale.

Comment faire alors ? Souvenir, souvenir ?

Non ?

Toujours pas ?

Il vous faut simplement donner l'autorisation à la fonction de modifier le x du corps du programme. Pour cela, il vous suffit de noter global x au début du code de la fonction. Attention, dans la plupart des langages, c'est l'inverse : on faut déclarer x en global dans le corps du programme.

08° Rajouter le global x dans la fonction. Lancer le programme. La fonction x parvient-elle à modifier le x du corps du programme ?

#!/usr/bin/env python

# -*- coding: utf-8 -*-


#########################################################

# Déclarations des fonctions

#########################################################


def test_fonction():

    global x

    print("Dans la fonction, x contient ",x)

    print(id(x))

    print("On augmente x de 10")

    x=x+10

    print("On obtient : ",x)

    print(id(x))


#########################################################

# Corps du programme

#########################################################

x=10

test_fonction()

print("Dans le corps du programme, x contient ",x)

print(id(x))

b = input("Tapez sur entrée")

REMARQUE : cette méthode de la variable globale ne doit être utilisée qu'en dernier recours car elle casse l'encapsulation et fragilise votre code en rendant des parties normalement indépendantes dépendantes des noms des variables d'une autre partie. Avec ce code simple, il aurait mieux fallu utiliser le code ci-dessous. Pensez-y lors de vos projets : les variables globales c'est l'Agence Tous Risques. Le dernier recours au dernier moment.

agence tous risques

2 - Méthodes sur les strings

Quelle est la différence fondamentale entre une fonction et une méthode ?

Une méthode est une sorte de fonction particulière : il s'agit d'une fonction qui ne peut agir que sur un objet particulier, un string par exemple.

Comment appliquer une méthode ? En plaçant un point (.) entre l'objet à utiliser et le nom de la fonction à utiliser. Par exemple : objet.méthode().

Tout ce que je vais renoter ici provient de la documentation officielle, ça ne s'invente pas, ça se trouve :

PYTHON.ORG AU BON ENDROIT POUR PYTHON 3.6

C'est dans le chapitre 4.4.2. Additional Methods on Integer Types pour les entiers.

C'est dans le chapitre 4.4.3. Additional Methods on Float pour les réels.

C'est dans le chapitre 4.7.1. String Methods pour les strings.

Pour retrouver les méthodes permettant d'agir sur les images Pillow, il suffit de revoir les fiches parlant de cela. Il s'agit des chapitres 3, 4 et 5.

Dans cette partie, nous allons surtout travailler sur les strings.

Voici ci-dessous un apercu de ce qu'on peut trouver dans la documentation de Python. str est à remplacer par le nom du string que vous utilisez. Elles sont ici plus ou moins classées par thème.

Les strings sont NON MODIFIABLES. Néanmoins, certaines des méthodes données ici permettent justement de donner l'illusion qu'on les transforme.

Des exemples d'utilisation se trouvent sous le tableau.

Attention : les crochets [ ] indiquent que l'argument qu'on y touve est optionnel.

Méthode Action réalisée
str.capitalize() Renvoie une version du string où le premier caractère est en majuscule (uppercase) et les autres en minuscule (lowercase).
str.title() Renvoie une version du string où chaque mot commence par une majuscule et les autres caractères en minuscule.
str.lower() Renvoie la chaîne de caractères en remplaçant les caractères par les minuscules correspondantes.
str.upper() Idem mais en majuscule.
str.swapcase() Renvoie une chaîne en transformant les majuscules en minuscules et inversement.
str.center(largeur [,remplissage]) Renvoie une version du string faisant "largeur" caractères, le caractère de remplissage étant donné via remplissage.
str.ljust(largeur [,remplissage]) Idem mais avec une mise à gauche (d'où le l pour left).
str.rjust(largeur [,remplissage]) Idem mais avec une mise à droite (d'où le r pour right).
str.count(sub[, start[, end]]) Renvoie le nombre d'occurences du string sub dans le string str. On peut rajouter les numéros de début et de fin des cases à analyser.
str.encode(encoding=”utf-8”, errors=”strict”)] Renvoie la version encodée du string str. L'encodage par défaut est utf-8
str.endswith(suffix[, start[, end]]) Retourne False si la chaîne utilisée ne finit pas par le suffix donné. Le suffixe peut également être un tuple, la fonction regardera alors si le string finit par l'ue des valeurs du tuple. Pratique pour vérifier le type d'extension d'un fichier.
str.startswith(suffix[, start[, end]]) Pareil mais avec le début.
str.expandtabs(tabsize=8) Renvoie une copie de str dans laquelle les tabulations \t sont remplacées par des espaces.
str.find(sub[, start[, end]]) Renvoie le numéro d'index de la première occurrence du string sub dans le string str sur lequel on travaille. On peut indiquer de ne travailler que sur un bout du string à l'aide de start et end. La réponse est -1 si elle ne trouve pas sub dans str.
str.index(sub[, start[, end]]) Comme la précédente mais lève une erreur de type ValueError plutôt que -1 si elle ne trouve pas la chaîne désirée.
str.rfind(sub[, start[, end]]) Comme find mais avec la valeur la plus grande trouvée, plutôt que la première.
str.rindex(sub[, start[, end]]) Comme la précédente mais avec une erreur plutôt que -1 si on ne trouve pas.
str.format(*args, **kwargs) Permet de placer des éléments à certains endroits précise d'un string Exemple : "La somme de 1 + 2 est {0}".format(1+2) va insérer le calcul (1+2) à la place de {0}. Voir les questions ci-dessous pour plus de précision.
str.join(iterable) Intercale le string str entre chaque valeur de l'objet iteritable : ainsi "*".join("A","B","C") renvoie A*B*C. Ou "ABC".join("/*-") renvoie /ABC*ABC-ABC".
str.lstrip([chars]) Renvoie une copie de str où on a supprimé une partie du début de str : la partie qui comporte les caractères présents dans chars. Ainsi 'www.example.com'.lstrip('cmowz.') renvoie example.com. Si on ne précise rien en utilisant juste lstrip(), la méthode supprime par défaut les espaces.
str.rstrip([chars]) Comme la précédente mais en commençant par la droite, donc la fin.
str.strip([chars]) Encore plus violent : cette méthode retire les caractères données de la chaîne de caractères au début et à la fin. Exemple : "Bonjour".strip("Br") renvoie "onjou".
str.partition(sep) Renvoie un tuple 3-uplet qui contient : (la sous-chaîne avant le séparateur), (le séparateur), (la sous-chaine après le séparateur). Exemple : "AB.CDE.FGHI".partition('.') renvoie ('AB','.','CDE.FGHI').
str.rpartition(sep) Comme la précédente mais en prenant le premier séparateur trouvé en partant de la droite.
str.replace(old, new[, count]) Renvoie une copie de str où la chaîne old sera remplacée par la chaîne new. Si on précise un integer count, le remplacement ne sera fait que ce nombre de fois.
str.split(sep=None, maxsplit=-1) Renvoie un tuple contenant les sous-chaînes qu'il trouve en utilisant le caractère séparateur fourni. Exemple : "A;B;C".split(";") fournit la liste ['A', 'B', 'C']. Si on ne précise pas maxsplit, il vaut -1 par défaut et on divise autant de fois qu'il le faut.
str.rsplit(sep=None, maxsplit=-1) Comme ci-dessus mais en commençant par la droite.
str.splitlines([keepends]) Renvoie une liste contenant les différentes chaînes de caractères, le séparateur étant ici le passage à la ligne, souvent noté \n. Néanmoins, la méthode intégre d'autres caractères de séparation. Allez voir la documentation si vous voulez l'utiliser.
str.zfill(largeur) Renvoie une copie du string en rajoutant des 0 au début de façon à ce que le str ai la bonne largeur (width). Si un caractère de signe ou autre se trouve devant (+, -), il restera à l'extrême gauche.

Exemple pour capitalize() :

>>> a="azerTY"

>>> print(a.capitalize())

Azerty

Exemple center(largeur [,remplissage]) :

>>> a="Bonjour"

>>> print(a.center(50,'-'))

---------------------Bonjour----------------------

Exemple count(sub[, start[, end]]) :

>>> a="Bonjour"

>>> print(a.count('o'))

2

>:>> print(a.count('o',0,2))

1

Exemple encode(encoding=”utf-8”, errors=”strict”)] :

>>> a="Cela a fonctionné"

>>> print(a.encode())

b'Cela a fonctionn\xc3\xa9'

>:>> for octet in a.encode():

...    print(octet, end=" ; ")

67 ; 101 ; 108 ; 97 ; 32 ; 97 ; 32 ; 102 ; 111 ; 110 ; 99 ; 116 ; 105 ; 111 ; 110 ; 110 ; 195 ; 169 ;

>>> print(a.encode('ansi'))

b'Cela a fonctionn\xe9'

>>> for octet in a.encode('ansi'):

...    print(octet, end=" ; ")

67 ; 101 ; 108 ; 97 ; 32 ; 97 ; 32 ; 102 ; 111 ; 110 ; 99 ; 116 ; 105 ; 111 ; 110 ; 110 ; 233 ;

Quelques explications : le 'b' signifie qu'on a en réalité affaire à un ensemble de bytes. Par contre, lorsque la valeur du byte est inférieure à 127 (en base 10) et correspond à une lettre de l'ASCII, Python affiche la lettre ASCII correspondante plutôt que la valeur. Si le code est supérieur à 127 (base 10), il donne la façon dont la lettre est codée en hexadécimal (il indique que c'est de l'hexa à l'aide du \x placé devant la valeur).

Ainsi dans l'encodage UTF-8, é est codé sur deux octets, dont les valeurs sont exprimées par c3 a9 en hexadécimal et 195 169 en décimal.

Par contre, dans l'encodage ANSI, é est codé sur un seul octet contenant e9 en hexadécimal ou 233 en décimal.

Exemple str.endswith(suffix[, start[, end]]) :

>>> a="Bonjour."

>>> print(a.endswith(';'))

False

>>> print(a.endswith('.'))

True

>>> print(a.endswith(('.',';')))

True

Exemple find(sub[, start[, end]]) :

>>> a="Bonjour"

>>> print(a.count('o'))

2

>>> print(a.count('o',0,2))

1

Exemple str.format(*args, **kwargs) :

L'utilisation basique est celle d'un remplissage progressif des "trous" provoqués par { } :

>>> a="Bonjour {}, aujourd'hui nous sommes {}."

>>> print(a.format('jeune Skywalker','jeudi'))

Bonjour jeune Skywalker, aujourd'hui nous sommes jeudi.

Mais on peut faire mieux encore : on peut donner un ordre d'affichage : {1} veut dire d'aller chercher l'élément classé 1 dans la liste des éléments donnés. Attention, l'élément classe 0 est le premier, comme toujours.

>>> a="Bonjour {1}, aujourd'hui nous sommes {0}."

>>> print(a.format("vendredi, pouf, ça passe vite","Yoda"))

Bonjour Yoda, aujourd'hui nous sommes vendredi, pouf, ça passe vite.

Ou encore :

>>> a = "Aujourd'hui, nous sommes {3}."

>>> a.format('lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi', 'dimanche')

'Aujourd'hui, nous sommes jeudi.'

Et ce n'est que le tout sommet de l'iceberg. Nous allons revenir sur cette méthode pendant une autre activité. Il y a beaucoup trop à dire.

Pour commencer à voir un peu ce qu'on peut faire, voilà une façon de faire la même chose sans avoir à retaper la liste des jours à chaque fois :

>>> jours=('lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi', 'dimanche')

>>> a = "Bonjour, nous sommes {b[3]}."

>>> a.format(b=jours)

'Bonjour, nous sommes jeudi.'

10° Réaliser un petit programme qui permet d'afficher la traduction française et anglaises de la couleur choisie. Exemple d'affichage :

Vous avez choisi la couleur rouge (traduit par red en anglais).

Le numéro de la couleur sera à choisir en utilisant les objets suivants :

couleur_fr = ('rouge','vert','bleu','jaune','rose')

couleur_an = ('red','green','blue','yellow','pink')

En réalité, ce n'est pas fini : il reste encore toutes les méthodes qui permettent de vérifier si la chaîne possède certaines propriétés. Ces méthodes commencent toutes par is pour dire : la chaîne est-elle ainsi ... Elles renvoient toutes True ou False.

Le test est plus ou moins explicite. Si vous voulez plus d'informations, allez voir la documentation officielle.

Méthode Action réalisée
str.isalpha() Retourne True si tous les caractères sont des lettres.
str.isdecimal() Retourne True si tous les caractères sont des chiffres : 0123456789.
str.isdigit() Comme le cas précédent mais avec en plus les caractères comme ² ³ ¹ ¼ ½ ¾ et tous les autres caractères considerés comme des nombres (sigle comme ⓫, nombres romains...)
str.isnumeric() Pareil. Il faut faire un test comparatif avec le cas précédent pour voir la différence. Utiliser une boucle for x, la fonction chr et tester chr(x).isdigit().
str.isprintable() Retourne True si tous les caractères (sans exception) sont imprimables.
str.isspace() Idem mais si tous les caractères peuvent être considérés comme des espaces.
str.isupper() Idem mais si tous les caractères sont des majuscules.
str.isalphanum() .Teste en même temps :isalpha(), isdecimal(), isdigit(), et isnumeric(). Renvoie True si l'une des méthodes renvoie True.

Et voilà. Des méthodes, il y a pour beaucoup d'autres objets que les strings : vous trouverez sur Python.org des méthodes pour les integers, les floats ... S'il vous prend l'idée de faire quelque chose avec un type prédéfini, pensez à aller y jeter un oeil : il existe peut-être une méthode déjà écrite qui fait exactement ce que vous voulez.

3 - Valeurs par défaut (complément)

Ici, on quitte les révisions.

Nous avons vu que certaines méthodes possèdents des paramètres qui peuvent prendre une valeur par défaut si on ne transmet pas d'arguments. Mais comment est-ce que cela fonctionne ?

En fait, c'est très simple. Commençons par créer une petite fonction qui calcule l'énergie en utilisant E = P .Δt.

#!/usr/bin/env python

# -*- coding: utf-8 -*-


def energie(puissance, fin, debut):

    "La fonction energie renvoie l'énergie en J après l'avoir calculée à paritr de E=P.dt si P est donnée en W et les temps en s."

    duree = fin-debut

    return(puissance*duree)


print("Si un système fournit 10W de t = 20s à t = 60s, il fournit : {} W".format(energie(10,60,20)))

input("Appuyer sur ENTREE")

11° Lancer le code via IDLE. Puis passer en console IDLE et taper :

>>> energie.__doc__

Vous devriez voir apparaitre le texte que vous avez inséré au début de la fonction. Cela se nomme documenter sa fonction. L'intérêt est limité au début mais rapidement, les programmes deviennent complexes et on ne souvient plus forcément de tout ce qu'ils font et pourquoi et comment. De plus, l'informatique est activité qui se réalise le plus souvent en groupe : quelqu'un aura donc certainement besoin un jour de modifier votre code. Encore faut-il qu'il le comprenne !

Si vous aviez à fournir une documentation plus fournie, il faudra utiliser """ pour indiquer le début de la documentation et """ pour indiquer la fin de la documentation.

#!/usr/bin/env python

# -*- coding: utf-8 -*-

def energie(puissance, fin, debut):

    """La fonction energie renvoie l'énergie après l'avoir calculée à paritr de E=P.dt

    E énergie en J

    puissance en W

    fin, temps final en s

    debut, temps initial en s"""

    duree = fin-debut

    return(puissance*duree)

print("Si un système fournit 10W de t = 20s à t = 60s, il fournit : {} W".format(energie(10,60,20)))

input("Appuyer sur ENTREE")

12° Lancer le code puis refaire un affiche de documentation avec energie.__doc.Normalement, ça ne marche pas vraiment...

13° Lancer ceci dans la console :

>>> print(energie.__doc__)

Cette fois, vous devriez avoir ceci :

La fonction energie renvoie l'énergie après l'avoir calculée à paritr de E=P.dt

    E énergie en J

    puissance en W

    fin, temps final en s

    debut, temps initial en s

A partir de maintenant, il faudra donc documenter un peu vos fonctions. De toutes manières, il faudra le faire quand vous travaillerez donc autant prendre de bonnes habitudes.

N'empêche que ça ne résoud pas notre problème de valeur par défaut ...

Pour cela, il suffit de donner une valeur dans la déclaration du paramètre de la fonction :

#!/usr/bin/env python

# -*- coding: utf-8 -*-

def energie(puissance=1, fin=10, debut=0):

    """La fonction energie renvoie l'énergie après l'avoir calculée à paritr de E=P.dt

    E énergie en J

    puissance en W

    fin, temps final en s

    debut, temps initial en s"""

    duree = fin-debut

    return(puissance*duree)

print("Si un système fournit 10W de t = 20s à t = 60s, il fournit : {} W".format(energie(10,60,20)))

print("De base, la fonction affiche, ",energie())

input("Appuyer sur ENTREE")

14° Pourquoi l'appel de energie() sans fournir de valeur donne 10 ? Expliquer ce phénomène.

...CORRECTION...

On ne donne aucun arguement lors de l'appel de la fonction.

L'interpréteur utilise donc les valeurs proposées par défaut.

Cela revient donc à faire l'appel de energie(1,10,0).

Il reste néanmoins encore un problème : que se passe-t-il si on oublie un argument mais pas un autre ?

15° Lancer energie(5,20). Le résultat est-il cohérent ? Pourquoi ?

...CORRECTION...

Oui le résultat est cohérent : on donne P=5W et tF=20s.

On ne donne pas de valeur pour le temps final, il prend donc la valeur par défaut : 0.

Le calcul donne E = P.(tF-tI) = 5*(20-0) = 100 J.

16° Peut-on omettre de donner la puissance mais donner tF et tI ?

...CORRECTION...

Non : Python récupère la première valeur donnée pour la fournir à P : on ne peut donc omettre de donner une valeur à P que si on ne donne pas non plus de valeur aux deux arguments suivants.

C'est ennuyeux. Heureusement, il existe une solution.

4 - Arguments fournis avec une étiquette

Jusqu'à présent, nous avions fourni des arguments dans l'ordre des paramètres. Nous allons maintenant faire des appels de fonctions en utilisant les noms des paramètres :

Cela va nous permettre de fournir des arguements dans n'importe quel ordre. Et s'il en manque, Python va aller voir s'il n'existe pas par hasard de valeur par défaut pour les paramètres n'ayant pas reçu de valeurs via un argument.

17° Utiliser le code suivant dans le corps du programme : j'ai simplement interverti les arguements étiquettés lors de l'appel de la fonction. Cela a-t-il une influence sur le calcul ? Python parvient-il à remettre les bonnes valeurs aux bons endroits ?

print("Si un système fournit 10W de t = 20s à t = 60s, il fournit : {} W".format(energie(puissance=10, fin=60, debut=20)))

print("Si un système fournit 10W de t = 20s à t = 60s, il fournit : {} W".format(energie(fin=60, debut=20, puissance=10)))

18° Peut-on maintenant lancer un calcul en omettant de donner la puissance et le temps initial ?

...CORRECTION...

Oui, il suffit de lancer energie(fin=30) par exemple.

Comme vous avez pu le constater, j'ai un peu triché puisqu'il ne s'agissait pas que de révisions. Mais vous allez avoir besoin de plus en plus de l'aspect documentation, des valeurs par défauts et des arguments nommés : nous allons voir la prochaine fois comment créer, non pas vos fonctions ,mais vos méthodes sur vos objets. Bref, vous allez créer vos premiers Objets, avec un O majuscule.