Enfin nous arrivons au dernier concept fondamental : les bifurcations.


Bifurcations, branchements, choix multiples, logique binaire

Définition : les bifurcations permettent de changer le sens du programme en fonction de critères spécifiques. Autremment dit, une bifurcation permet de changer le cours du programme — ce que le programme fait — la plupart du temps en fonction de données extérieures, c’est-à-dire en fonction d’interactions extérieures. Une bifurcation permet au programme de moduler son comportement pendant qu’il s’execute. C’est un pas fondamental vers l’interactivité.


If…else

Le plus connu des bifurcations (et le plus simple) est connu sous le nom “if…else”. C’est un des schémas les plus anciens de la programmation informatique : l’ordinateur fait quelque chose, mais seulement si un critère quelconque est vrai (if), sinon il ne fait rien ou fait autre chose à la place (else).

Comme pour les méthodes et les boucles, une bifurcation if( ) s’écrit avec des parenthèses et des accolades :


void setup() {
  size(200,200);
  stroke(128);
}

void draw() {

  if (mouseY > 100) {
    background(255);
  }

  line(0,100,200,100);

}

Ce programme dessine un fond gris, mais quand la souris est en dessous de la ligne du milieu (quand il est plus grand que 100 sur l’axe vertical) le fond devient blanc. Notez que le fond ne change plus de couleur dès que le fond est devenu blanc. C’est parce que nous n’avons pas de cas contraire : au début de l’animation le fond est gris (par défaut), puis dès qu’on passe en dessous la ligne le fond devient blanc.

On peut aussi changer légèrement notre programme pour dire ce que le programme doit faire dans le cas contraire, c’est-à-dire quand la souris n’est plus en dessous de la ligne. Du coup, l’animation peut alterner entre deux états.


void setup() {
  size(200,200);
  stroke(128);
}

void draw() {

  if(mouseY > 100) {
    background(255);
  } else {
    background(0);
  }

  line(0,100,200,100);

}

Voici le résultat de ce programme. Si on place la souris au dessus de la ligne grise, le fond devient noir. Si on place la souris en dessous de la ligne grise, le fond devient blanc.

Cet exemple nous montre le choix que l’ordinateur peut faire à votre place sur le fonctionnement de votre programme. C’est comme si notre programme contennait deux sous-programmes potentiels : un premier programme quand la position vertical de la souris est plus grande que 100 pixels, et un autre programme dans le cas contraire.

Attention (et vous l’avez peut-être déjà remarqué) : notre programme dessine une couleur de fond quand on est plus grand que 100, et une autre couleur dans le cas contraire. Ce qui veut dire qu’on est toujours noir, même quand on est directemment sur la ligne. Il n’y a que deux choix ici : au dessus, puis tout le reste. C’est le sens de else : tout le contraire de ce qui est marqué entre les parenthèses du if( ).

Si cela vous semple un peu complexe, méditez sur le prochain exemple qui donne trois états. Un état par défaut (rouge), puis deux états possibles (un état au dessus de la ligne, un autre état en dessous de la ligne).


void setup() {
  size(200,200);
}

void draw() {

  background(255,0,0);

  if (mouseY > 100) {
    background(255);
  } else if (mouseY < 100) {
    background(0);
  }

  stroke(128);
  line(0,100,200,100);

}

Comme on peut voir dans l’illustration, nous avons maitenant trois possibilités : fond noir quand on est au dessus de la ligne, fond rouge quand on est sur la ligne, et fond blanc quand on est en dessous de la ligne. Ces trois possibilités viennent du fait qu’avant de choisir entre noir ou blanc, nous déssinons un fond rouge. Du coup, seulement dans les cas où on n’est plus sur la ligne (supérieur à 100 ou inférieur à 100) on remplace ce fond rouge avec le blanc ou le noir. Cela revient à faire ce qu’on appelle souvent en informatique un choix “par défaut”.

Au fait, on aurait pu écrire cette animation d’une autre façon. Voici une alternative pour arriver au même résultat :


void setup() {
  size(200,200);
}

void draw() {

  if (mouseY == 100) {
    background(255,0,0);
  }

  if (mouseY > 100) {
    background(255);
  }

  if (mouseY < 100) {
    background(0);
  }

  stroke(128);
  line(0,100,200,100);

}

Deux programmes peuvent arriver à donner le même résultat (avec, bien sûr, quelques élegances en plus ou en moins — par exemple, ne choisir le rouge que si on est sur la ligne, plutôt que ralentir le processeur en dessinant le rouge avant, etc, etc). Quelque soit la différence dans les moyens, le résultat est plus ou moins le même. Après, c’est plutôt une question de style.

Les opérateurs, les comparaisons

