MAT281

Aplicaciones de la Matemática en la Ingeniería

Laboratorio 2: Bugs, bugs y más bugs

INSTRUCCIONES

  • Anoten su nombre y rol en la celda siguiente.
  • Desarrollen los problemas de manera secuencial.
  • Guarden constantemente con Ctr-S para evitar sorpresas.
  • Ejecuten cada celda de código utilizando Ctr-Enter
  • Pueden utilizar tabulación para obtener ayuda de ipython notebook.

In [1]:
#Configuracion para recargar módulos y librerías cada vez 
%reload_ext autoreload
%autoreload 2
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
%matplotlib inline
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
from mat281_code.lab import *
from IPython.core.display import HTML
from matplotlib import pyplot as plt

HTML(open("style/mat281.css", "r").read())

alumno_1 = (r"Sebastián Flores", "2004001-7") # FIX ME
alumno_2 = (r"María José Vargas", "2004007-8") # FIX ME

HTML(greetings(alumno_1, alumno_2))


Out[1]:
Alumno: Sebastián Flores rol: 2004001-7
Alumno: María José Vargas rol: 2004007-8
Este es un laboratorio práctico y de aprendizaje:Tome apuntes, intente lo sugerido y pruebe otros cambios.¡Buena suerte!

SOBRE EL LABORATORIO

Existen 4 desafíos:

  • En todos los casos, documenten lo encontrado. Escriban como un #comentario o """comentario""" los errores que vayan detectando.
  • En el desafío 1: Ejecute la celda, lea el output y arregle el código. Comente los 5 errores en la misma celda.
  • En el desafío 2: Ejecute la celda y encuentre los errores utilizando print. Comente los 3 errores en la misma celda.
  • En el desafío 3: Ejecute el archivo ./mat281_code/desafio_3.py, y encuentre los 3 errores utilizando pdb.set_trace()
  • En el desafío 4: Ejecute el archivo ./mat281_code/desafio_4.py, y encuentre los 3 errores utilizando IPython.embed()

AL TERMINAR

Enviar por correo, con copia a todos los integrantes del grupo, los siguientes archivos:

  • Bugs.ipynb (modificado)
  • desafio_3.py (modificado).
  • desafio_4.py (modificado).

Introducción

Debugging: Eliminación de errores de un programa computacional.

  • Fácilmente 40-60% del tiempo utilizado en la creación de un programa.
  • Ningún programa está excento de bugs/errores.
  • Imposible garantizar utilización 100% segura por parte del usuario.
  • Programas computaciones tienen inconsistencias/errores de implementación.
  • ¡Hardware también puede tener errores!

1. Introducción

¿Porqué se le llama bugs?

Existen registros en la correspondencia de Thomas Edisson, en 1848, hablaba de bugs para referirse a errores en sus inventos. El término se utilizaba ocasionalmente en el dominio informático. En 1947, el ordenador Mark II presentaba un error. Al buscar el origen del error, los técnicos encontraron una polilla, que se había introducido en la máquina.

Toda la historia en el siguiente enlace a wikipedia (ingles).

2. Técnicas para Debug

  1. Leer output entregado por python para posibles errores
  2. Utilizando print
  3. Utilizando pdb: python debugger
  4. Lanzamiento condicional de Ipython embed

2.1 Debug: Leer output de errores

Cuando el programa no funciona y entrega un error normalmente es fácil solucionarlo. El mensaje de error entregará: la línea donde se detecta el error y el tipo de error.

PROS:

  • Explicativo
  • Fácil de detectar y reparar

CONTRA:

  • No todos los errores arrojan error, particularmente los errores conceptuales.

2.1.1 Lista de errores comunes

Los errores más comunes en un programa son los siguientes:

  • SyntaxError:
    • Parentésis no cierran adecuadamente.
    • Faltan comillas en un string.
    • Falta dos puntos para definir un bloque if-elif-ese, una función, o un ciclo.
  • NameError:
    • Se está usando una variable que no existe (nombre mal escrito o se define después de donde es utilizada)
    • Todavía no se ha definido la función o variable.
    • No se ha importado el módulo requerido
  • IOError: El archivo a abrir no existe.
  • KeyError: La llave no existe en el diccionario.
  • TypeError: La función no puede aplicarse sobre el objeto.
  • IndentationError: Los bloques de código no están bien definidos. Revisar la indentación.

