![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
El operador m�dulo funciona con enteros (y expresiones enteras),
y devuelve el 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
>>> print cociente
2
>>> resto = 7 % 3
>>> print resto
1
\end{verbatim} 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,
\texttt{x \% 100} devuelve los dos �ltimos d�gitos.
\section{Expresiones booleanas}
\index{expresi�n booleana}
\index{booleana!expresi�n}
\index{operador l�gico}
\index{l�gico!operador}
Una {\bf expresi�n booleana} es una expresi�n que es cierta o falsa.
En Python, una expresi�n que es cierta tiene el valor 1, y una
expresi�n que es falsa tiene el valor 0.
El operador {\tt ==} compara dos valores y entrega una expresi�n
booleana:
\beforeverb
\begin{verbatim}
>>> 5 == 5
1
>>> 5 == 6
0
\end{verbatim}
\afterverb
%
En la primera sentencia, los dos operandos son iguales, as� que la
expresi�n se eval�a como 1 (verdadero); en la segunda sentencia, 5 no
es igual a 6, as� que obtenemos 0 (falso).
El operador {\tt ==} es uno de los {\bf operadores de comparaci�n}; los
otros son:
\beforeverb
\begin{verbatim}
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 o igual que y
x <= y # x es menor o igual que y
\end{verbatim}
\afterverb
%
Aunque probablemente estas operaciones le resulten familiares, los s�mbolos
en Python son diferentes de los matem�ticos. Un error habitual es utilizar
un signo igual sencillo ({\tt =}) en lugar del doble ({\tt ==}). Recuerde
que {\tt =} es un operador de asignaci�n y {\tt ==} es un operador de
comparaci�n. Adem�s, no existen \verb|=<| ni \verb|=>|.
\section {Operadores l�gicos}
\index{operador l�gico}
\index{l�gico!operador}
Hay tres {\bf operadores l�gicos}: {\tt and}, {\tt or}, y {\tt not}. La
sem�ntica (significado) de estos operadores es similar a sus significados
en ingl�s. Por ejemplo, {\tt x > 0 and x < 10} es verdadero s�lo si {\tt x}
es mayor que 0 {\em y} menor que 10.
{\tt n\%2 == 0 or n\%3 == 0} es verdadero si {\em cualquiera} de las
condiciones es verdadera, o sea, si el n�mero es divisible por 2 {\em o}
por 3.
Finalmente, el operador {\tt not} niega una expresi�n booleana, de forma
que {\tt not(x > y)} es cierto si {\tt (x > y)} es falso, o sea, si
{\tt x} es menor o igual que {\tt y}.
Hablando estrictamente, los operandos de los operadores l�gicos deber�an
ser expresiones booleanas, pero Python no es muy estricto. Cualqueir
n�mero que no sea cero se interpreta como ``verdadero''.
\beforeverb
\begin{verbatim}
>>> x = 5
>>> x and 1
1
>>> y = 0
>>> y and 1
0
\end{verbatim}
\afterverb
%
En general, este tipo de cosas no se considera buen estilo. Si quiere
comparar un valor con cero, deber�a hacerlo expl�citamente.
\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. Las \textbf{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 booleana tras el \texttt{if}
se llama \textbf{condici�n}. Si es verdadera, entonces la sentencia
indentada se ejecuta. Si la condici�n no es verdadera, no pasa nada.
\index{sentencias compuestas} \index{sentencias compuestas!cabecera}
\index{sentencias compuestas!cuerpo} \index{sentencias compuestas!bloque de sentencias}
\index{sentencias!compuestas}
Como otras sentencias compuestas, \texttt{if} consta de una cabecera y un
bloque de sentencias:
\begin{verbatim}
CABECERA:
PRIMERA SENTENCIA
...
ULITMA SENTENCIA
\end{verbatim} La cabecera comienza con una nueva l�nea y termina
con el signo de dos puntos. Los elementos indentados que siguen se
llaman \textbf{bloque} de la sentencia. La primera sentencia no
indentada marca el fin del bloque. Un bloque de sentencias dentro
de una sentencia compuesta recibe el nombre de \textbf{cuerpo} de la sentencia.
\index{bloque} \index{sentencias!bloque} \index{cuerpo}
No hay l�mite a la cantidad de sentencias que pueden aparecer en el
cuerpo de una sentencia \texttt{if}, pero debe haber al menos una. A veces,
es �til tener un cuerpo sin sentencias, (normalmente como reserva de espacio
para algo de c�digo que todav�a no ha escrito). En tales casos, puede usted
utilizar la sentencia {\tt pass}, que no hace nada.
\index{sentencia pass}
\index{pass!sentencia}
\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} entre 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. Llamamos {\bf ramas}
a las posibilidades porque son ramas del flujo de ejecuci�n.
\index{rama}
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)
>>> imprimeParidad(y+1)
\end{verbatim}
\section{Condiciones encadenadas}
\index{condiciones encadenadas}
\index{condiciones!encadenadas}
A veces hay m�s de dos posibilidades y necesitamos m�s de dos ramas.
Una forma de expresar tal computaci�n es un {\bf conditional encadenado}:
\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} \texttt{elif} es una abreviatura de \char`\"{}else if\char`\"{}.
De nuevo, s�lo se ejecutar� una rama. No hay l�mite al n�mero de sentencias
\texttt{elif}, pero s�lo se permite una sentencia {\tt else} (que puede omitirse)
y debe ser la �ltima rama de la sentencia:
\begin{verbatim}
if eleccion == 'A':
funcionA()
elif eleccion == 'B':
funcionB()
elif eleccion == 'C':
funcionC()
else:
print "Eleccion no valida."
\end{verbatim}
Las condiciones se comprueban en orden. Si la primera es falsa, se
comprueba la siguiente, y as�. Si una de ellas es cierta, se ejecuta
la rama correspondiente y termina la sentencia. Incluso si es cierta m�s de
una condici�n, s�lo se ejecuta la primera rama verdadera.
\begin{quote}
{\em Como ejercicio, envuelva estos ejemplos en funciones llamadas
{\tt compara(x, y)} y {\tt resuelve(eleccion)}.}
\end{quote}
\section{Condiciones anidadas}
Una condici�n puede estar anidada dentro de otra. Pod�amos haber escrito
as� el ejemplo de tricotom�a:
\begin{verbatim}
~~if x == y:
~~~~print x, "y", y, "son iguales"
~~else:
~~~~if x < y:
~~~~~~print x, "es menor que", y
~~~~else:
~~~~~~print x, "es mayor que", y
\end{verbatim} La condici�n externa que contiene dos ramas.
La primera rama contiene una sentencia simple de salida. La segunda
rama contiene otra sentencia \texttt{if}, que tiene dos ramas en s�
misma. Estas dos 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 en seguida se vuelven dif�ciles de leer.
En general es una buena idea evitarlas cuando pueda.
Los operadores l�gicos suelen facilitar un modo de simplificar las
sentencias condicionales anidadas. Por ejemplo, podemos reescribir
el c�digo siguiente con un s�lo condicional:
\beforeverb
\begin{verbatim}
if 0 < x:
if x < 10:
print "x es un n�mero positivo de un d�gito."
\end{verbatim}
\afterverb
%
La sentencia {\tt print} s�lo se ejecuta si conseguimos superar
ambos condicionales, as� que podemos usar el operador {\tt and}:
\beforeverb
\begin{verbatim}
if 0 < x and x < 10:
print "x es un n�mero positivo de un d�gito."
\end{verbatim}
\afterverb
%
Estos tipos de condiciones son habituales, por lo que Python nos
proporciona una sintaxis alternativa similar a la notaci�n matem�tica:
\beforeverb
\begin{verbatim}
if 0 < x < 10:
print "x es un n�mero positivo de un d�gito."
\end{verbatim}
\afterverb
%
Esta condici�n es sem�nticamente la misma que la expresi�n booleana
compuesta y que el condicional anidado.
\section{La sentencia \texttt{return} }
\index{sentencia return}
\index{sentencia!return}
La sentencia \texttt{return} le permite terminar la ejecuci�n de una
funci�n antes de alcanzar su final. 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} La funci�n \texttt{imprimeLogaritmo} 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 error y luego usa \texttt{return} para salir de la funci�n. El flujo de la
ejecuci�n vuelve inmediatamente al llamante y no se ejecutan las l�neas
restantes de la funci�n.
Recuerde que para usar una funci�n del m�dulo math tiene que
importarlo.
\section{Recursividad}
\label{recursion} \index{recursividad}
Ya mencionamos 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} \texttt{cuenta\_atras} espera que su par�metro, {\tt n},
sea un entero positivo. Si {\tt n} el par�metro es cero, muestra la palabra
{}``Despegando!''. En otro caso, muestra {\tt n} 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
Despegando!
\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
quisiera 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 por el que una funci�n se llama a s� misma se llama
\textbf{recursividad}, y dichas funciones se denominan recursivas.
\index{recursividad} \index{funciones!recursivas}
\section{Diagramas de pila para funciones recursivas}
\index{diagramas de pila}
\index{marco de funci�n}
\index{marco}
El la Secci�n~\ref{stackdiagram} 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, Python crea un nuevo marco para la
funci�n, que contiene sus variables locales y par�metros.
En el caso de una funci�n recursiva, puede haber m�s de un marco
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{../illustrations/stack2.eps} } \vspace{0.1in}
Como es habitual, en lo alto de la pila est� el marco de \texttt{\_\_main\_\_}.
Est� vac�a porque no hemos ninguna variable sobre \texttt{\_\_main\_\_} ni le hemos
pasado ning�n par�metro.
Los cuatro marcos de \texttt{cuenta\_atras} tienen valores diferentes para el
par�metro \texttt{n}. El fondo de la pila, donde \texttt{n=0}, se llama
{\bf caso base}. No hace una llamada recursiva, de manera que no hay
m�s marcos.
\begin{quote}
\emph{Como actividad, dibuje un diagrama de pila para} \texttt{nLineas}\emph{,
invocada con el par�metro} \texttt{n=4}.
\end{quote}
\index{caso base}
\index{recursividad!caso base}
\section{Recursividad infinita}
\index{recursividad!infinita} \index{recursividad infinita}
\index{error en tiempo de ejecuci�n}
\index{error!en tiempo de ejecuci�n}
\index{traza inversa}
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. Este es un programa m�nimo con recursividad infinita:
\beforeverb
\begin{verbatim}
def recurre():
recurre()
\end{verbatim}
\afterverb
%
El la mayor�a de los entornos de programaci�n, un programa con recursividad
infinita no se ejecutar� realmente para siempre. Python informar� de un
mensaje de error cuando se alcance el nivel m�ximo de recursividad:
\beforeverb
\begin{verbatim}
File "






