CALLEJÓN ADOQUINADO ENTRE CASAS SEÑERAS EN LA LOCALIDAD DE TAGANANA, NORTE DE ANAGA, NORESTE DE TENERIFE. |
Dentro de la herramientas de control de flujo toca ahora echarle un vistazo al bucle o loop, como prefiramos llamarlo, while. Del mismo modo que sucede con el bucle for/in que ya hemos visto en alguna ocasión y que estudiaremos en el apartado siguiente, se trata de un ITERADOR, esto es, tengámoslo en cuenta, que la condición es aplicada sobre cada elemento de una colección de datos, de uno en uno y por orden, evaluando la condición en cada caso sobre el primer dato que obtiene, luego sobre el segundo, a continuación el tercero y así sucesivamente n número de veces hasta que la condición se cumpla, deteniéndose el bucle, aplicándose en ese momento el bloque de código correspondiente al mismo y haciéndose efectiva la bifurcación.
Esta capacidad intrínseca para iterar que adorna a nuestro bucle while le permite ejecutar una serie de sentencias, agrupadas en su bloque de código, siempre y cuando se cumpla una determinada condición o condiciones, esto es, siempre que el resultado de la evaluación sea True.
Aquí mostramos un pequeño esquema:
WHILE (CONDICIÓN BOOLEANA):
BLOQUE_DE_CÓDIGO
En tanto que la veracidad de la condición se dilucida con un True o False, la condición debe ser de índole booleana. Ahora veremos un ejemplo práctico sencillo:
En este ejemplo constatamos lo siguiente:
En 1. creamos una variable con el nombre de identificador del espacio de memoria 'num' a la que asignamos el valor inicial 0 mediante el operador = de asignación.
En 2. establecemos un bucle while con la siguiente expresión: num < 10, que es la condición que establecemos. A continuación, recordemos que los bloques de código de las herramientas de control de flujo debe ir sangradas o indentadas, cerramos con dos puntos.
En 3., finalmente, colocamos las declaraciones que, en nuestro ejemplo, van a ser dos instrucciones: primero codificamos una función print() con una string como parámetro para poder mostrar el resultado en pantalla; y a continuación generamos un contador simple. Recurrimos a nuestra variable 'num' que, como sabemos, tiene asignado el valor (en los contadores es preceptivo inicializar la variable con un valor numérico) al que sumamos, +. 1. De esta forma, cuando el bucle while itere por primera vez, devolverá el valor 0, que es el primer valor de 'num'. Como la condición se cumple que da gusto (el valor booleano es True), prosigue con la iteración tras aplicar la declaración 0 + 1, de tal modo, que ahora 'num' vale 1. El bucle while vuelve a iterar tras ejecutarse la operación, y como la condición sigue cumpliéndose (1 es menor que 10), y vuelta a ejecutarse la declaración: ahora 'num' vale 1 y se le suma 1, es decir, 1 + 1 = 2. Como la condición continúa cumpliéndose dado que 2 es menor que 10, aplica la declaración nuevamente, 2 + 1,, es decir, 3, y vuelta a iterar. Todo continúa igual hasta llegar a 9 + 1. Aquí el valor es 10, y la condición, esta vez sí, deviene en False... y el bucle se detiene.
Digamos que aquí tenemos una descripción o lectura natural, y esperamos que comprensible, de lo que hace el bucle while tomando como base el ejemplo anterior: partiendo de que el valor inicial de 'num' es 0, mientras que el valor de 'num' sea menor que 10, seguimos sumando el entero 1 a cada valor consecutivamente hasta que el valor de 'num' sea igual a 10 (num = 10), lo que suscita la ruptura (break) del programa.
Vamos con otro ejemplo sencillo de uso de while.
Y puesto que le hemos cogido el gustillo a los ejemplos vamos con uno que resulta todo un clásico, un modelo recurrente en casi todos los manuales dedicados a Python cuando se ejemplariza el bucle while: la sucesión de Fibonacci. ¡Olé!
La llamada "sucesión de Fibonacci", mal llamada "secuencia"en algunos sitios, fue descrita por el matemático italiano Leonardo de Pisa, conocido como Fibonacci y de aquí el intitulado de la sucesión, allá por el siglo XIII, y consiste en una serie infinita de números naturales comenzando con 1 y 1 y, a partir de este último, se establece una relación de recurrencia donde cada término es la suma de los dos anteriores:1, 1 (0 + 1), 2 (1 + 1), 3 (1 + 2). 5 (2 + 3), 8 (3 + 5), 13 (5 + 8), 21 (8 + 13), 34 (13 + 21), 55 (21 + 34),...
¡Buff! Me he cansado ya de ladrar: con 55 ya tengo suficiente.
¡Hasta la próxima!
Estudiemos el caso: en 1, en nuestra primera instrucción, creamos dos variables de cabecera mediante asignación simplificada, ahorrando líneas de código usando a y b como nombres de identificadores a las que asignamos, respectivamente, los valores iniciales 0 y 1. Esto es así porque la sucesión de Fibonacci comienza con dos números enteros: 1 y 1.
Seguidamente, recurrimos en 2. al bucle while y creamos la condición pertinente, b < 100, entre los paréntesis, y completamos con los dos puntos, dado que el bloque de código del bucle debe escribirse indentado.
Ahora procedemos a introducir las declaraciones: en 3. llamamos a la función print() y le pasamos tres parámetros, como ya sabemos de ejemplos anteriores, convenientemente separados por sendas comas. En primer lugar, el valor de la variable b, a continuación una string para poner una coma entre los valores y dejar un espacio en blanco (whitespace), por cuestiones estéticas y para facilitar la lectura "y no se nos arrejunten las cabras" y, finalmente, el operador end="" para evitar que Python nos devuelva un resultado iterado, en formato columna que es el establecido por defecto, y nos lo muestre en línea.
En 4. introducimos la declaración clave: a, b = b, a + b. De nuevo recurrimos a nuestras variables de cabecera, tal y como ocurrió en el ejemplo anterior, y modificamos sus valores de partida. Ahora, tras la primera iteración de while, a valdrá lo que valga b, y b valdrá el resultado de sumar el valor de a y el valor de b: 2ª iteración => 0 + 1 = 1; 3ª iteración => 1, (1 + 1); 4ª iteración => 2, ( 1 + 2); 5ª iteración => 3, (2 + 3); 6ª iteración => 5, (3 + 5); etc.
Y así sucesivamente mientras b sea menor que 100. Cuando la condición no pueda cumplirse, es decir, devenga False, dejará de ejecutarse el programa.
La "sucesión de Fibonacci", ya que estamos, no es una simple 'boutade' tiene su valor matemático y está presente en la Naturaleza: la disposición de las ramas de los árboles en torno al tronco, la disposición de las hojas en el tallo de muchas plantas, en la estructura en espiral de algunas conchas de animales, en los vórtices de los huracanes, en la disposición en espiral de los brazos de las galaxias, y en muchísimos más ejemplos.
Sorprendente. No está mal saberlo.
VISTA DEL VALLE DE TAGANANA Y DE LA PARTE ALTA DEL PUEBLO DESDE LA DORSAL. ANAGA, NORESTE DE TENERIFE. |
El bucle o sentencia while soporta también la cláusula else, que es opcional, de acuerdo a la sintaxis:
WHILE (CONDICIÓN BOOLEANA):
BLOQUE_DE_CÓDIGO-WHILE
ELSE:
BLOQUE_DE_CÓDIGO-ELSE
Como ya sabemos, mientras la condición establecida en la expresión sea True, la declaración o declaraciones de while, su bloque de código asociado, si lo preferimos así, continuará ejecutándose con cada iteración hasta que la condición devenga False, en cuyo caso se rompe el bucle y, en el supuesto de que hubiéramos dispuesto una cláusula else, se ejecutará su declaración (es) o bloque de código asociado. Mostramos un ejemplo a continuación.
Sin embargo, a todas éstas, debemos tener presente que el recurso a la cláusula else implica que si el bucle while se ejecuta y finaliza correctamente, el bloque de código asociado a la misma siempre se ejecuta, salvo en estos tres supuestos:
- Si el bucle finaliza abruptamente por una sentencia break.
- Si el bucle finaliza por una sentencia return, si está integrado en un método o función.
- Si se lanza una excepción
Por último, el bucle while puede establecer un límite en una iteración llevada a cabo por un bucle for/in para evitar que, si no obtenemos un resultado, dicho bucle for/in continúe iterando hasta el final de la secuencia. Imaginemos que circulamos por una autopista y nuestra intención es tomar el primer desvío que nos lleve a una localidad o espacio determinado. Vamos dejando atrás diferentes desvíos que nos señalan distintas ubicaciones que no son de nuestro interés hasta que encontramos uno que indica nuestro lugar de destino. A pesar de que podemos encontrar nuevos lugares llamativos a lo largo de nuestra ruta, nos decidimos por éste en concreto y ya no tenemos necesidad de continuar circulando por la autopista: es como si hiciéramos un stop y bifurcáramos saliéndonos de la dirección y sentido de la autopista. Aquí nuestro stop es la sentencia while.
Aunque lo veremos a continuación, podemos adelantar que el bucle for/in recorre toda la secuencia de principio a fin, a menos que acotemos una subsecuencia con el concurso de la función range(), iterando ítem por ítem en orden a sus índices respectivos de izquierda a derecha, esto es, de menor a mayor: primero secuencia[0], luego secuencia[1], luego secuencia[2] y así sucesivamente hasta el final. Sin embargo, el bucle while necesita que le indiquemos con qué índice comienza a aplicar la condición y hasta que índice puede llegar.
Y un aspecto fundamental: el bucle while es DINÁMICO, esto es, que no opera sobre una secuencia de datos dada, como sí lo hace for/in sino que lo hace sobre una secuencia que se va generando progresivamente mientras el resultado de la evaluación de la sentencia while continúe siendo True.
Resumiendo:
Acabamos recordando que la estructura sintáctica de while es muy similar a la del condicional if/elif/else: se apoya en un análisis booleano, igual que if, donde la declaración se ejecuta mientras while devenga True. Sin embargo, la diferencia estriba en que en el caso de if, cuando el resultado es True, no continúa con el flujo del código y bifurca, mientras que while regresa a la cabeza y reevalúa nuevamente la expresión una y otra vez hasta que devenga False.
Observemos todavía un par de ejemplos más.
ADVERTENCIA: POR LA FORMA TAN PECULIAR QUE PYTHON TIENE DE TRATAR A LOS NÚMERO DECIMALES, float, NI SE NOS OCURRA ESTABLECER CONDICIONES CON ESTE TIPO DE DATOS, YA QUE CORREMOS UN RIESGO SERIO DE ENTRAR EN UN BUCLE INFINITO.
No nos resistimos a incluir un par de ejemplos más de uso del bucle while, esta vez, en situaciones de codificación, por así decirlo, más comunes, como por ejemplo, como verificadores de una condición:
Resumiendo:
- for/in: el bucle (loop) recorre una secuencia mediante una variable que ejerce como controlador (for item in secuencia: → item es la variable controladora) sobre una secuencia de tamaño conocido y/o cerrado (podemos no conocer la secuencia de antemano, por ejemplo, una lista que vaya almacenando durante un tiempo determinado todas las palabras que se nos vayan ocurriendo a lo largo de un minuto que empiecen por "z". Se nos pueden ocurrir 3, 10, 20, o más o menos, pero una lista SIEMPRE tiene un principio, lista[0], y un final, lista[-1])
- while: la "variable controladora" es, en este caso, una condición lógica en tanto que, si bien conocemos la condición que nos hace salir del bucle, desconocemos a priori el número de elementos sobre los que se puede iterar.
Acabamos recordando que la estructura sintáctica de while es muy similar a la del condicional if/elif/else: se apoya en un análisis booleano, igual que if, donde la declaración se ejecuta mientras while devenga True. Sin embargo, la diferencia estriba en que en el caso de if, cuando el resultado es True, no continúa con el flujo del código y bifurca, mientras que while regresa a la cabeza y reevalúa nuevamente la expresión una y otra vez hasta que devenga False.
Observemos todavía un par de ejemplos más.
No nos resistimos a incluir un par de ejemplos más de uso del bucle while, esta vez, en situaciones de codificación, por así decirlo, más comunes, como por ejemplo, como verificadores de una condición:
T4. BLOQUE DE EJERCICIOS 8. SOLUCIONES.
SISTEMA DE CUEVAS Y EROSIÓN PRODUCIDA POR LAS ESCORRENTÍAS EN LAS LADERAS DEL BARRANCO DE VALLESECO, SUR DE ANAGA, NORESTE DE TENERIFE. |
No hay comentarios:
Publicar un comentario