fonction le return

Identification

Infoforall

9 - Le Return des paramètres


Dans la première activité sur les fonctions, nous avons comment déclarer, utiliser et documenter les fonctions..

Nous avons également vu que les variables définies dans les fonctions sont des variables locales, variables qui n'ont d'existence que le temps de l'exécution du code de la fonction.

Nous allons aujourd'hui étendre vos connaissances. Nous allons voir

  • La façon dont les variables globales interagissent avec les fonctions
  • La façon dont les paramètres des fonctions sont gérés
  • Un peu de précision sur les paramètres (et les arguments)

Logiciel nécessaire pour l'activité : Python 3

Evaluation ✎ : questions 02 -

Résumé : Version HTML ou fond blanc ou ou PDF (couleur ou gris)

On rappelle qu'une procédure est une routine qui ne renvoie pas de réponse.

Une fonction est une routine qui renvoie une réponse à l'aide du mot-clé return.

Néanmoins, dans Python, fonction et procédure porte le même nom : functions. D'ailleurs, en Python, les procédures retournent une réponse même sans présence d'un return : None

1 - Spécifications d'entrée et de sortie

RAPPELS

Paramètres

Lors de la déclaration d'une routine (fonction, procédure ou méthode), on peut l'obliger à recevoir des informations, qu'on nomme des paramètres. Il s'agit simplement de variables locales, mais des variables dont le contenu sera déclaré lors de l'appel de la fonction.

Documentations

On peut insérer de la documentation sur la fonction. Elle se compose souvent :

  • d'une courte phrase explicative
  • d'une description des attendus sur les paramètres (type et contenu voulu)
  • d'une description de ce que va renvoyer la fonction

01° Utiliser le programme suivant dans Thonny pour vous convaincre que cela fonctionne.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
def convertir_sur_10(note) : '''Renvoie une note sur 10 à partir d'une note sur 20 :param note: nombre dans [ 0 ; 20 ] :type note: int or float :return: la note convertie sur 10 , dans [ 0 ; 10 ] :rtype: int or float .. note:: le retour a le même type que le paramètre note ''' reponse = note // 2 return reponse print(convertir_sur_10(20)) print(convertir_sur_10(10)) print(convertir_sur_10(5))

En utilisant au besoin le mode pas à pas de Thonny, pour visualiser le contenu de la variable note au fur et à mesure de l'exécution du programme :

  • Lors de l'exécution de la ligne 16, que contient le paramètre note ?
  • Lors de l'exécution de la ligne 17, que contient le paramètre note ?
  • Lors de l'exécution de la ligne 18, que contient le paramètre note ?

Dernière question : a-t-on vraiment besoin de deux lignes de code dans cette fonction ?

...CORRECTION...

Ligne 16 :

  • L'appel de la fonction est convertir_sur_10(20)
  • L'exécution de la fonction se fait donc comme si on avait tapé : note = 20

Ligne 17 :

  • L'appel de la fonction est convertir_sur_10(10)
  • L'exécution de la fonction se fait donc comme si on avait tapé : note = 10

Ligne 18 :

  • L'appel de la fonction est convertir_sur_10(5)
  • L'exécution de la fonction se fait donc comme si on avait tapé : note = 5

Pour la dernière question : non, on aurait très bien pu faire une fonction encore plus courte :

1 2 3 4 5 6 7 8 9 10 11 12 13
def convertir_sur_10(note) : '''Renvoie une note sur 10 à partir d'une note sur 20 :param note: nombre dans [ 0 ; 20 ] :type note: int or float :return: la note convertie sur 10 , dans [ 0 ; 10 ] :rtype: int or float .. note:: le retour a le même type que le paramètre note ''' return note // 2

Voici un exemple de déroulé avec une documentation plus personnelle : encore une fois, cela ne change rien au programme en lui-même :

CLIQUEZ ICI POUR VOIR LE CONTENU DES VARIABLES :

convertir_sur_10 :

note :

reponse :

1 2 3 4 5 6 7 8 9 10 11 12 13
def convertir_sur_10(note) : '''Renvoie une note sur 10 à partir d'une note sur 20 :: param note (int/float) :: entre 0 et 20 inclus :: return (int/float) :: entier, entre 0 et 10 inclus ''' reponse = note // 2 return reponse print(convertir_sur_10(20)) print(convertir_sur_10(10)) print(convertir_sur_10(5))
Spécifications - Préconditions - Postconditions

