Mathématiques avec Python et Ruby/Fonctions en Ruby

En Ruby, une fonction s'appelle une méthode, mais du point de vue mathématique, ce n'est guère qu'une question de vocabulaire.

Exemple

modifier

Sujet Bac STG CGRH Métropole-Réunion Septembre 2007

modifier
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].

Définition des méthodes

modifier

Donc pour Ruby, C et f seront des méthodes, dont l'antécédent s'appellera x et dont l'image sera envoyée par return:

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


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

Bien entendu, on pouvait aussi définir f directement par

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


Tableau de valeurs

modifier

Suite de l'énoncé du Bac STG 2007

modifier

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)

Tableau de valeurs

modifier

Certes, avec une boucle, on peut calculer plein de valeurs de f(x) différentes:

for x in 5..40 do
    puts("l'image de #{x} par f est #{f(x)}")
end

mais on a trop de valeurs de x pour remplir le tableau. Une meilleure variante sera donc

for x in [5,10,20,30,40] do
    puts("l'image de #{x} par f est #{f(x)}")
end

qui est déjà bien plus léger à exploiter.

Plus typiquement Ruby:

[5,10,20,30,40].collect {|x| puts(f(x))}

Image d'un ensemble par une fonction

modifier

Pour que la fonction f ne s'applique plus seulement à un réel, mais à tous les nombres du tableau, on utilise map (une méthode de l'objet tableau):

[5,10,20,30,40].map { |x| puts(f(x)) }

Cette notion d'image d'un ensemble par une fonction est à la base de pratiquement toute la géométrie: Alors que la symétrie centrale est définie comme une transformation qui associe un point à un point, on l'applique très vite à des ensembles de points comme dans l'expression la symétrique d'une droite par rapport à un point.

Arrondis

modifier

Enfin, pour avoir les arrondis au centime près:

[5,10,20,30,40].collect {|x| puts(f(x).round(2))}

qui remplit le tableau presque immédiatement.

Représentation graphique

modifier

Ruby n'étant pas très doué (pour le moment) en dessin, on va utiliser ses talents littéraires pour fabriquer un fichier au format svg. Ce fichier sera fabriqué comme une chaîne de caractères, et inscrit dans un fichier nommé FonctionRuby01.svg posté ci-dessous. Le fichier sera créé en mode écriture (w) avec

figure=File.open("FonctionRuby01.svg","w")

Création de la figure

modifier

On commence par écrire dans le fichier (qui, on l'a vu ci-dessus, s'appelle figure), ce qu'il faut pour dire que c'est un fichier svg (l'entête):

figure.puts('<?xml version="1.0" encoding="utf-8"?>')
figure.puts('<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"')
figure.puts('"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">')
figure.puts('<svg xmlns="http://www.w3.org/2000/svg" width="640" height="480">')

Le fichier fera donc 640 pixels de large et 480 pixels de haut.

Les axes et leurs graduations seront des traits, créés par des boucles puisque le travail des graduations est répétitif et que les boucles sont faites pour tout ce qui est répétitif.

Des abscisses

modifier

L'axe des abscisses et ses graduations sera bleu:

figure.puts('<line x1="20.0" y1="460.0" x2="540.0" y2="460.0" style="stroke:rgb(0,0,64);stroke-width:1"/>')
((0..500).select {|x| x%100==0}).collect { |x| figure.print('<text x="'+(x+20).to_s+'" y="475.0" style="font-size:16;fill:rgb(0,0,64);font-weight:normal">'+(x/10).to_s+'</text>\n'+'<line x1="'+(x+20).to_s+'" y1="455" x2="'+(x+20).to_s+'" y2="465" style="stroke:rgb(0,0,64);stroke-width:1"/>\n')}
((0..500).select {|x| x%50==0}).collect { |x| figure.print('<line x1="'+(x+20).to_s+'" y1="456" x2="'+(x+20).to_s+'" y2="464" style="stroke:rgb(0,0,64);stroke-width:1"/>\n')}
((0..500).select {|x| x%10==0}).collect { |x| figure.print('<line x1="'+(x+20).to_s+'" y1="458" x2="'+(x+20).to_s+'" y2="462" style="stroke:rgb(0,0,64);stroke-width:1"/>\n')}

Des ordonnées

modifier

L'axe des ordonnées est en vert:

figure.puts('<line x1="20.0" y1="460.0" x2="20.0" y2="40.0" style="stroke:rgb(0,40,0);stroke-width:1"/>')
((0..400).select {|y| y%40==0}).collect { |y| figure.print('<text x="0" y="'+(460-y).to_s+'" style="font-size:16;fill:rgb(0,40,0);font-weight:normal">'+(y/4).to_s+'</text>\n'+'<line x1="15" y1="'+(460-y).to_s+'" x2="25" y2="'+(460-y).to_s+'"  style="stroke:rgb(0,40,0);stroke-width:1"/>\n')}
((0..400).select {|y| y%20==0}).collect { |y| figure.print('<line x1="16" y1="'+(460-y).to_s+'" x2="24" y2="'+(460-y).to_s+'"  style="stroke:rgb(0,40,0);stroke-width:1"/>\n')}
((0..400).select {|y| y%4==0}).collect { |y| figure.print('<line x1="18" y1="'+(460-y).to_s+'" x2="22" y2="'+(460-y).to_s+'"  style="stroke:rgb(0,40,0);stroke-width:1"/>\n')}

On va représenter graphiquement la fonction en rouge, sous forme d'un polygone à 350 côtés:

(50..400).collect {|x| figure.print('<line x1="'+(19+x).to_s+'" y1="'+(460-4*f((x-1).to_f/10)).to_s+'" x2="'+(20+x).to_s+'" y2="'+(460-4*f(x.to_f/10)).to_s+'"  style="stroke:rgb(120,0,0);stroke-width:1"/>\n')}

Résultat

modifier

Pour que la figure soit reconnue, il reste encore à fermer la balise svg, ouvert au tout début de la figure, puis à fermer le fichier pour que Ruby le libère:

figure.puts('</svg>')

figure.close

L'exécution du script ci-dessus produit le fichier suivant:

 

Certes, le fichier Ruby a l'air encore plus compliqué que le fichier svg mais il est possible de créer des méthodes axes et trait pour en simplifier la lecture.