Aller au contenu

Fonctions

En cours

Ce chapitre est en cours de construction. Il est déconseillé de s'y attaquer pour le moment.

A propos du chapitre

Objectif :

  • Comprendre ce qu'est une fonction
  • Déclarer et appeler une fonction
  • Utiliser des fonctions pour structurer le code
  • Réfléchir à la structure d'un problème
  • Utiliser des fonctions écrites par d'autres
  • Faire un dessin plus complexe avec moins de prise de tête:

TODO examples ici

Modalités :

  • Programmation (Basthon)
  • De la réflexion autour du code

Prérequis : "Programmation/Boucle for"

Difficulté : facile. Mais un peu perché tant qu'on a pas compris l'idée.

Introduction et magie

A la fin du précédent chapitre, j'avais dit :

Le code commence à devenir très compliqué à gérer, tellement que ça en devient critique.

Donc si on veut faire un dessin complexe, il nous faut un outils pour gérer la complexité.

C'est l'objet du prochain chapitre : fonctions.

Activité : trolling

Vérifiez que le titre du chapitre est bien "fonctions"

Solution

Ca y est, on y est ! Les F O N C T I O N S !!!!!

On va donc commencer par voir ce qu'est une fonction, puis s'entrainer un peu à les utiliser sur des programmes simples, et enfin comprendre comment on peut les utiliser pour structurer le code et faire des programmes complexes sans trop d'effort.

Fonction ?

Voici un petit programme qui dessine un rectangle paramétrisé sur sa position et ses dimensions :

from turtle import *

hauteur_rectangle = 100
largeur_rectangle = 200
position_x = 0 
position_y = 0 

penup()
goto(position_x, position_y)
pendown()
setheading(90) #on oriente la tortue vers le nord 
forward(hauteur_rectangle)
right(90)
forward(largeur_rectangle)
right(90)
forward(hauteur_rectangle)
right(90)
forward(largeur_rectangle)

done()

Vous vous rappelez ? L'intérêt de paramétriser un programme, c'était de pouvoir le réutiliser facilement en changeant juste les paramètres...

Les fonctions permettent de faire ça au sein du même programme, en créant des sous-programmes paramétrisés !

Remarque

Les fonctions en programmation sont différentes des fonctions en mathématiques, même si elles ont beaucoup de similarités.

ce sujet est discuté plus en détail dans l'extension Lien avec les maths.

Réécrivons-donc le programme précédent avec une fonction :

from turtle import *

def dessiner_rectangle(x, y, largeur, hauteur):
    penup()
    goto(x, y)
    pendown()
    setheading(90) #on oriente la tortue vers le nord 
    forward(hauteur)
    right(90)
    forward(largeur)
    right(90)
    forward(hauteur)
    right(90)
    forward(largeur)

dessiner_rectangle(0, 0, 200, 100)

done()

Activité : me faites pas trop confiance

Executez le programme ci-dessus pour vérifier qu'il fait bien ce qu'on attend.

Le code a été transformé comme ça :

schema

La ligne avec def permet de donner un nom a la fonction, et de déclarer ses paramètres, on l'appelle le prototype:

#   nom de la fonction   param1, p2, p3,      p4
def dessiner_rectangle  (x,      y,  largeur, hauteur):

Le bloc indenté contient les instructions de la fonction, son corps. Dans le corps de la fonction, les paramètres sont des variables :

    penup()
    goto(x, y)
    pendown()
    setheading(90) #on oriente la tortue vers le nord 
    forward(hauteur)
    right(90)
    forward(largeur)
    right(90)
    forward(hauteur)
    right(90)
    forward(largeur)

