Mathématiques avec Python et Ruby/Fonctions en Python

Un livre de Wikilivres.

On va traiter un exemple de fonction, issu du Bac STG CGRH Métropole-Réunion de Septembre 2007:

Définition des fonctions[modifier | modifier le wikicode]

Énoncé[modifier | modifier le wikicode]

Extrait du sujet de l'exercice 3:
Une entreprise produit des appareils électroménagers. Le coût horaire de production de x appareils est donné en euros par :

pour

Et plus bas, dans le même exercice,

le coût moyen est défini par
Le coût moyen de production d’un objet est égal à

pour x appartenant à [5 ; 40].

Fonctions et procédures sous Python[modifier | modifier le wikicode]

Une fonction est un petit bout de programme Python qui possède un nom (typiquement f), et qui renvoie une valeur (l'image de x, son unique antécédent, par f). Une procédure est une fonction qui ne renvoie rien.

Les fonctions du sujet de Bac ci-dessus peuvent être définies par def en Python:

def C(x):
    return x**2+50*x+100.0


def f(x):
    return C(x)/x

Si on essaye de calculer l'image de 0 par f, on remarque qu'en lieu et place du calcul, Python affiche un message d'erreur: La fonction f n'est pas definie en 0. On peut aussi la définir directement par

def f(x):
    return x+50+100.0/x

On peut aussi définir des fonctions de plusieurs variables (comme le pgcd) ou des fonctions définies par des boucles ou des tests, comme la valeur absolue:

def abs(x):
    if x>0:
        return x
    else:
        return -x

Tableau de valeurs[modifier | modifier le wikicode]

Suite de l'énoncé du Bac 2007[modifier | modifier le wikicode]

Par la suite, on demande de reproduire et compléter le tableau suivant, arrondi au centième d'euro:

x 5 10 20 30 40
f(x)

Solution en Python[modifier | modifier le wikicode]

Pour remplir le tableau, on peut

  1. Faire 5 fois un print(f(x)) pour les 5 valeurs de x de l'énoncé;
  2. Faire une boucle avec les 5 valeurs de x de l'énoncé;
  3. Faire une boucle avec suffisamment de valeurs de x pour couvrir les 5 valeurs de l'énoncé;
  4. Transformer f en une fonction qui peut s'appliquer à une liste de valeurs et non à une valeur unique.

La méthode 3 peut se faire avec un itérateur de Python:

for x in range(5,40,5):
    print("l\'image de "+str(x)+" par f est "+str(f(x)))

Trop de calculs tuent le calcul! Les images de 25 et 35 par exemple encombrent le tableau. Mais Python permet d'utiliser des itérateurs beaucoup plus souples, et adaptés au problème présent:

for x in [5,10,20,30,40]:
    print("l\'image de "+str(x)+" par f est "+str(f(x)))

La méthode 4 peut s'implémenter en Python avec:

print([f(x) for x in [5,10,20,30,40]])

C'est aussi simple que ça!

Arrondis[modifier | modifier le wikicode]

L'énoncé demandait d'arrondir au centième d'euro près

for x in [5,10,20,30,40]:
    print("l\'image de "+str(x)+" par f est "+str(round(f(x),2)))

Représentation graphique[modifier | modifier le wikicode]

Pour représenter graphiquement une fonction comme f ci-dessus, on trace un polygone ayant suffisamment de sommets, et ceux-ci suffisamment proches les uns des autres, pour que la courbe ait l'air courbe. Plusieurs outils permettent de faire du graphisme avec Python mais le plus simple semble être le module tortue.

Avec Turtle[modifier | modifier le wikicode]

Courbe[modifier | modifier le wikicode]

Le plus simple est de faire

from turtle import *
setpos(5,f(5))
for x in range(5,40):
    setpos(x,f(x))

Difficile de rêver plus simple mais on peut voir trois problèmes:

  1. Il manque les axes
  2. Le trait qui relie l'origine au point de coordonnées (5;f(5)) est en trop
  3. La tortue gêne la visibilité de la figure

Courbe améliorée[modifier | modifier le wikicode]

Pour résoudre le deuxième problème, il suffit de lever le crayon avec penup() avant de commencer le tracé (et de le redescendre pour le tracé lui-même). Pour résoudre le troisième problème, il suffit de rendre la tortue invisible avec hideturtle(). Pour les axes, on peut les tracer avec la tortue:

from turtle import *
penup()
setpos(5,f(5))
pendown()
for x in range(5,40):
    goto(x,f(x))

penup()
setpos(0,0)
pendown()
for x in range(0,50,10):
    left(90)
    forward(2)
    backward(4)
    forward(2)
    right(90)
    forward(10)

stamp()
backward(50)
left(90)
for y in range(0,100,10):
    left(90)
    forward(2)
    backward(4)
    forward(2)
    right(90)
    forward(10)

stamp()

Le graphique est correct mais un peu petit et mal cadré.

Avec TkInter[modifier | modifier le wikicode]

TkInter permet de créer un affichage dans un canevas, lui-même membre d'une fenêtre. Il y a donc plusieurs lignes de Python à écrire avant même de commencer à dessiner. Et l'axe des ordonnées est dirigé vers le bas, ce qui oblige à une transformation des ordonnées. En contrepartie, on a un outil de dessin tout-à-fait correct, et même relativement classique. Et, bien que ce ne soit pas utile dans le cas présent, on peut avoir des boutons, curseurs etc.

On doit donc commencer par

  1. importer tkInter (s'installer dans l'atelier du peintre)
  2. créer une fenêtre (monter le chevalet, un cadre...)
  3. y placer un canevas (tendre la toile sur le chevalet)
  4. afficher le canevas avec pack (enlever la couverture qui cache le chef-d'œuvre)
  5. Enfin, dessiner (axes et fonction)

Ce qui peut donner ceci:

from tkinter import *
fenetre=Tk()
graphique=Canvas(fenetre,width=640,height=480)
graphique.pack()

#axe des abscisses
graphique.create_line(20,460,520,460)
for n in range(0,50,10):
    graphique.create_line(20+10*n,460,20+10*n,455)
for n in range(0,50,5):
    graphique.create_line(20+10*n,460,20+10*n,457)
for n in range(0,50):
    graphique.create_line(20+10*n,460,20+10*n,459)

#axe des y
graphique.create_line(20,460,20,60)
for n in range(0,100,10):
    graphique.create_line(20,460-4*n,25,460-4*n)
for n in range(0,100,5):
    graphique.create_line(20,460-4*n,24,460-4*n)
for n in range(0,100):
    graphique.create_line(20,460-4*n,22,460-4*n)

#courbe
for x in range(5,40):
    graphique.create_line(20+10*x-10,460-4*f(x-1),20+10*x,460-4*f(x))