Next Up Previous Hi Index

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}


Next Up Previous Hi Index