import this
The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than *right* now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those!
Durante este curso utilizaremos el notebook de IPython para trabajar. IPython no es más que un intérprete de Python con algunas mejoras sustanciales, pero además su interfaz notebook es más cómoda de manejar que la línea de comandos y nos da un poco más de flexibilidad.
Esto que estás leyendo ahora no es más que un notebook de IPython, que como diremos luego además de código puede contener texto e imágenes. Pero veamos primero cómo funciona.
Al iniciar el notebook de IPython, en la pantalla principal podemos ver una ruta y una lista de notebooks. Cada notebook es un archivo que está almacenado en el ordenador en la ruta que aparece. Si en esa carpeta no hay notebooks, veremos un mensaje indicando que la lista de notebooks está vacía.
Al crear un notebook o al abrir uno nuevo se abre la interfaz de IPython propiamente dicha donde ya podemos empezar a trabajar. Es similar a un intérprete, pero está dividida en celdas. Cada celda está marcada por la palabra In [<n>]
y están numeradas. Tan solo tenemos que escribir el código en ella y hacer click arriba en Cell -> Run, el triángulo ("Run cell") o usar el atajo shift + Enter
. El resultado de la celda se muestra en el campo Out [<n>]
, también numerado y coincidiendo con la celda que acabamos de ejecutar. Esto es importante, como ya veremos luego.
Vamos ahora a hacer una introducción muy rápida a la sintaxis de Python, y a medida que avancemos iremos describiendo más características de IPython que nos pueden resultar útiles.
Naturalmente disponemos de los tipos numéricos y las operaciones habituales:
2 * 4 - (7 - 1) / 3 + 1.0
7.0
Las divisiones por cero lanzan un error:
1 / 0
--------------------------------------------------------------------------- ZeroDivisionError Traceback (most recent call last) <ipython-input-3-b710d87c980c> in <module>() ----> 1 1 / 0 ZeroDivisionError: division by zero
1.0 / 0.0
--------------------------------------------------------------------------- ZeroDivisionError Traceback (most recent call last) <ipython-input-4-42176c28e89e> in <module>() ----> 1 1.0 / 0.0 ZeroDivisionError: float division by zero
La división entre enteros en Python 3 devuelve un número real, al contrario que en Python 2.
3 / 2
1.5
Para forzar la división entera, podemos usar el operador //
:
3 // 2
1
Además, Python incluye también números complejos:
2 + 3j
(2+3j)
(3 + 2j) * (1 - 1j)
(5-1j)
(1j) ** 2
(-1+0j)
Para hallar el valor absoluto:
abs(3 + 2j)
3.605551275463989
Para convertir entre tipos numéricos podemos usar las funciones int
, float
y complex
:
_10
3.605551275463989
int(_)
3
Al convertir a int
descartamos la parte entera. Si en realidad queremos redondear:
round(_10)
4
float(_)
4.0
complex(_)
(4+0j)
Otras funciones útiles:
max(0, -1, 1, 2)
2
min(1, 2, 0, -1)
-1
La asignación en Python funciona con el operador =
a = 1 + 2j
a = 1 + 2j
a
(1+2j)
Podemos encadenar varias asignaciones:
x, y = 1, 2
x, y
(1, 2)
x, y = y, x
x, y
(2, 1)
Los operadores de comparación son ==
, !=
, <
, <=
, >
, >=
.
x, y = 1, 2
x, y
(1, 2)
print(x == y)
False
print(x != y)
True
print(x < y)
print(x <= y)
print(x > y)
print(x >= y)
True True False False
print
es la que se usa para imprimir resultados por pantalla. En Python 2 era una sentencia y funcionaba de manera distinta, sin paréntesis y sin posibilidad de pasar argumentos adicionales.Si la ordenación no tiene sentido, obtenemos un error:
1 + 1j < 0 + 1j
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-26-9a32b6a036ce> in <module>() ----> 1 1 + 1j < 0 + 1j TypeError: unorderable types: complex() < complex()
Otro tipo de datos muy importante que vamos a usar son las secuencias: las tuplas y las listas. Ambos son conjuntos ordenados de elementos: las tuplas se demarcan con paréntesis y las listas con corchetes.
una_lista = [1, 2, 3.0, 4 + 0j, "5"]
una_tupla = (1, 2, 3.0, 4 + 0j, "5")
print(una_lista)
print(una_tupla)
print(una_lista == una_tupla)
[1, 2, 3.0, (4+0j), '5'] (1, 2, 3.0, (4+0j), '5') False
Para las tuplas, podemos incluso obviar los paréntesis:
1, 2, 3.0
(1, 2, 3.0)
Los dos tipos tienen varias cosas en común. En particular:
in
:2 in una_tupla
True
len
:len(una_lista)
5
[<inicio>:<final>:<salto>]
:print(una_lista[0]) # Primer elemento, 1
print(una_tupla[1]) # Segundo elemento, 2
print(una_lista[0:2]) # Desde el primero hasta el tercero, excluyendo este: 1, 2
print(una_tupla[:3]) # Desde el primero hasta el cuarto, excluyendo este: 1, 2, 3.0
print(una_lista[-1]) # El último: 4 + 0j
print(una_tupla[:]) # Desde el primero hasta el último
print(una_lista[::2]) # Desde el primero hasta el último, saltando 2: 1, 3.0
1 2 [1, 2] (1, 2, 3.0) 5 (1, 2, 3.0, (4+0j), '5') [1, 3.0, '5']
Fíjate en dos detalles:
[-1]
da el último elemento, [-2]
el penúltimo y así sucesivamente.[::2]
para el último caso. Esto es una manera abreviada de escribir [0:-1:2]
, es decir, si no decimos nada empezamos en el principio y terminamos en el final. Por eso [:]
devuelve todos los elementos de la secuencia.Naturalmente, las sequencias se pueden anidar: por ejemplo, una lista puede contener, a su vez, más listas.
a = [
[1, 2, 3],
[4, 5],
]
print(a)
print(a[0])
print(a[0][0])
[[1, 2, 3], [4, 5]] [1, 2, 3] 1
Esto nos será de gran ayuda en el futuro para construir arrays.
En Python, los condicionales siguen esta estructura:
print(x, y)
if x < y:
print("x es menor que y")
print("x sigue siendo menor que y")
1 2 x es menor que y x sigue siendo menor que y
if 1 < 0:
print("1 es menor que 0")
print("1 sigue siendo menor que 0") # <-- ¡Mal!
1 sigue siendo menor que 0
if 1 < 0:
print("1 es menor que 0")
print("1 sigue siendo menor que 0")
File "<ipython-input-35-89ceea330d08>", line 3 print("1 sigue siendo menor que 0") ^ IndentationError: unexpected indent
Si queremos añadir ramas adicionales al condicional, podemos emplear la sentencia elif
(abreviatura de else if). Para la parte final, que debe ejecutarse si ninguna de las condiciones anteriores se ha cumplido, usamos la sentencia else
:
print(x, y)
if x < y:
print("x es menor que y")
elif x == y:
print("x es igual a y")
else:
print("x no es ni menor ni igual que y")
1 2 x es menor que y
Los bucles también se demarcan con el sangrado. En Python hay dos tipos de bucles: while
y for
.
ii = 0
while ii < 5:
print(ii)
ii += 1
0 1 2 3 4
Podemos interrumpir el bucle a la mitad usando la sentencia break
:
ii = 0
while ii < 5:
print(ii)
ii += 1
if ii == 3:
break
0 1 2
Un bloque else
justo después del bucle se ejecuta si este no ha sido interrumpido por nosotros:
ii = 0
while ii < 5:
print(ii)
ii += 1
if ii == 3:
break
else:
print("El bucle ha terminado")
0 1 2
ii = 0
while ii < 5:
print(ii)
ii += 1
#if ii == 3:
#break
else:
print("El bucle ha terminado")
0 1 2 3 4 El bucle ha terminado
El otro bucle en Python es el bucle for
, y funciona de manera un poco peculiar. La idea es recorrer un conjunto de elementos:
for ii in 1, 2, 4:
print(ii)
1 2 4
for nombre in "Juan", "Luis", "Carlos":
print(nombre)
Juan Luis Carlos
Una cosa que haremos de manera recurrente será recorrer un rango de números. Esto lo conseguimos con la función range:
for ii in range(3):
print(ii)
0 1 2
for jj in range(2, 5):
print(jj)
2 3 4
Para definir nuestra propia función utilizamos la sentencia def
seguida del nombre de la misma y entre paréntesis los argumentos de entrada. La primera línea de la función puede ser una cadena de documentación.
def funcion(x, y):
"""Función de prueba."""
pass
funcion
<function __main__.funcion>
funcion.__doc__
'Función de prueba.'
Los valores de retorno de la función se especifican con la sentencia return
. Por ejemplo:
def al_cuadrado(x):
"""Función que eleva un número al cuadrado."""
y = x ** 2
return y
al_cuadrado(4)
16
def multiplica(x, y=2.0):
"""Multiplica dos números, por defecto el primero por 2."""
return x * y
multiplica(2, 3)
6
multiplica(4)
8.0
multiplica(x, y=1.0)
1.0
(Traducido de http://docs.python.org/3/tutorial/controlflow.html#intermezzo-coding-style)
Utilizando el módulo pep8
https://pypi.python.org/pypi/pep8
Y la extensión pep8magic
https://gist.github.com/Juanlu001/9082229/
Podemos comprobar si una celda de código cumple con las reglas del PEP8:
%load_ext pep8magic
%%pep8
if 6*9==42:print("Something fundamentally wrong..." )
stdin:1:7: E225 missing whitespace around operator if 6*9==42:print("Something fundamentally wrong..." ) ^ stdin:1:11: E231 missing whitespace after ':' if 6*9==42:print("Something fundamentally wrong..." ) ^ stdin:1:11: E701 multiple statements on one line (colon) if 6*9==42:print("Something fundamentally wrong..." ) ^ stdin:1:53: E202 whitespace before ')' if 6*9==42:print("Something fundamentally wrong..." ) ^
%%pep8
if 6*9 == 42:
print("Something fundamentally wrong...")
This code is PEP8-compliant!