78think Python (069-080) .En - Es
78think Python (069-080) .En - Es
com
CAPÍTULO 5
Condicionales y Recursión
Operador de módulo
Éloperador de módulofunciona con números enteros y produce el resto cuando el primer operando
se divide por el segundo. En Python, el operador de módulo es un signo de porcentaje (%). La sintaxis
es la misma que para otros operadores:
Además, puede extraer el dígito o dígitos más a la derecha de un número. Por ejemplo,x % 10produce
el dígito más a la derecha deX (en base 10). Similarmentex % 100produce los dos últimos dígitos.
Expresiones booleanas
Aexpresión booleanaes una expresión que es verdadera o falsa. Los siguientes ejemplos
usan el operador ==, que compara dos operandos y produceVerdaderosi son iguales yFalso
de lo contrario:
> > > 5 == 5
Verdadero
49
www.it-ebooks.info
VerdaderoyFalsoson valores especiales que pertenecen al tipobool;no son cadenas:
> > > tipo(Verdadero)
<tipo 'bool'>
> > > tipo(Falso)
<tipo 'bool'>
Aunque estas operaciones probablemente le resulten familiares, los símbolos de Python son
diferentes de los símbolos matemáticos. Un error común es usar un solo signo igual (=) en lugar
de un doble signo igual (==). Recuerda que = es un operador de asignación y == es un operador
relacional. No existe tal cosa como =< o =>.
Operadores logicos
Hay tresoperadores logicos:y, o,yno.La semántica (significado) de estos
operadores es similar a su significado en inglés. Por ejemplo,x > 0 y x < 10es
cierto solo siXes mayor que 0ymenos de 10.
n%2 == 0 o n%3 == 0es cierto sicualquierade las condiciones es verdadera, es decir, si el número
es divisible por 2o3.
Finalmente, elnoEl operador niega una expresión booleana, por lo queno (x > y)es cierto six > yes
falso, es decir, siXes menor o igual quey.
Estrictamente hablando, los operandos de los operadores lógicos deberían ser expresiones booleanas, pero Python
no es muy estricto. Cualquier número distinto de cero se interpreta como "verdadero".
Verdadero
Esta flexibilidad puede ser útil, pero tiene algunas sutilezas que pueden resultar confusas. Es
posible que desee evitarlo (a menos que sepa lo que está haciendo).
Ejecución Condicional
Para escribir programas útiles, casi siempre necesitamos la capacidad de verificar las condiciones y
cambiar el comportamiento del programa en consecuencia.Declaraciones condicionalesdanos esta
habilidad. La forma más simple es lasideclaración:
siX>0:
imprimir'x es positivo'
www.it-ebooks.info
La expresión booleana despuéssise llama elcondición. Si es verdadero, entonces se ejecuta la
declaración con sangría. Si no, no pasa nada.
siLas declaraciones tienen la misma estructura que las definiciones de función: un encabezado seguido de un
cuerpo sangrado. Declaraciones como esta se llamandeclaraciones compuestas.
No hay límite en la cantidad de declaraciones que pueden aparecer en el cuerpo, pero tiene que
haber al menos una. Ocasionalmente, es útil tener un cuerpo sin declaraciones (generalmente
como un guardián del código que aún no ha escrito). En ese caso, puede utilizar elpasar
declaración, que no hace nada.
siX<0:
pasar # ¡necesita manejar valores negativos!
Ejecución Alternativa
Una segunda forma de lasideclaración esejecución alternativa, en el que hay
dos posibilidades y la condición determina cuál se ejecuta. La sintaxis se ve así:
siX%2==0:
imprimir'x es par'
más:
imprimir'x es impar'
Condicionales encadenados
A veces hay más de dos posibilidades y necesitamos más de dos ramas. Una forma
de expresar un cálculo como ese es uncondicional encadenado:
siX<y:
imprimir'x es menor que y'
elifX>y:
imprimir'x es mayor que y'
más:
imprimir'x e y son iguales
elifes una abreviatura de "else if". Nuevamente, se ejecutará exactamente una rama. No
hay límite en el número deelifdeclaraciones. si hay unmáscláusula, tiene que estar al final,
pero no tiene que haber ninguna.
Ejecución Alternativa | 51
www.it-ebooks.info
sielección=='a':
dibuja un()
elifelección=='b':
dibujar_b()
elifelección=='C':
dibujar_c()
Condicionales anidados
El condicional externo contiene dos ramas. La primera rama contiene una declaración
simple. La segunda rama contiene otrasideclaración, que tiene dos ramas propias.
Esas dos ramas son declaraciones simples, aunque también podrían haber sido
declaraciones condicionales.
Los operadores lógicos a menudo proporcionan una forma de simplificar declaraciones condicionales
anidadas. Por ejemplo, podemos reescribir el siguiente código usando un solo condicional:
si0<X:
siX<10:
imprimir'x es un número positivo de un solo dígito.'
ÉlimprimirLa instrucción se ejecuta solo si superamos ambos condicionales, por lo que podemos
obtener el mismo efecto con elyoperador:
si0<XyX<10:
imprimir'x es un número positivo de un solo dígito.'
www.it-ebooks.info
recursividad
Es legal que una función llame a otra; también es legal que una función se llame a sí misma.
Puede que no sea obvio por qué eso es algo bueno, pero resulta ser una de las cosas más
mágicas que puede hacer un programa. Por ejemplo, observe la siguiente función:
definitivamentecuenta regresiva(norte):
sinorte<=0:
imprimir'¡Despegue!'
más:
imprimirnorte
cuenta regresiva(norte-1)
Sinortees 0 o negativo, emite la palabra “Blastoff!” De lo contrario, salenortey luego llama a una
función llamadacuenta regresiva-en sí mismo—pasandon-1como argumento.
Una función que se llama a sí misma esrecursivo; el proceso se llamarecursión. Como otro
Recursividad | 53
www.it-ebooks.info
definitivamenteimprimir_n(s,norte):
sinorte<=0:
retorno
imprimirs
imprimir_n(s,norte-1)
El resto de la función es similar acuenta regresiva:sinortees mayor que 0, muestrasy luego se llama a
sí mismo para mostrarsn-1tiempos adicionales. Así que el número de líneas de salida es1
+ (n - 1),lo que sumanorte.
Para ejemplos simples como este, probablemente sea más fácil usar unporcírculo. Pero veremos ejemplos
más adelante que son difíciles de escribir con unporloop y fácil de escribir con recursividad, por lo que es
bueno comenzar temprano.
Cada vez que se llama a una función, Python crea un nuevo marco de función, que
contiene las variables y parámetros locales de la función. Para una función recursiva,
puede haber más de un cuadro en la pila al mismo tiempo.
Como de costumbre, la parte superior de la pila es el marco para __principal__.Está vacío porque no
creamos ninguna variable en __principal__o pasarle argumentos.
www.it-ebooks.info
El cuatrocuenta regresivalos marcos tienen diferentes valores para el parámetronorte.La parte inferior
de la pila, donden=0,se llama elcaso base. No hace una llamada recursiva, por lo que no hay más
marcos.
Ejercicio 5-1.
Dibuja un diagrama de pila paraimprimir_nllamado cons = 'Hola'yn=2.
Ejercicio 5-2.
Escribe una función llamadadonque toma un objeto función y un número,norte,como argumentos, y
eso llama a la función dadanorteveces.
recursividad infinita
Si una recursión nunca llega a un caso base, continúa haciendo llamadas recursivas para siempre y el
programa nunca termina. Esto se conoce comorecursividad infinita, y generalmente no es una
buena idea. Aquí hay un programa mínimo con una recursividad infinita:
definitivamenterecursivo():
recursivo()
Este rastreo es un poco más grande que el que vimos en el capítulo anterior. Cuando
ocurre el error, hay 1000recursivomarcos en la pila!
Entrada de teclado
Los programas que hemos escrito hasta ahora son un poco toscos en el sentido de que no aceptan ninguna
entrada del usuario. Simplemente hacen lo mismo cada vez.
Python 2 proporciona una función integrada llamadaDatos crudosque recibe la entrada del
teclado. En Python 3, se llamaaporte.Cuando se llama a esta función, el programa se detiene y
espera a que el usuario escriba algo. Cuando el usuario presiona Return o Enter, el programa se
reanuda yDatos crudosdevuelve lo que el usuario escribió como una cadena.
Recursividad infinita | 55
www.it-ebooks.info
> > > entrada = raw_input()
¿Qué estás esperando?
> > > imprimir entrada
¿Que estas esperando?
Antes de obtener información del usuario, es una buena idea imprimir un aviso que le diga al usuario qué
debe ingresar.Datos crudospuede tomar un aviso como argumento:
La secuencia \norteal final del indicador representa unnueva línea, que es un carácter especial que
provoca un salto de línea. Es por eso que la entrada del usuario aparece debajo del aviso.
Si espera que el usuario escriba un número entero, puede intentar convertir el valor de retorno aEn t:
> > > prompt = '¿Cuál... es la velocidad aerodinámica de una golondrina sin carga?\n'
> > > velocidad = raw_input(prompt)
¿Cuál... es la velocidad aerodinámica de una golondrina sin carga? 17
Pero si el usuario escribe algo que no sea una cadena de dígitos, obtendrá un error:
depuración
El rastreo que muestra Python cuando ocurre un error contiene mucha información, pero
puede ser abrumador, especialmente cuando hay muchos marcos en la pila. Las partes
más útiles suelen ser:
Los errores de sintaxis suelen ser fáciles de encontrar, pero hay algunas trampas. Los errores de espacios en blanco pueden ser
complicados porque los espacios y las pestañas son invisibles y estamos acostumbrados a ignorarlos.
>>>x=5
>>>y=6
www.it-ebooks.info
Archivo "<stdin>", línea 1
y=6
^
Error de sintaxis: sintaxis invalida
En este ejemplo, el problema es que la segunda línea está sangrada por un espacio. Pero el
mensaje de error apunta ay,lo cual es engañoso. En general, los mensajes de error indican
dónde se descubrió el problema, pero el error real puede estar antes en el código, a veces en
una línea anterior.
Suponga que está tratando de calcular una relación señal-ruido en decibelios. la fórmula es SNR
base de datos=10log10 (PAGseñal/PAGruido). En Python, podrías escribir algo como esto:
importarMatemáticas
potencia_señal=9
ruido_potencia=10
relación=potencia_señal/ruido_potencia
decibelios=10*Matemáticas.registro10(relación)
imprimirdecibelios
El mensaje de error indica la línea 5, pero no hay nada de malo en esa línea. Para encontrar el
error real, puede ser útil imprimir el valor derelación,que resulta ser 0. El problema está en la
línea 4, porque dividir dos enteros hace división de piso. La solución es representar la potencia
de la señal y la potencia del ruido con valores de coma flotante.
En general, los mensajes de error le indican dónde se descubrió el problema, pero a menudo no
es allí donde se originó.
Glosario
Operador de módulo:
Un operador, denotado con un signo de porcentaje (%), que trabaja con números enteros y
produce el resto cuando un número se divide por otro.
Expresión booleana:
Una expresión cuyo valor esVerdaderooFalso.
Operador relacional:
Uno de los operadores que compara sus operandos: ==, !=, >, <, >= y <=.
Glosario | 57
www.it-ebooks.info
Operador lógico:
Uno de los operadores que combina expresiones booleanas:y, o,yno.
Sentencia condicional:
Una declaración que controla el flujo de ejecución dependiendo de alguna condición.
Condición:
La expresión booleana en una declaración condicional que determina qué rama se
ejecuta.
Declaración compuesta:
Una declaración que consta de un encabezado y un cuerpo. El encabezado termina con dos puntos (:). El cuerpo
está sangrado en relación con el encabezado.
Sucursal:
Una de las secuencias alternativas de sentencias en una sentencia condicional.
Condicional encadenado:
Una declaración condicional con una serie de ramas alternativas.
Condicional anidado:
Una declaración condicional que aparece en una de las ramas de otra declaración
condicional.
Recursividad:
El proceso de llamar a la función que se está ejecutando actualmente.
Caso base:
Una rama condicional en una función recursiva que no realiza una llamada recursiva.
recursividad infinita:
Una recursividad que no tiene un caso base, o nunca lo alcanza. Eventualmente, una recursividad infinita
provoca un error de tiempo de ejecución.
Ejercicios
Ejercicio 5-3.
El último teorema de Fermat dice que no hay números enterosa,b, yCtal que
anorte+bnorte=Cnorte
www.it-ebooks.info
anorte+bnorte=Cnorte
2. Escriba una función que solicite al usuario que ingrese valores paraa B Cynorte,los convierte
a números enteros y utilizacomprobar_fermatpara comprobar si violan el teorema de
Fermat.
Ejercicio 5-4.
Si le dan tres palos, es posible que pueda o no colocarlos en un triángulo. Por ejemplo, si uno de
los palos mide 12 pulgadas de largo y los otros dos tienen una pulgada de largo, está claro que
no podrá hacer que los palos cortos se encuentren en el medio. Para tres longitudes
cualesquiera, hay una prueba simple para ver si es posible formar un triángulo:
Si alguna de las tres longitudes es mayor que la suma de las otras dos, entonces no se puede formar un
triángulo. De lo contrario, puedes. (Si la suma de dos longitudes es igual a la tercera, forman lo que se
llama un triángulo "degenerado").
Ejercicio 5-5.
Lea la siguiente función y vea si puede averiguar lo que hace. Luego ejecútelo (vea los
ejemplos enCapítulo 4).
definitivamentedibujar(t,largo,norte):
sinorte==0:
retorno
ángulo=50
f.d.(t,largo*norte) es(t,
ángulo) dibujar(t,largo,
norte-1) rt(t,2*ángulo)
dibujar(t,largo,norte-1)
es(t,ángulo) bk(t,largo*
norte)
Ejercicio 5-6.
La curva de Koch es un fractal que se parece aFigura 5-2. Para dibujar una curva de Koch con longitud
X, todo lo que tienes que hacer es:
Ejercicios | 59
www.it-ebooks.info
1. Dibujar una curva de Koch con longitudx/3.
La excepción es siXes menor que 3: en ese caso, puedes dibujar una línea recta con una longitud
X.
1. Escribe una función llamadaKochque toma como parámetros una tortuga y una longitud, y que utiliza la
tortuga para dibujar una curva de Koch con la longitud dada.
2. Escribe una función llamadacopo de nieveque dibuja tres curvas de Koch para hacer el contorno de un
copo de nieve.
Solución:http://thinkpython.com/code/koch.py.
3. La curva de Koch se puede generalizar de varias formas. Verhttp://en.wikipedia.org/wiki/
Koch_copo de nievepara ejemplos e implementar su favorito.
www.it-ebooks.info