Chapter 4
\documentclass[oneside,english]{book
\usepackage[T1]{fontenc}
\usepackage[latin1]{inputenc}
\usepackage{babel}
\setcounter{secnumdepth}{3}
\setcounter{tocdepth}{3}
\usepackage{graphics}
\makeatletter
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LyX specific LaTeX commands.
\providecommand{\LyX}{L\kern-.1667em\lower.25em\hbox{Y}\kern-.125emX\@}
\makeatother
\begin{document}
\chapter{Condicionales y recursividad}
\section{El operador módulo}
\index{operador módulo} \index{módulo!operador}
El \textbf{operador módulo} funciona con enteros (y expresiones enteras),
y devuelve el \emph{resto} de dividir el primer operando entre el
segundo. En Python, el operador de módulo es el signo de tanto por
ciento, \texttt{\%}. La sintaxis es la misma de los otros operadores:
\begin{verbatim}
cociente = 7 / 3
resto = 7 % 3
\end{verbatim} El primer operador, división entera, devuelve 2. El
segundo operador devuelve 1. Así, 7 dividido entre 3 da 2 con 1 de
resto.
El operador de módulo resulta ser soprendentemente útil. Por ejemplo,
puede comprobar si un número es divisible entre otro: si \texttt{x
\% y} es cero, entonces \texttt{x} es divisible entre \texttt{y}.
También puede usar el operador módulo para extraer el dígito más a
la derecha de un número. Por ejemplo, \texttt{x \% 10} devuelve el
dígito más a la derecha de \texttt{x} (en base 10). De forma similar,
Similarly \texttt{x \% 100} devuelve los dos últimos dígitos.
\section{Ejecución condicional}
\label{conditional execution} \index{bifurcación condicional} \index{ejecución condicional}
Para escribir programas útiles, casi siempre necesitamos la capacidad
de comprobar ciertas condiciones y cambiar el comportamiento del programa
en consonancia. \textbf{Las sentencias condicionales} nos dan esta
capacidad. La forma más sencilla es la sentencia \texttt{if}:
\begin{verbatim}
if x > 0:
print "x es positivo"
\end{verbatim} La expresión que hay entre el \texttt{if} y el \texttt{:}
se llama \textbf{condición}. Si es verdadera, entonces la sentencia
indentada se ejecuta. Si la condición no es verdadera, no pasa nada.
La condición puede contener alguno de los \emph{operadores de comparación:}
\begin{verbatim}
x == y # x es igual a y
x != y # x no es igual a y
x > y # x es mayor que y
x < y # x es menor que y
x >= y # x es mayor que o igual que y
x <= y # x is menor que o igual que y
\end{verbatim} Aunque probablemente estas operaciones le resulten
familiares, la sintaxis que Python usa es un poco diferente de los
símbolos usados en matemáticas. Un error común es usar un único \texttt{=}
en lugar de uno doble \texttt{==}. Recuerde que \texttt{=} \emph{es
el operador de asignación}, y que \texttt{==} \emph{es un operador
de comparación}. Además no esite signo como \texttt{=<} o \texttt{=>}.
\section{Sentencias compuestas}
\label{compound statements} \index{sentencias compuestas} \index{sentencias compuestas!encabezamiento}
\index{sentencias compuestas!cuerpo} \index{sentencias compuestas!bloque de sentencias}
\index{sentencias!compuestas}
La sentencia \texttt{if} es el segundo ejemplo que hemos visto de
\textbf{sentencia compuesta}. El primero fue la definición de función.
Todas las sentencias compuestas tienen una sintaxis común: syntax:
\begin{verbatim}
ENCABEZAMIENTO:
PRIMERA SENTENCIA
...
ULITMA SENTENCIA
\end{verbatim} El encabezamiento comienza con una nueva línea y termina
con el signo de dos puntos. Los elementos indentados que siguen se
llaman \textbf{cuerpo} de la sentencia o \textbf{bloque} de sentencia.
La primera sentencia no indentada marca el fin del bloque.
\index{bloque} \index{sentencias!bloque} \index{cuerpo} \index{sentencias!cuerpo}
Todas las sentencias del cuerpo se tratan como una unidad. En el caso
de una sentencia \texttt{if} se ejecutan o bien todas ellas, o bien
ninguna de ellas.
\section{Ejecución alternativa}
\label{alternative execution}
Una segunda forma de la sentencia \texttt{if} es la ejecución alternativa,
en la que hay dos posibilidades, y la condición determina cuál de
ellas se ejecuta. La sintaxis tiene este aspecto:
\begin{verbatim}
if x%2 == 0:
print x, "es par"
else:
print x, "es impar"
\end{verbatim} Si el resto cuando se divide \texttt{x} emtre 2 es
cero, entonces sabemos que \texttt{x} es par, y este programa muestra
un mensaje a tal efecto. Si la condición es falsa, se ejecuta el segundo
lote de sentencias. Puesto que la condición debe ser verdadera o falsa,
se ejecutará exactamente una de las alternativas.
Como un aparte, si piensa que querrá comprobar con frecuencia la paridad
de números, quizá desee {}``envolver'' este código en una función:
\begin{verbatim}
def imprimeParidad(x):
if x%2 == 0:
print x, "es par"
else:
print x, "es impar"
\end{verbatim} Ahora tiene una función llamada \texttt{imprimeParidad}
que muestra el mensaje apropiado para cada número entero que Usted
le pase. Llame a esta función de la manera siguiente:
\begin{verbatim}
imprimeParidad(17)
\end{verbatim}
\section{Ramas múltiples}
Otro nombre para la ejecución condicional es el de \textbf{bifurcación
condicional}, ya que este tipo de estructuras hace que el flujo de
ejecución se divida en diferentes direcciones. A veces querrá comprobar
una serie de condiciones relacionadas y elegir una acción entre varias.
La siguiente prueba en tricotomía muestra cómo hacer esta ramificación
múltiple:
\begin{verbatim}
if x < y:
print x, "es menor que", y
elif x > y:
print x, "es mayor que", y
else:
print x, "y", y, "son iguales"
\end{verbatim} Como actividad, envuelva el código de tricotomía anterior
en una función llamada \texttt{compara(x, y)}.
La sentencia \texttt{elif} (\char`\"{}elif\char`\"{} es una abreviatura
de \char`\"{}else if\char`\"{}) puede repetirse tantas veces como
sea preciso para elegir entre varias condiciones:
\begin{verbatim}
if eleccion == 'A':
funcionA()
elif eleccion == 'B':
funcionB()
elif eleccion == 'C':
funcionC()
elif eleccion == 'D':
funcionD()
else:
print "Eleccion no valida."
\end{verbatim}
\section{Condiciones anidadas}
Una condición puede estar anidada dentro de otra. Podíamos haber escrito
el código el ejempOne conditional can also be nested within another.
We could have written the trichotomy example as:
\begin{verbatim}
~~if x == y:
~~~~print x, "and", y, "are equal"
~~else:
~~~~if x < y:
~~~~~~print x, "is less than", y
~~~~else:
~~~~~~print x, "is greater than", y
\end{verbatim} Ahora hay una condición externa que contiene dos ramas.
La primera rama contiene una sentencia simple de salida, pero la segunda
rama contiene otra sentencia \texttt{if}, que tiene dos ramas en sí
misma. Afortunadamente, estas dor ramas son ambas sentencias de salida
de datos, aunque podrían ser igualmente sentencias condicionales.
Aunque la indentación de las sentencias hace la estructura evidente,
las condiciones anidadas se vuelven difíciles de leer con rapidez.
En general es una buena idea evitarlas cuando pueda.
Por otra parte, este tipo de \textbf{anidamiento} es habitual, y lo
veremos otra vez, de manera que debe ir acostumbrándose a él.
\index{anidamiento}
\section{La sentencia \texttt{return} }
La sentencia \texttt{return} le permite terminar la ejecución de una
función antes de que alcance su fina. Una razón para usarla es detectar
una condición de error:
\begin{verbatim}
import math
def imprimeLogaritmo(x):
if x <= 0:
print "Solo numeros positivos, por favor."
return
result = math.log(x)
print "El log de x es", result
\end{verbatim} Esto define una función llamada \texttt{imprimeLogaritmo}
que toma un parámetro llamado \texttt{x}. Lo primero que hace es comprobar
si \texttt{x} es menor o igual que cero, en cuyo caso muestra un mensaje
de erroris less than or equal to zero, in which case it displays an
error message and then uses \texttt{return} to exit the function.
The flow of execution immediately returns to the caller and the remaining
lines of the function are not executed.
Remember that any time you want to use a function from the math module,
you have to import it.
\section{Recursividad}
\label{recursion} \index{recursión}
Ya mencionamos en el último capítulo que es legal que una función
llame a otra, y de ello hemos visto ya varios ejemplos. Olvidamos
mencionar que también es legal que una función se llame a sí misma.
Puede no resultar evidente por qué es bueno esto, pero viene a resultar
una de las cosas más interesantes y curiosas que puede hacer un programa.
Examine por ejemplo la siguiente función:
\begin{verbatim}
def cuenta_atras(n):
if n == 0:
print "Despegando!"
else:
print n
cuenta_atras(n-1)
\end{verbatim} El nombre de la función es \texttt{cuenta\_atras} y
toma un único parámetro. Si el parámetro es cero, muestra la palabra
{}``Despegando!''. En otro caso, muestra el parámetro y luego llama
a la función llamada \texttt{cuenta\_atras} (ella misma) pasándole
como argumento \texttt{n-1}.
¿Qué sucede si llamamos a la función de la siguiente manera?
\begin{verbatim}
cuenta_atras(3)
\end{verbatim} La ejecución de \texttt{cuenta\_atras} comienza con
\texttt{n=3}, y puesto que \texttt{n} no es cero, da como salida el
valor 3, y luego se llama a sí misma ...
\begin{quote}
La ejecución de \texttt{cuenta\_atras} comienza con \texttt{n=2},
y puesto que \texttt{n} no es cero, muestra el valor 2 y luego se
llama a sí misma ...
\begin{quote}
La ejecución de \texttt{cuenta\_atras} comienza con \texttt{n=1},
y puesto que \texttt{n} no es cero, muestra el valor 1, y luego se
llama a sí misma...
\begin{quote}
La ejecución de \texttt{cuenta\_atras} comienza con \texttt{n=0},
y puesto que \texttt{n} es cero, muestra la palabra {}``Despegando!''
y luego retorna.
\end{quote}
La \texttt{cuenta\_atras} que dio \texttt{n=1} retorna.
\end{quote}
La \texttt{cuenta\_atras} que dio \texttt{n=2} retorna.
\end{quote}
La \texttt{cuenta\_atras} que dio \texttt{n=3} retorna.
Y entonces ya está de vuelta en \texttt{\_\_main\_\_} (menudo viaje).
De manera que la salida completa presenta el siguiente aspecto:
\begin{verbatim}
3
2
1
Blastoff!
\end{verbatim} Como segundo ejemplo, consideremos de nuevo las funciones
\texttt{nuevaLinea} and \texttt{tresLineas}.
\begin{verbatim}
def nuevaLinea():
print
def tresLineas():
nuevaLinea()
nuevaLinea()
nuevaLinea()
\end{verbatim} Aunque todas funcionan, no serían de mucha ayuda si
quisieras mostrar 2 líneas nuevas o 106. Una mejor alternativa será:
\begin{verbatim}
def nLineas(n):
if n > 0:
print
nLineas(n-1)
\end{verbatim} Este programa es parecido a \texttt{cuenta\_atras};
mientras \texttt{n} sea mayor que cero, muestra una nueva línea, y
luego se llama a sí misma para mostrar \texttt{>n-1} nuevas líneas
más. De esta manera, el número total de nuevas líneas es \texttt{1
+ (n-1)}, que si rescata su álgebra verá que es \texttt{n}.
El proceso de llamar a una función en sí se llama \textbf{recursividad},
y dichas funciones se denominan \textbf{recursiv}as.
\index{recursion} \index{functions!recursive}
\section{Recursividad infinita}
\index{recursividad!infinita} \index{recursividad infinita}
En los ejemplos de la sección previa, cada vez que se llaman recursivamente
las funciones, el argumento disminuye en una unidad, de manera que
en algún momento ha de llegar a cero. Cuando el argumento es cero,
la función retorna inmediatamente, \emph{sin hacer más llamadas recursivas}.
Este caso (en el que la función se completa sin hacer una llamada
recursiva) se llama el \textbf{caso base}.
\index{recursividad!caso base}
Si una recursión no alcanza nunca el caso base, seguirá haciendo llamadas
recursivas para siempre y nunca terminará. Esta circunstancia se conoce
como \textbf{recursividad infinita}, y generalmente no se la considera
una buena idea.
El la mayoría de los entornos de programación, un programa con recursividad
infinita no se ejecutará realmente para siempre. En vez de eso, se
alcanzará el nivel máximo de recursividad y Python informará de un
mensaje de error:
\begin{verbatim}
RuntimeError: Maximum recursion depth exceeded
\end{verbatim}
\begin{quote}
\emph{Como actividad, escriba una función con recursividad infinita
y ejecútela en el intérprete de Python de manera que obtenga el mensaje
de error anterior.}
\end{quote}
\section{Diagramas de pila para funciones recursivas}
El el capítulo anterior utilizamos un diagrama de pila para representar
el estado de un programa durante la llamada de una función. El mismo
tipo de diagrama puede hacer más fácil interpretar una función recursiva.
Cada vez que se llama a una función, crea una nueva instancia de la
función. La instancia contiene las variables y parámetros locales
de la función. Cuando la función se completa, dicha instancia desaparece.
En el caso de una función recursiva, puede haber más de una instancia
en la pila al mismo tiempo.
La figura muestra un diagrama de pila para \texttt{cuenta\_atras},
invocada con \texttt{n = 3}:
\vspace{0.1in} \centerline{\includegraphics{stack2.eps} } \vspace{0.1in}
Hay una instancia de \texttt{\_\_main\_\_} y cuatro instancias de
\texttt{cuenta\_atras}, cada una con un valor diferente del parámetro
\texttt{n}. El fondo de la pila, \texttt{cuenta\_atras} con \texttt{n=0},
es el caso base. No hace una llamada recursiva, de manera que no hay
más instancias de \texttt{cuenta\_atras}.
La instancia de \texttt{\_\_main\_\_} está vacía porque no hemos creado
ninguna variable sobre ella ni le hemos pasado ningún parámetro.
\begin{quote}
\emph{Como actividad, dibuje un diagrama de pila para} \texttt{\emph{nLineas}}\emph{,
invocada con el parámetro} \texttt{\emph{n=4}}\emph{.}
\end{quote}
\section{Entrada por teclado}
Los programas que hemos escrito hasta ahora son un poco primitivos
en el sentido de que no aceptan entradas de datos del usuario. Simplemente
hacen lo mismo siempre.
Python proporciona funciones internas que obtienen entradas desde
el teclado. La más sencilla se llama \texttt{raw\_input}. Cuando llamamos
a esta función, el programa se detiene y espera a que el usuario escriba
algo. Cuando el usuario pulsa \texttt{return} or \texttt{enter}, el
programa se reanuda y \texttt{raw\_input} devuelve lo que el usuario
escribe como tipo \texttt{string}:
\begin{verbatim}
>>> entrada = raw_input ()
A que estas esperando?
>>> print entrada
A que estas esperando?
\end{verbatim} Antes de llamar a \texttt{raw\_input} es conveniente
mostrar un mensaje que le pida al usuario el dato por introducir.
Este mensaje se llama indicador. Puede proporcionarle un indicador
a \texttt{raw\_input} como argumento:
\index{indicador}
\begin{verbatim}
>>> nombre = raw_input ("Como te llamas? ")
Como te llamas? Aquiles, heroe de los griegos de Troya!
>>> print nombre
Aquiles, heroe de los griegos de Troya!
\end{verbatim} Si espera que la entrada sea un entero, utilice la
función \texttt{input}. Por ejemplo:
\begin{verbatim}
>>> indicador = "Cual es la velocidad de una golondrina que no hace verano?\n"
>>> velocidad = input (indicador)
\end{verbatim} Si el usuario teclea una cadena de números, se convertirá
en un entero y se asignará a \texttt{speed}. Por desgracia, si el
usuario escribe algo que no sea un dígito, el programa dará un error:
\begin{verbatim}
>>> velocidad = input (indicador)
Cual es la velocidad de una golondrina que no hace verano?
¿Se refiere Usted a la golondrina europea o a la africana?
SyntaxError: invalid syntax
\end{verbatim} Para evitar este tipo de error, generalmente es buena
idea usar \texttt{raw\_input} para obtener una cadena y usar entonces
las funciones de conversión para convertir a otros tipos.
\section{Glosario}
\begin{description}
\item [operador~módulo:]Operador que trabaja sobre enteros y devuelve el
resto cuando un número se divide entre otro. En python se señala con
un signo de tanto por ciento (\texttt{\%}).
\item [sentencia~condicional:]Sentencia que controla el flujo de ejecución
de un programa dependiendo de cierta condición.
\item [sentencia~compuesta:]Estructura de Python que está formado por una
cabecera terminada en dos puntos, y un bloque o cuerpo de una o más
sentencias que tienen la misma sangría.
\item [bloque:]Grupo de una o más sentencias que se tratan como una sentencia
única, en el sentido de que se ejecutan todas juntas secuencialmente.
En Python el boque de sentencias que constituye el cuerpo de una sentencia
compuesta debe estar sangrado la misma cantidad relativa a la cabecera
de la sentencia.
\item [cuerpo:]En una sentencia compuesta, el bloque de sentencias que sigue
a la cabecera de la sentencia.
\item [ejecución~condicional:]Flujo de ejecución que puede seguir varios
posibles caminos, dependiendo del efecto de las sentencias condicionales.
\item [anidamiento:]Una estructura de programa dentro de otra; por ejemplo,
una sentencia condidional dentro de una o ambas ramas de otra sentencia
condicional.
\item [recursividad:]El proceso de volver a llamar a la función que estás
ejecutando en ese momento.
\item [caso~base:]En una función recursiva, la rama de una sentencia condicional
que no ocasiona una llamada recursiva. Si la llamada a una función
recursiva no acaba llevando al caso base, el resultado será una recursión
infinita.
\item [recursividad~infinita:]Función que se llama a sí misma recursivamente
sin alcanzar nunca el caso base. A la larga una recursión infinita
provocará un error en tiempo de ejecución.
\item [línea~de~órdenes:]indicador visual que invita al usuario a introducir
datos.
\index{operador módulo} \index{cuerpo} \index{bloque} \index{sentencia condicional}
\index{sentencia compuesta} \index{ejecución condicional} \index{anidamiento}
\index{recursividad} \index{caso base} \index{recursividad infinita}
\index{línea de órdenes}\end{description}
\end{document}