AnteriorPosterior

06. Bucles (1: while)

Por: Nacho Cabanes
Actualizado: 08-08-2020 12:33
Tiempo de lectura estimado: 14 min.

 

Versión en video (8:52 min):

Fund.Prog con Python 2020

06. Bucles (1: while)

Vamos a tener nuestro primer contacto con lo que llamaremos las "estructuras repetitivas", que permitirán que una parte del programa se ejecute varias veces:

  • O bien un número prefijado a veces, por ejemplo, siete veces,

  • O bien mientras que se cumpla o no se cumpla una cierta condición.

Nuestro primer contacto va a ser con la orden "while" que permitirá que algo se repita, mientras que una cierta condición sea verdad.

Como primer ejemplo de por qué puede ser necesario realmente hacer algo así, vamos a hacer un programa que divida dos números.

Ya sabes que la división entre dos números dará problemas si el segundo número, el dividendo, es cero, con lo cual vamos a pedir al usuario... pedirle primero el dividendo, que va a ser el resultado de tomar como entero lo que un usuario introduzca como respuesta a la pregunta "Dime el dividendo".

dividendo = int(input("Dime el dividendo: "))

De la misma forma le pediríamos el divisor.

divisor = int(input("Dime el divisor: "))

La lógica para dividir, en principio ,haría algo parecido a esto:

print("La division es ", dividendo / divisor)

Pero en realidad, si el divisor es igual a cero, lo debería volver a pedir, con lo cual, puedo repetir esta estructura y si me ha dicho que es cero, le vuelvo a preguntar.

dividendo = int(input("Dime el dividendo: "))
divisor = int(input("Dime el divisor: "))
if divisor == 0:
  divisor = int(input("Dime el divisor (no debe ser 0): "))
print("La division es ", dividendo / divisor)

¿Qué ocurre? Que eso todavía puede tener problemas. Vamos a comprobarlo.

Primero lanzó el programa y supongo que son cinco y dos.

Dime el dividendo: 5
Dime el divisor: 2
La division es 2.5

Bien, me dice que es 2,5.

Si me despisto y digo "no, quiero 5 entre 0". Se da cuenta, me dice de que el divisor no debe ser cero, me lo vuelve a pedir y si ahora pongo un número que no es cero, funciona.

Dime el dividendo: 5
Dime el divisor: 0
Dime el divisor (no debe ser 0): 2
La division es 2.5

¿Pero qué ocurre si yo me equivoco más de una vez? Vamos a lanzarlo otra vez.

¿Qué ocurre si yo digo 5 entre cero? ¿Cómo que no? ¡Por supuesto que es cero!

Dime el dividendo: 5
Dime el divisor: 0
Dime el divisor (no debe ser 0): 0
Traceback (most recent call last):
  File "main.py", line 5, in <module>
    print("La division es ", dividendo / divisor)
ZeroDivisionError: division by zero

Sin darme cuenta, he vuelto a provocar el error, pero mi programa no estaba comprobando el error dos veces, lo estaba comprobando una única vez. Por eso, la segunda vez el programa ha fallado.

Qué ocurrirá en programas reales? Que tendremos que pensar hasta qué punto ese problema puede ser repetitivo o no.

Si ese problema puede ser repetitivo, no deberemos usar una única condición "if", deberemos repetir no si es cero, sino mientras sea cero, porque lo puede ser más de una vez, con lo cual, en un programa real esto no sería un"if", sino un "while":

dividendo = int(input("Dime el dividendo: "))
divisor = int(input("Dime el divisor: "))
if divisor == 0:
  divisor = int(input("Dime el divisor (no debe ser 0): "))
print("La division es ", dividendo / divisor)

Mientras que se equivoque y me diga que el divisor es cero, cosa que puede ocurrir varias veces, se lo voy a volver a pedir.

Pues esa es la forma más habitual de trabajar con la orden "while": el comprobar una condición de forma repetitiva porque se pueda dar varias veces. Antes de darlo por bueno, podemos comprobar que funciona...

Dime el dividendo: 5
Dime el divisor: 0
Dime el divisor (no debe ser 0): 0
Dime el divisor (no debe ser 0): 0
Dime el divisor (no debe ser 0): 0
Dime el divisor (no debe ser 0): 0
Dime el divisor (no debe ser 0): 0
Dime el divisor (no debe ser 0): 2
La division es  2.5

Si ahora pongo dividendo 5 y divisor 0, aunque yo me equivoque varias veces, va a seguir insistiendo hasta que yo finalmente ponga un dato que no sea cero y que, por tanto, sí que se pueda dividir.

Como segundo ejemplo, con un planteamiento un poco distinto, vamos a hacer un programa que sume muchos números. Lo que vamos a hacer es que el usuario introduzca un número, luego otro, luego otro, luego otro y vamos calculando la suma de todos esos números.

