0:08
Hay muchas situaciones donde quieres ejecutar la misma sección de un código varias veces seguidas.
0:13
Un bucle es una estructura de control que nos permite ejecutar una sentencia o un grupo de
0:18
sentencias varias veces, dependiendo si se cumplen condiciones en particular.
0:24
En esencia, cuando un script llega a un bucle, analiza la condición. Si la condición es cierta, entonces
0:29
realiza el código condicional y vuelve a analizar la condición. Seguirá haciendo esto hasta que la
0:35
condición sea falsa, el punto en el que ignora el código.
0:39
Lua Brinda 3 diferentes tipos de bucles, los cuales son muy similares, pero tienen ligeras variaciones
0:44
en cómo manejan sus sentencias condicionales.
0:48
Un bucle While (mientras) repite su código una y otra vez mientras su sentencia condicional sea
0:52
verdadera. Si la sentencia condicional nunca cambia, este bucle continuará indefinidamente, y nos
0:58
arrojará un error. Un bucle For (por) ejecutará su código por un determinado número de veces, el
1:04
cual tú puedes definir. Y un bucle Repeat (repite) repetirá su código una y otra vez hasta que se
1:10
cumpla una condición en específico.
1:13
Construyamos algunos bucles sencillos para demostrar cada uno de los tipos y después los
1:17
aplicaremos a nuestro diseño de QSYS. Primero el blucle While. Definamos una variable X como 5 y
1:25
construiremos un bucle que incremente “x” de 1 en 1 hasta que llegue al valor de 10.
1:31
Así que la sentencia condicional para el While puede ser (x<10). Después pondremos la
1:37
importantísima palabra reservada “Do”, la cual inicia el cuerpo de nuestro código condicional. Y solo
1:44
tomaremos a “x” y la redefiniremos como su valor actual + 1. Después imprimiré el nuevo valor de X
1:52
para que tengamos registro que el bucle está ocurriendo, y para escribiré “end” para finalizar nuestra
1:59
Cuando “x” pasa por este bucle la primera vez, se le sumará un 1, convirtiendo a “x” en 6, después
2:06
imprimirá el 6 y luego regresará a la sentencia condicional. Como “x”, ahora siendo 6, es aún menor
2:14
que 10, entonces pasará por el código condicional nuevamente para convertirse en 7 y luego en 8 y
2:20
luego en 9 y luego 10. Ahora, cuando llega a la sentencia condicional, ya no califica como menor a 10,
2:27
así que el código “do” no se realiza y se termina el bucle.
2:32
Podemos validar esto corriendo nuestro script, y podemos ver en nuestra ventana de depuración que
2:37
se imprime x al final de cada bucle, y luego se detiene. A nuestros ojos parece que esto sucede
2:43
instantáneamente en lugar de secuencial, pero créeme que la computadora está haciendo un bucle
2:50
Ahora hagamos un bucle for (por). Este es un bucle definido, el cual solo corre una vez por cada
2:55
iteración o repetición que especifiquemos. Quitaré la sentencia condicional While y la reemplazaré
3:00
con for i=1,5. Aquí, “i” representa una iteración o una instancia de este bucle.
3:08
El primer número de aquí será el número donde iniciamos, y el segundo número es el número donde
3:13
queremos que se detenga. Si lo corremos ahora, parecerá que hace lo mismo que el bucle anterior.
3:19
En la primer iteración correrá este bucle y cambiará x a 6, en la segunda iteración cambiará x a 7, etc.
3:27
Después de la quinta iteración, x es 10 y el bucle se termina. Pero la razón del porqué se termina es
3:33
completamente diferente a nuestro ejemplo anterior. En nuestro bucle while, se terminó porque x ya
3:39
no cumple con la sentencia condicional, pero en este bucle se termina solo porque ha terminado sus
3:45
instrucciones de cuántas veces debe de correr.
3:48
También quiero aclarar que la “i” no tiene nada que ver con la X, o que tenga que iniciar en 1. Puedo
3:54
tener esto corriendo desde 22 hasta 26 y nos dará el mismo resultado. Correrá el bucle por 22, luego
4:01
por 23, 24, 25 y 26. Esto es simplemente un rango, pero la iteración #22 hace exactamente lo mismo
4:09
que la iteración #1.
4:12
Por último, escribiré un bucle repeat (repite). Una vez más, mantendré mi código condicional, pero
4:17
reemplacemos esta primer línea con el comando repeat. La diferencia más grande es que el bucle
4:22
repeat no inicia con una sentencia condicional, sino que termina con ella. Esto significa que realizará
4:29
el primer bucle no importando qué, y después validará si debe o no continuar una vez que el bucle
4:37
En lo que respecta a nuestra sintaxis, esto significa que no necesitamos nada más que la palabra
4:42
repeat para iniciar nuestro bucle. También debo reemplazar el “end” con la sentencia condicional
4:48
“until” (hasta). Ahora definiremos cuál será la sentencia condicional: en este caso, x es equivalente a 10.
4:56
Es un concepto similar al bucle while, pero el bucle while realiza su análisis primero y después hace el
5:03
trabajo, mientras que el bucle repeat hace el trabajo primero y después analiza si debe continuar.
5:09
Ahora combinemos esto con otras herramientas que hemos aprendido hasta ahora para hacer un
5:14
bucle que realmente sea útil para nosotros. Podemos usar un bucle for, por ejemplo, para simplificar
5:19
un script repetitivo. Mira este componente de Scriptable Controls
5:24
… en el cual he añadido 5 botones Toggle llamados “Flippy”, y dentro estamos usando el
5:28
EventHandler de nuestro primer Flippy para llamar una función. Esta función contiene una sentencia
5:34
if/then. Si el valor de Flippy es 1, entonces su .Legend será “ON”. Si no, su .Legend será “OFF”.
5:43
Podemos ver que esto funciona, nuestro botón muestra la etiqueta correcta basada en este script.
5:49
Pero eso funciona solo para el primer botón. Si queremos darte este comportamiento a todos los
5:54
botones, tendría que copiar este script cuatro veces más ¿correcto?
5:59
Bueno, no necesariamente – ya que podemos usar un bucle for. Solamente tengo que añadir una
6:04
sentencia condicional for. For i=1,5 do… y luego hará este script. Todo lo que necesito hacer es
6:12
reemplazar el índice de cada control – en lugar de hacer referencia al número del primer control,
6:18
haré referencia al control i – en este caso, usaré nuestro número de iteraciones como una variable
6:24
para aplicar dentro de nuestra función.
6:26
Así que la primer iteración escribe esta función para el Flippy número 1, en la segunda iteración
6:32
escribe esta función para el Flippy número 2, etc. Todo lo que necesitamos hacer es terminar mi
6:38
bucle for aquí en la parte inferior, y he terminado. Cada uno de mis controles ahora tiene el mismo
6:44
comportamiento, y lo hice solo con 2 líneas de código adicionales en lugar de docenas.
6:50
Si comienzas a ampliar esto a más de 5 controles, puedes ver cuánto ahorras en tiempo y
6:55
procesamiento. También, vemos un ejemplo del porqué las iteraciones de nuestro bucle for NO
7:01
siempre tienen que iniciar en 1. Puedo establecer que este loop inicie desde la iteración 2 hasta la 5,
7:07
lo cual solo afectará a los controles 2 al 5, si quiero que 1 tenga un comportamiento distinto.
7:15
Ok, veamos ahora el Block Controller y construyamos estos bucles aquí. Encontrarás los bucles bajo la
7:21
sección de Flow Control. Primero, tomaré este bloque de Repeat. Esto debería ser familiar, está
7:27
configurado con una sentencia condicional while, pero puedes cambiar en este menú desplegable a
7:33
una sentencia condicional “until”.
7:35
Justo como lo hicimos en Lua, colocaré una variable y le daré un valor de 5, y haremos nuestro bucle
7:42
while con la condición de que x es menor a 10. Ahora, necesito arrastrar un operador lógico y
7:48
cambiarlo a “menor que”, después iremos a nuestras variables y tomaré nuestra x, después tomaré
7:56
un valor para la segunda mitad y lo colocaré en 10.
8:00
Para el espacio de nuestra sentencia o nuestra sección “do”, regresaré a las variables y le daré a “x” a
8:06
un valor. Necesitamos hacer algo de aritmética aquí así que regresaré a los operadores y tomaré este
8:13
bloque de suma. Una vez más, puedo tomar nuestra variable X de la primera ranura y un valor de 1
8:20
para nuestra segunda ranura. Todo lo que resta es ir a la carpeta de System y tomar un bloque de
8:26
Debug Print y hacer que se imprima nuestra nueva X.
8:30
Ok, si comparamos estos dos, son exactamente lo mismo. X igual a 5, mientras x sea menor a 10,
8:39
sumaremos 1 a x y lo imprimiremos. De hecho, si vemos el Lua que se crea con el block controller,
8:46
veremos que se genera exactamente el mismo código, palabra por palabra, que el código que
8:51
generamos nosotros mismos.
8:53
SIN EMBARGO. Quiero dejar algo bien claro. Cambiemos este bucle while a un bucle repeat-until. En
9:00
el lado de Lua recordarás que esto significa mover la sentencia condicional al final. En el lado de los
9:06
bloques, solo necesitamos cambiar el while por el until.
9:11
Pero ajustemos también nuestras sentencias condicionales para que se repita hasta que x sea mayor
9:15
que 9, lo cual nos da el mismo resultado que nuestro script anterior, y lo hará en ambos lados.
9:21
¡Perfecto! Pero fíjate en el Lua que el Block Controller genera. En lugar de escribir un bucle repeat-
9:28
until real, solo cambia el bucle while con un modificador “not”. Mientras que X NO sea mayor que 9.
9:37
Claro, hace lo mismo por ahora… pero hay algunos casos especiales donde esto puede ser
9:42
problemático. Mencioné anteriormente que el bucle repeat realiza su primer bucle y después al final,
9:48
checa su sentencia condicional para saber si debe continuar. Así que, ¿qué pasa si la sentencia
9:54
condicional se cumple antes de que el ciclo comience? Cambiaré el until para que sea mayor a 0
10:01
…en lugar de mayor que 9. Cuando x inicia en 5, ya es mayor que 0. Un bucle repeat en Lua, correrá
10:09
de todas formas su primer bucle antes de checar sus condiciones – así que tendremos un resultado
10:15
en pantalla mostrando que se realizó este primer ciclo antes de darse cuenta que la condición se ha
10:21
cumplido y se detengo.
10:23
Pero en el Block Controler, aún es un bucle while disfrazado – por lo que checa primero la condición:
10:29
y como 5 ya es mayor que 0, entonces no realiza ningún bucle. Así que estas dos funciones pueden
10:36
parecer idénticas, pero tendremos resultados diferentes. Es muy probable que esto no sea de mucho
10:43
cuidado para ti, pero pienso que vale la pena mencionarlo.
10:47
Ok, finalmente, construyamos nuestro bucle for en el block controller. Remplazaremos nuestro
10:53
bloque repeat con este bucle “for each item”. El cuerpo del bucle se mantiene igual, pero
10:59
necesitamos de un Array (arreglo) para definir cuántas veces realizará esta acción. Aún no hemos
11:05
jugado con arreglos, pero piensa en que un arreglo es un contenedor con muchos artículos
11:12
Este bloque dice que realizará esta acción una vez por cada artículo en el contenedor, así que solo
11:18
necesitamos definir un contenedor que tenga 5 cosas. Tomaré este bloque que crea un arreglo con
11:24
“nada” que se repite “nada” veces. No importa qué elementos haya en el arreglo, solo importa
11:31
cuántos de ellos están ahí.
11:33
Así que puedo crear un arreglo con nada en el mundo, un número, una cadena, cualquier cosa, y lo
11:40
repetiré tantas veces como quiera que se repita el bucle. Cuando actualizo el script, nuestro bucle
11:46
hace lo que esperamos.
11:48
Perfecto, esto es solo un vistazo a los bucles. Puedes ir más lejos y complicado con los bucles –
11:54
incluyendo bucles anidados dentro de otros bucles, pero no iremos tan profundo en este curso en
11:59
línea. Echa un vistazo a tu hoja de trabajo de control, en la sección de bucles y pasa al siguiente video
12:05
cuanto estés listo.