Programación I: Funciones y módulos Esteban De La Fuente Rubio 2 de abril de 23 Índice. Funciones.. Definición y llamado de funciones............................................. 2.2. Parámetros por omisión.................................................. 2.3. Ejemplos.......................................................... 2.3.. Factorial....................................................... 2 2. Módulos 3 2.. Definición y uso de un módulo.............................................. 3 2.2. Ejemplos.......................................................... 4 2.2.. Autómata que reconoce cantidad impar de s.................................. 4 3. Recursividad 4 3.. Ejemplos.......................................................... 5 3... Factorial....................................................... 5 4. Ejercicios 5. Funciones Existen diversas situaciones donde queremos hacer una determinada acción varias veces en un mismo programa, por ejemplo: Escribir a salida estándar. Leer desde entrada estándar. Generar una lista de a n. Obtener el largo de un string. Cada vez que hemos estado en alguno de los escenarios anteriores lo que hemos hecho es hacer uso de alguna función para conseguir lo que queremos, no hemos programado la función propiamente tal, solo la hemos usado. Una función nos permitirá encapsular código que presenta una funcionalidad determinada y, generalmente, bastante específica. Por ejemplo, para los casos anteriores tenemos: Escribir a salida estándar: print(). Leer desde entrada estándar: input(). Generar una lista de a n: range(). Obtener el largo de un string: len().
.. Definición y llamado de funciones Para poder definir una función debemos establecer: Nombre de la función: el cual debe ser único. Parámetros de la función: si la función tendrá alguna entrada. Cuerpo de la función: lo que la función realizará. Retorno de la función: si la función tendrá alguna salida. De lo anterior, el nombre y el cuerpo siempre son obligatorios. Pudiendo existir funciones sin parámetros y/o sin retornos. Un ejemplo fome de función sin parámetros y sin retornos es: def fome () : a = La función anterior no hace nada útil, pero nos sirve para analizar la definición de una función. Se debe utilizar la instrucción def, seguida del nombre de la función, paréntesis (donde de existir parámetros irán dentro), dos puntos y luego el cuerpo de la función. O sea: def nombre de la función (parámetros de la función) : cuerpo de la función Una función más interesante, con parámetros y valor de retorno, sería la función para sumar dos números: def suma (a, b) : Una vez que tenemos nuestra función construída, por ejemplo la función suma del ejemplo anterior, la llamamos simplemente con su nombre: resultado = suma (, 2) Donde en resultado se almacenará el valor retornado por la función. Es muy importante mencionar que la función debe estar definida antes de ser llamada. De forma contraría se producirá un error indicando que la función no es encontrada..2. Parámetros por omisión A veces pueder ser útil especificar parámetros por omisión, esto es, si en el llamado a la función no se especifica el parámetro se utilizará algún valor por defecto. # definición def suma (a, b=5) : # llamado print(suma()) # 6 print(suma(,3)) # 4 Notar que solo se entregó un valor por omisión al parámetro b, por lo cual siempre se deberá pasar como mínimo un parámetro, el valor de a..3. Ejemplos.3.. Factorial es: Tomemos el ejemplo de la ayudantía anterior que permitía calcular Π n i=i = 2 3... n, la solución de dicho ejemplo 2
n = 3 multiplicacion = for i in range(2, n+) : multiplicacion *= i print(multiplicacion) Lo anterior permite calcular n!, n. Transformamos el código anterior a una función y a sus llamadas correspondientes para obtener los valores de!,!, 2!, 3!: # definición def factorial (n) : factorial = for i in range(2, n+) : factorial *= i return factorial # llamadas print(factorial()) # print(factorial()) # print(factorial(2)) # 2 print(factorial(3)) # 6 2. Módulos Supongamos que nuestro programa requiere funciones que hemos programado, estás habría que definirlas antes de poder ser utilizadas: función función 2... función programa principal Lo anterior claramente podría ser molesto. Pensemos ahora que tenemos un grupo de funciones que hemos programado y queremos compartirlas con otro programador pues este tiene necesidades que nuestras funciones resuelven, cómo integra el otro programador nuestras funciones en su programa? las copia y pega en su propio archivo.py?. Los módulos nos permitirán agrupar diferentes funciones en un mismo archivo, generalmente se agruparán funciones que están relacionadas entre si. Por ejemplo hasta ahora hemos utilizado el módulo math el cual agrupa diferentes funciones asociadas a matemáticas, específicamente hemos utilizado la función factorial. Existen dos formas de cargar un módulo y usar sus funciones:. Cargar el módulo completo y luego hacer los llamados indicando el módulo.función: import math print(math.factorial(3)) 2. Cargar solo una (o varias, pero no todas) función de un módulo y llamarla simplemente con su nombre. from math import factorial print(factorial(3)) Durante el curso se utilizará la primera forma, ya que esta dejará claro y de forma explícita que estamos utilizando un módulo. 2.. Definición y uso de un módulo Supongamos que queremos crear nuestro módulo llamado mimodulo, para hacer esto creamos el archivo mimodulo.py en el mismo directorio que nuestro programa principal y supongamos que nuestro programa principal se llama main.py). Con lo anterio definamos una función dentro de nuestro módulo y llamémosla desde nuestro programa principal. Entonces: 3
# esto va en el archivo mimodulo.py def suma (a, b) : # esto va en el archivo main.py import mimodulo print(mimodulo.suma(,2)) 2.2. Ejemplos 2.2.. Autómata que reconoce cantidad impar de s El autómata de la figura reconoce los strings w que contienen una cantidad impar de s, independientemente de los s que se puedan haber visto en el string. q start q Figura : AFD que reconoce strings de s y s con cantidad impar de s Se creará un módulo automata donde se definirá la función impar de ceros que contendrá el algoritmo del autómata de la figura. # @file automata.py def impar_de_ceros (w) : estado = for i in range (len(w)) : if int(w[i]) == : estado = (estado+) % 2 if estado == : return True else : return False # @file main.py import automata print(automata.impar_de_ceros("")) print(automata.impar_de_ceros("")) # True print(automata.impar_de_ceros("")) # True print(automata.impar_de_ceros("")) print(automata.impar_de_ceros("")) 3. Recursividad Las funciones recursivas consisten en que una función hace llamadas a si misma. Un mal ejemplo de llamada recursiva es: def f () : return f() El ejemplo anterior es malo puesto que la ejecución de f() se llamará por siempre de forma recursiva. Una función recursiva debe tener siempre una condición de término que permita retornar y empezar a devolverse en las llamadas. O sea se deberá ver como sigue: 4
def función recursiva () : # condición de termino de la recursivad (retornar algo "fijo") # llamada recursiva 3.. Ejemplos 3... Factorial Nuevamente utilicemos el ejemplo n!. La definición del factorial de n se puede hacer mediante inducción matemática (esto es de forma recursiva) según: Caso base:! = y! =. Caso inductivo: n! = n(n )!. Con lo anterior tenemos la forma de construir la función factorial, pero ahora de forma recursiva: def factorial (n) : if n <= : return return n * factorial(n-) 4. Ejercicios. Cómo utilizar un módulo que no está en el mismo directorio que nuestro programa principal, sino que está en un subdirectorio llamado modules? 2. En el módulo automata creado en el ejemplo 2.2., programe la función impar de ceros y unos que procese el string w según el autómata descrito en la figura 2. Casos de prueba: # @file main.py import automata print(automata.impar_de_ceros_y_unos("")) print(automata.impar_de_ceros_y_unos("")) print(automata.impar_de_ceros_y_unos("")) print(automata.impar_de_ceros_y_unos("")) print(automata.impar_de_ceros_y_unos("")) print(automata.impar_de_ceros_y_unos("")) # True # True q start q q 2 q 3 Figura 2: AFD que reconoce strings de s y s con cantidad impar de s y cantidad impar de s 3. Programar de forma recursiva la función que permite calcular la sucesión de Fibonacci:,,, 2, 3, 5, 8, 3, 2, 34, 55, 89, 44..., donde la sucesión comienza con los números y y luego el siguiente es la suma de los dos anteriores (hint: defina primero de forma inductiva la sucesión de Fibonacci y luego programe la función recursiva). 5