Por Jose R. Zapata
Ultima actualización: 14/Mar/2025
En este notebook se encuentra los temas mas importantes para el uso de python en ciencia de datos, se debe tener un un conocimiento básico de programación para entender completamente el notebook.
!python --version
Python 3.11.11
Funciones
El beneficio de las funciones es que nos permiten reutilizar el código y evitar repetirnos.
Las funciones se definen con la palabra clave def
y tienen la sintaxis
def nombre_funcion(parametros):
pasos de la funcion
#si no se pone return, la función devuelve None
return algo
Para devolver un valor utilizamos la palabra clave return
.
def hola_funcion(): # `:` es obligatorio
print("Hola ciencia de datos en producción")
hola_funcion()
Hola ciencia de datos en producción
si no se pone return, la función devuelve None
salida = hola_funcion()
print(salida)
Hola ciencia de datos en producción
None
def cubo(x): # `:` es obligatorio
# el cuerpo de la función esta definido
# por la indentación (espacios en blanco)
# para devolver valores se usa `return`
return x**3
out = cubo(4)
out
64
Ejemplo de una función mas compleja
- ¿Que hace esta función?
- ¿Que tipo de datos recibe?
- ¿Que tipo de datos devuelve?
def algo(a):
# recordar la indentación en Python
s = 1
for e in a:
s = s * e
return s
# sera que funciona?
mi_lista = ["a", "b", "c"]
algo(mi_lista)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[8], line 3
1 # sera que funciona?
2 mi_lista = ["a", "b", "c"]
----> 3 algo(mi_lista)
Cell In[7], line 5, in algo(a)
3 s = 1
4 for e in a:
----> 5 s = s * e
6 return s
TypeError: can't multiply sequence by non-int of type 'str'
# y ahora?
mi_lista = [5, 2, 3, 4]
algo(mi_lista)
Buenas practicas básicas al definir Funciones
Ejemplo de la misma función pero con algunas buenas practicas de software:
- usar nombres descriptivos para las funciones
- usar nombres descriptivos para los argumentos
- docstrings (documentación)
- static typing
No es obligatorio para que funcione, pero es muy recomendable para entender que es lo que hace la función y tipos de datos se deben ingresar y que tipo de datos devuelve la función.
Esta información ayuda a otros programadores a entender el código y a nosotros mismos en el futuro.
Ademas de que ayuda a los IDEs y Herramientas de AI en el trabajo en la auto completar código, detección de errores y crear pruebas unitarias.
Leer la siguiente función y responder las preguntas anteriores
- ¿Que hace esta función?
- ¿Que tipo de datos recibe?
- ¿Que tipo de datos devuelve?
def multiplicar_elementos_lista(lista_numeros: list[int | float]) -> int | float:
"""multiplicar todos los elementos de una lista de números.
Args:
lista_numeros (list[int | float]): Una lista de valores numéricos.
Returns:
int | float: La suma de todos los elementos.
Examples:
>>> multiplicar_elementos_lista([1, 2, 3])
6
>>> multiplicar_elementos_lista([1.5, 2.5, 3.5])
13.125
"""
resultado = 1
for elemento in lista_numeros:
resultado = resultado * elemento
return resultado
mi_lista = [5, 2, 3, 4]
resultado_funcion = multiplicar_elementos_lista(mi_lista)
print(f"Los elementos de la lista multiplicados = {resultado_funcion}")
Static Typing
Python es un lenguaje de programación dinámico, lo que significa que no es necesario especificar el tipo de datos de una variable cuando se declara. Python infiere el tipo de datos de la variable en tiempo de ejecución. Pero a partir de Python 3.5, se introdujo la anotación de tipo de datos, que es una forma de declarar el tipo de datos de una variable.
EL static typing es una forma de declarar el tipo de datos de una variable, esto no afecta el funcionamiento del código, pero ayuda a los programadores a entender el código en la revision de los pull request, re usar código y ayuda a los IDEs a detectar errores y a completar el código.
Se puede ver un ejemplo de static typing en la siguiente función, donde se especifica el tipo de datos que recibe y el tipo de datos que devuelve la función.
def suma(a: int, b: int) -> int:
return a + b
Docstrings
Las docstrings son cadenas de texto que se encuentran en la primera línea de una función, clase, método o módulo. Se utilizan para documentar el código y explicar lo que hace una función o método. Las docstrings se pueden acceder utilizando el atributo __doc__
de la función o método
Los docstrings sirven para documentar el código y explicar lo que hace una función o método.
print(multiplicar_elementos_lista.__doc__)
# se puede ver los tipos de los argumentos y el tipo de retorno
multiplicar_elementos_lista.__annotations__
help()
Nos entrega la ayuda de una función, clase, etc
help(len)
# y la primera función que creamos?
help(algo)
Ayuda de la función creada con typing y docstrings
```python
help(multiplicar_elementos_lista)
Validación de argumentos
# Que ocurre con el siguiente código?
mi_lista = ["a", "b", "c"]
resultado_funcion = multiplicar_elementos_lista(mi_lista)
Que podemos hacer para evitar que se utilice la función con argumentos incorrectos?
R/ No se puede evitar, pero la estrategias son como se vio anteriormente:
- Especificar el tipo de datos que debe recibir la función
- realizar la documentación por ultimo podemos validar los argumentos con condicionales y lanzar un error si no son del tipo correcto o no cumplen con ciertas condiciones.
- Realizar validaciones de los argumentos existen diferentes librerias por ejemplo:
- beartype - https://beartype.readthedocs.io/en/latest/
- typeguard - https://typeguard.readthedocs.io/en/stable/
Beartype
Tiene un decorador simple que se puede usar para validar los argumentos de una función si esta tiene bien definidos los tipos de datos.
# importar el decorador @beartype
from beartype import beartype
@beartype
def multiplicar_elementos_lista(lista_numeros: list[int | float]) -> int | float:
"""multiplicar todos los elementos de una lista de números.
Args:
lista_numeros (list[int | float]): Una lista de valores numéricos.
Returns:
int | float: La suma de todos los elementos.
Examples:
>>> multiplicar_elementos_lista([1, 2, 3])
6
>>> multiplicar_elementos_lista([1.5, 2.5, 3.5])
13.125
"""
resultado = 1
for elemento in lista_numeros:
resultado = resultado * elemento
return resultado
Ahora al llamar la función con argumentos incorrectos, nos arrojara un error.
por que los argumentos no cumplen con el tipo de datos especificado en la función y ya sabemos directamente que debemos corregir los datos de entrada.
en el caso de no tener la validación de los datos de entrada el error se presentara por que falla la función y deberíamos revisar el código para encontrar el error.
mi_lista = ["a", "b", "c"]
resultado_funcion = multiplicar_elementos_lista(mi_lista)
multiplicar_elementos_lista([1.5, 2.5, 3.5])
Importar funciones de archivos externos
Crear un script de funciones y importarlas en otro archivo es algo básico para poder reutilizar el código.
Esto nos permite tener un código mas limpio, organizado y fácil de mantener.
por ejemplo creo un archivo en la misma carpeta del notebook llamado calculos.py
con la siguiente función:
@beartype
def sumar_elementos_lista(lista_numeros: list[int | float]) -> int | float:
"""sumar todos los elementos de una lista de números.
Args:
lista_numeros (list[int | float]): Una lista de valores numéricos.
Returns:
int | float: La suma de todos los elementos.
Examples:
>>> sumar_elementos_lista([1, 2, 3])
6
>>> sumar_elementos_lista([1.5, 2.5, 3.5])
7.5
"""
resultado = 0.0
for elemento in lista_numeros:
resultado = resultado + elemento
return resultado
se puede ahora llamar la función de dos maneras
import calculos
calculos.sumar_elementos_lista([1.5, 2.5, 3.5])
La forma anterior importa todas las funciones del archivo calculos.py
pero no es recomendable ya que si el archivo tiene muchas funciones, se importaran todas y no sabremos cuales funciones estamos utilizando.
lo recomendable es importar solo la función que necesitamos
from calculos import sumar_elementos_lista
sumar_elementos_lista([1.5, 2.5, 3.5])
Para importar funciones, clases o métodos de scripts externos que estén en otras carpetas una opcion es agregar la ruta de la carpeta al sys.path
para que python pueda encontrar el archivo.
Para mas información de como importar funciones de scripts que estan en otras carpetas revisar la siguiente documentación https://diveintopython.org/learn/classes/import#importing-classes-from-a-parent-directory-with-code-sys-path-code
Referencias
- https://realpython.com/defining-your-own-python-function/
- https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html
- https://docs.python.org/3/library/typing.html
- https://realpython.com/python-type-checking/
- https://beartype.readthedocs.io/en/latest/
- https://typeguard.readthedocs.io/en/stable/
Phd. Jose R. Zapata