Ir al contenido principal

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.

Comentarios

Entradas populares de este blog

3.11. Diagramas de pila

Para mantener el rastro de que variables pueden usarse y donde, a veces es útil dibujar un diagrama de pila. Como los diagramas de estado, los diagramas de pila muestran el valor de cada variable, pero también muestran la función a la que cada variable pertenece. Cada función se representa por una caja con el nombre de la función junto a el. Los parámetros y variables que pertenecen a una función van dentro. Por ejemplo, el diagrama de stack para el programa anterior tiene este aspecto: El orden de la pila muestra el flujo de ejecución. imprimeDoble fue llamado por catDoble y a catDoble lo invoco __main__ , que es un nombre especial de la función mas alta. Cuando crea una variable fuera de cualquier función, pertenece a main En cada caso, el parámetro se refiere al mismo valor que el argumento correspondiente. Así que parte1 en catDoble tiene el mismo valor que cantus1 en main . Si sucede un error durante la llamada a una función, Python imprime el nombre de la función ...

6.4. Tablas de dos dimensiones

Una tabla de dos dimensiones es una tabla en la que Usted elige una fila y una columna y lee el valor de la intersección. Un buen ejemplo es una tabla de multiplicar. Supongamos que desea imprimir una tabla de multiplicar para los valores del 1 al 6. Una buena manera de comenzar es escribir un bucle sencillo que imprima los múltiplos de 2, todos en una l³nea. 1: i = 1 2: while i <= 6: 3: print 2*i, '\t' , 4: i = i + 1 5: print La primera línea inicializa una variable lllamada i , que actuara como contador, o variable de bucle. Conforme se ejecuta el bucle, el valor de i se incrementa de 1 a 6. Cuando i vale 7, el bucle termina. Cada vez que se atraviesa el bucle, imprimimos el valor 2*i seguido por tres espacios. De nuevo, la coma de la sentencia print suprime el salto de línea. Despues de completar el bucle, la segunda sentencia print crea una línea nueva. La salida de este programa es: 2 4 6 8 10 12 Hasta ahora, bie...

C.3. Cartas, mazos y juegos Python

1: import random 2: class Carta: 3: listaDePalos = [ "Tr¶eboles" , "Diamantes" , "Corazones" , 4: "Picas" ] 5: listaDeValores = [ "nada" , "As" , "2" , "3" , "4" , "5" , "6" , "7" , 6: "8" , "9" , "10" , "Sota" , "Reina" , "Rey" ] 7: 8: def __init__(self, palo=0, valor=0): 9: self.palo = palo 10: self.valor = valor 11: def __str__(self): 12: return (self.listaDeValores[self.valor] + " de " +\ 13: self.listaDePalos[self.palo]) 14: def __cmp__(self, otro): 15: # controlar el palo 16: if self.palo > otro.palo: return 1 17: if self.palo < otro.palo: return -1 18: # si son del mismo palo, controlar el valor 19...