Thème 2 : répéter sans se fatiguer et choisir parmi les alternatives

Lors de la première séance, nous avons commencé à prendre en main processing en découvrant quelques instructions permettant de dessiner des formes géométriques (point, line, rect, ellipse) avec différentes couleurs (composantes R, V et B) pour leur contour (stroke) ou leur surface (fill).

Pour cette seconde séance, nous allons découvrir deux nouveaux outils fantastiques qui vont nous permettre de créer des oeuvres plus facilement et rapidement. En effet, pour l'instant nous sommes obligés d'expliquer à l'ordinateur le dessin de chaque élément individuellement.

Par exemple, si l'on souhaite créer une suite de 9 cercles, nous devons appeler 9 fois l'instruction ellipse avec les bonnes informations pour obtenir le dessin souhaité. On peut le faire ainsi, mais c'est un peu laborieux, surtout si l'on souhaite augmenter le nombre de cercles, en passant à 10 ou pire encore 100 !

Observez-bien les colonnes de nombres de la séquence d'instructions ellipse … ne remarquez-vous rien de particulier ?

Effectivement, les 3 derniers nombres sont toujours identiques ! Cela s'explique car le premier (100) correspond à la coordonnées de ligne qui reste toujours la même puisque les cercles sont alignés, et que les deux suivants (30) correspondent aux deux rayons de l'ellipse (et toutes les ellipses sont identiques).

Par contre, le premier nombre change à chaque instruction puisque cela correspond à la coordonnée de colonne du centre du cercle. Examinons de plus prêt cette suite de nombres: 10, 40, 70, 100, 130, 160, 190, 220, 250. Ne trouvez-vous pas une certaine régularité dans cette suite de nombres ?

Nous sommes dans une situation typique où l'on répète un même traitement ! En effet, on effectue *presque* toujours la même instruction ellipse(x, 100, 30, 30) avec x qui évolue de 30 en 30 (on dit aussi par pas de 30), en commençant à 10 et en s'arrêtant à 250 :)

Ce type de situation est tellement récurrent que l'on a un outil particulier pour faciliter l'écriture d'un traitement qui se répète plusieurs fois à l'identique ou presque, c'est ce que l'on appelle les répétitions (et parfois les boucles).

Répétitions : vive les boucles !

L'avantage d'un ordinateur c'est que contrairement à nous, il ne se lasse pas de refaire plusieurs fois la même chose :) Exploitons cela pour trouver une solution plus simple pour dessiner nos 9 cercles identiques (à leur placement près). Comme nous l'avons vu, la coordonnée de colonne x est la seule à varier en augmentant de 30 lors du dessin de chaque cercle. En python (c'est le nom du langage de programmation que nous utilisons !), il existe une instruction permettant de construire facilement une suite de nombres correspondant à celle que nous avons identifiée : range. Cette instruction signifie intervalle et permet de construire une suite de nombres dans un intervalle donné. Ainsi, si l'on souhaite créer la suite: 10, 40, 70, 100, 130, 160, 190, 220, 250, on peut le faire avec cette expression: range(10, 280, 30) qui signifie compte de 10 à 280 en augmentant de 30 à chaque fois. Pourquoi 280 au lieu de 250 ? Car la borne de fin est exclue… Du coup, comme nous voulons 250, il faut mettre un nombre strictement plus grand que 250 (changez le 280 en 251 pour vérifier cela !).

Après l'instruction print, les instructions ci-dessous sont en commentaires. Enlevez le # et lancez le programme pour voir ce qu'il se produit.

  for x in range(10, 280, 30):
    ellipse(x, 100, 30, 30)
    

L'instruction for est ce qui permet de définir des traitements répétitifs : toutes les instructions légèrement décalées vers la droite vont être répétées autant de fois qu'il y a de nombres dans la suite de nombres créée par range (donc 9 fois dans ce cas). Et comme les affichages le démontrent, le symbole x va prendre successivement les valeurs de la suite. Ce x est en fait une variable, c'est-à-dire une information qui a un nom. Si l'on utilise ce nom dans notre programme, on accède directement à sa valeur. Ainsi, print(x) signifie affiche la valeur que contient la variable x.

Nous avons maintenant tous les outils nous permettant de dessiner nos 9 cercles sans trop nous fatiguer (en tout cas au niveau des doigts parce que pour les méninges ;))

