Desarrollo, conocimientos complementarios
Introducción
Aquí encontrará algunos complementos que nos han resultado muy útiles. Esta selección restringida de técnicas complementarias es muy empírica. No dude en escribirnos para animarnos a ampliarla de cara a una posible reedición del libro.
Manipulación de datos con Pandas
Encontrará una lista de instrucciones de Pandas con breves ejemplos de sintaxis en el capítulo Prontuario, al final del libro.
1. Introducción a Pandas
En 2023, se podía leer en el sitio web de Pandas (en inglés; traducción propia): «Pandas es una herramienta de código abierto de análisis y manipulación de datos, rápida, potente, flexible y fácil de usar, basada en el lenguaje de programación Python».
Además, se destacaba que Pandas proporciona las dos características siguientes:
-
«Un objeto DataFrame rápido y eficaz para la manipulación de datos con indexación integrada».
-
«Herramientas para leer y escribir datos entre estructuras de datos en memoria y distintos formatos: archivos CSV y de texto, Microsoft Excel, bases de datos SQL y el formato rápido HDF5».
2. Lectura y transformación de un archivo csv con Pandas
Vamos a intentar leer un archivo .csv (disponible en el sitio web de ENI, pero usted puede crear fácilmente un archivo equivalente).
Para crear este archivo, extrajimos datos de texto de una página del sitio FUN, una plataforma francesa de cursos en línea; esta acción de tomar texto de una página web suele denominarse scraping. El resultado no era muy legible, así que utilizamos Pandas para limpiar rápidamente el contenido del archivo. Es una oportunidad para utilizar un mínimo de Pandas y un poco de programación funcional.
Existen varios paquetes dedicados al scraping, como Beautiful Soup y scrapy, que ayudan a seleccionar y limpiar los datos extraídos de las páginas web. El siguiente código no pretende sustituir a estas soluciones profesionales.
# pandas, csv, transformaciones por map en un archivo
# scraping del sitio FUN
# leer un csv con pandas, procesar el dataframe, guardar y comprobar
el resultado
import pandas as pd
ruta_csv = "dataFUN.csv"
df = pd.read_csv(path_csv, sep=' ') # preste atención a la elección
#...
Validar y asignar tipos simples con total seguridad
Vamos a utilizar un paquete bastante antiguo, de forma muy parcial, invocando los controles de tipo que proporciona: el package hug.
# !pip install hug
# Asignación, validación y traducción de tipos simples:
# import de los tipos
from hug import types as typ_h
Creemos una función genérica que valide, asigne y traduzca un valor al formato requerido. Usando las sentencias try, except y raise, hacemos que el programa «se rompa» si el valor propuesto no es conforme. Esta técnica es otra forma de conseguir lo que antes hemos llamado «morir rápido».
def valida(x,f_tipo) :
try :
x = f_tipo(x)
return x
except :
lib = "tipo no válido, necesita un: " + f_tipo.__doc__
print(lib)
raise Exception(lib)
Vamos a comprobar si un valor representa un número entero válido.
# asignación de un número entero válido
x = valida(10,typ_h.number)
print(x, tipo(x))
--| 10 <class 'int'>
x = valida("100",typ_h.number)
print(x, tipo(x))
--| 100 <class 'int>
Esto «bloquea» el programa:
x = valida("100.1",typ_h.number)
x = valida("eee",typ_h.number)
Se genera...
Gestión de las excepciones, de un vistazo
El tratamiento de excepciones (try ... except), que permite «morir rápido», se utiliza tanto al principio del proceso de codificación para comprobar que el programa funciona de verdad como más adelante en el proceso para atrapar esas excepciones, tratarlas y registrarlas sin «romper» el programa, que ya ha sido depurado a fondo. De este modo, el programa no se detiene durante su funcionamiento en condiciones reales, a pesar de que, durante su desarrollo, se fomentó, precisamente, el comportamiento contrario. Lo bueno de esto es que la misma técnica de tratamiento de excepciones se aplica durante las dos fases del proceso (desarrollo y puesta en producción).
Python maneja una jerarquía de errores comunes, denominada exception hierachy en su documentación. Si sospecha que su código puede contener alguno de estos tipos de error, puede tratarlos individualmente. El siguiente código detecta seis tipos de error.
try:
# código probado
pass# no hace nada, es un placeholder
# donde pones tu propio código
except (RuntimeError,
ValueError,
ZeroDivisionError,
ArithmeticError...
Ordenación recursiva de un vector de datos (lista)
Vamos a implementar la ordenación de una lista. Obviamente, las listas tienen un método de ordenación, que ordena la lista in situ, es decir, se pierde el orden original de la lista (pero no se duplica, para ahorrar espacio).
La idea es la siguiente: tomamos el primer elemento de la lista y posicionamos todos los elementos menores antes de él, y los demás, después, tras haber realizado esta misma operación en ambas listas (la de los menores y la de los mayores). Como estamos llamando a nuestra función desde dentro de ella misma, estamos en un proceso recursivo. El peligro de un proceso así es que nunca se detenga. Para pararlo, establecemos un criterio, una excepción; en este caso, una prueba sobre la longitud de la lista: la recursividad se detendrá cuando la lista esté vacía.
Esto nos da el algoritmo clásico siguiente:
def ordena_R(lista): if len(lista) > 1:
e _ = lista[0] # valor del primer elemento
l = lista[1: ] # el resto de la lista
l_izquierda = [e for e in l if e <= e_] # define lista izquierda
...
Gestión de fechas de forma estandarizada y eficaz, datetime y pytz
Se puede acceder a las fechas gestionando timezones y manipularlas de diferentes formas.
from datetime import datetime as dt
importar pytz
d = dt.now()
print("formato completo: ",d)
--| formato completo: 2023-10-22 00:58:47.016094
print("en cadena de caracteres con separador de espacios: ",
d.isoformat(sep " ")
--| en cadena de caracteres con separador de espacios:
2023-10-22 00:58:47.016094
print("el día de la semana: ", d.isoweekday())
--| día de la semana: 7
print("Versión Unix de la hora, útil para cálculos: ",d.timestamp())
--| Versión Unix de la hora, útil para cálculos: 1697929127.016094
UTC = pytz.utc
d_utc = dt.now(UTC)
print("fecha y hora en utc: ", d_utc.isoformat(sep=" "))
--| fecha y hora en utc: 2023-10-21 22:58:51.613521+00:00
Si existe una diferencia horaria de una o varias horas entre la hora local y la hora UTC, puede gestionarla según los requisitos de su aplicación.
UTC (tiempo universal coordinado, en inglés Coordinated Universal Time) es una escala de tiempo utilizada como referencia internacional. Se basa en el tiempo atómico internacional (TAI) y se ajusta para tener en cuenta...
Un programa utilizable desde la línea de comandos
Existen varias técnicas para pasar parámetros a un programa Python que se utiliza en la línea de comandos. Le sugerimos que use el package click para ello. Sus características se implementan usando decoradores, lo que significa que puede dividir su trabajo en dos pasos: crear la característica que desea exponer y, a continuación, hacer que esté disponible en la línea de comandos, añadiendo cualquier ayuda que necesite.
El siguiente programa escribe en mayúsculas la primera letra de una palabra o frase introducida.
# Documentación click :
# https://click.palletsprojects.com/en/8.1.x/
import click
@click.command()
@click.option('--expresión',
prompt='Expresión cuya inicial debe ponerse en mayúsculas',
help='La inicial se pondrá en mayúsculas, prueba con la palabra:
evaluar')
def cap(expresión):
click.echo(f'Aquí está el resultado: \n{expresión.capitalize()}')
if __name__ == '__main__':
cap()
Este es el diálogo interactivo que puede obtener a través de la línea de comandos (ejecutar el archivo python click_cap.py...