Boucles

Q-SYS Control 101 Training (French) : Contrôle de flux

3 ) Communication simple

12m 48s

4 ) Blocs de contrôle

19m 7s

5 ) Notions de base sur les scripts

32m 5s

6 ) Contrôle de flux

34m 20s

7 ) Conclusion du Control 101

1m 43s

Description de la leçon

Boucles 12m 9s

Apprenez à organiser et à manipuler votre script pour répéter les fonctions plusieurs fois à l'aide de boucles.

Transcription Vidéo

Boucles 12m 9s
0:08
Il peut souvent vous arriver de vouloir exécuter la même section de code plusieurs fois de suite. Une
0:12
boucle est une structure de contrôle qui nous permet d'exécuter plusieurs fois une instruction ou un
0:17
groupe d'instructions, selon que des conditions particulières sont remplies ou non.
0:23
Essentiellement, quand le script arrive à votre boucle, il analyse la condition. Si la condition est vraie,
0:29
alors il exécute le code conditionnel et réanalyse ensuite la condition. Il continuera à le faire jusqu'à ce
0:36
que la condition soit fausse, auquel cas il ignorera le code.
0:40
Lua nous fournit trois types de boucles différents, tous très similaires, mais avec de légères variations de
0:45
la façon dont ils traitent leurs instructions conditionnelles :
0:48
Une boucle « while » répète son code encore et encore tant que votre instruction conditionnelle est
0:54
vraie. Si l'instruction conditionnelle ne change jamais, cette boucle se poursuivra indéfiniment et finira en erreur.
1:02
Une boucle « for » exécutera son code pour un nombre de fois que vous pouvez prédéterminer.
1:09
Et une boucle « repeat » répétera son code encore et encore jusqu'à ce qu'une condition spécifique soit remplie.
1:16
Construisons quelques boucles simples montrant chacun de ces types, et ensuite nous les appliquerons
1:21
à notre projet Q-SYS. D'abord, la boucle While. Définissons la variable x comme 5, et nous allons
1:28
construire une boucle qui incrémentera x de 1 jusqu'à la valeur 10.
1:33
Ainsi, notre instruction conditionnelle pour While peut être (x est inférieur à 10). Ensuite, nous ajoutons
1:40
« do », un mot réservé très important qui marque le début du corps de notre code conditionnel. Nous
1:45
allons simplement prendre x et le redéfinir comme étant sa valeur actuelle plus un. Ensuite, nous
1:53
imprimerons la nouvelle valeur x afin d'avoir une trace de l’action de cette boucle, et nous taperons
1:58
« end » pour terminer notre instruction « do ».
2:01
Quand x entre dans cette boucle la première fois, cela ajoute 1, transformant x en 6, puis cela imprime
2:08
6, avant le retour à l'instruction conditionnelle. Puisque x, qui vaut maintenant 6, est toujours inférieur à
2:14
10, il passe de nouveau par le code conditionnel pour devenir 7, puis 8, puis 9, puis 10. Maintenant,
2:22
quand il atteint l'instruction conditionnelle, il n’est plus qualifié comme inférieur à 10, donc le code
2:27
« do » n'est pas exécuté, et la boucle est terminée.
2:31
Nous pouvons valider cela en exécutant notre script, et nous pouvons voir que notre fenêtre de
2:36
débogage affiche x à la fin de chaque boucle, puis s'arrête. Maintenant, visuellement, tout semble se
2:41
passer instantanément plutôt que séquentiellement, mais soyez certain que l'ordinateur traite une
2:45
boucle après l'autre.
2:48
Ensuite, faisons une boucle « For ». Il s'agit d'une boucle déterminée, qui ne sera exécutée qu'une seule
2:54
fois pour chaque itération que nous aurons spécifiée. Je vais supprimer l'instruction conditionnelle
2:59
« while » et la remplacer par « for i=1,5 ». Ici, « i » représente une itération, ou une exécution de cette boucle.
3:10
Le premier nombre sera le nombre auquel nous commençons et le deuxième celui auquel nous voulons
3:15
nous arrêter. Si nous l'exécutons maintenant, cela semblera faire la même chose que notre boucle
3:19
précédente. Lors de la 1ère itération, cela a lancé cette boucle et a changé x en 6, lors de la seconde
3:26
itération, cette boucle a changé x en 7, etc.
3:30
Après la cinquième itération, x vaut 10 et la boucle est terminée. Mais la raison pour laquelle elle est
3:35
terminée n’a rien à voir avec celle de notre exemple précédent. Dans notre boucle « while », elle s'est
3:40
terminée parce que x ne répondait plus à l'instruction conditionnelle mais ici, c’est tout simplement
3:44
parce qu'elle a terminé le nombre d’exécutions voulu par ses instructions.
3:49
Je tiens également à souligner que « i » n'a rien à voir avec « x », et qu'il n'est pas nécessaire de
3:54
commencer à 1. Je pourrais le faire aller de 22 à 26, et cela nous donnerait les mêmes résultats. Cela
4:02
lance une boucle pour 22, une autre pour 23, 24, 25 et 26. Il s'agit simplement d'une plage, mais la 22e
4:09
itération fait exactement la même chose que la 1re.
4:14
Enfin, écrivons une boucle « repeat ». Encore une fois, je vais garder mon code conditionnel, mais
4:20
remplaçons cette première ligne par la commande « repeat ». La plus grande différence ici est que la
4:25
boucle « repeat » ne commence pas par l'instruction conditionnelle, elle se termine par elle. Cela signifie
4:30
que la première boucle est exécutée quoi qu'il arrive, puis vient la validation pour savoir si cela doit
4:34
continuer après que cette boucle soit terminée.
4:37
En ce qui concerne notre syntaxe, cela signifie que nous n'avons besoin de rien d'autre que du mot
4:41
« repeat » pour commencer notre boucle. Nous pouvons également remplacer « end » par notre
4:46
instruction conditionnelle « until » qui signifie « jusqu‘à ». Nous définissons maintenant cette instruction
4:51
conditionnelle : dans ce cas, x est équivalent à 10.
4:55
C'est un concept très similaire à la boucle « while », mais la boucle « while » effectue d'abord son
5:00
analyse, puis fait le travail, tandis que la boucle « repeat » fait le travail en premier, puis analyse si elle doit continuer.
5:07
Combinons donc cela avec d'autres outils que nous avons découverts jusqu'à présent pour créer une
5:11
boucle qui nous sera vraiment utile. Nous pourrions par exemple utiliser une boucle pour simplifier un
5:17
script qui serait sinon répétitif. Jetez un coup d'œil à ce composant Scriptable Controls–…
5:22
...dans lequel nous avons ajouté cinq boutons Toggle nommés « Flippy », et à l'intérieur nous utilisons
5:27
l’EventHandler du premier Flippy pour lancer une fonction. Cette fonction contient une instruction
5:33
if/then. Si la valeur de Flippy est 1, alors sa légende indique ON. Sinon, sa légende indique OFF.
5:42
Nous pouvons voir que cela fonctionne, notre bouton affiche l'intitulé approprié d’après ce script. Mais
5:48
cela ne fonctionne que pour le premier bouton. Si je veux donner à chaque bouton ce même
5:52
comportement, je dois dupliquer ce script quatre autres fois, non ?
5:57
Eh bien, pas nécessairement – car nous pourrions utiliser une boucle « for ». Je peux ainsi simplement
6:03
ajouter une Instruction conditionnelle « for », « for i=1,5 do ».... et cela lancera ce script. Tout ce que j'ai
6:13
à faire est de remplacer l'index de chaque contrôleur – plutôt que de faire référence au numéro du
6:18
premier contrôleur, je vais faire référence au ième contrôleur – et dans ce cas utiliser notre numéro
6:24
d'itération comme variable à appliquer dans notre fonction.
6:27
Ainsi, lors de la première itération, il écrit cette fonction pour Flippy numéro 1, lors de la deuxième
6:33
itération, il écrit cette fonction pour Flippy numéro 2, etc. Il ne me reste qu'à terminer ma boucle « for »
6:39
en bas avec « end », et mon travail est terminé. Chacun de mes contrôleurs a maintenant le même
6:43
comportement, et je l'ai obtenu avec seulement deux lignes de code plutôt que des dizaines.
6:49
Si vous transposez cela à un nombre de contrôleurs beaucoup plus grand que cinq, vous imaginez le
6:54
temps et le traitement que cela pourrait vous faire gagner. Aussi, nous voyons ici un exemple de la
6:58
raison pour laquelle nos itérations dans une boucle « for » ne doivent pas forcément partir de 1. Si je
7:03
voulais que le contrôleur 1 ait un type de comportement différent, je pourrais définir ceci pour que la
7:08
boucle s'exécute des itérations 2 à 5, ce qui n'affecterait que les contrôleurs 2 à 5.
7:14
Très bien, passons au Block Controller et construisons toutes ces boucles avec lui. Vous trouverez les
7:19
boucles dans la section Flow Control. D'abord, prenons ce bloc Repeat. Il devrait vous sembler familier, il
7:27
est actuellement réglé sur une instruction conditionnelle « while », mais vous pouvez en changer pour
7:31
une instruction conditionnelle « until » avec sa liste déroulante.
7:35
Tout comme nous l'avons fait dans Lua, nous allons établir une variable et la régler sur 5, et ensuite nous
7:41
allons effectuer notre boucle « while » avec comme condition que x soit inférieur à 10. Nous devrons
7:47
donc prendre un opérateur logique et le changer en « inférieur à », et nous irons dans nos variables et
7:53
prendrons notre x, puis une valeur pour le second terme et la fixerons à 10.
8:00
Pour l’échancrure de notre instruction, ou section « do », revenons aux variables et réglons x autrement.
8:08
Nous devons faire ici un peu d'arithmétique donc retournons voir les opérateurs et prenons ce bloc
8:13
d'addition. Une fois encore, nous pouvons prendre notre variable x pour la première encoche et une
8:20
valeur de 1 pour la deuxième. Il ne reste plus qu'à récupérer dans le dossier Système un bloc de
8:27
débogage pour imprimer notre nouveau x.
8:34
Bien, si on regarde ces deux-là côte à côte, c'est exactement la même chose. x est égal à 5, et tant que x
8:41
est inférieur à dix, nous ajoutons un à x, et l'imprimons. En fait, si nous regardons la sortie Lua du Block
8:49
Controller, nous pouvons voir qu'il génère exactement le même code Lua, mot pour mot, que la boucle
8:55
« while » que nous avons écrite nous-mêmes.
8:57
TOUTEFOIS. J'aimerais vous signaler quelque chose. Changeons cette boucle « while » en boucle
9:02
« repeat until ». Du côté Lua, vous vous souvenez que cela signifie déplacer l’instruction conditionnelle
9:09
jusqu'à la toute fin. Côté Block Controller, il suffit de changer le « while » en « until ».
9:14
Mais ajustons aussi nos instructions conditionnelles pour qu'elles se répètent jusqu'à ce que x soit
9:19
supérieur à 9, ce qui nous donnera les mêmes résultats que notre script précédent, et je vais le faire des
9:24
deux côtés. D'accord, jusqu'à présent, tout va bien ! Mais regardez le code Lua généré par le Block
9:30
Controller. Plutôt que d'écrire une vraie boucle « repeat until », il change simplement sa boucle
9:37
« while » avec un modificateur « not ». Tant que X n’est PAS supérieur à 9.
9:44
Bien sûr, cela fait la même chose pour l'instant… mais il y a un cas particulier où cela pourrait être
9:49
problématique. J'ai mentionné plus tôt que la boucle « repeat » effectue d'abord sa boucle, puis vérifie
9:56
son instruction conditionnelle à la fin pour décider si elle doit continuer. Mais si l'instruction
10:01
conditionnelle est déjà remplie avant que la boucle ne débute ? Je vais changer « until » en supérieur à 0…
10:07
… plutôt que supérieur à 9. Lorsque x commence à 5, il est déjà supérieur à 0. Une boucle repeat Lua
10:16
passera quand même une fois par sa boucle avant de vérifier ses conditions – le débogage nous montre
10:22
qu'elle est passée par un cycle avant de réaliser que la condition était remplie et de s'arrêter d’elle-même.
10:28
Mais le Block Controller est toujours une boucle « while » déguisée, qui vérifie donc d'abord la
10:33
condition : et comme 5 est déjà plus supérieur à zéro, il n'exécute aucune fois la boucle. Ces deux
10:40
fonctions peuvent donc sembler identiques, mais nous obtenons un résultat légèrement différent. Ce ne
10:46
sera probablement jamais un gros problème pour vous, mais j'ai pensé que ça valait la peine d'être mentionné.
10:51
Bien, enfin, construisons notre boucle « For » avec le Block Controller. Nous allons remplacer le bloc
10:57
repeat par cette boucle « for each item » qui signifie "pour chaque élément ». Le corps de la boucle
11:02
restera le même, mais nous avons besoin d'un Array pour définir combien de fois nous effectuons cette
11:07
action. Nous n'avons pas encore joué avec les arrays, mais il suffit de les comparer à des collections
11:12
contenant plusieurs éléments organisés.
11:14
Ce bloc dit qu'il va effectuer cette action une fois pour chaque élément de la collection, donc nous avons
11:20
simplement besoin de définir une collection de 5 choses. Je vais prendre ce bloc, qui crée un array avec
11:26
une chose répétée un certain nombre de fois. Peu importe quels éléments sont réellement dans l’array,
11:32
seul compte leur nombre.
11:35
Donc je pourrais créer un array avec n'importe quoi dans le monde, un nombre, une chaîne, peu
11:40
importe, et je vais le répéter autant de fois que je veux d’exécutions de la boucle. Quand je mets à jour
11:46
le script, notre boucle fonctionne comme prévu.
11:50
D'accord, ce n'est qu'un aperçu des boucles. Ce que font les boucles peut devenir beaucoup plus
11:55
compliqué – notamment les boucles imbriquées dans d’autres boucles, mais nous n'irons pas plus loin
12:00
dans ce cours en ligne. Jetez un coup d'œil à notre Cahier d'exercices Q-SYS Contrôle sur les boucles,
12:04
puis poursuivez lorsque vous êtes prêt.