Para aquellas funciones que no están dentro de la librería estandar, se utilizan módulos (librerías), archivos Python .py** que constan de código Python. Un módulo puede definir funciones, clases y variables, además puede incluir código ejecutable. Se puede hacer referencia a cualquier archivo de Python como un módulo. Un archivo de Python llamado hello.py tiene el nombre de módulo "hello" que se puede importar a otros archivos de Python o utilizar en el intérprete de línea de comandos de Python. Estos módulos, a la vez, pueden formar parte de paquetes. Un paquete, es una carpeta que contiene archivos .py, pero para que una carpeta pueda ser considerada un paquete, debe contener un archivo de inicio llamado init.py**.
Nota: este archivo, no necesita contener ninguna instrucción. De hecho, puede estar completamente vacío.
La estructura general de un módulo es:
# Operaciones matemáticas comunes
import math
print("sin(2\u03c0/3) = {}".format(math.sin(2 * math.pi / 3)))
print("cos(2\u03c0/3) = {}".format(math.cos(2 * math.pi / 3)))
# En cmath tambien se encuentran las de números complejos
import cmath
z = 2 + 3j
print("{0:.3} = modulo = {1[0]:.3} fase = {1[1]:.3}".format(z,cmath.polar(z)))
print("sin(z) = {0:.3f}".format(cmath.sin(z)))
Para hacer referencia a los elementos de un módulo, puede usar la declaración de from ... import
. Cuando se importa un módulo de esta manera, puede referirse a las funciones por nombres y no a través de la notación de punto.
from math import floor
# redondear un número al entero anterior
floor(5 / 2)
from math import ceil
# redondear un número al entero posterior
math.ceil(5 / 2)
Es posible modificar los nombres de los módulos utilizando la palabra clave as
. Esto es útil para abreviar un nombre más largo. La construcción de esta declaración se ven así:import [module] as [another_name]
.
%matplotlib inline
import matplotlib.pyplot as p # módulo para hacer plot
p.plot(range(7),range(7),'-.',color='b' )
[<matplotlib.lines.Line2D at 0x7fae69290e50>]
Veamos otro ejemplo, la aproximación de orden 3 del desarrollo de Taylor en 0 de la función seno es (crean que es así...):
$sen(x)\approx x-x^{3}/6$
import numpy as np # módulo para trabajar con array
import matplotlib.pyplot as plt # módulo para hacer plot
x = np.linspace(-np.pi,+np.pi,100)
aprox = x - np.power(x,3)/6
plt.plot(x/np.pi,np.sin(x),'r',x/np.pi,aprox,'.')
plt.xlabel("Radianes [$\pi$]")
plt.ylabel("Amplitud")
plt.grid()
Hay módulos de infinidad de disciplinas, a continuación algunas referencias de librerias más utilizadas:
Y muchas más. Lo ideal es, antes de comenzar a trabajar en un problema, investigar qué herramientas hay disponibles, para evitar hacer trabajo en vano.
Una función es la forma de agrupar expresiones y sentencias que realicen determinadas acciones, pero que éstas, solo se ejecuten cuando son llamadas. Es decir, que al colocar un algoritmo dentro de una función y se corre el archivo, el algoritmo no será ejecutado si no se ha hecho una referencia a la función que lo contiene. Las funciones se pueden considerar como una herramienta para controlar flujo.
En definitiva lo más importante para programar, y no solo en Python, es saber organizar el código en piezas más pequeñas que hagan tareas independientes y combinarlas entre sí. Las funciones son el primer nivel de organización del código: reciben unas entradas, las procesan y devuelven unas salidas.
Por defecto, los archivos fuente de Python son codificados en UTF-8 [G. Van Rossum., 2017].
El encoding (o codificación) es otro de los elementos del lenguaje que no puede omitirse a la hora de hablar de estructuras de control. El encoding no es más que una directiva que se coloca al inicio de un archivo Python, a fin de indicar al sistema, la codificación de caracteres utilizada en el archivo.
# -*- coding: utf-8 -*-
Lo vemos con un ejemplo concreto:
def fib(n):
""" Escribe la serie de Fibonacci hasta n. """
a, b = 0, 1 # asignacion multiple
while a < n:
print (a, end = ' ') # es para imprimirlos seguidos y no uno debajo del otro.
a, b = b, a + b
?fib(n)
Object `fib(n)` not found.
# Invocamos la función definida.
fib(2000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
La palabra reservada def
se usa para definir funciones. Debe seguirle el nombre de la función y la lista de argumentos entre paréntesis. Las sentencias que forman el cuerpo de la función empiezan en la línea siguiente, y deben estar con identado. La primer sentencia del cuerpo de la función puede ser opcionalmente una cadena de texto literal (utilizar """
, en lugar de #
); esta es la cadena de texto de documentación de la función, o docstring. Es una buena práctica, no solo documentar las funciones, sino hacerlo con un estilo único y estandarizado. Una referencia respaldada en el ecosistema científico es el estilo de documentación de NumPy.
Si lo que buscamos es escribir una función que retorne una lista con los números de la serie de Fibonacci en lugar de imprimirlos, podemos pensar en el siguiente ejemplo para completar:
def fib2(n):
"""Devuelve una lista conteniendo la serie de Fibonacci hasta n."""
resultado = [] # inicializo la lista completar!
a, b = 0, 1 # asignacion multiple
while a < n:
resultado # completar!
a, b = # completar!
return # completar!
# Invocamos la función definida.
fib2000 = fib2(2000)
print() # completar
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597]
%run ../code/fibo.py
Es importante resaltar que las variables que se crean dentro de las funciones no son accesibles una vez que termina la ejecución de la función. En cambio, la función si que puede acceder a cosas que se han definido fuera de ella. No obstante, esto último no constituye una buena práctica de cara a la reproducibilidad, mantenibilidad y testeo de la función.
También es posible definir funciones con un número variable de argumentos. Hay tres formas que pueden ser combinadas:
La forma más útil es especificar un valor por omisión para uno o más argumentos. Esto crea una función que puede ser llamada con menos argumentos que los que permite. Por ejemplo:
def pedir_confirmacion(prompt, reintentos=4, recordatorio="Por favor, intente nuevamente!"):
while True:
ok = input(prompt)
if ok in ("s", "S", "si", "Si", "SI", "sI"): # contemplando todos los casos, "in" palabra resevada para probar si una secuencia contiene o no un determinado valor.
return True
if ok in ("n", "N", "no", "No", "NO", "nO"): # contemplando todos los casos
return False
reintentos -= 1
if reintentos < 0:
raise ValueError("respuesta de usuario inválida")
print (recordatorio)
# pasando solo el argumento obligatorio
pedir_confirmacion("¿Realmente queres salir?")
# pasando uno de los argumento opcionales
pedir_confirmacion("¿Sobreescribir el archivo?", 2)
# pasando todos los argumentos
pedir_confirmacion("¿Sobreescribir el archivo?", 2, "Vamos, solo si o no!")
Las funciones también puede ser llamadas usando argumentos con palabras claves (o argumentos nombrados) de la forma keyword = value. Por ejemplo, la siguiente función:
def loro(tension, estado='muerto', accion='explotar', tipo='Azul Nordico'):
print("-- Este loro no va a", accion, end=' ')
print("si le aplicás", tension, "voltios.")
print("-- Gran plumaje tiene el", tipo)
print("-- Está", estado, "!")
Acepta un argumento obligatorio (tensión) y tres argumentos opcionales (estado, accion, y tipo). Esta función puede llamarse de cualquiera de las siguientes maneras:
loro(1000) # 1 argumento posicional
loro(tension=1000) # 1 argumento nombrado, palabra clave
loro(tension=1000000, accion='BOOOOOM') # 2 argumentos nombrados
loro(accion='BOOOOOM', tension=1000000) # 2 argumentos nombrados, sin orden
Cuando un parámetro formal de la forma **nombre
está presente al final, recibe un diccionario conteniendo todos los argumentos nombrados excepto aquellos correspondientes a un parámetro formal. Esto puede ser combinado con un parámetro formal de la forma *nombre
que recibe una tupla conteniendo los argumentos posicionales además de la lista de parámetros formales. (*nombre
debe ocurrir antes de **nombre
). Por ejemplo, si definimos una función así:
def venta_de_queso (tipo, *argumento, **palabrasclaves):
print("-- ¿Tiene", tipo, "?")
print("-- Lo siento, nos quedamos sin", tipo)
for arg in argumento:
print(arg)
print("-" * 40)
for c in palabrasclaves:
print(c, ":", palabrasclaves[c])
Puede ser llamada así:
venta_de_queso("Limburger", "Es muy liquido, sr.", "Realmente es muy liquido, sr.",
cliente="Juan Gomez",
vendedor="Miguel Paez",
puesto="Venta de Queso Argentino")
Finalmente, la opción menos frecuentemente usada es especificar que una función puede ser llamada con un número arbitrario de argumentos. Estos argumentos serán organizados en una tupla.
def f(*args):
return args
f(1, 5, True, False, "Hello, world!")
Este documento se destribuye con una licencia Atribución CompartirIgual 4.0 Internacional de Creative Commons.
© 2020. Infiniem Labs Acústica. infiniemlab.dsp@gmail.com (CC BY-SA 4.0))