Vous avez peut-être remarqué dans notre dernier exemple, un signe un peu particulier. Au lieu d’écrire un seul signe égale à (=), nous en avons écrit deux (==). Il s’agit d’un “operateur” qui ne fait pas un calcul arithmétique, mais une comparaison “logique”.

Quoi? Qu’est-ce qu’une comparaison logique?

Sans entrer dans les détails, disons qu’il faut mettre à l’intérieur des parenthèses d’une bifurcation if( ) ou else( ), quelque chose qui expliquera à l’ordinateur ce que vous rechercher comme condition. Autremment dit, il faut expliquer ce qui doit être le cas, ce qui doit être vrai, pour que l’ordinateur bifurque et execute votre programme optionnel. En réalité, l’ordinateur est en train de transformer votre question (est-ce que mouseY est plus grand que 100 ?) en une “operation” qui donnera le resultat de true ou de false : c’est le fameux 0 et 1 de l’ordinateur.

“Ah oui! 0 et 1! j’ai vu le film matrix, je connais ça, je connais ça!”

Dans certains langages de programmation, comme le C ou Lingo, on peut carrément mettre la valeur 1 à l’intérieur d’une boucle while( ) ou une bifurcation if( ); par contre, dans le langage Java (et donc Processing), il y a une différence sémantique entre la valeur 1 et la valeur true.

Pour expliquer de manière plus concret, demandons au processeur de nous montrer comment il voit toute ces choses. Voici un petit exemple pour démontrer la façon dont un ordinateur utilise le signe == et ce qu’il attend à voir à l’intérieur des parenthèses pour executer votre code. Nous utiliserons la méthode println( ) pour voir avec la “vision” du processeur.

Comme le montre l’exemple (regardez bien en bas de la fenêtre), l’ordinateur pose une question quand il voit le code x == 0. Par contre, il attribue une valeur quand il voit le code x = 0. Le signe égale à (=) donne une valeur, alors que signe est-il-égale-à (==) compare les valeurs et donne un résultat “vrai” (true) ou “faux” (false). Ce sont donc, en langage informatique, une opérateur de comparaison. C’est une opérateur parce qu’il donne des résultats, mais ces résultats ne sont pas de valeurs normales : ces résultats sont des valeurs true ou false. D’ailleurs, si on essaie de mettre une égale-à classique (=) à l’intérieur des parenthèses, Processing va râler :

Il nous informe que ce qui se trouve entre les parenthèses n’est pas un “boolean”, c’est-à-dire des chiffres selon George Boole link:George_Boole, le célèbre mathématicien qui a introduit la logique de true et false en utilisant le langage mathématique. Il ne s’agit pas de mathématique à proprement parler, il s’agit de ce qu’on appelle de la “logique”. Il s’agit également d’un nouveau type de variable, qui ne s’appelle ni int, ni float, mais boolean.

Voici quelques opérateurs “logiques” :

|opérateur logique|signification|
|==|égale à?|
|!=|n’est pas égale à?|
|>|est supérieur à?|
|<|est inférieur à?|

On peut aussi poser deux questions ensembles, genre est-ce que ceci est vrai et cela est aussi vrai?


// le signe "et"
if ( 1 == 1 && 2 == 2) {
  background(255, 0, 0);
} else {
  background(0, 0, 255);
}

// le signe "ou"
if ( 1 != 0 || 2 == 3) {
  line(10, 50, 90, 50);
}

En utilisant le signe && et le signe || on peut soit demander si deux questions sont tous les deux vrais, ou demander si au moins une des deux questions est vrai. C’est ce qu’on appelle les signes “et” / “ou”.

Résumé

Cela fait beaucoup de choses, et vous n’avez probablement pas tout retenu. L’essentiel de ce chapitre est de comprendre que les bifurcations if( ) servent à poser une question à l’ordinateur, ou plutôt à demander à l’ordinateur à se poser une question pendant le déroulement du programme. En fonction de la réponse à cette question, l’ordinateur doit bifurquer dans son déroulement et faire autre chose.

On à aussi vu que les questions que l’ordinateur se pose, sont toujours formulées pour donner une réponse vraie (true) ou fausse (false). C’est l’introduction de la logique dans notre programme.

Vous avez peut-être noté que cette logique a déjà été au travail dans le chapitre précédent sur les boucles : dans le boucle while( ) et dans le boucle for( ) nous avons déjà vu que l’ordinateur doit se poser des questions pour faire tourner le boucle.

Vous avez aussi, j’espère, remarqué que les quatres concepts commence à s’imbriquer de plus en plus les uns dans les autres.

Exercise

Allez-vous reposer. On vient de sérieusement se faire chier travailler, il faut maintenant digérer. Les prochains chapitres vont chercher à mettre à l’épreuve ces concepts bien difficiles.