Sesión 16: Funciones (2)
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Repaso En el momento de crear mi_función debo seguir 2 pasos fundamentales: 1 Definición de la función 2 Llamado a la función
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Definición de una Función def nombre( param_1, param_N ): Palabra reservada que indica que estamos creando una función (definición de una función) def Es el nombre de la función es el nombre que le damos al conjunto de instrucciones que ella representa. nombre Son todos aquellos parámetros que la función necesita para su funcionamiento. Si la función no necesita parámetros se dejan los paréntesis vacios. parámetros
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Definición de una Función Definición de una Función: Retomando la función que calcula el máximo de dos números anteriormente mostrada: 4 def nombre de la funcion(lista de parametros formales): cuerpo de la funcion nombre de la función Parametros Cuerpo de la funcion def mini(x, y): if x < y: return x else: return y x y menor mini
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Una vez se ha definido la función, podemos pasar a la fase en el que la funcion ya se puede utilizar. varRetorno = nomb_funcion(variables) Para hacer que las instrucciones contenidas en una función, se ejecuten en determinado momento, no es necesario más que escribir su nombre como una línea de sentencia en el programa. raiz=sqrt(a) print (¨el valor es:¨, val ) 2 Llamado a la función
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Módulos Buenas practicas de programación Variables globales y locales Argumentos y retornos A continuación…
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Envío de argumentos 7 Hay dos maneras de pasar de argumentos en las funciones en Python. Teniendo la siguiente definición de una función: Posicionalmente: Requiere que el argumento sea pasado siguiendo el mismo orden de los parámetros de la función. Los nombres de las variables que se envían no tienen que ser iguales a los nombres de las variables de la definición: En este caso, las variables de la función tomaran los valores en el mismo orden en el que se envían. def nombre( vble1, vble2, vbleN): x = nombre( a, b, c)
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Envío de argumentos 8 Hay dos maneras de pasar de argumentos en las funciones en Python. Teniendo la siguiente definición de una función: Por palabra clave: Aquí se pasan los argumentos de la forma clave = valor. Se debe poner el nombre de la variable a la que se desea pasar el valor: Al utilizar este modo de envió, las variables de la función toman los valores según se especifique en el llamado sin importar el orden: def nombre( vble1, vble2, vbleN): x = nombre( vble1=valor1, vble2=valor2, vbleN=valorN) x = nombre( vble2=valor1, vble1=valor2, vbleN=valor1) x = nombre( vbleN=valor1, vble2=valor2, vble1=valorN)...
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Envío de argumentos 9 Realizar un programa que determine cual es menor de dos números. def mini(x,y): if (x<y): menor = x return menor else: menor = y return menor a = mini(1,2) # posicional b = mini(x = 1, y = 2) # Por palabra clave c = mini(y = 2, x = 1) # Por palabra clave e = mini(1, y = 2) # Ambas e = mini(y = 2, 1) # ERROR!!! def mini(x,y): if (x<y): menor = x return menor else: menor = y return menor a = mini(1,2) # posicional b = mini(x = 1, y = 2) # Por palabra clave c = mini(y = 2, x = 1) # Por palabra clave e = mini(1, y = 2) # Ambas e = mini(y = 2, 1) # ERROR!!! Código online
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Parámetros por defecto 10 Es posible que en ocasiones no necesitemos enviar todos los parámetros a las funciones. Si esto ocurre tendríamos que llenar de valores innecesarios al momento de realizar el llamado: Por ejemplo: def nombre( vble1, vble2, vbleN): x = nombre( a, b, 0 ) x = nombre( a, 0, 0 ) x = nombre( a, 0 ) #Error: Falta un valor
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Parámetros por defecto 11 Para evitar esto, en Python existe los valores por defecto. Estos son valores que toman las variables cuando no se envían todos los valores en el llamado def nombre( vble1, vble2, vbleN=valorD1): x = nombre( a, b, c ) x = nombre( a, b ) x = nombre( vble1=valor1, vbleN=valor2 ) #Error x = nombre( vble1=valor1, vble2=valor2 ) x = nombre( vbleN=valor1, vble1=valor2, vble2=valor3)
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Parámetros por defecto 12 def strIsIn(str1, str2, sen): if not sen: str1 = str1.lower() str2 = str2.lower() if str1 in str2: return 'Yes' else: return 'No' s1 = 'Hola' s2 = 'holas' print(strIsIn(s1, s2, False))# imprime Yes print(strIsIn(s1, s2, True))# imprime No print(strIsIn(s2, s1, False)) print(strIsIn(sen=False, str2=s1, str1=s2)) print(strIsIn(str2=s1, str1=s2)) def strIsIn(str1, str2, sen): if not sen: str1 = str1.lower() str2 = str2.lower() if str1 in str2: return 'Yes' else: return 'No' s1 = 'Hola' s2 = 'holas' print(strIsIn(s1, s2, False))# imprime Yes print(strIsIn(s1, s2, True))# imprime No print(strIsIn(s2, s1, False)) print(strIsIn(sen=False, str2=s1, str1=s2)) print(strIsIn(str2=s1, str1=s2)) def strIsIn(str1, str2, sen=True): parámetros con valores por defecto argumentos asignados por nombre (keyword) argumento omitido por tener valor por defecto
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Valores de retorno 13 Python es un lenguaje especial al momento de retornar valores. Ya que la mayoría de los lenguajes de alto nivel solo son capaces de retornar un único valor (variable). Por su parte, Python permite retornar toda una lista de variables de acuerdo a la siguiente expresión: Por ejemplo: def nombre( vble1, vble2, vbleN):... return v1,v2,.. vN x,y,..z = nombre( a, b, c )
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Valores de retorno 14 def division(dividendo, divisor): cociente = dividendo//divisor residuo = dividendo%divisor return cociente,residuo x,y = division(23,5)# Se guarda sobre x,y respectivamente print(“El cociente de la division es:”,x)# imprime 4 print(“El residuo de la division es:”, y)# imprime 3 def division(dividendo, divisor): cociente = dividendo//divisor residuo = dividendo%divisor return cociente,residuo x,y = division(23,5)# Se guarda sobre x,y respectivamente print(“El cociente de la division es:”,x)# imprime 4 print(“El residuo de la division es:”, y)# imprime 3
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Módulos Buenas practicas de programación Variables globales y locales Argumentos y retornos Variables globales y locales A continuación…
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Alcance de una variable 16 Cuando trabajamos con funciones debemos conocer muy bien los límites y alcances que tienen las variables. Cuando utilizamos una variable dentro de una función, estas variables existe únicamente dentro del contexto de dicha función (variables locales) Mientras que si creamos una variable por fuera de todas las funciones, ésta tiene un contexto general el cual le permite ser accedida por todas las funciones (variables globales) Según el contexto de las variables podemos describir el comportamiento de las variables en un programa.
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia 17 La visibilidad o Scope de una variable es la parte del programa en la que esa variable está definida y puede ser utilizada. La duración o Lifetime hace referencia al tiempo que transcurre entre la creación de una variable y el instante en que es destruida. Visibilidad y Duración
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Locales Una variable local se declara dentro de una función Son visibles solo dentro de la función Ocultan a las variables globales con el mismo nombre. “Nacen” y “mueren” con la función. Globales Una variable global se declara fuera de todas las funciones Son visibles en todo el programa Se le puede cambiar el valor en cualquier parte del programa. Existen durante toda la ejecución del programa Clasificación de Variables
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Scoping Es el ámbito en el que es válido el nombre de una variable o función. 19 def f(x): y = 1 x = x + y print('x =', x) return x x = 3 y = 2 z = f(x) # valor de x usado como argumento print('z =', z) print('x =', x) print('y =', y) def f(x): y = 1 x = x + y print('x =', x) return x x = 3 y = 2 z = f(x) # valor de x usado como argumento print('z =', z) print('x =', x) print('y =', y) variables locales a f variables globales
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Variables Globales vs localesGlobales vs locales Variables Globales vs localesGlobales vs locales 20 def f1(): global a a = a + 1 b = b + 1 global c c = 7 d = 23 print(a, b, c, d) a=4 b=15 f1() print(a, b) print(c) print(d) def f1(): global a a = a + 1 b = b + 1 global c c = 7 d = 23 print(a, b, c, d) a=4 b=15 f1() print(a, b) print(c) print(d) Error: d no existe en este ámbito Error: b no ha sido inicializada variables globales variable local ¡Las variables globales hacen que los programas sean muy difíciles de entender y depurar!
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Variables Globales vs locales 21 Dados los siguientes fragmentos de código cual es la salida en pantalla para cada caso: globalVar = 1 def f1(): localVar = 2 print(globalVar) print(localVar) f1() print(globalVar) # print(localVar) # Out of scope, so this gives an error Código 1Código 1:
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Variables Globales vs locales 22 Dados los siguientes fragmentos de código cual es la salida en pantalla para cada caso: x = 1 def f1(): x = 2 print(x) # Displays 2 f1() print(x) # Displays 1 Código 2Código 2: x = eval(input("Enter a number: ")) if x > 0: y = 4 # print(y) # This gives an error if y is not created Código 3Código 3:
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Variables Globales vs locales 23 Dados los siguientes fragmentos de código cual es la salida en pantalla para cada caso: sum = 0 for i in range(5): sum += i print(i) Código 4Código 4: x = 1 def increase(): global x x = x + 1 print(x) # Displays 2 increase() print(x) # Displays 2 Código 5Código 5:
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Módulos Buenas practicas de programación Variables globales y locales Argumentos y retornos Buenas practicas de programación A continuación…
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Buenas prácticas 25 Cuando tenemos problemas mas complejos, surge la necesidad de utilizar más técnicas de programación como lo son las funciones. Sin embargo, el uso de una sola función en muchas ocasiones no es suficiente para resolver el problema. Entre las técnicas utilizadas en Python tenemos las funciones anidadas y la creación de módulos.
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Funciones anidadas 26 def compare(): def mini(x, y): if x<y: return x else: return y age1 = int(input('Enter age of first person: ')) weight1 = int(input('Enter weight of first person: ')) age2 = int(input('Enter age of second person: ')) weight2 = int(input('Enter weight of second person: ')) young = mini(age1, age2) slim = mini(weight1, weight2) print('The young one is', young, 'years old') print('and the slim one weights', slim, 'kilos') while(True): #print(mini(7,8)) wish = input('Do you want to compare people? ') if wish == 'no': break compare() def compare(): def mini(x, y): if x<y: return x else: return y age1 = int(input('Enter age of first person: ')) weight1 = int(input('Enter weight of first person: ')) age2 = int(input('Enter age of second person: ')) weight2 = int(input('Enter weight of second person: ')) young = mini(age1, age2) slim = mini(weight1, weight2) print('The young one is', young, 'years old') print('and the slim one weights', slim, 'kilos') while(True): #print(mini(7,8)) wish = input('Do you want to compare people? ') if wish == 'no': break compare() función anidada función desconocida en este ámbito Archivo: nested.py
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Funciones anidadas 27 Como se ve en el ejemplo anterior, el manejo de funciones dentro de funciones puede aumentar la funcionalidad del sistema, pero tambien aumenta la dificultad de entendimiento. Además, no debemos olvidar que el orden en el desarrollo del programa es parte fundamentas para obtener soluciones eficientes. Por estas razones, y buscar acercar Python a la mayoría de los lenguajes de programación de alto nivel, podemos realizar una función principal llamada generalmente main. Esta función será la que coordine el funcionamiento del programa.
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Estructuras Básicas de los programas Encabezado Titulo: Autor: Fecha: Descripción: Definicion main(): Proceso Principal Definicion de funciones(): Procesos internos main():
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia 29 def main(): i = 5 j = 2 k = maxi(i, j) print("El numero mayor de",i,"y",j,"es",k) def maxi(num1,num2): if num1 > num2: result = num1 else: result = num2 return result main() def main(): i = 5 j = 2 k = maxi(i, j) print("El numero mayor de",i,"y",j,"es",k) def maxi(num1,num2): if num1 > num2: result = num1 else: result = num2 return result main() Código online main
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia 30 main
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia 31 main
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia 32 main
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia 33 main
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia 34 main
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Especificación de una función 35 Docstring: comentario entre comillas triples que resume la especificación de la función def findRoot(x, power, epsilon=0.01): ''' Asume que x y epsilon son int o float, que power es int, epsilon > 0 y power >= 1 Retorna un dato float tal que dato**power está dentro de una distancia epsilon de x Si no existe tal dato, retorna None''' if x<0 and power%2==0: return None low = min(-1.0, x) high = max(1.0, x) ans = (high + low)/2.0 while abs(ans**power - x) >= epsilon: if ans**power < x: low = ans else: high = ans ans = (high + low)/2.0 return ans Especificación de una función: condiciones de uso de una función. Suposiciones: requisitos de los argumentos Garantías: lo que la función garantiza hacer Las especificaciones de las funciones permiten desarrollar un programa entre varias personas Archivo: findRoot.py
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Especificación de una función 36
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Test manual de una función 37 Consiste en invocar la función en la consola de python de manera manual para verificar que esta funcione de acuerdo a lo que garantiza siempre y cuando los requisitos (suposiciones) necesarios para su funcionamiento se cumplan. Valores para probar en el programa xpowerepsionresultado ? ? ? Tabla de test xPowerresultado
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Test manual de una función 38 Valores para probar en el programa xpowerepsionresultado Tabla de test xPowerresultado Hacer el test de una manera tan manual puede volverse engorroso.
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Funciones de Test 39 def findRoot(x, power, epsilon=0.01):... return ans def testFindRoot(): epsilon = for x in (0.25, -0.25, 2, -2, 8, -8): for power in range(1,4): print('Testing x = ' + str(x) +\ ' and power = ' + str(power)) result = findRoot(x, power, epsilon) if result == None: print(' No root') else: print(' ', result**power, '~=', x) testFindRoot() def findRoot(x, power, epsilon=0.01):... return ans def testFindRoot(): epsilon = for x in (0.25, -0.25, 2, -2, 8, -8): for power in range(1,4): print('Testing x = ' + str(x) +\ ' and power = ' + str(power)) result = findRoot(x, power, epsilon) if result == None: print(' No root') else: print(' ', result**power, '~=', x) testFindRoot() Función para calcular raíces Función para hacer el test de la función que calcula la raíces Invacion de la función de test Archivo: testFindRoot.py
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Funciones de Test 40
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Módulos Buenas practicas de programación Variables globales y locales Argumentos y retornos Módulos A continuación…
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Modularizando el código 42 Modularizar el código hace mas fácil mantenerlo y depurarlo, así mismo, permite el reúso del código. Concepto clave - Modulo: –Un modulo es un archivo python en el cual se coloca se colocan las definición de una o mas funciones. –El modulo puede ser luego importado en el programa para reúso. –El modulo puede ser colocado en el mismo directorio con sus otros programas. main.py import geom... geom.py pi = def area(radio):......
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Modularizando el código 43 import geom r = input('Ingrese el radio: ') r = float(r) print('pi: ', geom.pi) print('área: ', geom.area(r)) print('perímetro: ', geom.perimetro(r)) print('superficie: ', geom.sfEsfera(r)) print('volumen: ', geom.volEsfera(r)) import geom r = input('Ingrese el radio: ') r = float(r) print('pi: ', geom.pi) print('área: ', geom.area(r)) print('perímetro: ', geom.perimetro(r)) print('superficie: ', geom.sfEsfera(r)) print('volumen: ', geom.volEsfera(r)) pi = def area(radio): return pi*(radio**2) def perimetro(radio): return 2*pi*radio def sfEsfera(radio): return 4*pi*(radio**2) def volEsfera(radio): return (4/3)*pi*(radio**3) pi = def area(radio): return pi*(radio**2) def perimetro(radio): return 2*pi*radio def sfEsfera(radio): return 4*pi*(radio**2) def volEsfera(radio): return (4/3)*pi*(radio**3) main.pygeom.py módulos
2009/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Circuitos Digitales III 2010/1 Informática I Universidad de Antioquia Modularizando el código 44 Archivo: main.py Archivo: geom.py