6.2. La sentencia while

Una de las tareas para las que los computadores se usan con frecuencia es la automatización de tareas repetitivas. Repetir tareas similares o idénticas es algo que los computadores hacen bien y las personas no hacen tan bien.

Hemos visto dos programas, nLineas y cuenta atrás, que usan la recursividad para llevar a cabo la repetición, que también se llama iteración.

Por ser la iteración tan habitual, Python proporciona como lenguaje varias características que la hacen mas fácil.

La primera característica que vamos a considerar es la sentencia while.

Este es el aspecto de cuenta atrás con una sentencia while:

   1: def cuenta_atras(n):
   2:     while n > 0:
   3:         print n
   4:         n = n-1
   5:         print "Despegando!"

Como eliminamos la llamada recursiva, esta funcion no es recursiva.
Casi podía leer una sentencia while como si fuera ingles (castellano “mientras”). Quiere decir que “Mientras n sea mayor que cero, continua mostrando el valor de n y despues restandole 1 al valor de n. Cuando llegues a cero, muestra la palabra "¡Despegando!".


Mas formalmente, el flujo de ejecucion de una sentencia while es el siguiente:




  • Evaluar la condicion, devolviendo 0 o 1.


  • Si la condicion es falsa (0), salir de la sentencia while y continuar la ejecución en la siguiente sentencia.


  • Si la condicion es verdadera (1), ejecutar cada una de las sentencias en el cuerpo del bucle while, y luego volver al paso 1.

El cuerpo esta formado por todas las sentencias bajo el encabezado que tienen el mismo sangrado.


Este tipo de flujo de llama bucle porque el tercer paso vuelve de nuevo arriba.


Nótese que si la condicion es falsa la primera vez que se atraviesa el bucle, las sentencias del interior del bucle no se ejecutan nunca.


El cuerpo del bucle debe cambiar el valor de una o mas variables de manera que, llegado el momento, la condicion sea falsa y el bucle termine. En caso contrario, el bucle se repetira para siempre, que es lo que se llama bucle infinito. Una infinita fuente de diversion para los científicos informaticos es la observacion de que las instrucciones del champu \lavar, aclarar, repetir", son un bucle infinito.


En el caso de cuenta atras, podemos probar que el bucle terminara porque sabemos que el valor de n es finito, y podemos ver que el valor de n disminuye cada vez que se atraviesa el bucle (cada iteracion), de manera que ea la larga tenemos que llegar a cero. En otros casos no es tan facil decirlo:




   1: def secuencia(n):
   2:     while n != 1:
   3:         print n,
   4:         if n%2 == 0: # n es par
   5:             n = 
   6:             n/2
   7:         else: # n es impar
   8:             n = n*3+1
   9:         

La condicion de este bucle es n != 1, de manera que el bucle continuara hasta que n sea 1, que hara que la condicion sea falsa.
En cada iteracion, el programa muestra como salida el valor de n y luego comprueba si es par o impar. Si es par, el valor de n se divide entre dos. Si es impar, el valor se sustituye por 3n+1. Por ejemplo, si el valor de comienzo (el argumento pasado a la secuencia) es 3, la secuencia resultante es 3, 10, 5, 16, 8, 4, 2, 1.


Puesto que n a veces aumenta y a veces disminuye, no hay una prueba obvia de que n alcance alguna vez el valor 1, o de que el programa vaya a terminar. Para algunos valores particulares de n, podemos probar la terminacion. Por ejemplo, si el valor de inicio es una potencia de dos, entonces el valor de n sera par cada vez que se pasa a traves del bucle, hasta que lleguemos a 1. El ejemplo anterior acaba con dicha secuencia, empezando por 16.


Dejando aparte valores particulares, la pregunta interesante es si podemos probar que este programa terminara para todos los valores de n.


Hasta la fecha, nadie ha sido capaz de probarlo o negarlo.


Como actividad, reescriba la funcion nLines de la seccion 4.9 utilizando iteracion en lugar de recursividad.

0