La sentencia while

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

Hemos visto dos funciones/programas, nLineas y cuenta_atras, 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 más fácil. La primera característica que vamos a considerar es la sentencia while.

Éste es el aspecto de cuenta atras con una sentencia while:

Al eliminar la llamada recursiva, esta función deja de ser recursiva.

La sentencia while significa «mientras». O sea que quiere decir que “Mientras n sea mayor que cero, continúa mostrando el valor de n y después le resta 1 al valor de n. Cuando llegues a cero, muestra la palabra “Despegando!”.

El flujo de ejecución de una sentencia while es el siguiente:

  1. Evaluar la condición, devolviendo 0 o 1.
  2. Si la condición es falsa (0), salir de la sentencia while y continuar la ejecución en la siguiente sentencia.
  3. Si la condición es verdadera (1), ejecutar cada una de las sentencias en el cuerpo del bucle while, y luego volver al paso 1.

El cuerpo está 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 condición 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 más variables de manera que, llegado el momento, la condición sea falsa y el bucle termine. En caso contrario, el bucle se repetirá para siempre, que es lo que se llama bucle infinito. Una infinita fuente de diversión para los científicos informáticos es la observación de que las instrucciones del champú “lavar, aclarar, repetir”, son un bucle infinito.

En el caso de nuestra función cuenta_atras, podemos probar que el bucle terminará 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 iteración), de manera que a la larga tiene que llegar a cero. En otros casos no es tan fácil decirlo:

La condición de este bucle es n != 1, de manera que el bucle continuará hasta que n sea 1, que hará que la condición sea falsa.

En cada iteración, 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 n * 3 +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 terminación. Por ejemplo, si el valor de inicio es una potencia de dos, entonces el valor de n será par cada vez que se pasa a través 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 terminará para todos los valores de n. Hasta la fecha,
nadie ha sido capaz de probarlo o negarlo.