Un programa de ordenador es una serie de instrucciones que le dicen a la máquina qué tiene que hacer. Las máquinas no entienden nuestro lenguaje, por lo que tenemos que aprender un lenguaje para poder comunicarnos con ellas y darles órdenes. Hay muchísimos lenguajes de programación hoy en día, cada lenguaje se usa para hacer un tipo de programa. Por ejemplo, si quieres hacer una página web puedes usar HTML, CSS y Javascript, si quieres hacer un programa para consultar una base de datos puedes usar SQL. En el caso de Python, es un lenguaje usado para muchas cosas: desde hacer cálculos científicos hasta programación web, pasando por robótica, seguridad, ciencia de datos, física y muchísimas cosas más. Además, Python es muy sencillo de entender y programar, ya que simplifica muchas tareas que en otros lenguajes como C son muy tediosas. Por eso, es ideal para entender los conceptos básicos de programación y para iniciarse en este mundillo.
Python viene instalado por defecto en todas las distribuciones Linux. En Ubuntu, la versión que viene instalada es python2
y en otras distribuciones como Arch Linux, la versión es python3
. Lo recomendable si vas a iniciarte en Python es que empieces directamente por python3
. Para comprobar la versión que tenemos instalada ejecutamos el siguiente comando en consola:
[marta@marta-PC ~]$ python -V
Python 3.6.0
En mi caso, tengo la versión 3.6 instalada. En el caso de que tengas una versión de python2
, instala la versión 3 usando el siguiente comando:
sudo apt-get install python3
sudo yum install python3
Para instalar Python en otros sistemas operativos, descarga el instalador de la página oficial de python.
Python es un lenguaje de programación interpretado, ¿qué quiere decir esto? que interpreta cada instrucción que hemos escrito en nuestro programa a la hora de ejecutar. Otros lenguajes, como C o Java son compilados, por lo que necesitamos generar un ejecutable (los famosos .exe
, para que nos entendamos) para poder ejecutarlos. El hecho de que Python sea interpretado nos permite tener una consola donde introducir comandos sin tener que crear un programa y compilarlo. Podemos ejecutar esta consola simplemente ejecutando el siguiente comando:
[marta@marta-PC ~]$ python
Python 3.6.0 (default, Dec 24 2016, 08:03:08)
[GCC 6.2.1 20160830] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
También tenemos disponible la consola ipython
, una consola de Python que resalta el código que escribimos y autocompleta si pulsamos el tabulador. Para ejecutarla simplemente tenemos que poner el siguiente comando en consola:
[marta@marta-PC ~]$ ipython
Python 3.6.0 (default, Dec 24 2016, 08:03:08)
Type "copyright", "credits" or "license" for more information.
IPython 5.1.0 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.
In [1]:
Tanto el >>>
de la consola de Python como el In [1]:
de la consola de iPython son conocidos como el prompt, donde podemos escribir instrucciones para que el intérprete las ejecute.
Un notebook de Jupyter es una especie de consola de Python que nos permite poder escribir comentarios en Markdown. Es muy útil para poder hacer tutoriales como éste, ya que dispones de la explicación y el código para ejecutar y probar en el mismo sitio. Vamos a empezar a usar la consola de python incluida en jupyter para hacer las primeras pruebas. Para instalar Jupyter podemos usar tanto pip
como anaconda
:
[marta@marta-PC ~]$ sudo pip3 install --upgrade pip && sudo pip3 install jupyter
También puedes seguir las instrucciones de la página oficial de Jupyter ```
Una vez tenemos Python instalado y hemos elegido nuestro intérprete favorito, vamos a empezar a programar. El primer programa que se suele hacer en todos los lenguajes de programación es conocido como el hola mundo. En otros lenguajes como C, tendríamos que hacer varias líneas de código y, después, compilar nuestro programa para poder ejecutarlo, en cambio, en Python lo podemos ejecutar en una sola línea!
In [1]:
print("Hola mundo!")
Ahora imagina que quieres hacer un programa para saludar a tu amiga Marta, ¿cómo lo harías? De primeras, podrías hacer lo siguiente:
In [2]:
print("Hola Marta!")
Así, tendríamos un programa para saludar a cualquier Marta del mundo, pero, ¿y si quisiéramos un programa para poder saludar a cualquier persona? Para poder llevar esto a cabo necesitamos introducir un concepto de programación básico: las variables.
Una variable en programación describe un lugar donde guardar información, que puede ser diferente en cada ejecución. En nuestro caso, queremos saludar al usuario que ejecute nuestro programa, pero no sabemos su nombre a priori y no lo sabremos hasta la ejecución, por tanto, necesitamos reservar un espacio para poder guardar ahí el nombre del usuario durante la ejecución de nuestro programa.
Hay muchos tipos de variables:
int
)float
o double
)char
) y cadenas de caracteres (string
)bool
), estos últimos sólo pueden tomar dos valores: verdadero (True
) o falso (False
).En otros lenguajes de programación, como C, necesitamos indicar el tipo que tiene cada variable que declaramos. En cambio, en python no es necesario ya que el propio intérprete lo infiere por sí mismo.
Una vez hemos aprendido el concepto de variable, ya sí podemos hacer nuestro programa para saludar a cualquier persona.
In [4]:
nombre = input("¿Cómo te llamas? ")
print("Hola ", nombre,"!")
En Python podemos hacer operaciones sobre las variables que tenemos de forma muy sencilla. A modo de resumen, las principales operaciones en python son:
Símbolo | Operación |
---|---|
+ | suma |
- | resta |
* | multiplicación |
/ | división |
Estos operadores se pueden usar con cualquier tipo de variable, tanto números como letras. A continuación, te muestro varios ejemplos.
Podemos concatenar dos palabras usando el operador +.
In [5]:
nombre1 = "Marta"
nombre2 = "María"
suma_nombres = nombre1 + " y " + nombre2
print(suma_nombres)
También podemos multiplicar una palabra por un número usando el operador *.
In [6]:
num1 = 5
mult_letra_num = nombre1 * 5
print(mult_letra_num)
Y por último, también podemos hacer operaciones numéricas. En las operaciones numéricas Python respeta el orden de los operadores: primero se realizan las multiplicaciones y divisiones y, después, las sumas y restas. Si queremos cambiar este orden simplemente tenemos que usar paréntesis.
In [7]:
num2 = 6
operacion1 = num1 + num2 * 2
print(operacion1)
operacion2 = (num1 + num2) * 2
print(operacion2)
En el primer caso hemos realizado la operación
$$5 + (6 * 2) = 5 + 12 = 17$$y en el segundo, en cambio
$$ (5 + 6) * 2 = 11 * 2 = 22$$Haz un pequeño programa que le pida al usuario introducir dos números ($x_1$ y $x_2$), calcule la siguiente operación y muestre el resultado de la misma ($x$):
$$ x = \frac{20 * x_1 - x_2}{x_2 + 3} $$Si intentas operar con el resultado de la función input
obtendrás un error que te informa que no se pueden restar dos datos de tipo str
. Usa la función int
para convertir los datos introducidos por teclado a datos numéricos.
In [ ]:
math
Una librería es un conjunto de operaciones relacionadas entre sí, guardadas en una especie de "paquete". En este caso, vamos a hablar de la librería math
que tiene operaciones matemáticas más avanzadas tales como la raíz cuadrada.
Para poder usar esta librería debemos importarla a nuestro programa. Esto se hace usando la instrucción import
:
In [8]:
import math
print(math.sqrt(4))
Usando sólo la instrucción import
debemos preceder la instrucción que queremos del nombre de la librería. Si este nombre es muy largo, podemos importar la librería usando un alias:
In [9]:
import math as m
print(m.sqrt(4))
Ahora bien, si sólo vamos a usar unas operaciones concretas de una librería, podemos especificar cuáles son y así no tener que usar el nombre de la librería para poder utilizarlas.
In [10]:
from math import sqrt
print(m.sqrt(4))
Esta librería tiene muchas más operaciones que puedes consultar en la documentación oficial
Hasta ahora, nuestros programas se basan en una serie de instrucciones que se ejecutan una detrás de otra. Esto limita mucho los programas que podemos hacer, ya que no nos permite controlar el flujo de ejecución (control flow) de nuestro programa. A continuación vamos a ver una serie de instrucciones especiales que nos permiten hacer precisamente eso.
if
Imagina que estás operando con raíces cuadradas, como sabrás la raíz cuadrada de un número es negativa, y quieres evitar hacer la raíz cuadrada si el número introducido por el usuario es negativo.
In [11]:
num = int(input("Introduce un número: "))
raiz = sqrt(num)
¿Qué podemos hacer para que no ocurra esto? Controlar con un if
la condición de que el número sea positivo para hacer la raíz cuadrada y avisar al usuario en caso contrario:
In [12]:
num = int(input("Introduce un número: "))
if num > 0:
raiz = sqrt(num)
else:
print("No puedo hacer la raíz de un número negativo!")
Si quisiéramos controlar una condición más, usaríamos la instrucción elif
, que en otros lenguajes como C es conocida como else if
:
In [13]:
if num > 0:
raiz = sqrt(num)
elif num == 0:
print("Para qué quieres saber eso jaja saludos")
else:
print("No puedo hacer la raíz de un número negativo!")
Haz un programa que le pida al usuario un número (de ninjas). Si dicho número es menor que 50 y es par, el programa imprimirá "puedo con ellos!", en caso contrario imprimirá "no me vendría mal una ayudita..."
Nota: para saber si un número es par o no debes usar el operador $\%$ y para saber si dos condiciones se cuplen a la vez, el operador lógico and
In [ ]:
while
En el ejemplo anterior le decíamos al usuario que no podíamos hacer la raíz negativa de un número pero, ¿cómo haríamos para, en vez de darle este mensaje, volver a pedirle un número una y otra vez hasta que fuese negativo? Necesitamos ejecutar el mismo código hasta que se dé la condición que buscamos: que el usuario introduzca un número positivo.
Esto podemos hacerlo usando un bucle while
!
In [14]:
num = int(input("Introduce un número: "))
while (num < 0):
num = int(input("Introduce un número: "))
raiz = sqrt(num)
print(raiz)
In [ ]:
for
En lenguajes de programación como C o Java, un bucle for
sirve para recorrer una secuencia de números, de la siguiente forma:
for (int i=0; i<maximo_numero; i++)
Donde maximo_numero
es una variable previamente definida.
Hay también otro tipo de bucles for denominados forEach
en Java que sirven para iterar sobre los elementos de cualquier estructura de datos (más adelante veremos lo que es). En Python, los bucles for
tienen esta función: iterar sobre una serie de elementos.
Para iterar sobre una serie de números, debemos generar dicha serie usando la función range()
. Así, el ejercicio anteriormente pleanteado para resolverse con un bucle while
sería:
In [15]:
for i in range(num):
print(i)
¿Qué es eso de la función range()
? Sirve para generar una secuencia de números. Puedes consultar más sobre esta función en la documentación de Python. En Python 2, existían tanto range
como xrange
aunque en Python 3, range
hace lo mismo que hacía xrange
en Python 2.
Genera con range
los números pares del 0 al 10, ambos inclusive. ¿Qué cambiarías para generar del 2 al 10?
In [ ]:
break
La sentencia break
sirve para detener un bucle antes de que llegue al final (en un bucle for
) o antes de que la condición sea falsa (en un bucle while
).
Los bucles (for
y while
) pueden tener una sentencia else
como los if
. Esta sentencia else
se ejecuta si el bucle no ha terminado por un break
y nos puede servir para controlar cuando un bucle termina o no debido a un break
de forma sencilla.
El código siguiente refleja muy bien esto: para saber si un número $n$ es primo calculamos su módulo entre todos los números en el intervalo $[2,n)$ y, en el momento en el que uno de estos módulos sea igual a $0$, sabremos que $n$ no es primo.
In [16]:
for n in range(2,10):
for x in range(2, n):
if n % x == 0:
print(n, " = ", x, " * ", n//x)
break
else:
print(n, " es primo!")
Cuando $n \% x = 0$, dejamos de hacer módulos con $n$ pues ya sabemos que no es primo. Por tanto, nos salimos del bucle con un break
. Al salirnos con el break
, no entramos en el else
sino que volvemos al bucle inicial. En cambio, no hemos encontrado ningún $x$ tal que $n \% x = 0$, ejecutamos la condición else
para decir que $n$ es primo.
¿Cuál es la diferencia entre la sentencia break
y la sentencia continue
?
Pista: consúltalo en la documentación de Python.
In [ ]:
Por ahora sólo hemos estudiado variables en las que podemos guardar un único valor: un número, una letra, una frase... ¿No te da la impresión de que esto se queda algo corto? Sí, y probablemente no eres la única persona que lo ha pensado. Las estructuras de datos son variables compuestas, esto quiere decir que en ellas podemos almacenar muchos datos. Hay estructuras de datos de todo tipo, en python tenemos las siguientes:
Imagina que quieres guardar en una variable los nombres de tus mejores amigos. Una muy buena opción para hacerlo es una lista. Al igual que en la vida real hacemos listas como lista de cosas por hacer, lista para la compra, lista de propósitos de año nuevo, etc. en Python también podemos hacerlas usando esta estructura de datos.
Con las listas, podemos guardar en un mismo sitio variables relacionadas entre sí. Esto nos permite poder aplicar operaciones sobre todas ellas sin tener que repetir código.
Para declarar una lista, usaremos los [].
In [17]:
mis_amigos = ['Paloma', 'Paula', 'Teresa', 'Marina', 'Braulio']
print(mis_amigos)
Al imprimir la lista vemos los diferentes elementos que contiene. Pero, ¿y si queremos acceder a sólo uno de los elementos? En ese caso, necesitarás acceder mediante índices. Cada elemento de la lista tiene un número asociado con su posición dentro de la misma:
Elemento | Posición |
---|---|
Paloma | 0 |
Paula | 1 |
Teresa | 2 |
Marina | 3 |
Braulio | 4 |
así, si por ejemplo queremos únicamente mostrar a nuestro mejor amigo, accederemos a él mediante el índice 0:
In [18]:
mis_amigos[0]
Out[18]:
Si intentamos acceder a un índice superior al último de todos, 4, obtendremos un error:
In [19]:
mis_amigos[5]
Entonces, uno podría pensar que está obligado a conocer la longitud de la lista si quiere acceder al último elemento pero nada más lejos de la realidad! En python, también existen los índices inversos que nos permiten acceder a los elementos de la lista al revés:
Elemento | Posición |
---|---|
Paloma | -5 |
Paula | -4 |
Teresa | -3 |
Marina | -2 |
Braulio | -1 |
Por lo que para acceder al último elemento de nuestra lista sólo tendríamos que usar el índice -1:
In [20]:
mis_amigos[-1]
Out[20]:
Otra cosa que nos podemos hacer usando índices es quedarnos con una sublista. Por ejemplo, si quisiéramos quedarnos únicamente con un top 3 de amigos guays podríamos hacerlo usando el operador :
In [21]:
mis_amigos[0:3]
Out[21]:
Pero si queremos quedarnos con los tres primeros, podemos simplemente hacerlo de la siguiente forma:
In [22]:
mis_amigos[:3]
Out[22]:
¿Y si queremos saber el resto? Simplemente, lo hacemos al revés!
In [23]:
mis_amigos[3:]
Out[23]:
In [ ]:
In [24]:
for i in range(len(mis_amigos)):
print(mis_amigos[i])
Ahora bien, en Python existe una forma mucho más cómoda de iterar sobre los valores de una lista sin tener que estar pendiente de un índice i
:
In [25]:
for amigo in mis_amigos:
print(amigo)
En Python también existe lo que se llama list comprehesions, que son una forma mucho más sencilla y fácil de leer para crear listas. Por ejemplo, si queremos hacer una lista con las potencias de 2, podríamos hacerlo de la siguiente forma:
In [26]:
potencias = []
for x in range(10):
potencias.append(2**x)
print(potencias)
Tendríamos nuestra lista de potencias de 2 en tres líneas, pero con los list comprehesions podemos hacerlo en una única línea:
In [27]:
potencias = [x**2 for x in range(10)]
print(potencias)
In [ ]:
Seguramente te habrás preguntado si se puede hacer una lista cuyos elementos sean listas, y la respuesta es ¡sí!. Esta representación de listas anidadas se suele usar para representar matrices. Por ejemplo, si queremos representar la siguiente matriz en Python:
$$ M_{2 \times 3} = \left ( \begin{matrix} 1 & 2 & 3 \\ 2 & 3 & 4 \end{matrix} \right)$$Lo haríamos de la siguiente forma:
In [28]:
M = [[j for j in range(i, i+3)] for i in range(1,3)]
M
Out[28]:
In [ ]:
Imagina que deseas guardar tanto los nombres de tus mejores amigos como su edad. De primeras podrías pensar en hacer dos listas, de la siguiente forma:
índice | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
nombres | Paloma | Paula | Teresa | Marina | Braulio |
edades | 25 | 20 | 19 | 19 | 21 |
De tal forma que para saber la edad de Paloma (primer elemento de la lista nombres
) tendríamos que mirar el primer elemento de la lista edades
. Pero, ¿y si te dijera que en Python podríamos guardar en una misma variable la edad y el nombre de una persona? Se puede! Con las llamadas tuplas.
Una tupla es una serie de valores separados por comas.
In [29]:
tupla_ejemplo = 5, 'perro', 3.6
print(tupla_ejemplo)
Por tanto, para guardar en una lista tanto el nombre como la edad de nuestros amigos podríamos hacerlo de la siguiente forma:
In [30]:
amigos_edades = [('Paloma', 25), ('Paula', 20), ('Teresa', 19), ('Marina', 19), ('Braulio', 21)]
print(amigos_edades)
Los valores de las tuplas también tienen índices, por tanto, en nuestro caso el nombre tendría el índice 0 y la edad el índice 1. Por tanto, si queremos acceder a la edad de Paloma tenemos que usar el operador []
dos veces: una para acceder al elemento de la lista que queremos y otra para acceder al elemento de la tupla que queremos.
In [31]:
amigos_edades[0][1]
Out[31]:
Si queremos crear dos variables separadas para guardar el nombre y la edad de nuestro mejor amigo, podemos hacerlo en una sola línea!
In [32]:
nombre, edad = amigos_edades[0]
print(nombre)
print(edad)
Cuidado! Si por casualidad un amigo cumpliese un año más no podríamos ponerlo en la tupla, debido a que las tuplas no pueden modificarse.
In [33]:
amigos_edades[0][1] += 1
Vuelve a hacer la lista de la compra que hiciste en el último ejercicio, pero esta vez guarda cada elemento de la lista de la compra junto con su precio. Después, imprime los siguientes elementos:
In [ ]:
Un conjunto es una lista de elementos ordenados y en la que no hay elementos repetidos. Se definen con el operador {
. Sus operadores básicos son eliminar elementos repetidos, consultar si un elemento está en el conjunto o no y, por supuesto, operaciones típicas de los conjuntos como la unión, la intersección, la diferencia...
¿Qué ventajas puede darte usar un conjunto en lugar de una lista? Al estar ordenados, es mucho más rápido encontrar un elemento aunque esto también hace que insertar nuevos elementos sea más costoso.
Podemos crear un conjunto a partir de una lista:
In [34]:
mi_lista = [5,4,6,3,7,5,1,9,3]
print(mi_lista)
mi_conjunto = set(mi_lista)
print(mi_conjunto)
Además, podemos hacer las operaciones típicas sobre conjuntos.
In [35]:
A = {1,2,4,5,6,7}
B = {2,3,5,6,8,9}
Elementos de A que no están en B (diferencia):
In [36]:
A - B
Out[36]:
Elementos que están o bien en A o bien en B (unión):
In [38]:
A | B
Out[38]:
Elementos que están tanto en A como en B (intersección):
In [39]:
A & B
Out[39]:
Elementos que están en A o en B pero no en ambos (diferencia simétrica):
In [40]:
A ^ B
Out[40]:
¿Podríamos hacer un conjunto de listas?
In [1]:
{[1,2,3],[4,5,6]}
¡No! Esto es debido a que los elementos de los conjuntos deben ser hashables. Tal y como se explica en la documentación, un objeto es hashable si su clase define la función __hash__()
, que calcula un entero para caracterizar a un objeto, por lo que objetos con el mismo valor deben tener el mismo entero hash, y la función __eq__()
, que sirve para comparar objetos.
Las estructuras de datos que pueden cambiar su valor, como las listas o los diccionarios, no son hashables y, por lo tanto, no pueden ser elementos de un conjunto.
In [35]:
{x for x in 'abracadabra' if x not in 'abc'}
Out[35]:
In [36]:
for c in mi_conjunto:
print(c)
In [ ]:
Un último detalle sobre conjuntos: para crear un conjunto vacío usamos set()
ya que usar {}
creará un diccionario vacío.
A diferencia de las estructuras de datos que hemos visto hasta ahora, los diccionarios no se indexan por números sino por claves (keys). Cada entrada de nuestro diccionario está formada por dos valores distintos: la clave y el valor. La clave nos sirve para acceder al elemento (valor) de forma rápida. Debido a que las claves sirven para identificar a cada elemento,deben ser únicas: si introduces un nuevo elemento en el diccionario con clave repetida, se sobreescribirá el elemento anterior así que ¡mucho cuidado!
Vamos a ver un pequeño ejemplo de uso de los diccionarios para que nos quede más claro. Volvamos al ejemplo anterior sobre nuestros amigos y su edad.
In [41]:
mis_amigos = {'Paloma':25, 'Paula':20, 'Teresa':19, 'Marina':19,
'Braulio':21}
print(mis_amigos)
Para obtener la edad de Paloma, antes teníamos que estar mirando qué índice tenía en la lista, en cambio, ahora lo tenemos mucho más sencillo:
In [42]:
print(mis_amigos['Paloma'])
Si queremos saber los nombres de cada uno de nuestros amigos podemos listar las claves:
In [43]:
list(mis_amigos.keys())
Out[43]:
Y también podemos ver si hemos incluido a un amigo o no en nuestro diccionario:
In [44]:
'Marta' in mis_amigos
Out[44]:
La función dict
nos permite hacer diccionarios directamente desde Tuplas de la siguiente forma:
In [46]:
dict([('Paloma',25), ('Paula',20), ('Teresa',19), ('Marina', 19),
('Braulio', 21)])
Out[46]:
Y cuando las keys son simples string también es posible definir un diccionario de la siguiente forma:
In [47]:
dict(Paloma=25, Paula=20, Teresa=19, Marina=19, Braulio=21)
Out[47]:
In [42]:
{x: x**2 for x in (2,4,6)}
Out[42]:
Aunque también es posible iterar sobre diccionarios usando bucles for
. Para ello, usamos la función items
:
In [48]:
for nombre, edad in mis_amigos.items():
print(nombre, edad)
Cuando iteramos sobre una lista o un conjunto, podemos usar la función enumerate
para obtener la posición y el elemento de la misma forma:
In [49]:
for posicion, elemento in enumerate(['tic', 'tac', 'toe']):
print(posicion, elemento)
Por último, si queremos iterar sobre dos listas o conjuntos a la vez (del mismo tamaño), podemos hacerlo usando la función zip
:
In [50]:
questions = ['name', 'quest', 'favourite color']
answers = ['lancelot', 'the holy grail', 'blue']
for q, a in zip(questions, answers):
print("What is your {}? It is {}.".format(q,a))
En este ejemplo también vemos el uso de la función format
, que sirve para meter valores en un string. No sólo se puede usar para imprimir por pantalla sino para guardar valores en una variable y mucho más!
Usando la tupla que creaste en el ejercicio sobre tuplas, crea un diccionario de tu lista de la compra. Una vez tengas el diccionario creado:
format
: "he comprado __ y me ha costado __".del
In [ ]: