Introducción a la sintaxis de Python

En esta clase haremos una rápida introducción a la sintaxis de Python. Veremos cuáles son los tipos y estructuras básicas de este lenguaje. Seguro que ya has oído hablar mucho sobre las bondades de Python frente a otros lenguajes. Si no es así, échale un vistazo a esto. ¿Estás preparado? ¡Pues Empezamos!

Tipos numéricos

Python dispone de los tipos numéricos y las operaciones más habituales:


In [1]:
2 * 4 - (7 - 1) / 3 + 1.0


Out[1]:
7.0

Las divisiones por cero lanzan un error:


In [2]:
1 / 0


---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-2-e542b24897df> in <module>()
----> 1 1 / 0

ZeroDivisionError: division by zero

In [3]:
1.0 / 0.0


---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-3-42176c28e89e> in <module>()
----> 1 1.0 / 0.0

ZeroDivisionError: float division by zero
Más adelante veremos cómo tratar estos errores. Por otro lado, cuando usemos NumPy esta operación devolverá `NaN`.

La división entre enteros en Python 3 devuelve un número real, al contrario que en Python 2.


In [4]:
3 / 2


Out[4]:
1.5

Se puede forzar que la división sea entera con el operador //:


In [5]:
3 // 2


Out[5]:
1

Se puede elevar un número a otro con el operador **:


In [6]:
2 ** 16


Out[6]:
65536

Otro tipo que nos resultará muy útil son los complejos:


In [7]:
2 + 3j


Out[7]:
(2+3j)

In [8]:
1j


Out[8]:
1j

In [9]:
# Valor absoluto
abs(2 + 3j)


Out[9]:
3.605551275463989
Tip de IPython: podemos recuperar resultados pasados usando `_`. Por ejemplo, para recuperar el resultado correspondiente a `Out [7]`, usaríamos `_7`. Esta variable guarda ese valor para toda la sesión.

In [10]:
abs(_13)


---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-10-46d0568fb609> in <module>()
----> 1 abs(_13)

NameError: name '_13' is not defined

Podemos convertir variables a int, float, complex, str...


In [11]:
int(18.6)


Out[11]:
18

In [12]:
round(18.6)


Out[12]:
19

In [13]:
float(1)


Out[13]:
1.0

In [14]:
complex(2)


Out[14]:
(2+0j)

In [15]:
str(256568)


Out[15]:
'256568'

Podemos comprobar el tipo de una variable:


In [16]:
a = 2.
type(a)


Out[16]:
float

In [17]:
isinstance(a, float)


Out[17]:
True

Otras funciones útiles son:


In [18]:
print('hola mundo')


hola mundo

In [19]:
max(1,5,8,7)


Out[19]:
8

In [20]:
min(-1,1,0)


Out[20]:
-1

¡Acabas de utilizar funciones! Como ves es una manera bastante estándar: los argumentos se encierran entre paréntesis y se separan por comas. Se hace de esta manera en otros lenguajes de programación y no requiere mayor explicación, de momento.

La función print es la que se usa para imprimir resultados por pantalla. Por si lo ves en algún sitio, en Python 2 era una sentencia y funcionaba de manera distinta, sin paréntesis y sin posibilidad de pasar argumentos adicionales.

Asignación y operadores de comparación

La asignación se realiza con el operador =. Los nombres de las variables en Python pueden contener caracteres alfanuméricos (empezando con una letra) a-z, A-Z, 0-9 y otros símbolos como la _.

Por cuestiones de estilo, las variables suelen empezar con minúscula, reservando la mayúcula para clases.

Algunos nombres no pueden ser usados porque son usados por python:

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, while, with, yield

In [21]:
a = 1 + 2j

En Python la asignación no imprime el resultado por pantalla, al contrario de como sucede en MATLAB y Octave (salvo que se incluya el punto y coma al final). La mejor manera de visualizar la variable que acabamos de asignar es esta:


In [22]:
b = 3.14159
b


Out[22]:
3.14159

En una celda podemos escribir código que ocupe varias líneas. Si la última de ellas devuelve un resultado, este se imprimirá.


In [23]:
x, y = 1, 2
x, y


Out[23]:
(1, 2)
Podemos realizar **asignación múltiple**, que hemos hecho en la celda anterior con las variables `x` e `y` para intercambiar valores de manera intuitiva:

In [24]:
x, y = y, x
x, y


Out[24]:
(2, 1)

Los operadores de comparación son:

  • == igual a
  • != distinto de
  • < menor que
  • <= menor o igual que

Devolverán un booleano: True o False


In [25]:
x == y


Out[25]:
False

In [26]:
print(x != y)


True

In [27]:
print(x < y)
print(x <= y)
print(x > y)
print(x >= y)


False
False
True
True

In [28]:
# incluso:
x = 5.
6. < x < 8.


Out[28]:
False

Si la ordenación no tiene sentido nos devolverá un error:


In [29]:
1 + 1j < 0 + 1j


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-29-9a32b6a036ce> in <module>()
----> 1 1 + 1j < 0 + 1j

TypeError: unorderable types: complex() < complex()

In [30]:
# En las cadenas de texto sí existe un orden
'aaab' > 'ba'


Out[30]:
False

Booleanos


In [31]:
True and False


Out[31]:
False

In [32]:
not False


Out[32]:
True

In [33]:
True or False


Out[33]:
True

In [34]:
# Una curiosidad:
(True + True) * 10


Out[34]:
20

Otros tipos de datos

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.


In [35]:
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:


In [36]:
tupla_sin_parentesis = 2,5,6,9,7
type(tupla_sin_parentesis)


Out[36]:
tuple

En los dos tipos podemos:

  • Comprobar si un elemento está en la secuencia con el operador in:

In [37]:
2 in una_lista


Out[37]:
True

In [38]:
2 in una_tupla


Out[38]:
True
  • Saber cuandos elementos tienen con la función len:

In [39]:
len(una_lista)


Out[39]:
5
  • Podemos indexar las secuencias, utilizando la sintaxis [<inicio>:<final>:<salto>]:

In [40]:
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']

Veremos más cosas acerca de indexación en NumPy, así que de momento no te preocupes. Sólo recuerda una cosa:

¡En Python, la indexación empieza por CERO!

Podemos complicarlo un poco más y hacer cosas como una lista de listas:


In [41]:
mis_asignaturas = [
['Álgebra', 'Cálculo', 'Física'],
['Mecánica', 'Termodinámica'],
['Sólidos', 'Electrónica']
]
mis_asignaturas


Out[41]:
[['Álgebra', 'Cálculo', 'Física'],
 ['Mecánica', 'Termodinámica'],
 ['Sólidos', 'Electrónica']]

Esto nos será de gran ayuda en el futuro para construir arrays.

Estructuras de control (I): Condicionales

if <condition>:
    <do something>
elif <condition>:
    <do other thing>
else:
    <do other thing>
Importante: En Python los bloques se delimitan por sangrado, utilizando siempre cuatro espacios. Cuando ponemos los dos puntos al final de la primera línea del condicional, todo lo que vaya a continuación con *un* nivel de sangrado superior se considera dentro del condicional. En cuanto escribimos la primera línea con un nivel de sangrado inferior, hemos cerrado el condicional. Si no seguimos esto a rajatabla Python nos dará errores; es una forma de forzar a que el código sea legible.

In [42]:
print(x,y)
if x > y:
    print("x es mayor que y")
    print("x sigue siendo mayor que y")


5.0 1
x es mayor que y
x sigue siendo mayor que y

In [43]:
if 1 < 0:
    print("1 es menor que 0")
print("1 sigue siendo menor que 0")  # <-- ¡Mal!


1 sigue siendo menor que 0

In [44]:
if 1 < 0:
    print("1 es menor que 0")
     print("1 sigue siendo menor que 0")


  File "<ipython-input-44-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:


In [45]:
print(x,y)
if x > y:
    print("x es mayor que y")
else:
    print("x es menor que y")


5.0 1
x es mayor que y

In [46]:
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")


5.0 1
x no es ni menor ni igual que y

Estructuras de control (II): Bucles

En Python existen dos tipos de estructuras de control típicas:

  1. Bucles while
  2. Bucles for

while

Los bucles while repetiran las sentencias anidadas en él mientras se cumpla una condición:

while <condition>:
    <things to do>

Como en el caso de los condicionales, los bloques se separan por indentación sin necesidad de sentencias del tipo end


In [47]:
ii = -2
while ii < 5:
    print(ii)
    ii += 1


-2
-1
0
1
2
3
4
Tip: `ii += 1` equivale a `ii = ii + 1`. En el segundo Python, realiza la operación ii + 1 creando un nuevo objeto con ese valor y luego lo asigna a la variable ii; es decir, existe una reasignación. En el primero, sin embargo, el incremento se produce sobre la propia variable. Esto puede conducirnos a mejoras en velocidad. Otros operadores 'in-place' son: `-=`, `*=`, `/=`

Se puede interrumpir el bucle a la mitad con la sentencia break:


In [48]:
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:


In [49]:
ii = 0
while ii < 5:
    print(ii)
    ii += 1
    if ii == 3:
        break
else:
    print("El bucle ha terminado")


0
1
2

In [50]:
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

for

El otro bucle en Python es el bucle for, y funciona de manera un que puede resultar chocante al principio. La idea es recorrer un conjunto de elementos:

for <element> in <iterable_object>:
    <do whatever...>

In [51]:
for ii in (1,2,3,4,5):
    print(ii)


1
2
3
4
5

In [52]:
for nombre in "Juan", "Luis", "Carlos":
    print(nombre)


Juan
Luis
Carlos

In [53]:
for ii in range(3):
    print(ii)


0
1
2

In [54]:
for jj in range(2, 5):
    print(jj)


2
3
4

PEP 8

La guía de estilo:

  • Usa sangrado de 4 espacios, no tabuladores [IPython o tu editor se encargan de ello].
  • Acota las líneas a 79 caracteres.
  • Usa líneas en blanco para separar funciones y bloques de código dentro de ellas.
  • Pon los comentarios en líneas aparte si es posible.
  • Usa cadenas de documentación (docstrings).
  • Pon espacios alrededor de los operadores y después de coma.
  • Usa la convención minuscula_con_guiones_bajos para los nombres de las funciones y las variables.
  • Aunque Python 3 te lo permite, no uses caracteres especiales para los identificadores.

(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:


Hemos visto como la sintaxis de Python nos facilita escribir código legible así como aprendido algunas buenas prácticas al programar. Características como el tipado dinámico (no hace falta declarar variables) y ser lenguaje interpretado (no hace falta compilarlo) hacen que el tiempo que pasamos escrbiendo código sea menos que en otro tipo de lenguajes.

Se han presentado los tipos de variables, así como las estructuras de control básicas. En la siguiente clase practicaremos con algunos ejercicios para que te familiarices con ellas

Esperamos también que poco a poco te sientas cada vez más a gusto con el Jupyter Notebook y puedas sacarle todo el partido

Referencias



¡Síguenos en Twitter!



Este notebook ha sido realizado por: Juan Luis Cano, y Álex Sáez



<span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Curso AeroPython</span> por <span xmlns:cc="http://creativecommons.org/ns#" property="cc:attributionName">Juan Luis Cano Rodriguez y Alejandro Sáez Mollejo</span> se distribuye bajo una Licencia Creative Commons Atribución 4.0 Internacional.