Bucles de repetición

¿Qué son los bucles?

Al igual que las sentencias condicionales de control de flujo de programa IF ELIF y ELSE, los bucles son sentencias de control de flujo que permiten repetir el mismo bloque de código mientras se cumpla una condición en particular, ninguna, una, varias finitas e infinitas e indeterminadas veces, a diferencia de la sentencia IF que permite la ejecución de un bloque de código solamente una vez.

Haciendo una analogía con la vida cotidiana, la sentencia IF es como el portero que revisa la documentación en la entrada y deriva a una u otra puerta dependiendo de la  documentación presentada, pero solamente pudiendo hacer un único uso de las instalaciones a las cuales se han otorgado acceso, mientras que las sentencias de bucles repetitivos evalúan igualmente la documentación presentada pero el uso de las instalaciones se repite de manera indefinida hasta que se cumpla una condición en particular.

En Python esisten 2 tipos de sentencias de bucles de repetición, el bucle WHILE y el bucle FOR, si bien el bucle WHILE es muy similar a las de otros lenguajes de programación, el bucle FOR difiere un poco en su uso al conocido por los programadores que vienen de otros lenguajes. En Python el bucle FOR es mas una instrucción de recorrido dentro de una secuencia, ya sean cadenas, listas, tuplas, diccionarios o conjuntos.

Instrucciones BREAK y CONTINUE


Al usar bucles de repetición WHILE y FOR en Python, no estamos necesariamente sujetos a una única condición para finalizar el ciclo. Es cierto que es necesario definir una condición de salida desde el principio, sin embargo, se pueden definir las condiciones de salida que sean necesarias dentro del bloque de código que se ejecuta, para ajustarse a las necesidades del programa.

Sentencia BREAK

Para interrumpir un ciclo WHILE o FOR nos valdremos de una de las instrucciónes que existen para dicho cometido. La sentencia BREAK, su sintanxis es solamente la palabra reservada BREAK y se debe colocar en el punto donde se desea interrumpir el flujo del ciclo. Por ejemplo veamos como sería con uno de los ejemplos anteriores:

tupDiasSemana="Lunes","Martes","Miércoles","Jueves","Viernes","Sábado","Domingo"
x=0
while x < len(tupDiasSemana):    
    if tupDiasSemana[x] == "Jueves":
        print(f"Día {tupDiasSemana[x]}, encontrado en la lista")
        break
    else:
        print(tupDiasSemana[x])
    x=x+1
print(f"Se terminó la búsqueda en el elemento {x}")

Resultado:

Lunes
Martes
Miércoles
Día Jueves, encontrado en la lista
Se terminó la búsqueda en el elemento 3

Como podemos ver el ciclo WHILE, a pesar que inicialmente esta declarado para que recorra la tupla tupDiasSemana hasta el final, se interrumpe al darse la condición que uno de sus elementos sea la cadena de caracteres "Jueves", ya que, luego de dar el mensaje por pantalla de que se ha encontrado dicho elemento en la secuencia, el ciclo encuentra la instrucción BREAK lo cual redirige el fludo del programa directamente a la instrucción siguiente luego del bloque de código del ciclo WHILE. En este caso en particular, a la instrucción que muestra por pantalla el índice del elemento encontrado en la colección.

En el ejemplo de introducción de edades en el apartado de bucles WHILE vimos que el programa se ejecutaría de manera infinita si el usuario nunca ingresa un valor válido para la edad. Sin embargo, a pesar que esto técnicamente es correcto y perfectamente válido, es posible que deseáramos permitir un número finito de intentos, por ejemplo que al quinto intento el programa se salga. Veamos como quedaría aplicando la sentencia BREAK:

import os

iEdad = -1
iIntentos=5
while iEdad <0 or iEdad > 100:
    os.system('cls')
    print('* * * PROGRAMA DE VALIDACION DE EDAD * * *')    
    iEdad=int(input('Introduzca su edad: '))
    if iEdad <0 or iEdad> 100:
        iIntentos -=1
        if iIntentos == 0:
            break
        print(f'Error: Edad {iEdad} no válida, por favor introduzca un valor entre 0 y 100')
        _=input(f'Quedan {iIntentos} intentos. Presione <ENTER> tecla para continuar...')
    else:
        print('Edad introducida: ' + str(iEdad) + ' muchas gracias.')
if iIntentos>0:
    print('Fin del programa')
else:
    print(f'Error: Edad {iEdad} no válida, número máximo de intentos alcanzado. El programa se va a cerrar')

Resultado fallando en todos los intentos:

* * * PROGRAMA DE VALIDACION DE EDAD * * *
Introduzca su edad: 233
Error: Edad 233 no válida, por favor introduzca un valor entre 0 y 100
Quedan 4 intentos. Presione <ENTER> tecla para continuar...

* * * PROGRAMA DE VALIDACION DE EDAD * * *
Introduzca su edad: -23
Error: Edad -23 no válida, por favor introduzca un valor entre 0 y 100
Quedan 3 intentos. Presione <ENTER> tecla para continuar...

* * * PROGRAMA DE VALIDACION DE EDAD * * *
Introduzca su edad: 233
Error: Edad 233 no válida, por favor introduzca un valor entre 0 y 100
Quedan 2 intentos. Presione <ENTER> tecla para continuar...

* * * PROGRAMA DE VALIDACION DE EDAD * * *
Introduzca su edad: -533
Error: Edad -533 no válida, por favor introduzca un valor entre 0 y 100
Quedan 1 intentos. Presione <ENTER> tecla para continuar...