Dans la documentation précédente, les explications sur les paramètres ou le retour sont des spécifications.

Comme il s'agit d'une procédure déjà concue, il faut le voir de cette manière :

Les spécification d'entrée sont les conditions que vous devez respecter sur les paramètres lorsque vous faites appel à la fonction. Ici, :: param note (int/float) :: entre 0 et 20 inclus veut dire que vous devez envoyer un tel paramètre, sous peine de provoquer éventuellement une erreur. La personne ayant codé la fonction prévient ainsi qu'il n'a pas placé de filtre. 20.0 c'est ok. 21 ou 20.1 non.

Ces spécification d'entrée sont également nommés des preconditions.

Les spécification de sortie (le return) sont des certitudes que l'utilisateur peut avoir sur la nature de ce que renvoie la fonction ou la procédure. Sous condition que les paramètres d'entrée envoyés soient corrects ! :: return (int/float) :: entier, entre 0 et 10 inclus veut donc dire qu'on peut avoir la certitude que la réponse de la fonction est un integer compris entre 0 et 10. Pourquoi noter nombre entier et pas int ? Simplement car 5.0 // 2 renvoie 2.0, un nombre entier mais encodé comme un float, pas comme un int.

Ces spécification de sortie sont également nommés des postconditions.

Dans la norme RST, on sépare l'explication du paramètre et son type, comme avec le return :

:param note: nombre dans [ 0 ; 20 ] :type note: int or float

Ma version personnelle est plus concise mais ne sera pas comprise lors d'une génération automatique de documentation :

:: param note (int/float) :: entre 0 et 20 inclus

Bien entendu, on peut également réaliser des procédures avec des paramètres :

1 2 3 4 5 6 7 8 9 10 11 12 13
def presentation(nom, prenom, profession) : '''Affiche un texte formaté présentant le personnage :: param nom (str) :: le nom du personnage :: param prenom (str) :: le prenom :: param profession (str) :: la description de la profession :: return (None):: (c'est une procédure) ''' print(f"Nom\t{nom}\nPre.\t{prenom}\nPro.\t{profession}") presentation("Skywalker", "Luke", "Jedi sur le retour") presentation("Yoda", "Juste Yoda", "Maitre Jedi tout vert")

✎ 02° Tester la procédure ci-dessus et changer les valeurs fournies lors des appels lignes 12 et 13 pour voir si vous avez bien compris le principe. Quelle doit être la nature des paramètres d'après le concepteur de la procédure (voir la documentation) ?

03° Transformer cette procédure en fonction en tenant compte des spécifications d'entrée signalées et en respectant les spécifications de sortie.

1 2 3 4 5 6 7 8 9 10 11 12 13 14
def presentation(nom, prenom, profession) : '''retourne un texte formaté présentant le personnage :: param nom(str) :: le nom du personnage :: param prenom(str) :: le prenom :: param profession(str) :: décrit la profession :: return (str) :: contient la description créée ''' ???(f"Nom\t{nom}\nPre.\t{prenom}\nPro.\t{profession}") descLuke = presentation("Skywalker", "Luke", "Jedi sur le retour") print(descLuke) print(presentation("Yoda", "Juste Yoda", "Maitre Jedi tout vert"))

...CORRECTION...

1 2 3 4 5 6 7 8 9 10 11 12 13 14
def presentation(nom, prenom, profession) : '''retourne un texte formaté présentant le personnage :: param nom(str) :: le nom du personnage :: param prenom(str) :: le prenom :: param profession(str) :: décrit la profession :: return (str) :: contient la description créée ''' return(f"Nom\t{nom}\nPre.\t{prenom}\nPro.\t{profession}") descLuke = presentation("Skywalker", "Luke", "Jedi sur le retour") print(descLuke) print(presentation("Yoda", "Juste Yoda", "Maitre Jedi tout vert"))

04° Compléter le prototype (la ligne def) de la fonction note_valide pour qu'elle fonctionne correctement. Pour l'instant, elle ne possède aucun paramètre.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
def note_valide() : '''Renvoie True si note est dans l'intervalle [ 0 ; 20 ] :: param note (int/float) :: la note à tester :: return (bool):: True si note dans [ 0 ; 20 ] ''' if note > 20 : return False elif note < 0 : return False else : return True reponse = note_valide(5) print(reponse)

...CORRECTION...

Il suffit de compléter l'en-tête de la fonction. Vous auriez pu vous en rendre compte en exécutant le code fourni sans le modifier. On obtient alors :

