06. Contrôle de Flux
Ahhhh, le contrôle de flux. C'est là que tout se rejoint. Bien que ce chapitre soit plus court et plus facile que le chapitre sur les méthodes, il ouvrira un monde de possibilités de programmation. Après ce chapitre, nous pourrons écrire des programmes vraiment interactifs ; par le passé, nous avons écrit des programmes qui disent des choses différentes selon ce que vous tapez, mais après ce chapitre, ils feront aussi des choses différentes. Mais avant de pouvoir faire cela, nous devons être capables de comparer des objets dans notre programme. Nous avons besoin de...
Méthodes de Comparaison
Finissons-en rapidement pour pouvoir passer aux branchements, qui est là où les choses cool se passent. Pour voir si un objet est plus grand ou plus petit qu'un autre, nous utilisons les méthodes > et <, comme ceci :
puts 1 > 2
puts 1 < 2
false
true
Pas de problème. De même, nous pouvons découvrir si un objet est supérieur ou égal à (ou inférieur ou égal à) un autre avec les méthodes >= et <=.
puts 5 >= 5
puts 5 <= 4
true
false
Enfin, nous pouvons découvrir si deux objets sont égaux ou non en utilisant == (qui signifie "ces objets sont-ils égaux ?") et != (qui signifie "ces objets sont-ils différents ?"). Il est important de ne pas confondre = avec ==. = sert à dire à une variable de pointer vers un objet (affectation), et == sert à poser la question : "Ces deux objets sont-ils égaux ?".
puts 1 == 1
puts 2 != 1
true
true
Et bien sûr, nous pouvons aussi comparer des chaînes. Lorsque des chaînes sont comparées, elles comparent leur ordre lexicographique, ce qui signifie essentiellement leur ordre dans le dictionnaire. chien vient avant chat dans le dictionnaire, donc :
puts 'chien' < 'chat'
true
Il y a un hic, cependant : les ordinateurs pensent généralement que les lettres majuscules viennent avant les lettres minuscules (c'est comme ça qu'ils les stockent dans les polices, par exemple : toutes les majuscules d'abord, puis les minuscules). Cela signifie que l'ordinateur pensera que 'Zoo' vient avant 'abeille', donc si vous voulez savoir quel mot viendrait en premier dans un vrai dictionnaire, assurez-vous d'utiliser downcase (ou upcase ou capitalize) sur les deux mots avant d'essayer de les comparer.
Une dernière remarque avant les Branchements : les méthodes de comparaison ne nous donnent pas les chaînes 'true' et 'false' ; elles nous donnent les objets spéciaux true et false (bien sûr, true.to_s nous donne 'true', c'est pourquoi puts a affiché 'true'). true et false sont utilisés tout le temps dans...
Branchements (Branching)
Le "branchement" est un concept simple mais puissant. En fait, c'est si simple que je parie que je n'ai même pas besoin de l'expliquer du tout ; je vais juste vous le montrer :
puts 'Bonjour, quel est votre nom ?'
nom = gets.chomp
puts 'Bonjour, ' + nom + '.'
if nom == 'Chris'
puts 'Quel joli nom !'
end
Bonjour, quel est votre nom ?
Chris
Bonjour, Chris.
Quel joli nom !
Mais si nous mettons un nom différent...
Bonjour, quel est votre nom ?
Chewbacca
Bonjour, Chewbacca.
Et c'est ça le branchement. Si ce qui vient après le if (si) est true (vrai), nous exécutons le code entre le if et le end (fin). Si ce qui vient après le if est false (faux), nous ne le faisons pas. Simple et clair.
J'ai indenté le code entre le if et le end parce que je pense que cela rend plus facile de suivre le branchement. Presque tous les programmeurs font cela, quel que soit le langage dans lequel ils codent. Cela peut ne pas sembler très utile dans ce cas simple, mais quand les choses deviennent plus complexes, cela fait une énorme différence.
Souvent, nous aimerions qu'un programme fasse une chose si une expression est true, et une autre si elle est false. C'est à ça que sert else (sinon) :
puts 'Je suis un voyant. Dites-moi votre nom :'
nom = gets.chomp
if nom == 'Chris'
puts 'Je vois de grandes choses dans votre avenir.'
else
puts 'Votre avenir est... oh mon Dieu ! Regardez l\'heure !'
puts 'Je dois vraiment y aller, désolé !'
end
Je suis un voyant. Dites-moi votre nom :
Chris
Je vois de grandes choses dans votre avenir.
Maintenant essayons un nom différent...
Je suis un voyant. Dites-moi votre nom :
Ringo
Votre avenir est... oh mon Dieu ! Regardez l'heure !
Je dois vraiment y aller, désolé !
Le branchement est un peu comme arriver à une bifurcation dans le code : prenons-nous le chemin pour les personnes dont le nom == 'Chris', ou else (sinon) prenons-nous l'autre chemin ?
Et tout comme les branches d'un arbre, vous pouvez avoir des branches qui contiennent leurs propres branches :
puts 'Bonjour, et bienvenue en cours de français.'
puts 'Je m\'appelle Mme Gabbard. Et votre nom est... ?'
nom = gets.chomp
if nom == nom.capitalize
puts 'Veuillez vous asseoir, ' + nom + '.'
else
puts nom + ' ? Vous voulez dire ' + nom.capitalize + ', n\'est-ce pas ?'
puts 'Ne savez-vous même pas épeler votre nom ??'
reponse = gets.chomp
if reponse.downcase == 'oui'
puts 'Hmmph ! Eh bien, asseyez-vous !'
else
puts 'SORTEZ !!'
end
end
Bonjour, et bienvenue en cours de français.
Je m'appelle Mme Gabbard. Et votre nom est... ?
chris
chris ? Vous voulez dire Chris, n'est-ce pas ?
Ne savez-vous même pas épeler votre nom ??
oui
Hmmph ! Eh bien, asseyez-vous !
D'accord, je vais le mettre en majuscule...
Bonjour, et bienvenue en cours de français.
Je m'appelle Mme Gabbard. Et votre nom est... ?
Chris
Veuillez vous asseoir, Chris.
Parfois, il peut être déroutant d'essayer de savoir où vont tous les if, else, et end. Ce que je fais, c'est écrire le end en même temps que j'écris le if. Donc, pendant que j'écrivais le programme ci-dessus, il ressemblait d'abord à ceci :
puts 'Bonjour, et bienvenue en cours de français.'
puts 'Je m\'appelle Mme Gabbard. Et votre nom est... ?'
nom = gets.chomp
if nom == nom.capitalize
else
end
Ensuite, je l'ai rempli avec des commentaires, des choses dans le code que l'ordinateur ignorera :
puts 'Bonjour, et bienvenue en cours de français.'
puts 'Je m\'appelle Mme Gabbard. Et votre nom est... ?'
nom = gets.chomp
if nom == nom.capitalize
# Elle est polie.
else
# Elle se fâche.
end
Tout ce qui suit un # est considéré comme un commentaire (sauf, bien sûr, si vous êtes dans une chaîne). Après avoir rempli les commentaires, je les ai remplacés par du code fonctionnel. Certaines personnes aiment laisser les commentaires ; personnellement, je pense que le code bien écrit parle de lui-même. J'avais l'habitude d'écrire plus de commentaires, mais à mesure que je deviens plus "fluide" en Ruby, j'en écris de moins en moins. Je les trouve en fait distrayants la plupart du temps. C'est un choix personnel ; vous trouverez votre propre style (généralement votre style évoluera). Donc, ma prochaine étape ressemblait à ceci :
puts 'Bonjour, et bienvenue en cours de français.'
puts 'Je m\'appelle Mme Gabbard. Et votre nom est... ?'
nom = gets.chomp
if nom == nom.capitalize
puts 'Veuillez vous asseoir, ' + nom + '.'
else
puts nom + ' ? Vous voulez dire ' + nom.capitalize + ', n\'est-ce pas ?'
puts 'Ne savez-vous même pas épeler votre nom ??'
reponse = gets.chomp
if reponse.downcase == 'oui'
else
end
end
Encore une fois, j'ai écrit le if, le else, et le end tous en même temps. Cela m'aide vraiment à garder une trace de "où je suis" dans le code. Cela rend aussi le travail plus facile parce que je peux me concentrer sur une petite partie, comme remplir le code entre le if et le else. L'autre avantage de faire de cette façon est que l'ordinateur peut comprendre le programme à n'importe quel stade. Chacune des versions inachevées du programme que je vous ai montrées fonctionnerait. Ils n'étaient pas finis, mais c'étaient des programmes fonctionnels. De cette façon, je pouvais le tester pendant que je l'écrivais, ce qui m'aidait à voir comment il avançait et où il avait encore besoin de travail. Quand il a passé tous les tests, je savais que j'avais fini !
Ces conseils vous aideront à écrire des programmes qui se ramifient, mais ils aident aussi avec l'autre type principal de contrôle de flux :
Boucles (Looping)
Souvent, vous voudrez que votre ordinateur fasse la même chose encore et encore — après tout, c'est ce à quoi les ordinateurs sont censés être bons.
Lorsque vous dites à votre ordinateur de continuer à répéter quelque chose, vous devez également lui dire quand s'arrêter. Les ordinateurs ne s'ennuient jamais, donc si vous ne lui dites pas d'arrêter, il ne le fera pas. Nous nous assurons que cela n'arrive pas en disant à l'ordinateur de répéter certaines parties d'un programme while (tant que) une certaine condition est vraie. Cela fonctionne très similairement à la façon dont if fonctionne :
commande = ''
while commande != 'bye'
puts commande
commande = gets.chomp
end
puts 'Revenez bientôt !'
Bonjour ?
Bonjour ?
Salut !
Salut !
Très ravi de vous rencontrer.
Très ravi de vous rencontrer.
Oh... comme c'est charmant !
Oh... comme c'est charmant !
bye
Revenez bientôt !
Et c'est une boucle. (Vous avez peut-être remarqué la ligne vide au début de la sortie ; elle vient du premier puts, avant le premier gets. Comment changeriez-vous le programme pour vous débarrasser de cette première ligne ? Testez-le ! A-t-il fonctionné exactement comme le programme ci-dessus, à part cette première ligne vide ?)
Les boucles vous permettent de faire toutes sortes de choses intéressantes, comme je suis sûr que vous pouvez l'imaginer. Cependant, elles peuvent aussi causer des problèmes si vous faites une erreur. Et si votre ordinateur restait coincé dans une boucle infinie ? Si vous pensez que cela a pu arriver, maintenez simplement la touche Ctrl enfoncée et appuyez sur C.
Cependant, avant de commencer à jouer avec des boucles, apprenons quelques petites choses pour nous faciliter la tâche.
Un Peu de Logique
Regardons à nouveau notre premier programme de branchement. Et si ma femme rentrait à la maison, voyait le programme, l'essayait, et qu'il ne lui disait pas quel joli nom elle a ? Je ne voudrais pas blesser ses sentiments (ou dormir sur le canapé), alors réécrivons-le :
puts 'Bonjour, quel est votre nom ?'
nom = gets.chomp
puts 'Bonjour, ' + nom + '.'
if nom == 'Chris'
puts 'Quel joli nom !'
else
if nom == 'Katy'
puts 'Quel joli nom !'
end
end
Bonjour, quel est votre nom ?
Katy
Bonjour, Katy.
Quel joli nom !
Eh bien, ça marche... mais ce n'est pas un très joli programme. Pourquoi pas ? La meilleure règle que j'aie jamais apprise sur la programmation était la règle DRY : Don't Repeat Yourself (Ne Vous Répétez Pas). Je pourrais écrire un petit livre sur pourquoi c'est une si bonne règle. Dans notre cas, nous avons répété la ligne Quel joli nom !. Pourquoi est-ce un problème ? Eh bien, et si je faisais une faute de frappe quand je l'ai réécrit ? Et si je voulais changer joli en magnifique dans les deux lignes ? Je suis paresseux, vous vous souvenez ? Fondamentalement, si je veux que mon programme fasse la même chose quand il reçoit Chris ou Katy, alors il devrait vraiment faire la même chose :
puts 'Bonjour, quel est votre nom ?'
nom = gets.chomp
puts 'Bonjour, ' + nom + '.'
if (nom == 'Chris' or nom == 'Katy')
puts 'Quel joli nom !'
end
Bonjour, quel est votre nom ?
Katy
Bonjour, Katy.
Quel joli nom !
Bien mieux. Pour que cela fonctionne, j'ai utilisé or (ou). Les autres opérateurs logiques sont and (et) et not (non). Il est toujours bon d'utiliser des parenthèses lorsque vous travaillez avec ceux-ci. Voyons comment ils fonctionnent :
jeSuisChris = true
jeSuisViolet = false
jaimeLaNourriture = true
jeMangeDesCailloux = false
puts (jeSuisChris and jaimeLaNourriture)
puts (jaimeLaNourriture and jeMangeDesCailloux)
puts (jeSuisViolet and jaimeLaNourriture)
puts (jeSuisViolet and jeMangeDesCailloux)
puts
puts (jeSuisChris or jaimeLaNourriture)
puts (jaimeLaNourriture or jeMangeDesCailloux)
puts (jeSuisViolet or jaimeLaNourriture)
puts (jeSuisViolet or jeMangeDesCailloux)
puts
puts (not jeSuisViolet)
puts (not jeSuisChris)
true
false
false
false
true
true
true
false
true
false
Le seul qui pourrait vous piéger est or. En français, nous utilisons souvent "ou" pour signifier "l'un ou l'autre, mais pas les deux". Par exemple, votre mère pourrait dire : "Pour le dessert, tu peux avoir de la tarte ou du gâteau." Elle ne voulait pas dire que vous pouviez avoir les deux ! Un ordinateur, d'autre part, utilise or pour signifier "l'un ou l'autre, ou les deux." (Une autre façon de le dire est, "au moins l'un de ces éléments est vrai.") C'est pourquoi les ordinateurs sont plus amusants que les mamans.
Quelques Petites Choses à Essayer
- "99 Bouteilles de Bière sur le Mur..." Écrivez un programme qui imprime les paroles de ce grand classique, jusqu'à 100 bouteilles.
- Écrivez un programme de Grand-Mère Sourde. Quoi que vous disiez à grand-mère (quoi que vous tapiez), elle doit répondre par
HEIN ?! PARLE PLUS FORT, FISTON !, à moins que vous ne le criiez (tapez tout en majuscules). Si vous criez, elle peut vous entendre (ou du moins elle le pense) et crie en retour,NON, PAS DEPUIS 1938 !Pour rendre votre programme vraiment crédible, faites crier à grand-mère une année différente à chaque fois ; peut-être n'importe quelle année au hasard entre 1930 et 1950. (Cette partie est optionnelle, et serait beaucoup plus facile si vous lisiez la section sur le générateur de nombres aléatoires de Ruby à la fin du chapitre sur les méthodes.) Vous ne pouvez pas arrêter de parler à grand-mère tant que vous ne criez pasBYE.- Indice : N'oubliez pas
chomp!'BYE'avec une Entrée n'est pas la même chose que'BYE'sans ! - Indice 2 : Essayez de penser aux parties de votre programme qui doivent se produire encore et encore. Toutes celles-ci devraient être dans votre boucle
while.
- Indice : N'oubliez pas
- Étendez votre programme de Grand-Mère Sourde : Et si grand-mère ne veut pas que vous partiez ? Quand vous criez
BYE, elle pourrait faire semblant de ne pas vous entendre. Changez votre programme précédent pour que vous deviez crierBYEtrois fois de suite. Assurez-vous de tester votre programme : si vous criezBYEtrois fois, mais pas de suite, vous devriez toujours parler à grand-mère. - Années Bissextiles. Écrivez un programme qui demande une année de début et une année de fin, puis
putstoutes les années bissextiles entre elles (et les incluant, si elles sont aussi des années bissextiles). Les années bissextiles sont des années divisibles par quatre (comme 1984 et 2004). Cependant, les années divisibles par 100 ne sont pas des années bissextiles (comme 1800 et 1900) à moins qu'elles ne soient divisibles par 400 (comme 1600 et 2000, qui étaient en fait des années bissextiles). (Oui, c'est assez confus, mais pas aussi confus que d'avoir décembre au milieu de l'hiver, ce qui arriverait à la fin).
Quand vous avez fini ceux-là, faites une pause ! Vous avez déjà beaucoup appris. Félicitations. Êtes-vous surpris par le nombre de choses que vous pouvez dire à l'ordinateur de faire ? Quelques chapitres de plus et vous serez capable de programmer à peu près n'importe quoi. Vraiment ! Regardez toutes les choses que vous pouvez faire maintenant que vous ne pouviez pas faire avant d'apprendre les boucles et les branchements.
Maintenant, apprenons à connaître un nouveau type d'objet, un qui garde une trace de listes d'autres objets : les tableaux (arrays).