class: center, middle, inverse, title-slide .title[ #
Introducción a Python
] .subtitle[ ##
Clase 8: Errores y Debugging
] .author[ ### Daniel Miles Touya
Máster en Análisis de Datos · UdelaR-Uvigo
] .date[ ### 24 abril 2026 ] --- --- class: inverse, middle .huge[Clase 8] <br> ## Errores y excepciones --- # Guía de lectura .smallest[ Hasta ahora: - escribimos código - ejecutamos código ] -- .div_bloque[ Problema: > el código falla ] --- # Idea clave .div_bloque[ Los errores son objetos. ] -- .smallest[ Heredan de: BaseException ] --- # Ejemplo ```python try: 1 / 0 except ZeroDivisionError as e: print(type(e)) print(e) ``` --- # Idea clave .div_bloque[ Python crea un objeto error y lo lanza. ] --- # Jerarquía .smallest[ Ejemplo: ] - Exception - TypeError - ValueError - KeyError - IndexError --- # Idea importante .div_bloque[ Los errores tienen herencia. ] --- # isinstance ```python try: 1 / 0 except ZeroDivisionError as e: print(isinstance(e, Exception)) ``` -- .smallest[ True ] --- # Tipos más comunes .smallest[ - TypeError - ValueError - KeyError - AttributeError - IndexError ] --- # TypeError ```python "precio: " + 42 ``` -- .smallest[ Tipos incompatibles ] --- # ValueError ```python int("abc") ``` -- .smallest[ Tipo correcto, valor incorrecto ] --- # KeyError ```python d = {"a": 1} d["b"] ``` --- # AttributeError ```python x = 42 x.append(1) ``` --- # IndexError ```python [1, 2, 3][10] ``` --- # Idea clave .div_bloque[ Cada error indica un tipo de problema. ] --- # Traceback .div_bloque[ Cuando falla, Python muestra un traceback. ] --- # Idea clave .div_bloque[ El traceback es el stack. ] -- .smallest[ (Clase 6b) ] --- # Cómo leerlo .div_bloque[ Leer de abajo a arriba. ] --- # Ejemplo .smallest[ Error: ] ```python def f(x): return x * 2 f("hola") ``` --- # Interpretación .smallest[ - error: TypeError - línea concreta - función donde ocurre ] --- # Error típico .div_bloque[ Leer el traceback mal. ] -- .smallest[ Siempre empezar por abajo ] --- # Caso real (pandas) ```python import pandas as pd df = pd.DataFrame({"Ventas": [1,2,3]}) df["ventas"] ``` -- .div_bloque.small[ .hi-red[Error:] KeyError ] --- # Idea clave .div_bloque[ Python distingue mayúsculas/minúsculas. ] --- # Qué debes entender .smallest[ - errores como objetos - tipos de errores - jerarquía - traceback ] -- .div_bloque[ .hi-blue[Idea final:] > Entender errores = entender cómo falla el código. ] --- # Parte II · try / except class: inverse, middle .huge[Controlar errores] <br> ## Manejo de excepciones --- # Idea clave .div_bloque[ Podemos capturar errores. ] -- .smallest[ Evitar que el programa se rompa ] --- # Sintaxis básica ```python try: x = 1 / 0 except ZeroDivisionError: print("Error") ``` --- # Flujo .smallest[ 1. try 2. ocurre error 3. salta a except ] --- # Capturar el error ```python try: 1 / 0 except ZeroDivisionError as e: print(e) ``` -- .smallest[ Podemos usar el objeto error ] --- # Múltiples except ```python try: x = int("abc") except ValueError: print("valor incorrecto") except TypeError: print("tipo incorrecto") ``` --- # Except genérico ```python try: x = int("abc") except Exception: print("error") ``` -- .div_bloque.small[ .hi-red[Evitar abuso] ] --- # Idea importante .div_bloque[ No usar except vacío. ] ```python except: pass ``` -- .smallest[ Oculta errores ] --- # else .div_bloque[ Se ejecuta si NO hay error. ] --- ```python try: x = int("10") except ValueError: print("error") else: print("todo bien") ``` --- # finally .div_bloque[ Siempre se ejecuta. ] --- ```python try: f = open("file.txt") except FileNotFoundError: print("no existe") finally: print("fin") ``` --- # Uso típico .div_bloque[ Liberar recursos. ] --- # Ejemplo completo ```python try: x = int("5") except ValueError: print("error") else: print("ok") finally: print("fin") ``` --- # Lanzar errores .div_bloque[ Podemos crear errores. ] --- ```python def f(x): if x < 0: raise ValueError("x negativo") ``` --- # Idea clave .div_bloque[ raise crea un error manualmente ] --- # Encadenar errores .smallest[ (idea avanzada) ] ```python try: 1 / 0 except ZeroDivisionError as e: raise ValueError("fallo") from e ``` --- # Mini ejercicio 1 .smallest[ ¿Qué imprime? ] ```python try: x = int("abc") except ValueError: print("error") else: print("ok") ``` --- # Mini ejercicio 2 .smallest[ ¿Qué pasa? ] ```python try: x = 1 / 0 finally: print("fin") ``` --- # Mini ejercicio 3 .smallest[ Corrige: ] ```python try: x = int("abc") except: pass ``` --- # Patrón real .div_bloque[ Validación de inputs ] --- ```python def convertir(x): try: return int(x) except ValueError: return None ``` --- # Error típico .div_bloque[ Capturar demasiado. ] -- .smallest[ Pierdes información del error ] --- # Leer código IA .div_bloque[ Cuando veas try: ] -- .smallest[ - qué error espera - qué hace si ocurre ] --- # Qué debes entender .smallest[ - try / except - else / finally - raise - buenas prácticas ] -- .div_bloque[ .hi-blue[Idea final:] > Manejar errores permite escribir código robusto. ] --- # Parte III · Debugging class: inverse, middle .huge[Encontrar errores] <br> ## Debugging --- # Idea clave .div_bloque[ Programar = escribir + depurar ] -- .smallest[ Debugging es parte central del trabajo ] --- # Problema típico .div_bloque[ El código no funciona ] -- .smallest[ ¿Por qué? ] --- # Estrategia básica .div_bloque[ 1. reproducir error 2. leer traceback 3. aislar problema ] --- # Paso 1 · reproducir .smallest[ Siempre poder ejecutar el error ] -- .div_bloque.small[ .hi-red[Clave:] si no se reproduce, no se arregla ] --- # Paso 2 · traceback .smallest[ Leer de abajo a arriba ] --- ```python def f(x): return g(x) def g(x): return x + "a" f(3) ``` --- # Interpretación .smallest[ - error: TypeError - línea exacta - función donde ocurre ] --- # Paso 3 · aislar .div_bloque[ Reducir el problema ] -- .smallest[ Eliminar partes hasta encontrar el error ] --- # Técnica print ```python def f(x): print("x =", x) return x + 1 ``` -- .smallest[ Ver valores intermedios ] --- # Técnica paso a paso .smallest[ Ejecutar línea a línea ] --- # Ejemplo ```python a = 10 b = "5" print(a + b) ``` -- .div_bloque.small[ .hi-red[Error:] TypeError ] --- # Solución ```python print(a + int(b)) ``` --- # Error lógico .div_bloque[ No siempre hay error visible ] --- ```python def media(a, b): return a + b / 2 ``` -- .smallest[ Error de lógica ] --- # Corrección ```python return (a + b) / 2 ``` --- # Mini ejercicio 1 .smallest[ Encuentra el error: ] ```python def f(x): return x * 2 print(f("3")) ``` --- # Mini ejercicio 2 .smallest[ ¿Qué pasa aquí? ] ```python d = {"a": 1} print(d["b"]) ``` --- # Mini ejercicio 3 .smallest[ Corrige: ] ```python def suma(a, b): return a + b print(suma(2)) ``` --- # Uso de dir() ```python import os print(dir(os)) ``` -- .smallest[ Explorar objetos ] --- # Uso de help() ```python help(len) ``` -- .smallest[ Documentación integrada ] --- # Debugging en pandas ```python df["ventas"] ``` -- .smallest[ KeyError si columna no existe ] --- # Idea clave .div_bloque[ Errores ≠ fracaso ] -- .div_bloque.small[ .hi-blue[Idea:] son información ] --- # Buenas prácticas .smallest[ - mensajes claros - código simple - probar por partes ] --- # Leer código IA .div_bloque[ Cuando algo falla: ] -- .smallest[ - identifica input - identifica output - busca punto de fallo ] --- # Qué debes entender .smallest[ - cómo encontrar errores - traceback - debugging básico - errores lógicos ] -- .div_bloque[ .hi-blue[Idea final:] > Debugging es entender qué está pasando en el código. ] --- # Parte IV · Logging class: inverse, middle .huge[Debugging profesional] <br> ## Logging --- # Motivación .div_bloque[ print() no es suficiente ] -- .smallest[ Problemas: - no se puede controlar - no se puede desactivar fácilmente - ensucia el código ] --- # Solución .div_bloque[ Usar logging ] --- # Importación ```python import logging ``` --- # Uso básico ```python import logging logging.warning("Cuidado") ``` -- .smallest[ WARNING:root:Cuidado ] --- # Niveles de logging .smallest[ - DEBUG - INFO - WARNING - ERROR - CRITICAL ] --- # Ejemplo ```python logging.debug("debug") logging.info("info") logging.warning("warning") logging.error("error") logging.critical("critical") ``` --- # Idea clave .div_bloque[ Cada mensaje tiene nivel ] --- # Configuración ```python logging.basicConfig(level=logging.DEBUG) ``` -- .smallest[ Ahora se ven todos los niveles ] --- # Ejemplo completo ```python import logging logging.basicConfig(level=logging.INFO) logging.debug("debug") logging.info("info") logging.warning("warning") ``` --- # Uso en funciones ```python def dividir(a, b): logging.info("Dividiendo") return a / b ``` --- # Logging + errores ```python def dividir(a, b): try: return a / b except ZeroDivisionError: logging.error("División por cero") ``` --- # Mini ejercicio 1 .smallest[ ¿Qué se imprime? ] ```python logging.basicConfig(level=logging.WARNING) logging.info("info") logging.warning("warning") ``` --- # Mini ejercicio 2 .smallest[ Añade logging: ] ```python def f(x): return x * 2 ``` --- # Mini ejercicio 3 .smallest[ Corrige: ] ```python print("error:", e) ``` -- .div_bloque.small[ .hi-blue[Mejor:] logging.error(...) ] --- # Ventajas .smallest[ - control de mensajes - niveles - uso en producción ] --- # Idea clave .div_bloque[ Logging separa código y diagnóstico ] --- # Comparación .smallest[ print(): - rápido - informal ] -- .smallest[ logging: - estructurado - profesional ] --- # Patrón real ```python import logging logging.basicConfig(level=logging.INFO) def procesar(x): logging.info(f"Procesando {x}") return x * 2 ``` --- # Leer código IA .div_bloque[ Cuando veas logging: ] -- .smallest[ - qué información registra - en qué nivel ] --- # Qué debes entender .smallest[ - qué es logging - niveles - configuración - uso en funciones ] -- .div_bloque[ .hi-blue[Idea final:] > Logging permite monitorizar el código de forma profesional. ]