« Programmation objet et géométrie/Programmation avec DrGeoII » : différence entre les versions

Contenu supprimé Contenu ajouté
DannyS712 (discussion | contributions)
m <source> -> <syntaxhighlight> (phab:T237267)
Ligne 21 :
Pour commencer, on va tout faire en interne, avec la déclaration préalable des données (ici seulement ''x'') dont le programme a besoin, et les instructions d'affectation (notées par un ''double-point-égal''), chaque instruction étant finie par un point:
 
<sourcesyntaxhighlight lang="smalltalk">
EntreeInterne
|x|
Ligne 28 :
x:=x*x.
^x
</syntaxhighlight>
</source>
 
[[Fichier:Crystal Clear app Startup Wizard.png|right]]
Ligne 38 :
Pour entrer une donnée numérique dans un script, on va définir celui-ci comme dépendant d'une donnée (qui devra être numérique parce que des calculs seront effectués dessus). Lors de l'exécution du script, on va cliquer sur le nombre. Ce qui nécessite de placer un nombre dans la figure, puis d'entrer le script suivant:
 
<sourcesyntaxhighlight lang="smalltalk">
Entree: xInit
|x|
Ligne 45 :
x:=x*x.
^x
</syntaxhighlight>
</source>
 
Le paramètre dont ce script dépend a été appelé ''xInit'' (abréviation pour la valeur initiale de ''x'') pour le distinguer de la variable ''x'', qu'on affecte d'abord avec ''xInit valueItem'': ''xInit'' est en quelque sorte converti en nombre, ou plus précisément c'est sa valeur qui est récupérée. Le reste est fait comme précédemment.
Ligne 61 :
L'usage en ''Smalltalk'' est de créer une erreur pour que le débogueur vienne tout seul à la rescousse: Le meilleur moyen de voir un Saint-Bernard, c'est de déclencher une [[w:Avalanche|avalanche]]! En fait c'est très ergonomique, les bogues ayant tendance à survenir très souvent! Pour faire apparaître le débogueur on va donc fermer la figure ''DrGeo'' ce qui fait apparaître une sorte de bureau sur lequel était posée la figure, et là, avec ''Control+K'' (sous [[w:Windows|windows]] c'est ''Alt+K''), on crée (instancie!) un espace de travail ''Smalltalk'', qui ressemble à un éditeur de texte. Là on recopie le script précédent avec une nouvelle variable ''y'' que l'on va traîtreusement diviser par 0 à la fin (certes çe serait plus propre de remplacer la dernière ligne par ''self halt.'' qui là aussi arrêterait la machine Smalltalk en ouvrant le débogueur):
 
<sourcesyntaxhighlight lang="smalltalk">
|x y|
x:=3.
Ligne 67 :
x:=x*x.
y:=1/0.
</syntaxhighlight>
</source>
 
Ensuite, on essaye d'exécuter ce script erroné, en le sélectionnant (par exemple avec ''Control+A'') puis en effectuant ''Control+D'' qui appelle la méthode ''do it!'', et on voit un message d'erreur avec une invitation à faire sortir le génie de la bouteille, le génie ici étant bien entendu le débogueur. En cliquant sur ''Restart'' on arrive au début du script:
Ligne 109 :
On va regarder comment ''Dr. Geo'' peut représenter graphiquement la fonction <math>x \mapsto \frac{x^3}{25}-x</math>. Pour éviter d'avoir à écrire trop souvent cette expression, on va définir un objet ''Smalltalk'' appelé ''fonction'' qu'on pourra donc appeler par la suite:
 
<sourcesyntaxhighlight lang="smalltalk">
fonction := [:x | x*x*x/25-x].
</syntaxhighlight>
</source>
 
==Représentation graphique point par point==
Ligne 117 :
On crée une boucle sur ''x'' dans laquelle on va placer (créer) le point de coordonnées <math>\left(x;\frac{x^3}{25}-x\right)</math>. Pour cela, on va automatiser complètement la création de la représentation graphique, et créer la figure ''Dr. Geo'' avec, elle s'appellera ''figure''. Ceci ne se fait pas dans une figure existante (puisqu'on veut la créer!) mais sur le bureau de [[w:Squeak|Squeak]]. Une fois ce bureau vide, on entre ''Control+K'' pour ouvrir un éditeur de texte (''worKplace''). Après avoir défini la fonction comme ci-dessus, on crée une figure ''Dr. Geo'' avec la méthode ''new'' de ''DrGeoCanvas''. Puis dans une boucle allant de -5 à 5 par pas de 0,4 et dont l'indice s'appelle ''x'', on crée le point ''p'' de coordonnées ''x'' et la valeur que prend ''fonction'' en ''x'':
 
<sourcesyntaxhighlight lang="smalltalk">
| figure fonction p|
 
Ligne 125 :
-5 to: 5 by: 0.4 do:
[:x |p:=figure point: x@(fonction value: x)].
</syntaxhighlight>
</source>
 