¿Cuándo detendremos? cuando el número que introduzca sea cero, con lo cual lo que haríamos es decirle "Dime un número", pues lo guardaríamos, por ejemplo, en una variable "n".

n = int(input("Dime un numero "))

De hecho, vamos a empezar a jugar un poco más que antes. Vamos a hacer que sea un poco más real...

Los números no van a ser sólo enteros, también pueden ser números con decimales. Los números decimales en vez de "int" los llamaremos "float", como abreviatura de números con coma flotante, que es como se llama a nivel técnico a esos números cuya cantidad de decimales puede variar, que igual tienen dos decimales, que cuatro decimales, que cinco o que ninguno.

Pues lo que haríamos es algo parecido a lo de antes: Antes poníamos quiero convertido entero el resultado de que el usuario introduzca algo como respuesta a "dime un número"... pues la diferencia en este caso es que en vez de poner "int", pondremos "float".

n = float(input("Dime un numero "))

Así podremos introducir números con decimales.

Eso sí, cuidado: según el sistema que uses, quizá los decimales se usen con tu configuración regional, por ejemplo, con coma para los decimales o quizás con configuración americana, quizás tengas que poner un punto, aunque en tu país no se empleen en puntos para los decimales.

En cualquier caso, ¿qué es lo que haremos ahora? Pues decir... mi suma inicialmente va a ser cero.

suma = 0

Lo que voy a hacer es que a la suma le voy a añadir ese valor que me han dado. La forma habitual de hacer eso es poner "la suma va a ser igual a su valor anterior, más ese número que me han introducido".

suma = suma + n

Pero esto lo querré repetir una vez, y otra vez, y otra vez... mientras que el usuario haya introducido un número que no sea cero, con lo cual diré: mientras que ese número no sea cero... (recuerda que el "distinto de" es una admiración y un igual)

while n != 0:

Mientras que ese número no sea cero, calculo la suma y se lo vuelvo a pedir. Ya que se lo vuelvo a pedir, puedo hacer que el mensaje en esta ocasión sea distinto, sea "dime otro número más".

while n != 0:
    suma = suma + n
    n = float(input("Dime otro numero más "))

¿Qué va a ocurrir? Que el usuario introducirá un número. Si ese número no es cero, lo añadiré a la suma y le pediré otro. Si ese no es cero, lo añadiré y le pediré otro más. Si ese sigue sin ser cero, lo volveré a añadir, le volveré a pedir otro más y lo volveré a sumar... ese esqueleto se va a repetir... quizás una vez, quizás ninguna, quizás doscientas... tantas veces como el número que introdujo el usuario como respuesta no sea cero.

suma = 0
n = float(input("Dime un numero "))
while n != 0:
    suma = suma + n
    n = float(input("Dime otro numero más "))
print("La suma es", suma)

Sumo, vuelvo a pedir, compruebo.. sumo, vuelvo a pedir, compruebo.... Llegará un momento en el que introduzca un cero, con lo cual esta condición dejará de ser verdad. El número ya no será distinto de cero y en ese caso pasaremos a la siguiente orden. La siguiente ordenm que podría ser ya mostrar la suma, es decir "La suma es"... seguido por el valor de suma.

print("La suma es", suma)

Esta sería apariencia de un programa que pide al usuario un dato, otro, otro, otro, tantas veces como sea necesario y calculando la suma de todos ellos y termina cuando el número sea cero (o, dicho otra forma, repite mientras que no sea cero).

suma = 0
n = float(input("Dime un numero "))
while n != 0:
    suma = suma + n
    n = float(input("Dime otro numero más "))
print("La suma es", suma)

Vamos a comprobar que funciona...

Dime un numero 5
Dime otro numero más 4
Dime otro numero más 3
Dime otro numero más 2
Dime otro numero más 1
Dime otro numero más 0
La suma es 15.0

"Dime un número"... 5 4 3 2 1... Y cuando por fin pongo cero, deja de repetir y me muestra el valor de esa suma que había ido calculando y acumulando en distintas pasadas.

Pues este es otro planteamiento, otro ejemplo de cómo usar las órdenes "while", de como repetir algo mientras que se cumple una cierta condición.

En la próxima entrega hablaremos de otro tipo de bucles que serán los bucles for, su uso habitual va a ser o bien hacer contadores o bien recorrer listas de datos.

Ejercicio propuesto 6.1. Crea un programa que pida al usuario que introduzca la suma de 135 y 768. Deberá repetirse hasta que introduzca el resultado correcto.

Ejercicio propuesto 6.2. Pide un código y una contraseña al usuario. No se le dejará proseguir hasta que el código sea 1234 y la clave sea 5000.

6130 visitas desde el 08-08-2020

AnteriorPosterior