{ "metadata": { "name": "" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Parte 5 - Buenas pr\u00e1cticas" ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Correcci\u00f3n de c\u00f3digo y pruebas" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Escribir pruebas tiene muchas ventajas:\n", "\n", "* Comprobaci\u00f3n de que lo que funcionaba antes sigue funcionando ahora\n", "* Dan una idea de c\u00f3mo se usa el c\u00f3digo\n", "* Ayudan a descubrir casos raros y fallos ocultos" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from maxima import find_maxima" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 1 }, { "cell_type": "code", "collapsed": false, "input": [ "find_maxima([1, 2, 3, 2, 4, 1])" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 2, "text": [ "[2, 4]" ] } ], "prompt_number": 2 }, { "cell_type": "code", "collapsed": false, "input": [ "%run test_maxima.py" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 3 }, { "cell_type": "code", "collapsed": false, "input": [ "find_maxima([1, 2, 1, 2, 3])" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 4, "text": [ "[1, 4]" ] } ], "prompt_number": 4 }, { "cell_type": "code", "collapsed": false, "input": [ "find_maxima([1, 1, 1])" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 5, "text": [ "[]" ] } ], "prompt_number": 5 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Nociones de optimizaci\u00f3n de c\u00f3digo" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Hay un par de trucos que podemos utilizar en IPython para medir el rendimiento del c\u00f3digo. El primero es usa la *magic function* `%%timeit`, que mide cu\u00e1nto tiempo tarda en ejecutarse una celda." ] }, { "cell_type": "code", "collapsed": false, "input": [ "import numpy as np" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 14 }, { "cell_type": "code", "collapsed": false, "input": [ "a = np.random.randn(100, 200)\n", "b = np.random.randn(100, 200)\n", "c = np.zeros_like(a)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 15 }, { "cell_type": "code", "collapsed": false, "input": [ "%%timeit\n", "assert a.shape == b.shape\n", "N = a.shape[0]\n", "M = a.shape[1]\n", "for i in range(N):\n", " for j in range(M):\n", " c[i, j] = a[i, j] + b[i, j]" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "100 loops, best of 3: 17.2 ms per loop\n" ] } ], "prompt_number": 16 }, { "cell_type": "code", "collapsed": false, "input": [ "%%timeit\n", "c = a + b" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "100000 loops, best of 3: 18.4 \u00b5s per loop\n" ] } ], "prompt_number": 17 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Observamos que la versi\u00f3n vectorizada con NumPy es, en mi ordenador, cerca de 1000 veces m\u00e1s r\u00e1pida. Aun as\u00ed, en cuanto empecemos a escribir c\u00f3digo num\u00e9rico de cierta magnitud nuestro programa empezar\u00e1 a ir lento. Puede ser que lleguemos a unos tiempos de ejecuci\u00f3n inaceptables (8 horas para ejecutar un programa de un trabajo de clase por ejemplo). \u00bfC\u00f3mo hacer que vaya m\u00e1s r\u00e1pido?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Existen unas herramientas llamadas *profilers* que ejecutan nuestro programa y analizan cu\u00e1nto tiempo tarda cada funci\u00f3n dentro de nuestro programa. Podemos usar esta valiosa informaci\u00f3n para escoger qu\u00e9 partes de nuestro programa tenemos que optimizar *y qu\u00e9 partes **no** tenemos que optimizar*." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Por ejemplo, supongamos que quiero reproducir la gr\u00e1fica de la ecuaci\u00f3n de Kepler que aparece en la Wikipedia:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from IPython.display import HTML\n", "HTML('')" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "" ], "metadata": {}, "output_type": "pyout", "prompt_number": 18, "text": [ "\u201c Premature optimization is the root of all evil\u201d.
\n", "\n", "Donald E. Knuth