Variables : un peu de mémoire cela peut servir

L'exemple précédent nous a montré aussi qu'il est parfois pratique de nommer une information particulière, comme le x qui représente le compteur de boucle. En fait, cette possibilité peut être utilisée dans de multiples situations et correspond à la notion de variable en informatique.

Parfois, il est utile de mémoriser certaines informations, par exemple la couleur que l'on a utilisé ou encore la position du dernier dessin que l'on a réalisé. Afin de faire cela, il est possible de définir et utiliser des variables. Une variable et constituée d'un nom (qui permet de se rappeler ce que contient cette variable) et d'une valeur (le contenu de la variable).

Dans l'exemple des 9 cercles, nous aurions pu nommer la valeur 30 qui représente le rayon de notre cercle, afin de faciliter la lecture de notre programme:

Prenons un autre exemple : si l'on souhaite mémoriser la couleur que l'on utilise, on peut définir une variable pour cela:

  couleur = color(48, 128, 255)

L'expression ci-dessus indique à la machine de créer une couleur (instruction rgb) et la mémorise dans la variable couleur. Ensuite, nous pouvons utiliser le symbole couleur partout où une couleur est attendue, par exemple avec l'instruction fill.

Voici un exemple où l'on travaille avec trois couleurs et où l'on utilise des variables pour savoir à quoi elles correspondent (parce qu'avec juste les codes RGB, il est un peu difficile d'imaginer la couleur qui va apparaître à l'écran !);

Vous avez peut-être remarqué une différence entre les variables représentant les couleurs et celles représentant la coordonnée du centre des cercles (c-à-d. la variable x). Étrangement, le nom des couleurs est écrit en MAJUSCULES alors que celui de la coordonnée du centre est en minuscule ! Pourquoi cette nuance ? Généralement, lorsque l'on veut indiquer que des variables conservent la même valeur tout au long du programme, on écrit leur nom en majuscule pour indiquer que ce sont des constantes. Par contre, x qui change de valeur à chaque tour de boucle, n'est pas constante, ce qui explique pourquoi elle est écrite en lettres minuscules.

Œuvre 3 : Yahtzee !

Toujours inspiré par notre première oeuvre, le dé, on se propose ici de représenter un tirage particulièrement chanceux au jeu du Yahtzee.

En reprenant notre dé de la première oeuvre et en réduisant un peu sa taille, nous allons pouvoir dessiner 5 dés grâce à une boucle (qui contiendra les instructions de dessins d'un seul dé). Un conseil : commencez par dessiner un dé puis ajoutez une boucle pour répéter le dessin 5 fois. La boucle permet de changer la position en x du dé.

Faire des choix avec les alternatives

La première opération fondamentale que nous venons de voir, la répétition, nous permet de définir facilement des traitements répétitifs. Il existe aussi une seconde opération fondamentale, l'alternative, qui permet de prendre une décision sur ce qu'il faut faire à instant donné. Supposons que l'on souhaite transformer les cercles en disques de différentes couleurs dans le programme précédent en alternant deux couleurs. Il est possible de le faire si l'on peut tester la couleur courante. Le code suivant change la couleur de remplissage à chaque tour de boucle. Si elle était VERTE, elle devient bleue et réciproquement.

La syntaxe des tests est la suivante :

if comparaison1:
  séquences d'instructions à réaliser si comparaison1 == True
elif comparaison2:
  séquences d'instructions à réaliser si comparaison1 == False et comparaison2 == True
else:
  séquences d'instructions à réaliser si  comparaison1 == False et comparaison2 == False
  

Les expressions comparaison1 et comparaison2 sont des expressions de comparaison. Il est possible de tester l'égalité à l'aide de l'opérateur ==, à ne pas confondre avec l'opérateur = qui permet d'associer une valeur à une variable (cf. lige 12 du programme). Il est aussi possible de tester l'ordre à l'aide des opérateurs > (supérieur), < (inférieur), >= (supérieur ou égal), < = (inférieur ou égal).

If est un terme anglais qui signifie si. Si la comparaison du if est vraie, alors la séquence d'instructions qui suit est exécutée puis le code qui est après la série de ifelifelse est exécuté. Si cette expression n'est pas vraie, alors, la prochaine comparaison du elif (abréviation de else if qui signifie sinon si) est évaluée. Si cette expression est vraie, alors la séquence d'instructions qui suit est exécutée. Si elle n'est pas vraie, alors la comparaison du prochain elif est évaluée et ainsi de suite jusqu'au else dont le bloc qui suit est exécuté si aucune des comparaisons précédentes n'était vraie. Il peut y avoir autant de lignes elif que nécessaire (de 0 à l'infini ;-)).

Changez maintenant le programme pour que la couleur ne varie plus en fonction de la couleur précédente, mais en fonction de la position du cercle sur la toile. Si la position en Y du cercle est dans la première moitié, alors le cercle est bleu. Si elle est dans la deuxième moitié, alors le cercle est vert.

Mélangeons alternatives et répétitions :)

Afin de bien comprendre le problème et mieux apprécier le remède que l'on peut apporter, nous allons nous attaquer à la création d'un damier. Notre damier est constitué d'un quadrillage de 3×3 carrés alternant le bleu et le rouge lors du dessin de chaque carré comme l'illustre la figure ci-dessous.

RAPPEL : il peut être très utile de faire un schéma pour ne pas se perdre dans les coordonnées ;)

On remarque que parce que le dessin est construit à partir de 9 carrés, on se retrouve avec 9 instructions rect dont seulement certaines informations changent d'instruction en instruction. Intéressons-nous de plus prêt à cela car il y a peut-être une certaine régularité dans la manière dont les coordonnées évoluent dans les différents usages de rect. Il est donc possible de simplifier l'écriture de ce programme pour ne pas avoir à écrire les instructions pour dessiner chaque carré. Il faut utiliser à la fois des boucles et des tests.

Petite synthèse :)

