Semaine 2 - Jour 1 - 420-SN1

LES FONCTIONS

vues comme des travailleurs

Une fonction, c'est un travailleur

Un travailleur attend dans l'atelier qu'on lui confie une mission. Tant qu'on ne l'appelle pas, il ne bouge pas : il reste la, pret a servir.

Une fonction, c'est pareil : on la definit une fois, puis on la fait travailler autant de fois qu'on veut.

def : on l'embauche et on lui donne un nom

def saluerLaForet(): print("Bonjour la foret !") # On envoie le travailleur au boulot en l'APPELANT : saluerLaForet()

def forme le travailleur et inscrit son nom sur sa salopette. Tant qu'on ne l'appelle pas (saluerLaForet()), il reste les bras croises dans l'atelier.

Trois paliers, du plus simple au complet

1
def saluer(): print("Bonjour !") # ni baluchon, ni ballon
2
def saluer(nom): print("Bonjour", nom) # un baluchon, mais les mains vides
3
def calculerAireRectangle(largeur, hauteur): return largeur * hauteur # un baluchon ET un ballon

On monte une marche a la fois : d'abord une simple action, puis on lui tend un baluchon (un parametre), puis on lui fait relancer un ballon (un return).

Sans baluchon : il fait juste son travail

def saluer(): print("Bonjour le chantier !") # Les parentheses restent vides saluer() saluer() # on peut le rappeler autant de fois qu'on veut

Le palier le plus simple : aucun parametre. Pas de baluchon a lui tendre, les parentheses restent vides : saluer(). On l'appelle, il fait son action - ici, afficher un message.

Un baluchon, mais pas de ballon

def saluer(nom): print("Bonjour", nom) saluer("Maya") # Bonjour Maya saluer("Liam") # Bonjour Liam

On lui tend un baluchon (le parametre nom) et il s'en sert pour son action. Mais il ne relance aucun ballon : pas de return. La fonction agit (elle affiche), elle ne rend pas de valeur.

on lui tend →

Le baluchon : les parentheses

def calculerAireRectangle(largeur, hauteur): return largeur * hauteur # Dans les parentheses : le baluchon qu'on lui tend print(calculerAireRectangle(3, 4))

Les parentheses, c'est le baluchon qu'on glisse dans la main du travailleur en l'envoyant. Ce qu'on met dedans (les arguments), il le retrouve dans ses parametres : ici largeur vaut 3 et hauteur vaut 4.

on lui tend →

Le ballon : return

# Il finit son travail et relance le ballon : def calculerAireRectangle(largeur, hauteur): return largeur * hauteur # On attrape le ballon dans une variable : superficieJardin = calculerAireRectangle(5, 2) print(superficieJardin) # 10

return, c'est le lancer du ballon : a la fin, le travailleur te relance le resultat. Tu l'attrapes dans une variable (superficieJardin) et tu peux t'en reservir partout ensuite.

→ te relance

Les mains vides, ou le ballon ?

SANS return

  • il fait son action (dessiner, afficher)...
  • ...puis revient les mains vides
  • Python te rend None
def saluerLaForet():
    print("Bonjour !")

AVEC return

  • il fait son calcul...
  • ...puis te relance le ballon
  • tu attrapes la valeur dans une variable
def calculerAireRectangle(l, h):
    return l * h

Ce qui distingue les deux, c'est le ballon (le return), pas le baluchon : une procedure aussi peut recevoir un baluchon. La vraie question, c'est : est-ce qu'il te renvoie quelque chose ?

Le meme travailleur, plusieurs baluchons

def calculerAireRectangle(largeur, hauteur): return largeur * hauteur print(calculerAireRectangle(3, 4)) # 12 print(calculerAireRectangle(5, 2)) # 10 print(calculerAireRectangle(7, 1)) # 7

On embauche le travailleur une seule fois, puis on le rappelle avec un baluchon different a chaque fois. C'est toute la puissance des fonctions : ecris une fois, reutilise partout.

Son baluchon reste sur le chantier

def calculerAireRectangle(largeur, hauteur): resultat = largeur * hauteur return resultat print(calculerAireRectangle(5, 2)) # 10 print(largeur) # ERREUR : largeur n'existe pas ici