Après avoir sélectionné le texte et entré ''Control+D'', on voit la figure avec des points en forme de croix, qui suggèrent en pointillés la représentation graphique de la fonction. Pour améliorer la représentation, on peut mettre les points en plus petit et les choisir plus nombreux:
 
<sourcesyntaxhighlight lang="smalltalk">
| figure fonction p|
 
Ligne 140 :
p round.
p small.].
</syntaxhighlight>
</source>
 
Mais la représentation graphique est toujours en pointillés, et il vaut mieux représenter la courbe en l'approchant par un polygone, soit par des segments:
Ligne 150 :
On peut tout simplement modifier le script précédent pour qu'il joigne le point ''p'' au point ''q'' qui le suit (et qu'on doit donc rajouter dans le script), sans oublier toutefois de remplacer à chaque pas de la boucle, ''p'' par ''q'' (et en cachant les deux points):
 
<sourcesyntaxhighlight lang="smalltalk">
| figure fonction p q s|
 
Ligne 165 :
s color: Color blue.
p:=q.].
</syntaxhighlight>
</source>
 
On remarque la logique de ''Smalltalk'', pour qui un segment va d'un point à un autre, et n'est pas défini à partir de ses extrémités. Le segment s'appelle ''s'' ce qui permet de le colorier en bleu. On remarque aussi que pour cacher un point ''p'', on lui demande de se cacher, en lui envoyant un message ''hide''.
Ligne 175 :
La liste de sommets, initialement vide, se crée par
 
<sourcesyntaxhighlight lang="smalltalk">
sommets:=OrderedCollection new.
</syntaxhighlight>
</source>
 
Pour ajouter un sommet (la référence d'un point nouvellement créé, mais caché) on envoie à ''sommets'' le message ''add'' suivi du nom du sommet à insérer dans la liste. Comme on choisit l'intervalle ''[a;b]=[-1;1]'', on commence donc par le point de coordonnées (a;0):
 
<sourcesyntaxhighlight lang="smalltalk">
figure:=DrGeoCanvas new.
Ligne 187 :
b:=1.
sommets add: a@0.
</syntaxhighlight>
</source>
 
Ensuite on ajoute les points de la courbe:
 
<sourcesyntaxhighlight lang="smalltalk">
a to: b by: 0.1 do: [ :x | sommets add: x@(fonction value: x). ].
</syntaxhighlight>
</source>
 
Enfin, le point de coordonnées (b;0):
 
<sourcesyntaxhighlight lang="smalltalk">
sommets add: b@0.
</syntaxhighlight>
</source>
 
Le polygone construit avec la liste de sommets ainsi constituée s'appelle ''integrale''. En effet il est par défaut, rempli (ici en bleu) et son aire est <math>\int_{-1}^{1} x^2\,dx=\frac{2}{3}</math>:
 
<sourcesyntaxhighlight lang="smalltalk">
integrale:=figure polygon: sommets.
integrale color: Color blue.
</syntaxhighlight>
</source>
 
Voici le script intégral de l'intégrale:
 
<sourcesyntaxhighlight lang="smalltalk">
|figure fonction integrale sommets a b|
Ligne 226 :
integrale:=figure polygon: sommets.
integrale color: Color blue.
</syntaxhighlight>
</source>
 
==Représentation comme un lieu==
Ligne 238 :
On va rajouter à la figure précédente une variable ''pause'' qui est un objet ''Delay''. On place ''p'' au départ de son trajet, sur son [[w:Starting-block|starting-block]], et on règle la pause sur 0,2 secondes, une bonne vitesse d'escargot. Ensuite au lieu de créer d'autres points, on va déplacer celui qu'on a et lui faire parcourir la courbe, en rafraichissant l'affichage au fur et à mesure:
 
<sourcesyntaxhighlight lang="smalltalk">
|figure fonction p pause|
Ligne 255 :
pause wait.].
] fork
</syntaxhighlight>
</source>
 
===Trace du point===
Ligne 263 :
On va alors un segment ''s'' d'extrémités (-5;0) et (5;0), attacher un point ''mobile'' à ce segment, construire un point ''courbe'' sur la courbe, de coordonnées (x;y) où ''x'' est l'abscisse de ''mobile'' puis construire le lieu de ''courbe'' quand ''mobile'' bouge. Mais pour construire le point ''courbe'', on doit définir ses coordonnées par un ''bloc'' de ''Smalltalk'', c'est-à-dire une fonction qui récupère l'abscisse du point par ''mathItem point x'' et calcule l'image de l'abscisse par la fonction:
 
<sourcesyntaxhighlight lang="smalltalk">
|figure s mobile courbe bloc|
figure := DrGeoCanvas new.
Ligne 273 :
courbe := figure point: bloc parent: mobile.
figure locusOf: courbe when: mobile.
</syntaxhighlight>
</source>
 