Un error clásico y que es dificil de detectar es la asignación involuntaria: Escribir $a=b$ cuando realmente se quiere testear la igualdad $a==b$.

Desafío 1

Arregle el siguiente programa en python para que funcione. Contiene 5 errores. Anote los errores como comentarios en el código.

Al ejecutar sin errores, debería regresar el valor 0.333384348536


In [7]:
import numpy as np
def promedio_positivo(a):
    pos_mean = a[a>0].mean()
    return pos_mean

N = 100
x = np.linspace(-1,1,N)
y = 0.5 - x**2   # No cambiar esta linea
print promedio_positivo(y)

# Error 1:
# Error 2: 
# Error 3:
# Error 4:
# Error 5:


0.333384348536

2.2 Debug: Utilización de print

Utilizar print es la técnica más sencilla y habitual, apropiada si los errores son sencillos.

PRO:

  • Fácil y rápido de implementar.
  • Permite inspeccionar valores de variable a lo largo de todo un programa

CONTRA:

  • Requiere escribir expresiones más complicadas para estudiar más de una variable simultáneamente.
  • Impresión no ayuda para estudiar datos multidimensionales (arreglos, matrices, diccionarios grandes).
  • Eliminacion de múltiples print puede ser compleja en programa grande.
  • Inapropiado si la ejecución del programa tarde demasiado (por ejemplo si tiene que leer un archivo de disco), pues habitualmente se van insertando prints a lo largo de varias ejecuciones "persiguiendo" el valor de una variable.

Consejo

Si se desea inspeccionar la variable mi_variable_con_error, utilice

print "!!!", mi_variable_con_error

De esa forma será más facil ver en el output donde está la variable impresa, y luego de solucionar el bug, será también más fácil eliminar las expresiones print que han sido insertadas para debugear (no se confundirá con los print que sí son necesarios y naturales al programa).

Desafío 2

Detecte porqué el programa se comporta de manera inadecuada, utilizando print donde parezca adecuado.

No elimine los print que usted haya introducido, sólo coméntelos con #.

Arregle el desperfecto e indique con un comentario en el código donde estaba el error.


In [ ]:
def fibonacci(n):
    """
    Debe regresar la lista con los primeros n numeros de fibonacci.
    Para n<1, regresar [].
    Para n=1, regresar [1].
    Para n=2, regresar [1,1].
    Para n=3, regresar [1,1,2].
    Para n=4, regresar [1,1,2,3].
    Y sucesivamente
    """
    a = 1
    b = 1
    fib = [a,b]
    count = 2
    if n<1:
        return []
    if n=1:
        return [1]
    while count <= n:
        aux = a
        a = b
        b = aux + b
        count += 1
        fib.append(aux)
    return fib

print "fibonacci(-1):", fibonacci(-1) # Deberia ser []
print "fibonacci(0):", fibonacci(0) # Deberia ser []
print "fibonacci(1):", fibonacci(1) # Deberia ser [1]
print "fibonacci(2):", fibonacci(2) # Deberia ser [1,1]
print "fibonacci(3):", fibonacci(3) # Deberia ser [1,1,2]
print "fibonacci(5):", fibonacci(5) # Deberia ser [1,1,2,3,5]
print "fibonacci(10):", fibonacci(10) # Deberia ser ...

"""
ERRORES DETECTADOS:
1)
2)
3)
"""

2.3 Debug: Utilización de pdb

Python trae un debugger por defecto: pdb (python debugger), que guarda similaridades con gdb (el debugger de C).

PRO:

  • Permite inspeccionar el estado real de la máquina en un instante dado.
  • Permite ejecutar las instrucciones siguientes.

CONTRA:

  • Requiere conocer comandos.
  • No tiene completación por tabulación como IPython.

El funcionamiento de pdb similar a los breakpoints en matlab.