Ce qu'il y a dans le baluchon (largeur, hauteur, resultat) n'existe que pendant sa mission, sur le chantier.

Une fois le travail fini, tout ca disparait. Pour garder un resultat, il faut le relancer avec return : c'est ce qu'on appelle des variables locales.

Deleguer : il appelle un collegue

def dessinerCercles(tortue, taille, nombreCercles): for cercle in range(nombreCercles): tortue.circle(taille) def dessinerMandala(tortue, taille, repetitions): for tour in range(repetitions): dessinerCercles(tortue, taille, 6) tortue.right(360 / repetitions)

dessinerMandala appelle son collegue dessinerCercles a chaque tour. On batit un gros travail en faisant collaborer de petits travailleurs bien nommes.

La fiche de poste : la docstring

def calculerAireRectangle(largeur, hauteur): """Renvoie l'aire d'un rectangle (largeur x hauteur).""" return largeur * hauteur # N'importe qui peut lire sa fiche de poste : help(calculerAireRectangle)

La docstring, c'est la fiche de poste du travailleur : une phrase entre triples guillemets """…""", juste sous le def.

Elle decrit sa mission : ce qu'il prend dans son baluchon et le ballon qu'il relance. help() l'affiche a quiconque arrive sur le chantier.

Le contremaitre inspecte : assert

def calculerAireRectangle(largeur, hauteur): return largeur * hauteur # Le contremaitre verifie le ballon qu'on lui relance : assert calculerAireRectangle(3, 4) == 12 assert calculerAireRectangle(0, 5) == 0 assert calculerAireRectangle(2, 2) == 4

assert, c'est le contremaitre qui verifie que le travailleur relance bien le bon ballon. Si la valeur est fausse, le programme s'arrete et signale le bug.

Inspecter sa machine avant de s'en servir, c'est l'habitude des bons equipes.

Et si demain je veux…

def compterArbres(foret): # ... il compte ... return f"{compteurBouleau} bouleaux, {compteurSapin} sapins"

Ca marche ! Mais ce travailleur fait deux metiers a la fois : il compte et il redige la phrase.

  • … les memes chiffres dans un graphique a barres ?
  • … la phrase en anglais ?
  • additionner les sapins de deux forets ?

Avec un ballon qui contient deja une phrase toute faite, impossible : il faut tout reecrire. Le probleme n'est pas la f-string - c'est qu'on a charge le compteur de rediger en plus.

Une mission par travailleur

def compterArbres(foret): # METIER : compter # ... il compte ... return compteurBouleau, compteurSapin, compteurEpinette def decrireForet(bouleau, sapin, epinette): # METIER : mettre en mots return f"{bouleau} bouleaux, {sapin} sapins et {epinette} epinettes" # Le chef d'equipe fait circuler les ballons d'un travailleur a l'autre : bouleau, sapin, epinette = compterArbres(maForet) print(decrireForet(bouleau, sapin, epinette))

La f-string d'Adem a sa place - mais dans le travailleur decrireForet, pas chez le compteur. Besoin d'un graphique demain ? J'embauche un nouveau travailleur dessinerForet et je garde compterArbres tel quel. Le compteur ne change jamais.

La regle d'or

QUI CALCULE

  • fait un calcul
  • relance un ballon (return)
  • jamais de print
def compterArbres(foret):
    return total

QUI AFFICHE

  • montre a l'ecran
  • print seulement
  • jamais de calcul
def afficherForet(texte):
    print(texte)

Un travailleur qui calcule relance son ballon et n'affiche jamais. Un travailleur qui affiche ne calcule jamais. Chacun, un seul metier.

A TOI DE JOUER

Ouvre le jardin de mandalas. Repere les blocs de code repetes. Embauche tes propres travailleurs (des fonctions), tends-leur le bon baluchon (les parametres) et fais-les te relancer le ballon (return).

code.experimentations.xyz/fun/jardin/

AU TRAVAIL !

Seance 2-1 : transforme ton code repete en travailleurs, baluchon a l'entree, ballon au retour
⤺ Refermer le diaporama