Vous avez maintenant vu la quasi totalité des notions fondamentales en programmation ! En effet, si l'on excepte la notion de fonction que nous verrons un peu plus tard, voici ce que vous connaissez déjà:

  • une instruction: une action primitive que comprend et réalise la machine (exemple: ellipse, print …)
  • une séquence d'instructions: une suite d'actions primitives qui seront exécutées les unes à la suite des autres
  • une variable: associe un symbole à une valeur, ce qui permet de mémoriser des informations et les faire évoluer
  • une condition: représente une valeur booléenne, c'est-à-dire une valeur valant soit True (vrai), soit False (faux). On peut construire des conditions à partir des opérateurs d'égalité (==) ou de comparaison (> et <)
  • une répétition ou boucle: première structure de contrôle permettant de répéter une certain nombre de fois une séquence d'instructions
  • une alternative: seconde structure de contrôle permettant d'effectuer une séquence d'instructions plutôt qu'une autre en fonction d'une condition (c'est-à-dire une valeur booléenne).

Evidemment, il faut un peu de pratique et d'entraînement pour bien s'approprier tout cela, mais la bonne nouvelle est que ces quelques notions sont fondamentales et constituent les bases de la programmation (et cela quelque soit le langage de programmation ! :)).

Expérimentez ces nouveaux pouvoirs de création en réalisant ce que vous souhaitez dans l'oeuvre libre ci-dessous: