Lección 39 de 45 · Calidad y depuración

Depuración

Depurar no consiste en adivinar la línea correcta: consiste en reducir la incertidumbre hasta poder explicar por qué aparece el resultado incorrecto.

DebuggingHipótesis y observaciónTrazas
Índice · Lección 39/45
Cuando algo falla, tu primera tarea no es arreglarlo: es poder repetirlo

Un fallo reproducible te da un laboratorio. Si sabes qué entrada lo provoca y qué esperabas ver, puedes observar el programa sin perseguir síntomas cambiantes.

Usaremos una secuencia muy concreta: reproduce → reduce → observa → formula una hipótesis → cambia una sola cosa.

Evidencia de aprendizaje

Formular una hipótesis comprobable, observar la variable adecuada y hacer un cambio mínimo.

Fija una entrada pequeña que muestre claramente la diferencia

Esperamos 150, pero obtenemos 175
def precio_final(precio, descuento):
    return precio - descuento

print(precio_final(200, 25))

La entrada 200, 25 revela el problema: descuento representa un porcentaje, pero la función lo resta como si fueran euros.

Con un caso pequeño puedes escribir una frase precisa: «con 200 y 25%, espero 150».

Una traza debe responder una pregunta, no anunciar que “pasaste por aquí”

Observa el valor intermedio que decide el resultado
def precio_final(precio, descuento):
    importe_descuento = precio * descuento / 100
    print("importe_descuento:", importe_descuento)
    return precio - importe_descuento

print(precio_final(200, 25))

La traza muestra el dato que quieres verificar. Si aparece 50.0, sabes que el cálculo porcentual es coherente antes de mirar el return.

Pregunta antes de imprimir: «¿qué valor, si lo conociera, descartaría una de mis hipótesis?». Imprime ese valor.

Cambiar varias cosas a la vez destruye información

Si modificas la fórmula, renombras variables, cambias la entrada y reorganizas la función en el mismo intento, un resultado correcto no te dice qué cambio resolvió el fallo.

Haz el cambio mínimo que comprueba tu hipótesis. Cuando el comportamiento sea correcto, entonces limpia y mejora el código.

Depura como una investigación, no como una lotería

  1. Esperado vs. obtenido: para precio_final(200, 25) esperas 150, pero obtienes 175.
  2. Variable a observar: importe_descuento.
  3. Hipótesis: quizá 25 se está tratando como euros en vez de como porcentaje.
  4. Cambio mínimo: corrige únicamente el cálculo del importe del descuento y vuelve a probar.
¿Por qué esta hipótesis es mejor que “la función está mal”?

Porque es concreta y comprobable: predice que importe_descuento debería ser 50 y actualmente vale 25.

Comprueba la hipótesis con el cambio mínimo. No reescribas la función ni cambies la entrada de prueba.

Salida esperada
150.0
debug.py
La salida aparecerá aquí.

Necesito una pista
  • 25 representa un porcentaje. ¿Cuánto es el 25% de 200?
  • El importe se puede calcular como precio * descuento / 100.
Ver una solución razonada
def precio_final(precio, descuento):
    importe_descuento = precio * descuento / 100
    return precio - importe_descuento

print(precio_final(200, 25))

Un debugger es una herramienta; el método de depuración sigue siendo el mismo

Un depurador con breakpoints permite detener la ejecución e inspeccionar variables sin llenar el código de print(). Es muy útil, pero no decide qué observar por ti. La pregunta y la hipótesis siguen siendo tuyas.

  • Reproduce el fallo con una entrada concreta.
  • Reduce el caso hasta que la diferencia sea fácil de ver.
  • Observa datos relacionados con una hipótesis específica.
  • Cambia una sola causa probable y vuelve a ejecutar.
Puedes continuar si...

ante un resultado incorrecto sabes escribir primero «esperaba X, obtuve Y con esta entrada» antes de tocar el código.