""" FUNCION es una secuencia de sentencias que realiza una operación. Las mismas tienen un nombre y pueden recibir o no parámetros y devolver o no resultados. ej. """ def cero(): return 0 cero() # 0 cero() + 1 # 1 c = cero() c # 0 def suma_uno(un_numero): return un_numero + 1 suma_uno(3) # 4 suma_uno(cero()) #1 def suma(a, b): resultado = a + b return resulado def suma(a, b): resultado = a + b return resulado def maximo_2(a, b): "Devuelve el máximo entre a y b" maximo = a if b > a: maximo = b return maximo def maximo_3(a, b, c): "Devuelve el máximo enter a, b, y c" return maximo_2(a, maximo_2(b,c)) print(maximo_2(2,5)) # 5 print(maximo_3(6, 1, 5)) # 6 # MAS SOBRE FUNCIONES def peso(masa, gravedad=9.8): "Fórmula del peso" return masa * gravedad # Parametros opcionales print("Peso en la tierra:", peso(10)) # Peso en la tierra: 98.0 print("Peso en la luna:", peso(10, 1.63)) # Peso en la luna: 16.299999999999997 # Parámetros con palabras claves (o argumentos nombrados) print("Peso en la luna:", peso(10, gravedad=1.63)) # Peso en la luna: 16.299999999999997 print("Peso en la luna:", peso(masa=10, gravedad=1.63)) # Peso en la luna: 16.299999999999997 print("Peso en la luna:", peso(gravedad=1.63, masa=10)) # Peso en la luna: 16.299999999999997 # Los parámetros posicionales no pueden ir despues de un keyword # print("Peso en la luna:", peso(masa=10, 1,63)) # SyntaxError: positional argument follows keyword argument # Lista de parámetros def suma_numeros(*args): "Suma los números pasados por párametro" return sum(args) print("6 + 7 + 8 =", suma_numeros(*[6,7,8])) # 6 + 7 + 8 = 21 print("6 + 7 + 8 =", suma_numeros(6,7,8)) # 6 + 7 + 8 = 21 # Diccionario de parámetros def imprimir_ticket(*args, **kwargs): "Imprime el ticket de una compra" print("Detalle Ticket") for item, precio in kwargs.items(): print(item, ":", precio) # ARGUMENTOS DE FUNCIONES """ # FUNCIONES - Distintas formas de pasar los argumentos - Definir funciones anónimas o expresiones lambda Definiedo Funciones Función Fibonacci ( hasta limite determinado ) *def para definir la funcion """ >>> def fibo(n): """Muestra la serie Fibonacci hasta n.""" a, b = 0, 1 while a < n: print(a, end=' ') a, b = b, a+b print() fibo(2000) # 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 """ * return devuelve un valor en una funcion, sin una expresion como argumento retorna None, si se alcanza el fuba de una función, también retorna None. """ f = fibo f(1000) # 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 print(f(0)) # None type(f) # def fibo2(n): """Devuelve una lista con la serie de Fobonacci hasta n.""" result = [] a, b = 0, 1 while a < n: result.append(a) a, b = b, a+b return result f100 = fibo2(100) f100 # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] def pedir_confirmacion(prompt, reintentos=4, msj='Intenta nuevamente'): while True: ok = input(prompt) if ok in ('s', 'S', 'si', 'Si', 'SI'): return True if ok in ('n', 'no', 'No', 'NO'): return False reintentos -= 1 if reintentos < 0: raise ValueError('Respuesta de usuario invalida') print(msj) pedir_confirmacion('¿Quieres Salir?') # ¿Quieres Salir?no # False pedir_confirmacion('¿Sobreescribir?', 2) # ¿Sobreescribir?e # Intenta nuevamente # ¿Sobreescribir?3 # Intenta nuevamente # ¿Sobreescribir?3 # Traceback (most recent call last): # File "", line 1, in # File "", line 10, in pedir_confirmacion # ValueError: Respuesta de usuario invalida # >>> # >>> pedir_confirmacion('Sobreescribir?', 2, 'eeey! si o no?') # Sobreescribir?o # eeey! si o no? # Sobreescribir?no # False """ * Los valores por omisión son evaluados en el momento de la definición de la función, en el ámbito de la definición, entonces: """ i = 5 def f(arg=i): print(arg) i = 6 f() # 5 f(6) # 6 f() #5 """ El valor por omisión es evaluado solo una vez. Existe una diferencia cuando el valor por omisiónes un objeto mutable como una lista, diccionario, o instancia de la mayoría de las clases. Por ejemplo, la siguiente funciónacumula los argumentos que se le pasan en subsiguientes llamadas: """ def f(a, L=[]): L.append(a) return L print(f(1)) #[1] print(f(2)) #[1, 2] print(f(3)) #[1, 2, 3] """ * Si no se quiere que el valor por omisión sea compartido entre subsiguientes llamadas, la función se puede escribir así: """ >>> def f(a, L=None): ... if L is None: ... L = [] ... L.append(a) ... return L ... >>> print(f(1)) [1] >>> print(f(2)) [2] >>> print(f(3)) [3] >>> print(f(1, [1,2,3])) [1, 2, 3, 1] >>> """ * Palabras clave como argumentos Las funciones también puede ser llamadas usando argumentos de palabras clave (o argumentos nombrados) de la formakeyword = value. Por ejemplo: """ def loro(tension, estado='muerto', accion='explotar', tipo='Azul Nordico'): print("-- Este loro no va a", accion, end=' ') print("si le aplicas", tension, "voltios.") print("-- Gran plumaje tiene el", tipo) print("-- Está", estado,"!") loro(1000) # 1 argumento posicional # -- Este loro no va a explotar si le aplicas 1000 voltios. # -- Gran plumaje tiene el Azul Nordico # -- Está muerto ! loro(tension=1000) # 1 argumento nombrado # -- Este loro no va a explotar si le aplicas 1000 voltios. # -- Gran plumaje tiene el Azul Nordico # -- Está muerto ! loro(tension=1000000, accion='VOOOOM') # 2 argumentos nombrados # -- Este loro no va a VOOOOM si le aplicas 1000000 voltios. # -- Gran plumaje tiene el Azul Nordico # -- Está muerto ! loro(accion='VOOOOM', tension=1000000) # 2 argumentos nombrados # -- Este loro no va a VOOOOM si le aplicas 1000000 voltios. # -- Gran plumaje tiene el Azul Nordico # -- Está muerto ! loro('un millón', 'despojado de vida', 'saltar') # 3 args posicionales # -- Este loro no va a saltar si le aplicas un millón voltios. # -- Gran plumaje tiene el Azul Nordico # -- Está despojado de vida ! loro('mil', estado='viendo crecer las flores desde abajo') # uno pos. y uno nom. # -- Este loro no va a explotar si le aplicas mil voltios. # -- Gran plumaje tiene el Azul Nordico # -- Está viendo crecer las flores desde abajo ! '''Llamadas invalidas''' loro() # falta argumento obligatorio loro(tension=5.0, 'muerto') # argumento posicional luego de uno nombrado loro(110, tension=220) # valor duplicado para el mismo argumento loro(actor='Juan Garau') # nombre del argumento desconocido """ # Cuando un parámetro formal de la forma **nombre está presente al final, recibe un diccionario (ver Tipos integrados) conteniendo todos los argumentos nombrados excepto aquellos correspondientes a un parámetro formal. Esto puede sercombinado con un parámetro formal de la forma *nombre que recibe una tuplaconteniendo los argumentos posicionales además de la lista de parámetros formales. (*nombre debe ocurrir antes de **nombre). Por ejemplo: """ def ventadequeso(tipo, *argumentos, **palabrasclave): print("-- ¿Tiene", tipo,"?") print("-- Lo siento, nos quedamos sin", tipo) for arg in argumentos: print(arg) print("-" * 40) for c in palabrasclave: print(c, ":", palabrasclave[c]) ventadequeso("Limburger", "Es muy liquido, sr.", "Realmente es muy muy liquido, sr.", cliente="Juan Garau", vendedor="Miguel Paez", puesto="Venta de Queso") #- ¿Tiene Limburger ? #- Lo siento, nos quedamos sin Limburger # Es muy liquido, sr. # Realmente es muy muy liquido, sr. # ---------------------------------------- # cliente : Juan Garau # vendedor : Miguel Paez # puesto : Venta de Queso Argentino """ * Listas de argumentos arbitrarios Una función puede ser llamada con un número arbitrario de argumentos. Estos serán organizados en una tupla. Antes del número variable de argumentos, cero o más argumentos normales pueden estar presentes. """ >>> def muchos_items(archivo, separador, *args): ... archivo.write(separador.join(args)) ... >>> """ * Gralmente. argumentos de cantidad variable son útilmos en la lista de parametros formales, pq toman el remanente de argumentos q se pasan a la función. Cualquier parametro q suceda luego del +args solo sera 'nombrado', es decir, solo se pueden utilizar nombradros y no posicionales. """ concatenar("tierra", "marte", "venus") # 'tierra/marte/venus' concatenar("tierra", "marte", "venus", sep=" @ ") # 'tierra @ marte @ venus' """ * Desempaquetando una lista de argumentos Cuando los argumentos ya pertences a una lista o tupla, se pueden desempaquetar para llamar una funcion que requiere argumetnoss posicionaes separados. ej. range() espera los argumentos inicio y fin. También se puede llamar a la función con el operador para desempaquetar argumentos de una lista o tulpa * """ list(range(3, 6)) # llamada normal con argumentos separados # [3, 4, 5] args = [3, 6] list (range(*args)) # argumentos desempaquetados de la lista # [3, 4, 5] "* Los diccionarios pueden entregar argumentos nombrados con el operador **" def loro(tension, estado='rostizado', accion='apestar'): print("-- Este loro no va a", accion, end=' ') print("si toca", tension, "voltios.", end=' ') print("Está", estado, "!") d = {"tension": "cinco mil", "estado": "demacrado", "accion": "VOLAR"} loro(**d) # -- Este loro no va a VOLAR si toca cinco mil voltios. Está demacrado ! # Ejemplo Funcion FIBONACCI def fib(n): a, b = 0, 1 for i in range(n): a, b = b, a+b return a print(fib(35)) def fibo(n): a = fib(n-1) + fib(n-2) return a print(fibo(35))