Chapter 3
\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{Funciones}
\section{Llamadas a funciones}
\index{llamadas a funciones} \index{funciones!llamadas}
Ya hemos visto un ejemplo de una \textbf{llamada a una función:}
\begin{verbatim}
>>> type("32")
\end{verbatim} El nombre de la función es \texttt{type}, y muestra
el tipo de un valor o de una variable. El valor o variable, llamado
el \textbf{argumento} de la función, ha de estar encerrado entre paréntesis.
Es habitual decir que una función {}``toma'' un argumento y {}``devuelve''
un resultado. El resultado se llama \textbf{valor de retorno}.
\index{argumento} \index{valor de retorno}
En lugar de imprimir el valor de retorno, podemos asignárselo a una
variable.
\begin{verbatim}
>>> nereida = type("32")
>>> print nereida
\end{verbatim} Otro ejemplo más: la función \texttt{id} toma el valor
toma como argumento un valor o una variable y devuelve un entero que
actúa como identificador único de ese valor.
\begin{verbatim}
>>> id(3)
134882108
>>> yanira = 3
>>> id(yanira)
134882108
\end{verbatim} Cada valor tiene un \texttt{id}. El \texttt{id} de
una variable es el \texttt{id} del valor al que hace referencia.
\section{Conversión de tipos}
\index{conversión de tipos} \index{tipos!conversión}
Python proporciona una colección de funciones de serie que convierten
valores de un tipo a otro. La función \texttt{int} toma un valor y
lo convierte a un entero, si es posible, o da un error si no es posible.
\begin{verbatim}
>>> int("32")
32
>>> int("Hola")
ValueError: invalid literal for int(): Hello
\end{verbatim} \texttt{int} también convierte valores de coma flotante
a enteros, pero recuerde que siempre redondea hacia abajo:
\begin{verbatim}
>>> int(3.99999)
3
\end{verbatim} También hay una función \texttt{float} que convierte
enteros y cadenas:
\begin{verbatim}
>>> float(32)
32.0
>>> float("3.14159")
3.14159
\end{verbatim} Finalmente, está la función \texttt{str}, que convierte
a tipo \texttt{string}:
\begin{verbatim}
>>> str(32)
'32'
>>> str(3.14149)
'3.14149'
\end{verbatim} Pudiera parecer extraño que Python distinga entre el
valor entero \texttt{1} y el valor de coma flotante \texttt{1.0}.
Tal vez representen el mismo número, pero pertenecen a tipos distintos.
El motivo es que se representan de forma distinta dentro del computador.
Los detalles de tal representación no son importantes de momento,
pero afectan al comportamiento de algunos programas.
\section{Coerción de tipos}
\index{coerción de tipos} \index{tipos!coerción}
Ahora que ya sabemos convertir entre tipos, podemos resolver el problema
que tuvimos en el capítulo anterior con la división de enteros. Estábamos
intentando calcular qué fracción de una hora había pasado. La expresión
más obvia, \texttt{minuto / 60}, realiza aritmética de enteros, que
no es lo que queríamos.
Una alternativa es convetir \texttt{minuto} a tipo float (coma flotante)
y luego efectuar una división de coma flotante:
\begin{verbatim}
>>> minuto = 59
>>> float(minuto) / 60.0
0.983333333333
\end{verbatim} O bien podemos sacar provecho de la \textbf{coerción}
de tipos de Python. Para los operadores matemáticos, si uno de los
operadores matemáticos es tipo \texttt{float}, el otro se convierte
automáticamente en \texttt{float}.
\index{coercion}
\begin{verbatim}
>>> minuto = 59
>>> minuto / 60.0
0.983333333333
\end{verbatim} Al usar un denomidador que es \texttt{float}, obligamos
a Python a hacer división de coma flotante.
\section{Funciones matemáticas}
\index{funciones matemáticas} \index{matemáticas!funciones}
Es posible que ya haya visto Usted en matemáticas funciones como \texttt{sin}
(seno) y \texttt{log}, y que haya aprendido a evaluar expresiones
como \texttt{sin(pi/2)} y \texttt{log(1/x)}. Primero evalúa la expresión
entre paréntesis, (el argumento). Por ejemplo, \texttt{pi/2} es aproximadamente
1.571, y \texttt{1/x} es 0.1 (si \texttt{x} es igual a \texttt{10.0}).
Luego evalúa la función en sí misma, o bien mirándola en una tabla,
o bien llevando a cabo diversos cálculos. El \texttt{sin} (seno) de
1.571 es 1, y el \texttt{log} de 0.1 es -1 (suponiendo que \texttt{log}
indique el logaritmo de base 10).
Este proceso puede aplicarse repetidamente para evaluar expresiones
más complicadas como \texttt{log(1/sin(pi/2))}. Primero evaluamos
el argumento de la función más interna, luego se evalúa la función,
y así sucesivamente.
Python dispone de un módulo matemático que proporciona la mayoría
de las funciones matemáticas que nos resultan familiares. Un \textbf{módulo}
es un fichero que contiene una colección de funciones agrupadas juntas.
\index{módulo}
Antes de poder usar las funciones de un módulo, tenemos que importarlo:
\begin{verbatim}
import math
\end{verbatim} Para llamar a una de las funciones, tenemos que especificar
el nombre del módulo y el nombre de la función, separados por un punto:
\begin{verbatim}
decibelio = math.log10 (17.0)
angulo = 1.5
altura = math.sin(angulo)
\end{verbatim} La primera sentencia da a \texttt{decibelio} el valor
del logaritmo de 17, en base \texttt{10}. Hay también una función
llamada \texttt{log} que toma logaritmos en base \texttt{e}.
La tercera sentencia halla el seno del valor de la variable \texttt{angulo}.
\texttt{sin} y las otras funciones trigonométricas (\texttt{cos},
\texttt{tan}, etc.) toman sus argumentos en \emph{radianes}. Para
convertir de grados a radianes, puede dividir por 360 y multiplicar
por \texttt{2{*}pi}. Por ejemplo, para hallar el seno de 45 grados,
calcule primero el ángulo en radianes y luego halle el seno:
\begin{verbatim}
degrees = 45
angle = degrees * 2 * math.pi / 360.0
math.sin(angle)
\end{verbatim} La constante \texttt{pi} también es parte del módulo
\texttt{math}. Si se sabe la geometría, puede verificar el resultado
comparándolo con el de la raíz cuadrada de 2, dividida entre 2.
\begin{verbatim}
>>> math.sqrt(2) / 2.0
0.707106781187
\end{verbatim}
\section{Composición}
\index{composición} \index{funciones!composición}
Igual que con las funciones matemáticas, las funciones de Python se
pueden componer; eso quiere decir que se usa una expresión como parte
de otra. Por ejemplo, puede usar cualquier expresión como argumento
de una función:
\begin{verbatim}
x = math.cos(angulo + pi/2)
\end{verbatim} Esta sentencia toma el valor de \texttt{pi}, lo divide
entre dos y le añade el resultado al valor de \texttt{angulo}. La
suma se pasa luego como argumento a la función \texttt{cos}.
También puede tomar el resultado de una función y pasárselo como argumento
a otra:
\begin{verbatim}
x = math.exp(math.log(10.0))
\end{verbatim} Esta sentencia encuentra el logaritmo en base \texttt{e}
de 10 y luego eleva \texttt{e} a ese exponente. El resultado queda
asignado a \texttt{x}.
\section{Añadir funciones nuevas}
Hasta ahora sólo hemos usado las funciones que vienen incluidas con
Python, pero también es posible añadir nuevas funciones.
En contextos de programación, \textbf{función} es una secuencia de
instrucciones con nombre, que lleva a cabo la operación deseada. Esta
operación se especifica en una \textbf{definición de función}. Las
funciones que hemos usado hsta ahora las han definido por nosotros,
y esas definiciones se han ocultado. Eso es bueno, ya que nos permite
usar funciones sin preocuparnos sobre los detalles de sus definiciones.
\index{función} \index{definición de función} \index{función!definición}
La sintaxis de la definición de una función es:
\begin{verbatim}
def NOMBRE( LISTA DE PARAMETROS ):
SENTENCIAS
\end{verbatim} Puede inventarse el nombre que desee para su función,
con la excepción de que no puede usar las palabras reservadas de Python.
La lista de parámetros especifica qué información, en caso de haberla,
ha de proporcionar para usar la función nueva.
Puede haber cualquier número de sentencias dentro de la función, pero
tienen que estar indentadas desde el margen derecho. En los ejemplos
de este libro se usará una indentación de dos espacios.
El primer par de funciones que escribiremos no tienen parámetros,
de manera que su sintaxis es:
\begin{verbatim}
def nueva_linea():
print
\end{verbatim} Esta función se llama \texttt{nueva\_linea}. Los paréntesis
vacíos indican que no tiene parámetros. Contiene una única sentencia,
que muestra como salida un carácter de nueva línea (es lo que sucede
cuando utiliza una orden \texttt{print} sin argumentos).
Llamamos entonces a la función nueva usando la misma sintaxis que
usamos para las funcionesWe can call the new function using the same
syntax we use for built-in functions:
\begin{verbatim}
print "Primera linea."
nueva_linea()
print "Segunda linea."
\end{verbatim} The output of this program is
\begin{verbatim}
Primera linea.
Segunda linea.
\end{verbatim} Observe el espacio añadido que hay entre las dos líneas.
Si quisiéramos más espacios, entre las líneas, ¿qué haríamos? Podemos
llamar varias veces a la misma función:
\begin{verbatim}
print "Primera linea."
nueva_linea()
nueva_linea()
nueva_linea()
print "Segunda linea."
\end{verbatim} O bien podemos escribir una nueva función que llamaremos
\texttt{tresLineas}, y que imprima tres nuevas líneas:
\begin{verbatim}
def tresLineas():
nueva_linea()
nueva_linea()
nueva_linea()
print "Primera Linea."
tresLineas()
print "Segunda Linea."
\end{verbatim} Esta función contiene tres sentencias, las cuales están
todas indentadas con dos espacios. Puesto que la siguiente sentencia
no está indentada, Python sabe que no es parte de la función.
Observe los siguientes puntos con respecto a este programa:
\begin{enumerate}
\item Se puede llamar al mismo procedimiento repetidamente. De hecho es
bastante útil hacerlo, además de habitual.
\item Se puede llamar a una función desde dentro de otra función: en este
caso \texttt{tresLineas} llama a \texttt{nueva\_linea}.
\end{enumerate}
Hasta ahora puede no haber quedar claro por qué vale la pena crear
todas estas funciones nuevas. En realidad hay muchísimas razones,
pero este ejemplo demuestra dos:
\begin{itemize}
\item Crear una nueva función le da la oportunidad de dar un nombre a un
grupo de sentencias. Las funciones simplifican su programa al ocultar
cálculos complejos detrás de órdenes sencillas, y usar palabras inglesas
en vez de código arcano.
\item Crear una nueva función hace que el programa sea más pequeño, al eliminar
código repetitivo. Por ejemplo, una manera de imprimir nueve líneas
consecutivas es llamar a \texttt{tresLineas} tres veces.
\end{itemize}
\begin{quote}
\emph{Como actividad, escriba una función llamada} \texttt{\emph{nueveLineas}}
\emph{que use} \texttt{\emph{tresLineas}} \emph{para imprimir nueve
líneas en blanco. ¿Cómo imprimiría 27 líneas nuevas?}
\end{quote}
\section{Las definiciones y el uso}
Juntando los fragmentos de código de la sección anterior, el programa
completo queda de la siguiente manera:
\begin{verbatim}
def nueva_linea():
print
def tresLineas():
nueva_linea()
nueva_linea()
nueva_linea()
print "Primera Linea."
tresLineas()
print "Segunda Linea."
\end{verbatim} Este programa contiene dos definiciones de funciones:
\texttt{nueva\_linea} y \texttt{tresLineas}. Las definiciones de funciones
se ejecutan como el resto de sentencias, pero el efecto es crear una
nueva función. Las sentencias del interior de la función no se ejecutan
hasta que se llama a la función, y la definición de la función no
genera salida.
Como era de esperar, tiene que crear una función antes de poder ejecutarla.
En otras palabras, la definición de la función tiene que ejecutarse
antes de la primera vez que se la invoque.
\begin{quote}
\emph{Como actividad, pruebe a ejecutar este programa moviendo las
tres últimas sentencias al principio del programa. Registre qué mensaje
de error obtiene Usted.}
\emph{Como activada, prueba a tomar la versión del programa que funcionaba
y a mover la definción de} \texttt{\emph{nueva\_linea}} \emph{más
abajo que la definición de} \texttt{\emph{tresLineas}}\emph{. ¿Qué
ocurre cuando ejecuta el programa ?}
\end{quote}
\section{Flujo de ejecución}
\index{flujo de ejecución}
Para asegurarse de que una función se define antes de su primer uso,
tiene que conocer el orden en el que se ejecutan las sentencias; a
esto se le llama \textbf{flujo de ejecución}.
La ejecución comienza siempre por la primera sentencia del programa.
Las sentencias se ejecutan a razón de una cada vez, en orden, hasta
que se alcanza una llamada a una función.
Las definiciones de funciones no alteran el flujo de ejecución del
programa, pero recuerde que las sentencias que hay dentro de la función
no se ejecutan hasta que se hace la llamada a la función. Aunque no
es habitual, puede definir una función dentro de otra. En este caso,
la definición de función interior no se ejecuta hasta que no se llama
a la función exterior.
Las llamadas a funciones son como un desvío en el flujo de ejecución.
En lugar de ir a la siguiente sentencia, el flujo salta hasta la primera
línea de la función a la que se llama, ejecuta todas las sentencias
que encuentre allí, y vuelve a retomar la ejecución en el punto donde
lo dejó.
Esto suena bastante sencillo... hasta que se acuerda de que una función
puede llamar a otra. Mientras estamos en medio de una función, podríamos
vernos obligados a abandonarla e ir a ejecutar sentencias en otra
función más. Pero mientras estamos en esta nueva función, ¡podríamos
salirnos y ejecutar otra función más!
Afortunadamente, a Python se le da bien tomar nota de dónde está,
de manera que cada vez que se completa una función, el programa retoma
el punto en donde lo dejó en la función que hizo la llamada. Cuando
llega al final del programa, termina.
¿Cuál es la moraleja de toda esta historia? Cuando esté leyendo un
programa, no lo lea desde la parte superior a la inferior. En lugar
de eso, siga el flujo de ejecución.
\section{Parámetros y argumentos}
\label{parameters} \index{parámetros} \index{funciones!parámetros}
\index{argumentos} \index{funciones!argumentos}
Algunas de las funciones internas que hemos usado precisan de argumentos,
los valores que controlan cómo la función lleva a cabo su tarea. Por
ejemplo, si desea encontrar el seno de un número, tiene que indicar
de qué número se trata. Así pues, \texttt{sin} toma como argumento
un valor numérico.
Algunas funciones toman más de un argumento, como \texttt{pow}, que
toma dos argumentos: la base y el exponente. Dentro de la función,
los valores que se le han pasado se asignan a variables llamadas \textbf{parámetros}.
He aquí un ejemplo de una función definida por el usuario, que toma
un parámetro:
\begin{verbatim}
def imprimeDoble(paso):
print paso, paso
\end{verbatim} Esta función toma un único argumento y se lo asThis
function takes a single argument and assigns it to a parameter named
\texttt{paso}. El valor del parámetro (en este punto todavía no tenemos
ni idea de cuál será) se imprime dos veces, seguido por un carácter
de nueva línea. El nombre \texttt{paso} se eligió para sugerir que
en nombre que le dé a un parámetro depende de Usted, pero en general
es mejor que elija un nombre más ilustrativo que \texttt{paso}.
La función \texttt{imprimeDoble} sirve con cualquier tipo (de dato)
que se pueda imprimir:
\begin{verbatim}
>>> imprimeDoble('Mortadela')
Mortadela Mortadela
>>> imprimeDoble(5)
5 5
>>> imprimeDoble(3.14159)
3.14159 3.14159
\end{verbatim} En la primera llamada a la función, el argumento es
una cadena; en la segunda es un entero, y en la tercera es un número
de coma flotante.
Las mismas reglas de composición que se aplican a las funciones internas
se aplican también a las funciones definidas por el usuario, así que
puede usar cualquier tipo de expresión como argumento de \texttt{imprimeDoble}.
\begin{verbatim}
>>> imprimeDoble('Mortadela'*4)
MortadelaMortadelaMortadelaMortadela MortadelaMortadelaMortadelaMortadela
>>> imprimeDoble(math.cos(math.pi))
-1.0 -1.0
\end{verbatim} Como de costumbre, se evalúa la expresión antes de
ejecutar la función.
Asimismo podemos usar una variable como argumento:
\begin{verbatim}
>>> latoya = 'Dafne, es mitad laurel mitad ninfa'
>>> imprimeDoble(latoya)
Dafne, es mitad laurel mitad ninfa. Dafne, es mitad laurel mitad ninfa.
\end{verbatim} Observe un aspecto realmente importante en este caso:
el nombre de la variable que pasamos como argumento (\texttt{latoya})
no tiene nada que ver con el nombre del parámetro (\texttt{paso}).
No importa cómo se llamaba el valor en su lugar original (el lugar
desde donde se invocó); aquí en \texttt{imprimeDoble} llamamos a todo
el mundo \texttt{paso}.
\section{Las variables y los parámetros son locales}
\index{variables locales} \index{locales!variables}
Cuando crea una variable dentro de una función, sólo existe dentro
de dicha función, y no puede usarla fuera de ella. Por ejemplo, la
función
\begin{verbatim}
>>> def catDoble(parte1, parte2):
... cat = parte1 + parte2
... imprimeDoble(cat)
...
>>>
\end{verbatim} takes two arguments, concatenates them, then prints
the result twice. We can call the function with two strings:
\begin{verbatim}
>>> cantus1 = "Die Jesu domine, "
>>> cantus2 = "Dona eis requiem."
>>> catDoble(cantus1, cantus2)
Die Jesu domine, Dona eis requiem. Die Jesu domine, Dona eis requiem.
\end{verbatim} Cuando \texttt{catDoble} termina, la variable \texttt{cat}
se destruye. Si tratásemos de imprimirla, obtendríamos un error:
\begin{verbatim}
>>> print cat
NameError: cat
\end{verbatim} De la misma manera, si tratamos de usar \texttt{cat}
dentro de \texttt{imprimeDoble} obtendremos un error:
\begin{verbatim}
>>> def imprimeDoble(paso):
... print cat, cat
...
>>> catDoble(cantus1, cantus2)
NameError: cat
\end{verbatim} La misma regla que se aplica a las variables se aplica
también a los parámetros. Por ejemplo, fuera de la función \texttt{imprimeDoble},
no existe nada llamado \texttt{paso}. Si trata de usarla, Python se
quejará.
\section{Diagramas de pila}
\index{stack diagrams}
Para mantener el rastro de qué variables pueden usarse y dónde, a
veces es útil dibujar un \textbf{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 él. 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:
\vspace{0.1in} \centerline{\includegraphics{stack.eps} } \vspace{0.1in}
El orden de la pila muestra el flujo de ejecución. \texttt{imprimeDoble}
fue llamado por \texttt{catDoble} and \texttt{catDoble} fue invocado
por \texttt{\_\_main\_\_}, que es un nombre especial de la función
más alta. Cuando crea una variable fuera de cualquier función, pertenece
a \texttt{\_\_main\_\_}.
En cada caso, el parámetro se refiere al mismo valor que el argumento
correspondiente. Así que \texttt{parte1} en \texttt{catDoble} tiene
el mismo valor que \texttt{cantus1} en \texttt{\_\_main\_\_}.
\section{Funciones con resultado}
Seguramente ha notado ya que algunas de las funciones que estamos
usando, igual que las funciones matemáticas, devuelven un resultado.
Otras funciones, como \texttt{nueva\_linea}, llevan a cabo una acción
pero no devuelven un valor. Ello suscita varias preguntas:
\begin{enumerate}
\item ¿Qué sucede si llama Usted a uana función y no hace nada con el resultado
(es decir, no lo asigna a una variable ni lo usa como parte de una
expresión más amplia)?
\item ¿Qué sucede si usa una función sin resultado como parte de una expresión,
por ejemplo \texttt{nueva\_linea() + 7}?
\item Se pueden escribir funciones que devuelvan resultados, o debemos limitarnos
a posibilidades como \texttt{nueva\_linea} e \texttt{imprimeDoble}?
\end{enumerate}
La respuesta a la tercera pregunta es {}``sí, puede escribir funciones
que devuelvan valores'', y lo haremos en el capítulo 5.
\begin{quote}
\emph{Como actividad final, consteste a las otras dos preguntas intentando
hacerlas en la práctica. Cada vez que tenga una duda sobre lo que
es legal o ilegal en Python, perguntar al intérprete será una buena
manera de averiguarlo.}
\end{quote}
\section{Glosario}
\begin{description}
\item [llamada~a~función:]Una sentencia que ejecuta una función. Está
compuesta por el nombre de la función más una lista de argumentos
encerrados entre paréntesis.
\item [argumento:]Valor que se le pasa a una función cuando se la llama.
El valor se asigna al parámetro correspondiente de la función.
\item [valor~de~retorno:]Es el resultado de una función, que se envía
de vuelta a la parte del programa desde el que la función se llamó.
Si una llamada a función aparece en la parte derecha de una sentencia
de asignación, con una variable en la parte izquierda, entonces el
valor de retorno estará referenciado por la variable.
\item [coerción:]Conversión forzada de valores de un tipo matemático en
valores equivalentes de otro tipo matemático, para hacer posible la
evaluación de expresiones que conllevan tipos mixtos.Por ejemplo,
en la expresión \texttt{3/2.0}, \texttt{3} es de tipo \texttt{int},
y \texttt{2.0} es de tipo \texttt{float}, así que \texttt{3} must
first be \emph{coersed} into a \texttt{float} antes de poder llevar
a cabo la división de coma flotante.
\item [módulo:]Fichero que contiene una colección de funciones y clases
relacionadas.
\item [función:]Secuencia de sentencias etiquetadas que llevan a cabo determinada
operación de utilidad. Las funciones pueden tomar parámetros o no,
y pueden producir un resultado o no.
\item [definición~de~función:]Sentencia que crea una nueva función, especificando
su nombre, parámetros y la sentencia que ejecuta.
\item [flujo~de~ejecución:]Orden en el que las sentencias se ejecutan
durante la The order in which statements are executed during a program
run.
\item [parámetro:]Nombre que se usa dentro de una función para referirse
a el valor que se le pasa como argumento.
\item [variable~local:]variable definida dentro de una función. Las variables
locales sólo pueden usarse dentro de su función.
\item [diagrama~de~pila:]Representación gráfica de una pila de funciones,
sus variables y los valores a los que se refieren.
\index{llamada a función} \index{valor de retorno} \index{argumento}
\index{coerción} \index{módulo} \index{función} \index{definición de función}
\index{flujo de ejecución} \index{parámetro} \index{variable local}
\index{diagrama de pila}\end{description}
\end{document}