Le prototype et le corps sont la définition de la fonction (d'où le def). Quand Python lit ces lignes, il enregistre la fonction, pour qu'on puisse l'executer plus tard, mais il ne l'exécute pas.

Pour exécuter la fonction, il faut l'appeler. Et comment on l'appelle ? Par son nom !

Et c'est pas une blague. On utilise le nom de la fonction, et on donne des valeurs pour ses paramètres, dans le même ordre que celui où on les a déclarés.

# nom  fonction    valeur1, v2, v3,      v4
dessiner_rectangle(0,       0,  200,     100)

#def ...          (x,       y,  largeur, hauteur):

Allez, quelques activités pour voir si tout est clair !

Activité : ALLO ?

Reprenez le code du programme avec la fonction :

from turtle import *

def dessiner_rectangle(x, y, largeur, hauteur):
    penup()
    goto(x, y)
    pendown()
    setheading(90) #on oriente la tortue vers le nord 
    forward(hauteur)
    right(90)
    forward(largeur)
    right(90)
    forward(hauteur)
    right(90)
    forward(largeur)

dessiner_rectangle(0, 0, 200, 100)

done()

Et ajoutez un appel pour dessiner un second rectangle.

Solution
from turtle import *

def dessiner_rectangle(x, y, largeur, hauteur):
    penup()
    goto(x, y)
    pendown()
    setheading(90) 
    forward(hauteur)
    right(90)
    forward(largeur)
    right(90)
    forward(hauteur)
    right(90)
    forward(largeur)

dessiner_rectangle(0, 0, 200, 100)

#ici, on rajoute un appel, avec des valeurs différentes.
dessiner_rectangle(0, 120, 100, 40)

done()

Activité : bodybuilding !

Ajoutez un corps à fonction dans le code suivant :

from turtle import *

def dessiner_triangle(x, y, taille):


dessiner_triangle(10, 20, 100)

done()
Solution
from turtle import *

def dessiner_triangle(x, y, taille):
    # on va a la position
    penup()
    goto(x, y)
    pendown()
    # on dessine un triangle
    forward(taille)
    left(120)
    forward(taille)
    left(120)
    forward(taille)

dessiner_triangle(10, 20, 100)

done()

Activité : en entier

Dans un nouveau programme, écrivez et appelez une fonction qui dessine une forme de votre choix.

Solution
from turtle import *

def dessiner_losange(x, y, taille):
    # on va a la position
    penup()
    goto(x, y)
    pendown()
    # on dessine un triangle
    forward(taille)
    left(60)
    forward(taille)
    left(120)
    forward(taille)
    left(60)
    forward(taille)

dessiner_losange(0, 0, 100)

done()

Valeur de retour

TODO implementer ici

Et voilà. Vous venez d'acquérir les bases des fonctions.

Vous ne l'avez pas encore remarqué, mais à mesure que vous progressez dans ce chapitre, votre aura augmente fortement.

C'est parce que les fonctions, quand elles sont bien utilisées, sont un outils qui permettent de dépasser certaines limites du cerveau humain !

Structurer le code : écoupage et abstraction

Imaginons que l'on veuille dessiner la maison de l'activité précédente :

alt text

C'est notre problème. Mais il est compliqué. Alors on peut le découper en un ensemble de sous-problèmes :

  • Dessiner un mur
  • Dessiner un toit
  • Dessiner une porte
  • Dessiner des fenêtres

Visuellement, ça donne ça :

decoupage

On peut continuer le découpage pour chaque sous problème, et ainsi de suite. Par exemple, pour dessiner des fenetres.

decoupage recursif

Quand est-ce qu'on s'arrête ? Quand les problèmes semblent simples à résoudre.

TODO continuer ici, mais est-ce que c'est bon ?

abstraction (ancien)

Une fonction permet de séparer quoi du comment.

Activité : découpage

Activité : le jeu des différences

Voici une maison :

maison abstraction

Et deux versions du code qui dessine la maison :

from turtle import *

speed(0)

largeur_maison = 100
hauteur_maison = 100
taille_toit = 140



penup()
goto(0, 0)
pendown()
setheading(90)
forward(hauteur_maison)
right(90)
forward(largeur_maison)
right(90)
forward(hauteur_maison)
right(90)
forward(largeur_maison)


penup()
goto((largeur_maison - taille_toit) / 2, hauteur_maison)
pendown()
setheading(0)
forward(taille_toit)
left(120)
forward(taille_toit)
left(120)
forward(taille_toit)

done()
from turtle import *

speed(0)



def dessiner_rectangle(x, y, largeur, hauteur):
    penup()
    goto(x, y)
    pendown()
    setheading(90) 
    forward(hauteur)
    right(90)
    forward(largeur)
    right(90)
    forward(hauteur)
    right(90)
    forward(largeur)


def dessiner_triangle(x, y, taille):
    penup()
    goto(x, y)
    pendown()
    setheading(0)
    forward(taille)
    left(120)
    forward(taille)
    left(120)
    forward(taille)

largeur_maison = 100
hauteur_maison = 100
taille_toit = 140

dessiner_rectangle(0, 0, largeur_maison, hauteur_maison)
dessiner_triangle((largeur_maison - taille_toit) / 2, hauteur_maison, taille_toit)

done()

Dans chacune des deux versions du code, encadrez les lignes qui dessinent la maison avec des commentaires :

# début
ICI LE CODE ENCADRÉ 
# fin

IMPORTANT

AVANT DE REGARDEZ LA SOLUTION, DISCUTEZ IMPERATIVEMENT DE VOTRE REPONSE AVEC VOTRE PROF. Ensuite, lisez attentivement la solution.

Solution

Je commence par vous donnez les deux encadrements, puis on en discute :

from turtle import *

speed(0)

# DE LÀ
largeur_maison = 100
hauteur_maison = 100
taille_toit = 140

penup()
goto(0, 0)
pendown()
setheading(90)
forward(hauteur_maison)
right(90)
forward(largeur_maison)
right(90)
forward(hauteur_maison)
right(90)
forward(largeur_maison)


penup()
goto((largeur_maison - taille_toit) / 2, hauteur_maison)
pendown()
setheading(0)
forward(taille_toit)
left(120)
forward(taille_toit)
left(120)
forward(taille_toit)
# A DE LÀ

done()
from turtle import *

speed(0)

def dessiner_rectangle(x, y, largeur, hauteur):
    penup()
    goto(x, y)
    pendown()
    setheading(90)
    forward(hauteur)
    right(90)
    forward(largeur)
    right(90)
    forward(hauteur)
    right(90)
    forward(largeur)


def dessiner_triangle(x, y, taille):
    penup()
    goto(x, y)
    pendown()
    setheading(0)
    forward(taille)
    left(120)
    forward(taille)
    left(120)
    forward(taille)

# DE LÀ
largeur_maison = 100
hauteur_maison = 100
taille_toit = 140

dessiner_rectangle(0, 0, largeur_maison, hauteur_maison)
dessiner_triangle((largeur_maison - taille_toit) / 2, hauteur_maison, taille_toit)
# À DE LÀ

done()

Vous avez sans doute remarqué, avec étonnement, que les fonctions dessiner_triangle et dessiner_rectangle ne sont pas incluses dans le code de la maison. C'est une histoire de point de vue.

Un appel de fonction, comme :

dessiner_rectangle(0, 0, largeur_maison, hauteur_maison)

TODO revoir l'activité ci dessus et faire mieux

Peut-être montrer un arbre de sous-problèmes, et expliquer qu'une fonction permet de "couper" les branches. ?

reprendre du début avec cet exemple ??

ptet leur faire construire un programme en mode "appel d'abord" ?

ouais franchement des arbres de problème proche du code ??

Partage

NE PAS OUBLIER DE PARLER DE VALEUR DE RETOUR

INDEPENDANCE DES APPELS

Extensions

Lien avec les maths