Cap.1: Haciendo cálculos con fórmulas

Ene 13, 2015

Basado en las láminas hechas por Hans Petter Langtangen como apoyo al libro de texto A Primer on Scientific Programming with Python 4ta edición, Springer 2014.

http://hplgit.github.io/scipro-primer/slides/index.html

Francisco Palm

¿Porqué programar?

Para preparar a la humanidad para los próximos 100 años, necesitamos que mas de nuestras niñas y nuestros niños aprendan destrezas de programación, sin importar su futura profesión. Junto con leer y escribir, la habilidad de programar va a definir que es una persona educada. Salman Khan Fundador de la Khan Academy


Los programadores del mañana serán los magos del futuro. Parecerá que tienes poderes mágicos comparado con todos los demás. Gabe Newell, Fundador y Presidente de Valve.

La estrategia de aprendizaje es basada en ejemplos

  • Se presenta un caso (ejemplo)

  • Se presenta el programa completo

  • Se analiza línea por línea

  • Simula los programas a mano (¡se la computadora!)

Evaluando una fórmula matemática

Altura de una pelota en movimiento vertical.

$$ y(t) = v_0t- \frac{1}{2}gt^2 $$

donde

  • $y$ es la altura (posición) como función del tiempo $t$

  • $v_0$ es la velocidad inicial en $t=0$

  • $g$ es la aceleración de la gravedad

Tarea: dados $v_0$, $g$ y $t$, calcular $y$.

¿Usar una calculadora? ¡Si un programa es mucho mas poderoso!

¿Qué es un programa?

Una secuencia de instrucciones para la computadora, escritas en un lenguaje de programación, parecido al inglés, pero mucho mas simple - y mucho mas estricto.

En este curso aprenderás el lenguaje de programación Python.

Nuestro primer programa de ejemplo:

Evalua $y(t) = v_0t- \frac{1}{2}gt^2$ para $v_0=5$, $g=9.81$ y $t=0.6$:

$$ y = 5\cdot 0.6 - \frac{1}{2}\cdot 9.81 \cdot 0.6^2 $$

El programa completo de Python sería:


In [1]:
print(5*0.6 - 0.5*9.81*0.6**2)


1.2342

Como escribir y ejecutar un programa

  • Un programa es texto plano, escrito en un editor de texto plano

  • Utiliza Gedit, Emacs, Vim, Spyder, o IDLE (no MS Word!)

Paso 1. Escribe el programa en un editor de texto, aquí está la línea:


In [1]:
print(5*0.6 - 0.5*9.81*0.6**2)

Paso 2. Guarda el programa en un archivo (digamos) pelota1.py. (.py denota Python.)

Paso 3. Abre una ventana del terminal y ve a la carpeta que contiene el archivo del programa.

Paso 4. Ejecuta el programa:

    Terminal> python pelota1.py

El programa imprime 1.2342 en la ventana del terminal.

En este curso es probable que se use la computadora de una forma diferente a la que estás acostumbrado

  • Cuando usas una computadora, siempre ejecutas algunos programas.

  • La computadora no puede hacer nada a menos que se le indique con precisión que hacer, y los humanos escriben y usan programas para decirle a la computadora que hacer.

  • La mayoría de las personas están acostumbrados a hacer doble clic sobre un ícono para ejecutar un programa- en este curso se le darán comandos en un terminal porque es mas eficiente si trabajas intensamente en programación.

  • Los problemas de matemáticas difíciles de repente se vuelven fáciles escribiendo programas.

Un pequeño programa que calcula una integral

No puedes calcular esta integral a mano:

$$ \int_{-\infty}^1 e^{-x^2}dx{\thinspace .} $$

Un pequeño programa puede calcular esta y "todas" las demás integrales:


In [2]:
from numpy import *

def integrate(f, a, b, n=100):
    """
    Integrate f from a to b,
    using the Trapezoidal rule with n intervals.
    """
    x = linspace(a, b, n+1)    # Coordinates of the intervals
    h = x[1] - x[0]            # Interval spacing
    I = h*(sum(f(x)) - 0.5*(f(a) + f(b)))
    return I

# Define my special integrand
def my_function(x):
    return exp(-x**2)

minus_infinity = -20  # Approximation of minus infinity
I = integrate(my_function, minus_infinity, 1, n=1000)
print('Value of integral:', I)


Value of integral: 1.63302401873

¡El programa calcula una aproximación con error de $10^{-12}$ en 0.1 s ($n=10^6$)!

Las Computadoras son muy exigentes con las reglas gramaticales y errores tipográficos

Examine lo siguiente:

    print 5*0.6 - 0.5*9.81*0.6**2
    write 5*0,6 - 0,5*9,81*0,6^2

¿Piensas que esas dos líneas son iguales?

  • Los humanos dirán si, las computadoras no

  • La segunda líneano tiene sentido como un programa de Python

  • write no es una palabra con sentido para Python en este contexto, la coma tiene un significado diferente al que tiene en matemáticas, y el acento circunflejo no se utiliza para las potencias

  • !Hay que ser en extremo exacto sobre como escribimos programas de computadora!

  • Toma tiempo y experiencia aprenderlo

Programar te abre a una nueva vida

La gente solamente se hace programadora si son obsesivos por los detalles, anhelan poder sobre las máquinas, y pueden soportar que se les diga día tras día lo estúpidos que son. G. J. E. Rawlins


Para mi programar es mas que un importante arte práctico. Es también una empresa gigantesca en los cimientos del conocimiento. Grace Hopper, citada en La Gestión y la Computadora del Futuro (1962) por el Sloan School of Management, p. 277

Almacena números en variables para hacer un programa mas legible

Desde las matemáticas estás acostumbrada a utilizar variables, por ejemplo,

$$ v_0=5,\quad g=9.81,\quad t=0.6,\quad y = v_0t -\frac{1}{2}gt^2 $$

También se pueden utilizar variables en un programa, y esto hace que el programa anterior sea más fácil de leer y entender:


In [3]:
v0 = 5
g = 9.81
t = 0.6
y = v0*t - 0.5*g*t**2
print(y)


1.2342

Este programa abarca varias líneas de texto y utiliza variables, por otro lado el programa realiza los mismos cálculos y devuelve el mismo resultado del programa anterior. This program spans several lines of text and use variables, otherwise the program performs the same calculations and gives the same output as the previous program

Hay una gran flexibilidad al escoger los nombre de las variables

  • En matemáticas usualmente se selecciona una letra para una variable

  • El nombre de una variable en un programa puede contener las letras a-z, A-Z, guión bajo _ y los dígitos 0-9, pero no puede empezar con un dígito

  • Los nombres de variables diferencian entre minúsculas y mayúsculas (por ejemplo, a es diferente de A)

(nota: En Python 3 las letras pueden ser cualquier caracter Unicode siempre que no formen una palabra reservada.)


In [5]:
initial_velocity = 5
accel_of_gravity = 9.81
TIME = 0.6
VerticalPositionOfBall = initial_velocity*TIME - \
                         0.5*accel_of_gravity*TIME**2
print(VerticalPositionOfBall)


1.2342

(Nota: la barra invertida permite que una instrucción continue en la siguiente línea)

¡Los buenos nombres de variable hacen que el programa sea mas fácil de entender!

Algunas palabras están reservadas en Python

Ciertas palabras tienen un significado especial en Python y no pueden ser utilizadas como nombres de variables. Estas son: and, as, assert, break, class, continue, def, del, elif, else, except, exec, finally, for, from, global, if, import, in, is, lambda, not, or, pass, print, raise, return, try, with, while, and yield.

Comments are useful to explain how you think in programs

Program with comments:


In [3]:
# program for computing the height of a ball
# in vertical motion
v0 = 5    # initial velocity
g = 9.81  # acceleration of gravity
t = 0.6   # time
y = v0*t - 0.5*g*t**2  # vertical position
print(y)


1.2342

Nota:

  • Todo después de # en una línea es un comentario y es ignorado por Python

  • Los comentarios son utilizados para explicar (en lenguaje humano) que significan las instrucciones para la computadora, que significan las variables, como la programadora razonó cuando escribió el programa, etc.

  • Los malos comentarios no dicen mas que el código: a = 5 # set a to 5

Los comentarios no son siempre ignorados....

Regla normal: Los programas de Python, incluyendo los comentarios, solo pueden contener caracteres del alfabeto inglés (ASCII).

El notebook de Python permite caracteres distintos del inglés (pero el Python ordinario no los permite a menos que se coloque la línea # -*- coding: utf-8 -*- al principio del código).


In [7]:
hilsen = 'Kjære Åsmund!'  # er æ og Å lov i en streng?
print(hilsen)


Kjære Åsmund!

la sintaxis de print() provee una gran flexibilidad para dar formato al texto con números

La salida de los cálculos con frecuencia puede contener texto y números, por ejemplo,

    En t=0.6 s, y es 1.23 m.

Se quiere controlar el formato de los números: número de decimales, estilo: 0.6 vs 6E-01 o 6.0e-01. El llamado formato printf es útil para este propósito:


In [4]:
print('En t=%g s, y es %.2f m.' % (t, y))


En t=0.6 s, y es 1.23 m.

El formato printf tiene "ranuras" donde se pone el valor de las variables que aparecen al final: %g $\leftarrow$ t, %.2f $\leftarrow$ y

Ejemplos de varios formatos printf

    %g         formato mas compacto para un número real
    %f         notación decimal (-34.674)
    %10.3f     notación decimal, 3 decimales, ancho de campo 10
    %.3f       notación decimal, 3 decimales, ancho de campo mínimo
    %e or %E   notación científica (1.42e-02 o 1.42E-02)
    %9.2e      notación científica, 2 decimales, ancho de campo 9
    %d         entero
    %5d        entero en un ancho de campo de 5 caracteres
    %s         cadena (texto)
    %-20s      cadena, ancho de campo 20, ajustado a la izquierda
    %%         el propio símbolo de porcentaje %

(Ver el libro para mas explicaciones y revisión)

Uso del formato printf en nuestro programa

Las cadenas entre comillas triples (""") pueden utilizarse para salidas de varias líneas, a continuación se combina una de estas cadenas con el formato printf:


In [7]:
v0 = 5
g = 9.81
t = 0.6
y = v0*t - 0.5*g*t**2

print("""
En t=%f s, una pelota con
velocidad inicial v0=%.3E m/s
está a una altura de %.2f m.
""" % (t, v0, y))


En t=0.600000 s, una pelota con
velocidad inicial v0=5.000E+00 m/s
está a una altura de 1.23 m.

Ejecutar el programa:

    Terminal> python imprimir_pelota2.py

    En t=0.600000 s, una pelota con
    velocidad inicial v0=5.000E+00 m/s
    está a una altura de 1.23 m.

Algunos términos de computación frecuentes

  • Programa o código o aplicación
  • Código fuente (texto del programa)
  • Código/trozo de código
  • Ejecutar o correr un programa
  • Algoritmo (la receta de un programa)
  • Implantación (escritura del programa)
  • Verificación (¿Funciona el programa correctamente?)
  • Bugs (errores) y depuración

El significado de los términos en computación es con frecuencia diferente al significado en lenguaje humano

Un programa consiste de sentencias


In [8]:
a = 1      # 1era sentencia (sentencia de asignación)
b = 2      # 2da sentencia (sentencia de asignación)
c = a + b  # 3era sentencia (sentencia de asignación)
print(c)    # 4ta sentencia (sentencia de impresión)


3

Regla normal: una sentencia por línea, pero es posible tener varias sentencias por línea separándolas con punto y coma:


In [9]:
a = 1;  b = 2;  c = a + b;  print(c)


3

Las sentencias de asignación evaluan la expresión del lado derecho y asignan el resultado a la variable del lado izquierdo


In [10]:
myvar = 10
myvar = 3*myvar   # = 30

Sintaxis es la especificación exacta de las instrucciones de la computadora

Los programas deben tener una sintaxis correcta, es decir, el uso correcto de las reglas gramáticales del lenguaje de la computadra, ¡sin errores de tipeo!

Este es un programa con dos errores de sintaxis:


In [11]:
myvar = 5.2
prinnt Myvar


  File "<ipython-input-11-b8bfd2138e5c>", line 2
    prinnt Myvar
               ^
SyntaxError: invalid syntax
        prinnt Myvar
                   ^
    SyntaxError: invalid syntax

Only the first encountered error is reported and the program is stopped (correct the error and continue with next error)

Programming demands significantly higher standard of accuracy. Things don't simply have to make sense to another human being, they must make sense to a computer. Donald Knuth, computer scientist, 1938-

Los espacios en blanco pueden utilizarse para darle un formato agradable al texto

Los espacios en blanco pueden o no ser importantes en los programas de Python.

Las siguientes sentencias son equivalentes (los espacios en blanco no son relevantes):


In [12]:
v0=3
v0  =  3
v0=   3
v0 = 3

Aquí los espacios en blanco si son importantes:


In [13]:
while counter <= 10:
    counter = counter + 1   # correct (4 leading blanks)

while counter <= 10:
counter = counter + 1       # invalid syntax


  File "<ipython-input-13-16b8204f33df>", line 5
    counter = counter + 1       # invalid syntax
          ^
IndentationError: expected an indented block

(mas sobre esto en el Capítulo 2)


In [ ]:
### A program takes some known *input* data and computes some *output* data

In [1]:
v0 = 3;  g = 9.81;  t = 0.6
position = v0*t - 0.5*g*t*t
velocity = v0 - g*t
print 'position:', position, 'velocity:', velocity
  • Input: v0, g, and t

    • Output: position and velocity

An operating system (OS) is a set of programs managing hardware and software resources on a computer

  • Linux, Unix (Ubuntu, RedHat, Suse, Solaris)

  • Windows (95, 98, NT, ME, 2000, XP, Vista, 7, 8)

  • Macintosh (old Mac OS, Mac OS X)

  • Mac OS X $\approx$ Unix $\approx$ Linux $\neq$ Windows

  • Typical OS commands are quite similar:

    • Linux/Unix: mkdir folder; cd folder; ls

    • Windows: mkdir folder; cd folder; dir

  • Python supports cross-platform programming, i.e., a program is independent of which OS we run the program on

Evaluating a formula for temperature conversion

Given $C$ as a temperature in Celsius degrees, compute the corresponding Fahrenheit degrees $F$:

$$ F = \frac{9}{5}C + 32 $$

Program:


In [1]:
C = 21
F = (9/5)*C + 32
print F

Execution:

    Terminal> python c2f_v1.py
    53

We must always check that a new program calculates the right answer

Using a calculator:

9/5 times 21 plus 32 is 69.8, not 53.

The error is caused by (unintended) integer division

  • 9/5 is not 1.8 but 1 in most computer languages (!)

  • If $a$ and $b$ are integers, $a/b$ implies integer division: the largest integer $c$ such that $cb\leq a$

  • Examples: $1/5=0$, $2/5=0$, $7/5=1$, $12/5=2$

  • In mathematics, 9/5 is a real number (1.8) - this is called float division in Python and is the division we want

  • One of the operands ($a$ or $b$) in $a/b$ must be a real number ("float") to get float division

  • A float in Python has a dot (or decimals): 9.0 or 9. is float

  • No dot implies integer: 9 is an integer

  • 9.0/5 yields 1.8, 9/5. yields 1.8, 9/5 yields 1

Corrected program (with correct output 69.8):


In [1]:
C = 21
F = (9.0/5)*C + 32
print F

Everything in Python is an object

Variables refer to objects:


In [1]:
a = 5       # a refers to an integer (int) object
b = 9       # b refers to an integer (int) object
c = 9.0     # c refers to a real number (float) object
d = b/a     # d refers to an int/int => int object
e = c/a     # e refers to float/int => float object
s = 'b/a=%g' % (b/a)  # s is a string/text (str) object

We can convert between object types:


In [1]:
a = 3              # a is int
b = float(a)       # b is float 3.0
c = 3.9            # c is float
d = int(c)         # d is int 3
d = round(c)       # d is float 4.0
d = int(round(c))  # d is int 4
d = str(c)         # d is str '3.9'
e = '-4.2'         # e is str
f = float(e)       # f is float -4.2

Arithmetic expressions are evaluated as you have learned in mathematics

  • Example: $\frac{5}{9} + 2a^4/2$, in Python written as 5/9 + 2*a**4/2

  • Same rules as in mathematics: proceed term by term (additions/subtractions) from the left, compute powers first, then multiplication and division, in each term

  • r1 = 5/9 (=0)

  • r2 = a**4

  • r3 = 2*r2

  • r4 = r3/2

  • r5 = r1 + r4

  • Use parenthesis to override these default rules - or use parenthesis to explicitly tell how the rules work: (5/9) + (2*(a**4))/2

Standard mathematical functions are found in the math module

  • What if we need to compute $\sin x$, $\cos x$, $\ln x$, etc. in a program?

  • Such functions are available in Python's math module

  • In general: lots of useful functionality in Python is available in modules - but modules must be imported in our programs

Compute $\sqrt{2}$ using the sqrt function in the math module:


In [1]:
import math
r = math.sqrt(2)
# or
from math import sqrt
r = sqrt(2)
# or
from math import *   # import everything in math
r = sqrt(2)

Another example on computing with functions from math

Evaluate

$$ Q = \sin x\cos x + 4\ln x $$

for $x=1.2$.


In [1]:
from math import sin, cos, log
x = 1.2
Q = sin(x)*cos(x) + 4*log(x)   # log is ln (base e)
print Q

Computers have inexact arithmetics because of round-off errors

Let us compute $1/49\cdot 49$ and $1/51\cdot 51$:


In [1]:
v1 = 1/49.0*49
v2 = 1/51.0*51
print '%.16f %.16f' % (v1, v2)

Output with 16 decimals becomes

     0.9999999999999999 1.0000000000000000
  • Most real numbers are represented inexactly on a computer (16 digits)

    • Neither 1/49 nor 1/51 is represented exactly, the error is typically $10^{-16}$

    • Sometimes such small errors propagate to the final answer, sometimes not, and somtimes the small errors accumulate through many mathematical operations

    • Lesson learned: real numbers on a computer and the results of mathematical computations are only approximate

Another example involving math functions

The $\sinh x$ function is defined as

$$ \sinh (x) = \frac{1}{2}\left(e^{x} - e^{-x}\right) $$

We can evaluate this function in three ways:

  1. math.sinh

  2. combination of two math.exp

  3. combination of two powers of math.e


In [1]:
from math import sinh, exp, e, pi
x = 2*pi
r1 = sinh(x)
r2 = 0.5*(exp(x) - exp(-x))
r3 = 0.5*(e**x - e**(-x))
print '%.16f %.16f %.16f' % (r1,r2,r3)

Output: r1 is $267.744894041016\underline{4369}$, r2 is $267.744894041016\underline{4369}$, r3 is $267.744894041016\underline{3232}$ (!)

Python can be used interactively as a calculator and to test statements

  • So far we have performed calculations in Python programs

  • Python can also be used interactively in what is known as a shell

  • Type python, ipython, or idle in the terminal window

  • A Python shell is entered where you can write statements after >>> (IPython has a different prompt)


In [1]:
C = 41
F = (9.0/5)*C + 32
print F
F

Previous commands can be recalled and edited

Python has full support for complex numbers

  • $2+3i$ in mathematics is written as 2 + 3j in Python

In [1]:
a = -2
b = 0.5
s = complex(a, b)  # make complex from variables
s
s*w                # complex*complex
s/w                # complex/complex
s.real
s.imag

See the book for additional info

Python can also do symbolic computing

  • Numerical computing: computation with numbers

  • Symbolic computing: work with formulas (as in trad. math)


In [1]:
from sympy import *
t, v0, g = symbols('t v0 g')
y = v0*t - Rational(1,2)*g*t**2
dydt = diff(y, t)                     # 1st derivative
dydt
print 'acceleration:', diff(y, t, t)  # 2nd derivative
y2 = integrate(dydt, t)
y2

SymPy can do a lot of traditional mathematics


In [1]:
y = v0*t - Rational(1,2)*g*t**2
roots = solve(y, t)    # solve y=0 wrt t
roots
x, y = symbols('x y')
f = -sin(x)*sin(y) + cos(x)*cos(y)
simplify(f)
expand(sin(x+y), trig=True)  # requires a trigonometric hint

Summary of Chapter 1 (part 1)

  • Programs must be accurate!

  • Variables are names for objects

  • We have met different object types: int, float, str

  • Choose variable names close to the mathematical symbols in the problem being solved

  • Arithmetic operations in Python: term by term (+/-) from left to right, power before * and / - as in mathematics; use parenthesis when there is any doubt

  • Watch out for unintended integer division!

Summary of Chapter 1 (part 2)

Mathematical functions like $\sin x$ and $\ln x$ must be imported from the math module:


In [1]:
from math import sin, log
x = 5
r = sin(3*log(10*x))

Use printf syntax for full control of output of text and numbers!

Important terms: object, variable, algorithm, statement, assignment, implementation, verification, debugging

Programming is challenging

  • You think you know when you can learn, are more sure when you can write, even more when you can teach, but certain when you can program

  • Within a computer, natural language is unnatural

  • To understand a program you must become both the machine and the program

Alan Perlis, computer scientist, 1922-1990.

Summarizing example: throwing a ball (problem)

We throw a ball with velocity $v_0$, at an angle $\theta$ with the horizontal, from the point $(x=0,y=y_0)$. The trajectory of the ball is a parabola (we neglect air resistance):

$$ y = x\tan\theta - \frac{1}{2v_0}\frac{gx^2}{\cos^2\theta} + y_0 $$
  • Program tasks:

    • initialize input data ($v_0$, $g$, $\theta$, $y_0$)

    • import from math

    • compute $y$

  • We give $x$, $y$ and $y_0$ in m, $g = 9.81\hbox {m/s}^2$, $v_0$ in km/h and $\theta$ in degrees - this requires conversion of $v_0$ to m/s and $\theta$ to radians

Summarizing example: throwing a ball (solution)

Program:


In [1]:
g = 9.81    # m/s**2
v0 = 15     # km/h
theta = 60  # degrees
x = 0.5     # m
y0 = 1      # m

print """v0    = %.1f km/h
theta = %d degrees
y0    = %.1f m
x     = %.1f m""" % (v0, theta, y0, x)

# convert v0 to m/s and theta to radians:
v0 = v0/3.6
from math import pi, tan, cos
theta = theta*pi/180

y = x*tan(theta) - 1/(2*v0)*g*x**2/((cos(theta))**2) + y0

print 'y     = %.1f m' % y