* * * PROGRAMA DE VALIDACION DE EDAD * * *
Introduzca su edad: 444
Error: Edad 444 no válida, número máximo de intentos alcanzado. El programa se va a cerrar

Hemos podido limitar un bucle WHILE potencialmente infinito (si el usuario se equivocara indefinidamente) a solamente 5 intentos como máximo, gracias al uso de la sentencia BREAK.

En la versión usando el bucle FOR, el código quedaría de la siguiente manera:

for x in range(10):
    if x == 5:
        break
    print(x)

Con el resultado:

0
1
2
3
4

Como era de esperarse el programa termina al darse la condición x == 5, haciendo que el flujo del programa salte directamente a la instrucción siguiente del bloque de código definido en el bucle for, que en este caso en particular es el final del programa, terminando así en el elemento de valor 5, siendo interrumpido y no dejando iterar el objeto completo.

La instrucción CONTINUE

Si bien la sentencia CONTINUE interrumpe el ciclo WHILE y FOR al igual que lo hace la sentencia, BREAK, ambas difieren en el punto a donde se dirige el flujo del programa al ejecutarse. En el caso de la sentencia CONTINUE, el flujo es dirigido a la siguiente iteración, omitiendo el resto de código que se encuentra luego de la sentencia CONTINUE en ese momento en particular sin salir enteramente del bucle. Veamos el siguiente ejemplo:

tupDiasSemana="Lunes","Martes","Miércoles","Jueves","Viernes","Sábado","Domingo"
x=-1
while x < len(tupDiasSemana) -1:
    x=x+1
    if tupDiasSemana[x] == "Jueves":
        print("Se ha encontrado el día Jueves")
        continue
    print(tupDiasSemana[x])

el resultado es:

Lunes
Martes
Miércoles
Se ha encontrado el día Jueves
Viernes
Sábado
Domingo

Como podemos ver el flujo del programa transcurre dentro del ciclo WHILE como lo hemos venido viendo hasta ahora, sin embargo, al encontrar la palabra "Jueves" en uno de los elementos de la tupla, se muestra por pantalla un mensaje indicando que se ha encontrado el día Jueves pero saltando a la siguiente ciclo sin imprimir el elemento de la tupla como en los otros ciclos y sin salirse del bucle.

Nota: Para los efectos de este ejemplo se inició la variable x en -1 ya que el primer elemento de la tupla tiene índice 0 y es necesario realizar el incremento al principio de cada ciclo ya que si se coloca al final del ciclo, ésta no podría ejecutarse una vez encontrado el día Jueves ya que la instrucción CONTINUE siempre enviaría el flujo del programa al principio entrando en un ciclo sin fin al no poderse dar la condición de salida del bucle. Una opción hubiera sido repetir la instrucción de incremento dentro del bloque IF, pero buscando optimizar el código y hacerlo mas corto, se hizo de esta manera. En todo caso es mas óptimo usar para este caso un bucle FOR, como veremos en el siguiente ejemplo:

tupDiasSemana="Lunes","Martes","Miércoles","Jueves","Viernes","Sábado","Domingo"

for x in tupDiasSemana:
    if x=="Jueves":
        print("Día Jueves encontrado")
        continue
    print(x)

El resultado sería:

Lunes
Martes
Miércoles
Día Jueves encontrado
Viernes
Sábado
Domingo

Como se puede apreciar el código usando FOR hace exactamente lo mismo que el código anterior usando WHILE pero con menos líneas de código y lo mas importante, sin tener que usar la variable de control del índice, ya que el ciclo FOR recorre automáticamente el objeto a iterar sin necesidad de la intervención del programador, evitando así también los posibles errores que esto conlleva.

La instrucción PASS

Devuelve NULL en un bucle WHILE o FOR, como si el bucle no se ejecutara. Se usa normalmente cuando se definan clases que se van a desarrollar luego, pero necesitan estar declaradas con anticipación para que a parte que se esta desarrollando funcione, o cuando se desea dejar definido el bucle pero el desarrollo interno se va a programar posteriormente y de momento se necesita tener el bucle aunque no realice nada para poder proseguir con el desarrollo del programa. Es como dejar el trabajo a medias para terminarlo mas tarde.

La instrucción ELSE

A diferencia que en un condicional IF, el ELSE en un bucle FOR O WHILE determina la ejecución de un bloque de código solamente al completar satisfactoriamente el bucle entero, por ejemplo si un bucle FOR se completa de principio a fin sin encontrar ninguna sentencia BREAK, entonces se ejecuta el ELSE de la instrucción FOR. Veamos un ejemplo sencillo para ilustrarlo mejor:

sEmail=input('Escriba una dirección de email: ')

for i in sEmail:
    if i=='@':
        bContieneArroba=True
        break
else:
    bContieneArroba=False

print(bContieneArroba)

Resultado ingresando cesargamboa13hotmail.com

Escriba una dirección de email: cesargamboa13hotmail.com
False

Resultado ingresando cesargamboa13@hotmail.com

Escriba una dirección de email: cesargamboa13@hotmail.com
True

Como podemos comprobar el ciclo FOR se interrumpe si encuentra que uno de los caracteres de la cadena analizada es igual al símbolo arroba, en cuyo caso no se completa el bucle y salta incluso el ELSE que forma parte del bucle FOR, sin embargo si llega al final del bucle FOR inmediatamente se ejecuta el contenido de la instrucción ELSE perteneciente al bucle FOR. En este caso entraría al ELSE cuando la cadena introducida no contiene arroba haciendo que el bucle llegue a su fin satisfactoriamente.

Comentarios

Entradas populares