Se debe realizar lo siguiente:

  1. Importar la librería

     import pdb
  2. Solicitar que se ejecute la inspección en las líneas que potencialmente tienen el error. Para ello es necesario insertar en una nueva línea, con el alineamiento adecuado, lo siguiente:

     pdb.set_trace()
  3. Ejecutar el programa como se realizaría normalmente:

     $ python mi_programa_con_error.py

Al realizar las acciones anteriores, pdb ejecuta todas las instrucciones hasta el primer pdb.set_trace() y regresa el terminal al usuario, para que inspeccione las variables y revise el código. Los comandos principales a memorizar son:

  • n + Enter: Permite ejecutar la siguiente instrucción (línea).
  • c + Enter: Permite continar la ejecución del programa, hasta el próximo pdb.set_trace() o el final del programa.
  • l + Enter: Permite ver qué línea esta actualmente en ejecución.
  • p mi_variable + Enter: Imprime la variable mi_variable.
  • Enter: Ejecuta la última accion realizada en pdb.

2.3.1 Ejemplo

Ejecute el archivo ./mat281_code/ejemplo_pdb.py y siga las instrucciones que obtendrá:

 $ python  ./mat281_code/ejemplo_pdb.py

Desafío 3

Utilice pdb para debuggear el archivo ./mat281_code/desafio_3.py.

El desafío 3 consiste en hallar 3 errores en la implementación defectuosa del método de la secante: link wikipedia

Instrucciones:

  • Después de utilizar pdb.set_trace() no borre la línea creada, solo coméntela con # para poder revisar su utilización.
  • Anote en la celda a continuación los errores que ha encontrado en el archivo ./mat281_code/desafio_3.py

In [ ]:
# Desafio 3 - Errores encontrados en ./mat281_code/desafio_3.py
"""
Se detectaron los siguientes errores:
1- FIX ME - COMENTAR AQUI
2- FIX ME - COMENTAR AQUI
3- FIX ME - COMENTAR AQUI
"""

2.4 Debug: Utilización de IPython

PRO:

  • Permite inspeccionar el estado real de la máquina en un instante dado.
  • Permite calcular cualquier expresión, de manera sencilla.
  • Permite graficar, imprimir matrices, etc.
  • Tiene completación por tabulación de IPython.
  • Tiene todo el poder de IPython (%who, %whos, etc.)

CONTRA:

  • No permite avanzar a la próxima instrucción como n+Enter en pdb.

El funcionamiento de IPython es el siguiente:

  1. Importar la librería

     import IPython
  2. Solicitar que se ejecute la inspección en las líneas que potencialmente tienen el error. Para ello es necesario insertar en una nueva línea, con el alineamiento adecuado, lo siguiente:

     IPython.embed()
  3. Ejecutar el programa como se realizaría normalmente:

     $ python mi_programa_con_error.py

Al realizar las acciones anteriores, python ejecuta todas las instrucciones hasta el primer IPython.embed() y regresa el terminal interactivo IPython al usuario en el punto seleccionado, para que inspeccione las variables y revise el código.

Para salir de IPython es necesario utilizar Ctr+d.

2.3.1 Ejemplo

Ejecute el archivo ./mat281_code/ejemplo_ipython.py y siga las instrucciones que obtendrá:

 $ python  ./mat281_code/ejemplo_ipython.py

Desafío 4

Utilice IPython para debuggear el archivo ./mat281_code/desafio_4.py.

El desafío 4 consiste en reparar una implementación defectuosa del método de bisección: link wikipedia

Instrucciones:

  • Después de utilizar IPython.embed() no borre la línea, solo coméntela con # para poder revisar su utilización.
  • Anote en la celda a continuación los errores que ha encontrado en el archivo ./mat281_code/desafio_4.py

In [ ]:
# Desafio 4 - Errores encontrados en ./mat281_code/desafio_4.py
"""
Se detectaron los siguientes errores:
1- FIX ME - COMENTAR AQUI
2- FIX ME - COMENTAR AQUI
3- FIX ME - COMENTAR AQUI
"""

Resumen

El siguiente blog tiene una imagen que resume gran parte de los errores más comunes: