Esta presentación/notebook está disponible:
Repositorio Github FIFA BsAs (para descargarlo, usen el botón raw
o hagan un fork
del repositorio)
Página web de talleres FIFA BsAs
Programar es dar una lista de tareas concretas a la computadora para que haga. Esencialmente, una computadora sabe:
Y nada más que esto,. Así, la computadora pasa a ser suna gran gran calculadora que permite hacer cualquier tipo de cuenta de las que necesitemos dentro de la Física (y de la vida también) mientras sepamos cómo decirle a la máquina qué cómputos hacer.
Python es un lenguaje para hablarle a la computadora, que se denominan lenguajes de programación. Este lenguaje, que puede ser escrito y entendido por la computadora debe ser transformado a un lenguaje que entieda la computadora (o un intermediario, que se denomina maquina virtual) así se hacen las transformaciones. Todo este modelo de programación lo podemos ver esquematizado en la figura siguiente
Python nació en 1991, cuando su creador Guido Van Rossum lo hizo público en su versión 0.9. El lenguaje siempre buscó ser fácil de aprender y poder hacer tareas de todo tipo. Es fácil de aprender por su sintaxis, el tipado dinámico (que vamos a ver de que se trata) y además la gran cantidad de librerías/módulos para todo.
Para trabajar vamos a usar algún editor de texto (recomendamos Visual Studio Code, que viene con Anaconda), una terminal, o directamente el editor Spyder (que pueden buscarlo en las aplicaciones de la computadora si instalaron Anaconda o si lo instalaron en la PC del aula). También, si quieren podemos trabajar en un Jupyter Notebook, que permite hacer archivos como este (y hacer informes con código intercalado)
Esto es a gusto del consumidor, sabemos usar todas esas herramientas. Cada una tiene sus ventajas y desventajas:
Para instalar Python, conviene descargarse Anaconda. Este proyecto corresponde a una distribución de Python, que al tener una interfaz grafica amigable y manejador de paquetes llamado conda te permite instalar todas las librerías científicas de una. En Linux y macOS instalar Python sin Anaconda es más fácil, en Windows diría que es una necesidad sin meterse en asuntos oscuros de compilación (y además que el soporte en Windows de las librerías no es tan amplio).
Existe un proyecto llamado pyenv que en Linux y macOS permite instalar cualquier versión de Python. Si lo quieren tener (aunque para empezar Anaconda es mejor) pregunte que lo configuramos rápidamente.
Para hacer cuentas, primero necesitamos el medio para guardar o almacenar los datos. El sector este se denomina memoria. Nuestros datos se guardan en espacios de memoria, y esos espacios tienen un nombre, un rótulo con el cual los podremos llamar y pedirle a la computadora que los utilice para operar con ellos, los modifique, etc.
Como esos espacios son capaces de variar al avanzar los datos llegamos a llamarlos variables, y el proceso de llenar la variable con un valor se denomina asignación, que en Python se corresponde con el "=".
Hasta ahora sólo tenemos en la cabeza valores numéricos para nuestras variables, considerando la analogía de la super-calculadora. Pero esto no es así, y es más las variables en Python contienen la información adicional del tipo de dato. Este tipo de dato determina las operaciones posibles con la variable (además del tamaño en memoria, pero esto ya era esperable del mismo valor de la variable).
Veamos un par de ejemplos
x = 5
y = 'Hola mundo!'
z = [1,2,3]
Aquí hemos guardado en un espacio de memoria llamado por nosotros "x" la información de un valor de tipo entero, 5, en otro espacio de memoria, que nosotros llamamos "y" guardamos el texto "Hola mundo!". En Python, las comillas indican que lo que encerramos con ellas es un texto. x no es un texto, así que Python lo tratará como variable para manipular. "z" es el nombre del espacio de memoria donde se almacena una lista con 3 elementos enteros.
Podemos hacer cosas con esta información. Python es un lenguaje interpretado (a diferencia de otros como Java o C++), eso significa que ni bien nosotros le pedimos algo a Python, éste lo ejecuta. Así es que podremos pedirle por ejemplo que imprima en pantalla el contenido en y, el tipo de valor que es x (entero) entre otras cosas.
print(y)
print(type(x))
print(type(y), type(z), len(z))
Hola mundo! <class 'int'> <class 'str'> <class 'list'> 3
Vamos a utilizar mucho la función type() para entender con qué tipo de variables estamos trabajando. type() es una función predeterminada por Python, y lo que hace es pedir como argumento (lo que va entre los paréntesis) una variable y devuelve inmediatamente el tipo de variable que es.
En el siguiente bloque cree las variables "dato1" y "dato2" y guarde en ellas los textos "estoy programando" y "que emocion!". Con la función type() averigue qué tipo de datos se almacena en esas variables.
# Realice el ejercicio 1
Para las variables integers(enteros) y floats (flotantes) podemos hacer las operaciones matemáticas usuales y esperables. Veamos un poco las compatibilidades entre estos tipos de variables.
a = 5
b = 7
c = 5.0
d = 7.0
print(a+b, b+c, a*d, a/b, a/d, c**2)
12 12.0 35.0 0.7142857142857143 0.7142857142857143 25.0
Calcule el resultado de $$ \frac{(2+7.9)^2}{4^{7.4-3.14*9.81}-1} $$ y guárdelo en una variable
# Realice el ejercicio 2. El resultado esperado es -98.01
Las listas son cadenas de datos de cualquier tipo, unidos por estar en una misma variable, con posiciones dentro de esa lista, con las cuales nosotros podemos llamarlas. En Python, las listas se enumeran desde el 0 en adelante.
Estas listas también tienen algunas operaciones que le son válidas.
Distintas son las tuplas. Las listas son editables (en jerga, mutables), pero las tuplas no (inmutables). Esto es importante cuando, a lo largo del desarrollo de un código donde necesitamos que ciertas cosas no cambien, no editemos por error valores fundamentales de nuestro problema a resolver.
lista1 = [1, 2, 'saraza']
print(lista1, type(lista1))
print(lista1[1], type(lista1[1]))
print(lista1[2], type(lista1[2]))
print(lista1[-1])
[1, 2, 'saraza'] <class 'list'> 2 <class 'int'> saraza <class 'str'> saraza
lista2 = [2,3,4]
lista3 = [5,6,7]
#print(lista2+lista3)
print(lista2[2]+lista3[0])
9
tupla1 = (1,2,3)
lista4 = [1,2,3]
lista4[2] = 0
print(lista4)
#tupla1[0] = 0
print(tupla1)
[1, 2, 0] (1, 2, 3)
Hay formas muy cómodas de hacer listas. Presentamos una que utilizaremos mucho, que es usando la función range. Esta devuelve como una receta de como hacer los numeros; por lo tanto tenemos que decirle al generador que cree la lista, por medio de otra herramienta incorporada de Python, list
listilla = list(range(10))
print(listilla, type(listilla))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] <class 'list'>
Cómo en general no se hace seguido esto, no existe una forma "rápida" o "más elegante" de hacerlo.
Ejemplo de lo que debería mostrarse en pantalla
['estoy programando', 'que emocion!', -98.01]
['estoy programando', -98.01, 'que emocion!']
# Realice el ejercicio 3
Con la misma lista, haga el producto de los primeros 4 elementos de esa lista
Con la misma lista, reste el último valor con el primero
# Realice el ejercicio 4
Ahora, el titulo hablaba de diccionarios... pero no son los que usamos para buscar el significado de las palabras. ¡Aunque pueden ser parecidos o funcionar igual!.
Un diccionario es un relación entre una variable llamada llave y otra variable llamado valor. Relación en el sentido de función que veíamos en el secundario, pero usualmente de forma discreta.
La magia es que sabiendo la llave, o key, ya tienes el valor, o value, por lo que podés usarlo como una lista pero sin usar indices si no cosas como cadenas. Las keys son únicas, y si quiero crear un diccionario con las mismas keys se van a pisar y queda la última aparición
Veamos un ejemplo
d = {"hola": 1, "mundo": 2, 0: "numero", (0, 1): ["tupla", 0, 1]} # Las llaves pueden ser casi cualquier cosa (lista no)
print(d, type(d))
print(d["hola"])
print(d[0])
print(d[(0, 1)])
# Podés setear una llave (o key) vieja
d[0] = 10
# O podes agregar una nueva. El orden de las llaves no es algo en qué confiar necesariamente, para eso está OrderedDict
d[42] = "La respuesta"
# Cambiamos el diccionario, así que aparecen nuevas keys y cambios de values
print(d)
# Keys repetidas terminan siendo sobreescritas
rep_d = {0: 1, 0: 2}
print(rep_d)
# Otra cosas menor, un diccionario vacío es
empt_d = {}
print(empt_d)
{'hola': 1, 'mundo': 2, 0: 'numero', (0, 1): ['tupla', 0, 1]} <class 'dict'> 1 numero ['tupla', 0, 1] {'hola': 1, 'mundo': 2, 0: 10, (0, 1): ['tupla', 0, 1], 42: 'La respuesta'} {0: 2} {}
Es particularmente mágico el diccionario y lo podes usar para muchisimas cosas (y además Python lo usa para casi todo internamente, así que está muy bueno saber usarlos!).
El largo de un diccionario es la cantidad de keys que tiene, por ejemplo
new_d = {0: '0', '0': 0}
print(len(new_d))
# Diccionario vacío
print(len({}))
2 0
Haga un diccionario con tal que con el siguiente código
print(tu_dict[1] + tu_dict["FIFA"] + tu_dict[(3,4)])
Imprima "Programador, hola mundo!". Puede tener todas las entradas que quieras, no hay limite de la creatividad acá
# Realice el ejercicio 5
# Descomente esta línea y a trabajar
# print(tu_dict[1] + tu_dict["FIFA"] + tu_dict[(3,4)])
Este tipo de variable tiene sólo dos valores posibles: 1 y 0, o True y False. Las utilizaremos escencialmente para que Python reconozca relaciones entre números.
print(5 > 4)
print(4 > 5)
print(4 == 5) #La igualdad matemática se escribe con doble ==
print(4 != 5) #La desigualdad matemática se escribe con !=
print(type(4 > 5))
True False False True <class 'bool'>
También podemos comparar listas, donde todas las entradas deberíán ser iguales
print([1, 2, 3] == [1, 2, 3])
print([1, 2, 3] == [1, 3, 2])
True False
Lo mismo para tuplas (y aplica para diccionarios)
print((0, 1) == (0, 1))
print((1, 3) == (0, 3))
True False
Con la función id() podemos ver si dos variables apuntan a la misma dirección de memoria, es decir podemos ver si dos variables tienen exactamente el mismo valor (aunque sea filosófico, en Python la diferencia es importante)
a = 5
b = a
print(id(a) == id(b))
a = 12 # Reutilizamos la variable, con un nuevo valor
b = 12
print(id(a) == id(b)) # Python cachea números de 16bits
a = 66000
b = 66000
print(id(a) == id(b))
# No cachea listas, ni strings
a = [1, 2, 3]
b = [1, 2, 3]
print(id(a) == id(b))
a = "Python es lo más"
b = "Python es lo más"
print(id(a) == id(b))
True True False False False
Las listas, tuplas y diccionarios también pueden devolver booleanos cuando se le pregunta si tiene o no algún elemento. Los diccionarios trabajaran sobre las llaves y las listas/tuplas sobre sus indices/valores
nueva_l = [0, 42, 3]
nueva_t = (2.3, 4.2);
nuevo_d = {"0": -4, (0, 1): "tupla"}
# La frase es
# >>> x in collection
# donde collection es una tupla, lista o diccionario. Parece inglés escrito no?
print(42 in nueva_l)
print(3 in nueva_t)
print((0,1) in nuevo_d)
True False True
Averigue el resultado de 4!=5==1
. ¿Dónde pondría paréntesis para que el resultado fuera distinto?
# Realice el ejercicio 5
Si en el fondo un programa es una serie de algoritmos que la computadora debe seguir, un conocimiento fundamental para programar es saber cómo pedirle a una computadora que haga operaciones si se cumple una condición y que haga otras si no se cumple. Nos va a permitir hacer programas mucho más complejos. Veamos entonces como aplicar un if.
parametro = 5
if parametro > 0: # un if inaugura un nuevo bloque indentado
print('Tu parametro es {} y es mayor a cero'.format(parametro))
print('Gracias')
else: # el else inaugura otro bloque indentado
print('Tu parametro es {} y es menor o igual a cero'.format(parametro))
print('Gracias')
print('Vuelva pronto')
print(' ')
Tu parametro es 5 y es mayor a cero Gracias Vuelva pronto
parametro = -5
if parametro > 0: # un if inaugura un nuevo bloque indentado
print('Tu parametro es {} y es mayor a cero'.format(parametro))
print('Gracias')
else: # el else inaugura otro bloque indentado
print('Tu parametro es {} y es menor o igual a cero'.format(parametro))
print('Gracias')
print('Vuelva pronto')
print(' ')
Tu parametro es -5 y es menor o igual a cero Gracias Vuelva pronto
Haga un programa con un if que imprima la suma de dos números si un tercero es positivo, y que imprima la resta si el tercero es negativo.
# Realice el ejercicio 7
Para que Python repita una misma acción n cantidad de veces, utilizaremos la estructura for. En cada paso, nosotros podemos aprovechar el "número de iteración" como una variable. Eso nos servirá en la mayoría de los casos.
nueva_lista = ['nada',1,2,'tres', 'cuatro', 7-2, 2*3, 7/1, 2**3, 3**2]
for i in range(10): # i es una variable que inventamos en el for, y que tomará los valores de la
print(nueva_lista[i]) #lista que se genere con range(10)
nada 1 2 tres cuatro 5 6 7.0 8 9
# Realice el ejercicio 8
La estructura while es poco recomendada en Python pero es importante saber que existe: consiste en repetir un paso mientras se cumpla una condición. Es como un for mezclado con un if.
i = 1
while i < 10: # tener cuidado con los while que se cumplen siempre. Eso daría lugar a los loops infinitos.
i = i+1
print(i)
2 3 4 5 6 7 8 9 10
# Realice el ejercicio 8
Pero si queremos definir nuestra propia manera de calcular algo, o si queremos agrupar una serie de órdenes bajo un mismo nombre, podemos definirnos nuestras propias funciones, pidiendo la cantidad de argumentos que querramos.
Vamos a usar las funciones lambda (también llamadas anonimas) más que nada para funciones matemáticas, aunque también tenga otros usos. Definamos el polinomio $f(x) = x^2 - 5x + 6$ que tiene como raíces $x = 3$ y $x = 2$.
f = lambda x: x**2 - 5*x + 6
print(f(3), f(2), f(0))
0 0 6
Las funciones lambda son necesariamente funciones de una sola linea y también tienen que retornar nada; por eso son candidatas para expresiones matemáticas simples.
Las otras funciones, las más generales, se las llama funciones def, y tienen la siguiente forma.
def promedio(a,b,c):
N = a + b + c # Es importante que toda la función tenga su contenido indentado
N = N/3.0
return N
mipromedio = promedio(5,5,7) # Aquí rompimos la indentación
print(mipromedio)
5.666666666666667
Algo muy interesante y curioso, es que podemos hacer lo siguiente con las funciones
def otra_funcion(a, b):
return a + b * 2
# Es un valor!
otra_f = otra_funcion
print(otra_f)
print(type(otra_f))
print(otra_f(2, 3))
<function otra_funcion at 0x7f23f85f42f0> <class 'function'> 8
Las funciones pueden ser variables y esto abre la puerta a muchas cosas. Si tienen curiosidad, pregunten que está re bueno esto!
Hacer una función que calcule el promedio de $n$ elementos dados en una lista.
Sugerencia: utilizar las funciones len() y sum() como auxiliares.
# Realice el ejercicio 9
Usando lo que ya sabemos de funciones matemáticas y las bifurcaciones que puede generar un if, hacer una función que reciba los coeficientes $a, b, c$ de la parábola $f(x) = ax^2 + bx + c$ y calcule las raíces si son reales (es decir, usando el discriminante $\Delta = b^2 - 4ac$ como criterio), y sino que imprima en pantalla una advertencia de que el cálculo no se puede hacer en $\mathbb{R}$.
# Realice el ejercicio 10
Modificar la función anterior para que calcule las raíces de todos modos, aunque sean complejas. Python permite usar números complejos escritos de la forma 1 + 4j
. Investiguen un poco
# Bonus track 1
Repitan el ejercicio 8, es decir
¿Se les ocurre otra forma de hacer el factorial? Piensen la definición matemática y escribanla en Python, y prueben calcular el factorial de 100 con esta definición nueva
# Realice el ejercicio 12
Pero las operaciones básicas de suma, resta, multiplicación y división son todo lo que un lenguaje como Python puede hacer "nativamente". Una potencia o un seno es álgebra no lineal, y para hacerlo, habría que inventarse un algoritmo (una serie de pasos) para calcular por ejemplo sen($\pi$). Pero alguien ya lo hizo, ya lo pensó, ya lo escribió en lenguaje Python y ahora todos podemos usar ese algoritmo sin pensar en él. Solamente hay que decirle a nuestro intérprete de Python dónde está guardado ese algoritmo. Esta posibilidad de usar algoritmos de otros es fundamental en la programación, porque es lo que permite que nuestro problema se limite solamente a entender cómo llamar a estos algoritmos ya pensados y no tener que pensarlos cada vez.
Vamos entonces a llamar a un paquete (como se le llama en Python) llamada math que nos va a extender nuestras posibilididades matemáticas.
import math # Llamamos a una biblioteca
r1 = math.pow(2,4)
r2 = math.cos(math.pi)
r3 = math.log(100,10)
r4 = math.log(math.e)
print(r1, r2, r3, r4)
16.0 -1.0 2.0 1.0
Para entender cómo funcionan estas funciones, es importante recurrir a su documentation. La de esta biblioteca en particular se encuentra en
Use Python como calculadora y halle los resultados de
# Realice el ejercicio 13
Bueno, ahora que sabemos como usar bibliotecas, nos queda saber cómo podemos crearlas. Pero para saber eso, tenemos que saber que es un módulo en Python y cómo se relaciona con un paquete.
Se le llama módulo a los archivos de Python, archivos con la extensión *.py, como por ejemplo taller_python.py (como tal vez algunos hicieron ya). En este archivo se agregan funciones, variables, etc, que pueden ser llamadas desde otro módulo con el nombre sin la extensión, es decir
import taller_python # Vean el repositorio!
Python para buscar estos módulos revisa si el módulo importado (con el comando import
) está presente en la misma carpeta del que importa y luego en una serie de lugares estándares de Python (que se pueden alterar y revisar usando sys.path
, importando el paquete sys
). Si lo encuentra lo importa y podés usar las funciones, y si no puede salta una excepción
print(taller_python.func(5, 6))
# Veamos la documentación
help(taller_python.func)
25 Help on function func in module taller_python: func(x, y) Documentación de la función. Hace x * y - 5
Traten de importar la función __func_oculta
. Se puede, pero es un hack de Python y la idea es que no sepa de ella. Es una forma de ocultar y encapsular código, que es uno de los principios de la programación orientada a objetos.
Finalmente, un paquete como math
es un conjunto de módulos ordenados en una carpeta con el nombre math
, con un archivo especial __init__.py
, que hace que la carpeta se comporte como un módulo. Python importa lo que vea en el archivo __init__.py
y permite además importar los módulos dentro (o submodulos), si no tienen guiones bajos antes.
Usualmente no es recomendable trabajar en el __init__.py
, salvo que se tenga una razón muy necesaria (o simplemente vagancia)
Creen una libraría llamada mi_taller_python
y agregen dos funciones, una que devuelva el resultado de $\sqrt{x^2+2x+1}$ para cualquier x y otra que resuelva el resultado de $(x^2+2x+1)^{y}$, para cualquier x e y. Hagan todas las funciones ocultas que requieran (aunque recomendamos siempre minimzarlas)
# Realice el ejercicio 14
Ahora que nos animamos a buscar nuevas bibliotecas y definir funciones, buscar la función newton() de la biblioteca scipy.optimize para hallar $x$ tal que se cumpla la siguiente ecuación no lineal $$\frac{1}{x} = ln(x)$$
#Acá va el bonus track 2, para ya saborear la próxima clase
Con esto terminamos la primera sesión del taller! Para la próxima vamos a aprender a manejar muchos datos al mismo tiempo, graficarlos y crear datos estadísticos, usando un par de librerías especificas del set científico de Python (numpy, scipy y matplotlib).
En nuestro repositorio en Github (https://github.com/fifabsas/talleresfifabsas) está colgado este material así como el de la próxima clase. Además tiene ejemplos (hasta de automatización de instrumental) y otras instancias de talleres que hemos dado a traves del tiempo.
Para más referencias pueden googlear. Dejamos algunas de referencia:
http://pybonacci.org/2012/06/07/algebra-lineal-en-python-con-numpy-i-operaciones-basicas/
http://relopezbriega.github.io/blog/2015/06/14/algebra-lineal-con-python/
http://pendientedemigracion.ucm.es/info/aocg/python/modulos_cientificos/numpy/index.html
Pero es importantísimo manejarse con la documentación de las bibliotecas que se utilizan
https://docs.python.org/2/library/math.html
http://docs.scipy.org/doc/numpy/reference/routines.linalg.html
Para seguir profundizando con la programación en Python, ofrecemos distintos recursos
Un tutorial: http://www.learnpython.org/
How to think like a computer scientist (aprendizaje interactivo): http://interactivepython.org/runestone/static/thinkcspy/index.html
Otro tutorial, en inglés, pero muy completo: http://learnpythonthehardway.org/book
Coursera, que nunca está de más: https://www.coursera.org/learn/interactive-python-1
Otro más: https://es.coursera.org/learn/python
Y por fuera del taller, seguimos en contacto. Tenemos un grupo de Facebook donde pueden hacerse consultas y otros chicos que fueron al taller antes o aprendieron por sus medios podrán responderles. El grupo es https://www.facebook.com/groups/303815376436624/?fref=ts
Todo esto es posible gracias al aporte de mucha gente.