Cette méthode consistant à calculer les coordonnées d'un point par bloc permet aussi de représenter des courbes paramétrées, ou des images de droites et cercles par des transformations complexes...
Ligne 283 :
Pour avoir un nombre aléatoire entier, par exemple entre 1 et 6 comme avec un dé, on peut faire
 
<sourcesyntaxhighlight lang="smalltalk">
de:=[(1 to: 6) atRandom] value.
</syntaxhighlight>
</source>
 
On choisit au hasard un élément de la liste des entiers de 1 à 6 et on demande sa valeur (sinon on n'aurait pas un nombre). Cette méthode est très puissante, permettant par exemple de choisir un petit nombre premier au hasard avec
 
<sourcesyntaxhighlight lang="smalltalk">
de:=#(2 3 5 7 11 13 17) atRandom.
</syntaxhighlight>
</source>
 
mieux encore, si on ne se souvient pas des nombres premiers, on peut les faire tester par ''Smalltalk'':
 
<sourcesyntaxhighlight lang="smalltalk">
gener:=[((2 to: 100) select: [:n | n isPrime]) atRandom].
de:=gener value.
</syntaxhighlight>
</source>
 
(parmi les nombres de 2 à 100, on sélectionne les ''n'' tels que ''n'' est premier; on fabrique avec eux une liste au sein de laquelle on peut choisir un nombre au hasard)
Ligne 308 :
Pour lancer deux dés, il suffit de faire la même chose que ci-dessus, mais en double, et d'additionner les résultats. Si ''de1'' et ''de2'' sont les résultats des lancers des deux dés, alors leur somme est comprise entre 2 et 12, et on peut faire une statistique sur celle-ci pour voir si par exemple, le 3 sort aussi souvent que le 7. La complexité supplémentaire vient de l'utilisation d'un tableau pour les effectifs. On le crée par
 
<sourcesyntaxhighlight lang="smalltalk">
stats:=Array new: 12.
</syntaxhighlight>
</source>
 
Le tableau est alors vide, mais il contient 12 places où placer les effectifs. Pour que ''Dr. Geo'' sache que ce sont des entiers, on va les initialiser à 0:
 
<sourcesyntaxhighlight lang="smalltalk">
stats:=Array new: 12.
2 to: 12 do: [:i | stats at: i put: 0].
</syntaxhighlight>
</source>
 
À ce stade, comme on n'a pas mis de ''0'' dans le premier emplacement du tableau (la somme des résultats des deux dés ne peut jamais être 1), il contient ceci:
Ligne 327 :
Ensuite on lance les dés: Pour chaque valeur de l'indice ''i'' de la boucle, on additionne (après les avoir calculés) les nombres ''de1'' et ''de2'', puis on ajoute 1 à l'entrée du tableau indexée par la somme:
 
<sourcesyntaxhighlight lang="smalltalk">
stats:=Array new: 12.
2 to: 12 do: [:i | stats at: i put: 0].
Ligne 338 :
stats at: s put: ((stats at: s)+1).
].
</syntaxhighlight>
</source>
 
Un résultat typique est celui-ci:
Ligne 349 :
Pour avoir un diagramme en bâtons, on peut dessiner les segments à partir des éléments du tableau (abscisses: les indices; longueurs: les affectifs, divisés par 100 pour ne pas avoir de dessin trop allongé). Pour effectuer 10 000 lancers, on peut faire ainsi:
 
<sourcesyntaxhighlight lang="smalltalk">
|figure gobelet de1 de2 s stats a b|
Ligne 372 :
s color: Color red.
].
</syntaxhighlight>
</source>
 
Il faut moins d'une seconde pour créer le graphique.
Ligne 379 :
 
Et une version légèrement différente :
<sourcesyntaxhighlight lang="smalltalk">
|figure gobelet stats item|
Ligne 395 :
item := figure point: i@0.
item show; square; color: Color blue; name: i asString].
</syntaxhighlight>
</source>
 
=Suites=
Ligne 401 :
La [[w:Suite logistique|suite logistique]] définie par <math>u_{n+1}=4u_n \left(1 - u_n \right)</math> est chaotique. Pour le vérifier, on peut la représenter graphiquement avec ''Dr. Geo'' :
 
<sourcesyntaxhighlight lang="smalltalk">
|figure s r u|
figure:=DrGeoCanvas new.
Ligne 419 :
u round small.
u color: Color blue].
</syntaxhighlight>
</source>
 
La manipulation des curseurs montre dynamiquement le phénomène de dédoublement de période. En simplifiant légèrement le script, on peut vérifier l'effet de la raison d'une suite géométrique sur sa convergence.
Ligne 426 :
On peut aussi utiliser une réglette de valeur pour simplifier le code source :
 
<sourcesyntaxhighlight lang="smalltalk">
| figure r u |
figure:=DrGeoCanvas new.
Ligne 441 :
parent: u.
u round small color: (n even ifTrue: [Color blue] ifFalse: [Color red])].
</sourcesyntaxhighlight>
 
[[File:Suite et réglette.png|Sketch result of Smalltalk code]]