Traceback (most recent call last): File "/home/rv/test5.py", line 18, in reponse = note_valide(5) TypeError: note_valide() takes 0 positional arguments but 1 was given

Il suffit donc d'écrire ceci :

def note_valide(note) :
Documentation rapide des paramètres et du retour

Pour information, il existe également un moyen plus rapide de décrire le type des paramètres attendus et le type du retour.

Néanmoins, ce type de documentation est moins détaillé puisqu'on ne pas pas y mettre de phrases par exemple.

1 2 3
def plusGrand(a:int, b:int) -> bool : '''Renvoie True si l'entier a est plus grand que l'entier b. False sinon''' return a > b

Ici, on voit dans la déclaration de la fonction que a et b sont attendus en tant qu'integer (codification : nom de la variable suivi de : suivi du type attendu) et que la réponse sera un booléen (codification : -> suivi du type de la réponse).

Nous alternerons cette année entre ces deux types de documentation. Elles ont des avantages et des désavantages l'une et l'autre.

Après cette partie, on voit donc que la fonction informatique se rapproche fortement de la fonction mathématique :

  • On fournit des données d'entrée (soumises à des preconditions ou spécifications d'entrée) à la fonction (contenues dans les paramètres de la fonction informatique)
  • auxquelles on applique un certain nombre d'instructions qui permettent
  • de déterminer une sortie (qu'on transmet via le return de la fonction informatique) soumise à des postconditions ou spécifications de sortie.
  • représentation d'une fonction

2 - Arguments et paramètres

Vocabulaire : argument et paramètre

Arguments et paramètres caractérisent simplement :

  • ce qu'on envoie à la fonction : les arguments
  • ce qui est utilisé pour stocker les informations reçues : les paramètres

Voici un exemple :

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
def note_valide(note) : '''Renvoie True si note est dans l'intervalle [ 0 ; 20 ] :: param note (int/float) :: la note à tester :: return (bool):: True si note dans [ 0 ; 20 ] ''' if note > 20 : return False elif note < 0 : return False else : return True reponse = note_valide(5) print(reponse)

Dans ce cas :

  • 5 est un argument : c'est ce qu'on envoie à la fonction
  • note est un paramètre : on l'utilise pour stocker une copie de l'argument.

05° Analyser le programme suivant sans le lancer. Répondre aux questions puis vérifier vos réponses en lançant directement le code.

  • 5.1 Que contient note-du-programme à la ligne 5 ?
  • 5.2 Que contient l'argument envoyé à la fonction lors de la ligne 6 ?
  • 5.3 Que contient alors note-de-la-fonction à la ligne 1 ?
  • 5.4 Que contient note-de-la-fonction à la ligne 2 ?
  • 5.5 Quelle est l'information renvoyée par la fonction sur la ligne 3 ?
  • 5.6 Que contient alors note2-du-programme une fois revenu sur la ligne 6 ?
  • 5.7 Qu'affiche la ligne 7 ?
  • 5.8 Qu'affiche la ligne 8 ?
1 2 3 4 5 6 7 8
def fois_deux(note) : note = note * 2 return note note = 10 note2 = fois_deux(note) print(note) print(note2)

...CORRECTION...

  • 5.1 Que contient note-du-programme à la ligne 5 ? 10

  • 5.2 Que contient l'argument envoyé à la fonction lors de la ligne 6 ? On transmet le contenu de note donc 10

  • 5.3 Que contient alors note-de-la-fonction à la ligne 1 ? 10

  • 5.4 Que contient note-de-la-fonction à la ligne 2 ? 20 mais attention, il y a eu affection : il s'agit d'une nouvelle variable locale qui a écrasé l'ancienne. L'ID de la variable note-de-la-fonction ligne 2 ne correspond pas à l'ID de la variable note-de-la-fonction ligne 1

  • 5.5 Qu'elle est l'information renvoyée par la fonction sur la ligne 3 ? 20

  • 5.6 Que contient alors note2-du-programme une fois revenu sur la ligne 6 ? 20

  • 5.7 Qu'affiche la ligne 7 ? 10 ! En effet, la variable globale note-du-programme n'est pas la variable locale note-de-la-fonction, même si elles portent le même nom. L'espace des noms permet de faire la différence.

  • 5.8 Qu'affiche la ligne 8 ? 20.
Bonne pratique

J'ai fourni un code avec deux instructions pour vous laissez le temps de comprendre comment ça fonctionne : j'ai crée une variable note globale et une variable note locale. Mais encore une fois, en une ligne, c'est fait :

1 2
def fois_deux(note) : return note * 2

Sauf que là, il n'y aurait eu aucun doute sur les variables portant le même nom...

3 - Documentation rapide avec typing

Taper de la documentation permet de bien comprendre ce que fait une fonction. Par contre, c'est long...

Certaines fonctions ont une documentation qui dépasse de loin en taille le code de la fonction elle-même !

1 2 3 4 5 6 7 8 9 10 11 12 13
def convertir_sur_10(note) : '''Renvoie une note sur 10 à partir d'une note sur 20 :param note: nombre dans [ 0 ; 20 ] :type note: int or float :return: la note convertie sur 10 , dans [ 0 ; 10 ] :rtype: int or float .. note:: le retour a le même type que le paramètre note ''' return note // 2

Pour ces fonctions, où le code n'est pas long et où on peut comprendre assez facilement ce qu'on veut faire, on peut passer par une documentation moins longue (avantage) mais moins précise (désavantage).

Exemple :

1 2 3
def convertir_sur_10(note:int) -> int : '''Renvoie une note sur 10 à partir d'une note sur 20''' return note // 2

Il s'agit bien d'une documentation : on dit que

  • le paramètre note devrait être un integer (note:int) et
  • que la fonction renvoie un integer (-> int).

Si la fonction ne renvoie rien (c'est une sorte de procédure), il suffit de dire qu'elle renvoie None ou ne rien signaler. Mais autant être explicite.

Exemple :

1 2 3 4 5 6
def afficher_le_plus_grand(a:int, b:int) -> None : '''Affiche la plus grande valeur dans la console''' if a > b : print(a) else : print(b)

Conclusion : cette forme de documentation est pratique mais moins complète qu'une vraie documentation. Elle est par contre très pratique pour fournir le prototype d'une fonction.

On peut ainsi indiquer le nom de la fonction, le nom ET le type attendu des paramètres et de la réponse renvoyée.

4 - Portée des variables globales

Nous avons donc vu les variables locales. Il reste à voir les variables globales.

Variables globales

On nomme variables globales toutes les variables définies en dehors des fonctions. Elles sont donc directement définies dans le programme principal.

06° Utilisez le programme ci-dessous dans Thonny (en mode DEBUG en utilisant Step Into pour aller dans la procédure) ou simplement Python Tutor. Ce programme permet d'afficher le contenu de quelques variables et surtout affiche l'identifiant mémoire de la variable ennemi (en ne gardant que le reste après division par 1000 pour avoir un affichage plus lisible). Répondre aux questions suivantes  :

  • la variable ennemi est-elle déclarée et affectée (avec un  = ) dans la procédure ?
  • la variable ennemi est-elle globale ou locale du coup ?
  • une variable globale (définie dans le corps du programme) peut-elle être lue dans une fonction ?
1 2 3 4 5 6 7 8 9 10 11 12 13
# PARTIE 1 - Variables globales définies dès le départ ennemi = 'Darth Vador' # PARTIE 2 - Déclaration des fonctions def presentation(nom) : print(f"\n{nom} vs {ennemi}") print(f"Dans la fonction : ennemi a comme id {id(ennemi)%1000}") # PARTIE 3 - Programme principal print(f"Dans le corps du programme : ennemi a comme id {id(ennemi)%1000}") presentation("Yoda") presentation("Luke")

...CORRECTION...

On voit clairement que la variable ennemi-du-programme-principal est définie en dehors des fonctions. On ne trouve aucune affectation d'une variable portant ce nom dans les fonctions : nulle part dans les fonctions n'apparait ennemi = ...

Il s'agit donc d'une variable globale.


Le programme pourrait afficher ceci :

Dans le corps du programme : ennemi a comme id 520 Yoda vs Darth Vador Dans la fonction : ennemi a comme id 520 Skywalker vs Darth Vador Dans la fonction : ennemi a comme id 520

On voit donc que les fonctions et les procédures peuvent accéder et lire le contenu associé à une variable globale dans Python. En effet, depuis les fonctions, on lit bien le contenu associé à l'id de ennemi. 520 ici.

On voit donc que les fonctions peuvent accéder aux variables globales.

Cela veut dire que les fonctions parviennent à accéder à ennemi-du-programme-principal.

Mais peuvent-elles les modifier ?

07° Modifier le code de la procédure presentation comme proposé (rajout de la ligne 7, en jaune).
Lancer le code en mode pas à pas (dans Thonny ou Python Tutor) et répondre aux questions suivantes :

  • Quel est l'id de ennemi-du-programme-principal dans le corps du programme ?
  • Dans presentation, quel est l'id de cette variable ? Devrait-on la nommer ennemi-du-programme-principal ou ennemi-de-presentation ?
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# PARTIE 1 - Variables globales définies dès le départ ennemi = 'Darth Vador' # PARTIE 2 - Déclaration des fonctions def presentation(nom) : ennemi = "Sénateur Palpatine" print(f"\n{nom} vs {ennemi}") print(f"Dans la fonction : ennemi a comme id {id(ennemi)%1000}") # PARTIE 3 - Programme principal print(f"Dans le corps du programme : ennemi a comme id {id(ennemi)%1000}") presentation("Yoda") print(f"Dans le corps du programme, ennemi reste {ennemi}")

...CORRECTION...

On peut croire que la variable ennemi est modifiée dans la fonction. Mais non !

Le programme pourrait afficher ceci :

Dans le corps du programme : ennemi a comme id 024 Yoda vs Sénateur Palpatine Dans la fonction : ennemi a comme id 976 Dans le corps du programme, ennemi reste Darth Vador

Il suffit de regarder les id pour voir ce qui se passe.

  • Dans le programme principal : ennemi_du_programme_principal a comme id 024.
  • Dans la fonction presentation : ennemi-de-presentation a comme id 976 : il ne s'agit donc pas de la même variable que la précédente : on fait référence à une autre zone mémoire.
  • Lorsqu'on revient dans le programme, on affiche Darth Vador puisqu'il s'agit de la variable ennemi_du_programme_principal

08° Alors, la fonction presentation a-t-elle réussi à modifier réellement la variable ennemi-du-programme-principal ?

...CORRECTION...

Non, la ligne 8, ennemi = "Sénateur Palpatine", ne permet que de créer une variable locale ennemi-presentation portant le même nom que la variable globale ennemi-du-programme-principal. Mais leurs ids sont différents : il s'agit donc bien de variables différentes.

09° La variable ennemi-presentation-yoda existe-elle encore à la ligne 20  ?

...CORRECTION...

Non. Il s'agit d'une variable locale à la fonction. La référence est donc détruire lorsqu'on sort de la fonction.

Deux dernières questions pour voir si vous avez bien compris cette partie assez délicate :

10° Que vont afficher les lignes du programme suivant ? Donnez les réponses dans l'ordre d'exécution !

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
# - - - Variables globales définies dès le départ ennemi = 'Darth Vador' # - - -Déclaration des fonctions - - - - def presentation_yoda() : nom = "Yoda" print(ennemi) ennemi = "Sénateur Palpatine" print(ennemi) def presentation_luke() : nom = "Skywalker" print(ennemi) # - - - Programme principal - - - - - - - - - print(ennemi) presentation_yoda() presentation_luke()

...CORRECTION...

Ligne 17 : la variable ennemi-programme-principal contient 'Darth Vador'.

Ligne 08 : la variable ennemi-presentation-yoda n'existe pas. L'interpréteur va donc chercher dans l'espace des noms pour trouver une variable globale portant le nom ennemi-programme-principal. Il trouve. Le print va donc afficher 'Darth Vador'.

Ligne 10 : une variable ennemi-presentation-yoda a été déclarée juste au dessus. Cette fois, l'espace des noms de la fonction trouve donc une référence locale. Le print va donc afficher "Sénateur Palpatine".

Ligne 14 : la variable ennemi-presentation-luke n'existe pas. L'interpréteur va donc chercher dans l'espace des noms pour trouver une variable globale portant le nom ennemi-programme-principal. Il trouve. Le print va donc afficher 'Darth Vador'.

Portée des variables globales

Si on résume la portée des variables globales en image, ça donne ceci :

portee-variable-globale

La fonction peut lire la variable globale tant qu'on ne tente pas d'y faire une affectation sur une variable portant le même nom (avec un =).

Si la fonction utilise une affectation sur ce nom de variable, la fonction crée simplement une variable locale portant le même nom que la variable globale.

Une fonction ne peut donc pas modifier une variable globale.

5 - Plus loin : mot-clé Global

Cette partie comporte des informations qui ne sont pas au programme de NSI. On va vous montrer une fois qu'on peut modifier les variables globales depuis une fonction. Ensuite, il ne faudra plus le faire. Cela pose des problèmes de stabilité et de solidité des applications réalisées.

Par contre, on trouve sur le Web de nombreux codes qui l'utilise. Bref, autant savoir que ça existe, même si son utilisation n'est pas autorisée ou conseillée.

Comment faire alors pour modifier la variable globale ennemi-programme-principal depuis une fonction ? Cela pourrait être sympathique de pouvoir changer l'ennemi en fonction de la saga non ?

Voyons comment avec ce petit bout de cours :

Rappel : comportement de Python par défaut
  • une fonction peut lire une variable globale.
  • une fonction ne peut pas modifier une variable globale
    • l'utilisation d'une affectation (=) crée simplement une variable locale portant le même nom.
Nouveau : modification du comportement par défaut
  • une fonction peut modifier une variable globale si on lui en donne l'autorisation :
    • en utilisant le mot-clé global suivi du nom de la variable avant de l'affecter

Mise en pratique immédiate :

1 2 3 4 5 6 7 8 9
ennemi = "Darth Vador"
def test(): global ennemi ennemi = "Palpatine"
print(ennemi) test() print(ennemi)

Ligne 7 : On affiche le contenu "Darth Vador"

Lignes 8 puis 4 et 5 : On permet à la fonction de modifier la variable en "Palpatine"

Ligne 9 : La variable globale contient bien "Palpatine" maintenant.

11° Lancer ce programme sur Python Tutor ou Thonny en mode DEBUG pour visualiser la modification du contenu de la variable.

12° Utiliser maintenant Thonny en mode DEBUG avec visualisation du tas (heap) pour connaitre le contenu ET l'id de la variable au cours de l'execution du programme. L'id de la variable globale a-t-elle été modifié après la ligne 5 ? Pour vous convaincre de la différence sans la ligne 4, vous pouvez la supprimer et relancer un nouveau debug.

CLIQUEZ ICI POUR VOIR LE CONTENU DES VARIABLES :

test :

ennemi :


Id 0x6E18 :

Id 0x3FC0 :

Id 0xB030 :

1 2 3 4 5 6 7 8 9
ennemi = "Darth Vador"
def test(): global ennemi ennemi = "Palpatine"
print(ennemi) test() print(ennemi)

Voilà, nous sommes parvenus à modifier une variable globale depuis une fonction. Attention, n'oubliez pas que la variable change d'identifiant associé, comme à chaque fois qu'on utilise une affectation  = .

Spécificités des portées en fonction des variables

La portée des variables globales et locales, ainsi que la façon dont on peut les modifier est variable en fonction du langage de programmation. Il s'agit d'une des premières choses qu'il faut regarder et comprendre lorsqu'on s'attaque à un nouveau langage. Pour vous, c'est fait avec Python maintenant.

Note finale : Limitez l'utilisation des variables globales !

La modification des variables globales avec global doit rester marginale dans vos programmes. Il est en effet difficile de maintenir fonctionnel un code qui comporte plusieurs variables modifiées par plusieurs fonctions créées par des personnes différentes.

Si vous devez utilisez des variables globales (même en lecture simple), respectez au moins ces trois points :

  1. Placer les clairement en début de code dans la partie adéquate de façon à clairement les mettre en évidence.
  2. Placer des commentaires pour expliquer à quoi elles servent
  3. Donner leur des noms suffisamment rares pour que quelqu'un ne les écrase dans une fonction par une variable locale portant le même nom : si l'une de vos variables globales se nomme x, il ne faudra pas vous plaindre si l'une des personnes de votre équipe utilise aussi ce nom dans l'une de ses fonctions !

Sachez que nous verrons plus tard des outils nous permettant de nous passer des modifications de variables globales depuis les fonctions. Vous pouvez donc les utiliser pour l'instant, mais gardez à l'esprit qu'il s'agit plutôt d'une mauvaise pratique.

Nous allons encore en découvrir beaucoup sur les fonctions.

Si on récapitule, nous avons vu aujourd'hui :

  • la différence entre fonction (avec retour) et procédure (sans retour)
  • les paramètres
  • la différence entre arguments et paramètres

Dans l'activité suivante, nous allons voir comment travailler en équipe sur un projet utilisant les fonctions (c'est le cas de 100% des projets) :

  • créer une documentation
  • les doctest visant à fournir de la documentation ET à tester les fonctions
  • la structuration d'un programme complexe en multiples petites fonctions

Activité publiée le 28 08 2019
Dernière modification : 27 09 2020
Auteur : ows. h.