U2 - Fundamentos de Programacion en Python
U2 - Fundamentos de Programacion en Python
I. Introducción
II. Objetivos
V. Estructuras de control
VII. Funciones
VIII. Excepciones
X. Gestión de archivos
XI. Resumen
XIII. Glosario
XIV. Bibliografía
Lección 1 de 14
I. Introducción
Un elemento básico para cualquier científico de datos es el conocimiento de algún lenguaje de programación que le permita desarrollar programas con los que
procesar la información. Aunque sería posible utilizar cualquier lenguaje de propósito general, hay algunos que incluyen funcionalidades específicas para las
operaciones más comunes en este ámbito. En este sentido, existen varias alternativas.
Actualmente, hay dos lenguajes de programación que cubren las necesidades de procesamiento para
un proyecto de análisis de datos: el lenguaje R y el lenguaje Python.
En esta unidad, se va a estudiar el lenguaje Python. Se trata de un lenguaje de propósito general al que se han añadido, en forma de librerías, las funcionalidades
necesarias para análisis de datos de cualquier complejidad. Presenta funciones y estructuras de datos eficientes semejantes al lenguaje R. Asimismo, este
lenguaje se ha popularizado por varios motivos, entre los que destacan su facilidad de aprendizaje y su uso intensivo en la industria para este tipo de tareas.
Aparte de la facilidad de aprendizaje que ofrece el lenguaje, hay otros motivos por los que es muy popular:
Dispone de una amplia comunidad de desarrolladores. Continuamente se están desarrollando nuevas funcionalidades en forma de librerías,
de manera que es fácil encontrar en sus repositorios la funcionalidad que permita ahorrar tiempo en los desarrollos.
Al tratarse de un lenguaje muy popular, contratar personal cualificado en Python es más sencillo que para otras disciplinas.
Al tratarse de un lenguaje de propósito general, se puede utilizar para construir cualquier tipo de aplicación, no solo orientadas a datos.
Ofrece una gran capacidad de abstracción sobre el sistema, con un lenguaje muy expresivo, de manera que se puede hacer uso de todo el
hardware de la máquina, reduciendo al mínimo la cantidad de código necesaria.
C O NT I NU A R
En esta unidad se estudiará, en primer lugar, uno de los entornos de desarrollo más utilizados por
analistas y científicos de datos, denominado Jupyter Notebook, y, a continuación, se revisarán los
principales elementos del lenguaje de programación.
Sintaxis del lenguaje. Es preciso conocer los bloques más básicos que permitan construir los algoritmos.
Estructuras de control que permitan ejecutar sentencias del programa en función de determinadas condiciones.
Ten en cuenta:
En esta unidad se incluyen ejercicios que muestran la estructura y los elementos de Python. Se recomienda ejecutarlos en cuadernos de Jupyter Notebook, ya que
será beneficioso para el entendimiento de la sintaxis y relevancia del lenguaje. Al finalizar la unidad, el alumno será capaz de leer y codificar programas básicos en
Python.
Lección 2 de 14
II. Objetivos
3 Conocer las estructuras de control y las principales estructuras de datos del lenguaje Python.
5 Entender lo que hace una parte de código Python de complejidad media y simple.
Es un lenguaje interpretado
–
Por lo que no es necesario compilar el código antes de su ejecución.
Es multiparadigma
–
En este sentido, permite varios estilos de programación: imperativo, orientado a objetos y funcional.
Es multiplataforma
–
Python es un lenguaje disponible en los principales sistemas operativos (Windows, Linux y Mac).
En comparación con otros lenguajes de programación, Python es un lenguaje simple, fácil de leer y escribir y simple de depurar. Por estas razones es fácil de
aprender, de manera que la curva de aprendizaje es corta.
Asimismo, Python cuenta con una gran cantidad de librerías, tipos de datos y funciones incorporadas en el propio lenguaje, lo que lo dota de una gran capacidad
de procesamiento. En particular, se utiliza ampliamente en el ámbito del análisis de datos y, en general, en tareas de procesamiento de ciencias e ingeniería.
Desde el punto de vista del análisis de datos, dispone de una amplia variedad de librerías y herramientas como Numpy, Pandas, Matplotlib, Scipy, Scikit-learn,
C O NT I NU A R
Jupyter lleva estas funcionalidades a un espacio más visual, ya que permite no solo desarrollar código Python, sino también integrar fragmentos de código
(ejecutable) con otros contenidos multimedia o textuales. Esto convierte a Jupyter en una potente herramienta de documentación y elaboración de informes
analíticos.2
Los documentos generados se visualizan con un navegador (Explorer, Chrome, Firefox...) y pueden incluir cualquier elemento accesible a una página web, además
de permitir la ejecución de código escrito en el lenguaje de programación Python.
Jupyter contiene todas las herramientas científicas estándar de Python que permiten realizar tareas propias en el contexto del análisis de datos: importación y
exportación, manipulación y transformación, visualización, etc.
Para instalarlo, lo mejor es hacerlo a través de la suite de Anaconda, la cual incluye un conjunto de herramientas de desarrollo para Python entre las
que se encuentra el propio Jupyter Notebook. Anaconda se puede descargar desde la página web de Anaconda.3 En la zona de descargas, aparecen dos
versiones. Se debe bajar la versión para Python 3.x (figura 1).
Figura 1. Zona de descargas de Anaconda.
Fuente: elaboración propia.
C O NT I NU A R
1
Una vez descargado el software, se pueden seguir las instrucciones de instalación para cada sistema operativo que aparecen en la
misma página de descargas.4
No obstante, a continuación se sigue el procedimiento de instalación estándar de la versión 64-bit para Windows.
Se selecciona el ámbito de uso de la suite de Anaconda (local al usuario, o global al sistema). Para este ejemplo, se sigue la opción
recomendada (figura 3).
3
Se puede añadir Anaconda al PATH del sistema. Esto implica que los comandos de Anaconda (Python, etc.) se podrán ejecutar desde
cualquier parte del sistema. Sin embargo, esta opción no es recomendable, puesto que puede causar problemas en caso de
desinstalar y volver a instalar Anaconda. Asimismo, se registra la versión Python de Anaconda como el intérprete Python por defecto
del sistema (figura 5).
5
En este punto se inicia el proceso de instalación, que puede durar algunos minutos. Una vez finalizado, se pulsa en Next (figura 6).
6
El propio asistente da la recomendación de usar PyCharm5 como entorno integrado de desarrollo (figura 7). Instalarlo es opcional y
no es necesario para el estudio de esta unidad. No obstante, se recomienda su instalación, ya que PyCharm ofrece herramientas
adicionales que ayudan en la gestión de grandes proyectos (navegación entre funciones, refactorización de código, etc.).
5 PyCharm Download.
Figura 8. Ejecución de Jupyter Notebook.
Fuente: elaboración propia.
Para ejecutar Jupyter Notebook, basta con buscarlo en la lista de aplicaciones instaladas y pulsar en Open (figura 8).
Jupyter Notebook es una aplicación web bajo el modelo cliente-servidor. Al ejecutar Jupyter, se iniciará un servicio que se ejecuta localmente, por defecto, en la
URL http://127.0.0.1:8888, y que es accesible desde el navegador, por lo cual aparece un nuevo terminal donde se ejecuta la herramienta (figura 9). Este terminal no
debe cerrarse mientras se esté trabajando con Jupyter Notebook, de lo contrario el servicio se detendrá.
Figura 9. Terminal de ejecución de Jupyter Notebook.
Fuente: elaboración propia.
1
A la vez, se lanza un navegador donde se puede acceder a la interfaz principal de Jupyter Notebook (figura 10).
Esta interfaz actúa como un navegador de archivos y es posible moverse entre distintas carpetas —basta pinchar sobre la carpeta
correspondiente y se accede a su contenido—, además de crear nuevos ficheros y carpetas. Para ello se pulsa sobre el desplegable
que aparece en la parte derecha, denominado New, y allí se selecciona Text File o Folder, según lo que se quiera crear. También es
posible renombrar y eliminar las carpetas y archivos. Para ello basta con seleccionar la correspondiente carpeta o archivo. Una vez
seleccionado, en la parte superior aparecen las opciones Rename y el icono de la papelera, que permiten renombrar y eliminar
respectivamente.
2
Los notebooks de Jupyter son unos archivos con extensión .ipyb, en los que se puede escribir código Python ejecutable, texto, dibujar
gráficas y otras operaciones más. Para crearse un nuevo notebook basta con pulsar sobre el desplegable que aparece en la parte
superior derecha, denominado New, y seleccionar la opción Python 3 que se muestran debajo de Notebook (figura 11).
3
Título del notebook. Cada notebook tiene un título asociado. Por defecto, aparece con el nombre “Untitled”. Para modificarlo,
basta con pulsar sobre “Untitled” y aparece una ventana en la que se puede modificar el nombre.
Menús y barra de herramientas. En la parte superior de la interfaz del notebook, aparece un conjunto de menús con diferentes
opciones para gestionar los archivos, para editar, visionar, etc.
Iconos de acceso rápido. Iconos que permiten realizar las acciones más comunes sobre los elementos del notebook.
Celdas. La unidad de edición de un notebook es la celda. Cada celda contiene código Python o la información que documenta
dicho código. En este sentido, un notebookes una secuencia de celdas. Las celdas pueden ser de diferentes tipos según el
contenido que almacenan:
Markdown: permite escribir texto formateado con el objetivo de documentar. Se usa el lenguaje de marcas Markdown.6
Raw NBConvert: son celdas que permiten escribir fragmentos de código sin que sean ejecutados.
Code: sirven para escribir código Python ejecutable. Están marcadas por la palabra In [n] y están numeradas. El resultado
de la ejecución de cada celda se muestra en el campo Out [n], también numerado.
Para elegir el tipo de celda, se selecciona en un desplegable que aparece en la fila superior junto a los iconos.
6 Markdown Guide.
5
Todas las celdas son susceptibles de ejecutarse. La ejecución de una celda de código Python ejecutará el código escrito en la celda y
producirá una salida. La ejecución de celdas de tipo Markdown dará formato al texto. Para ejecutar una celda, hay que colocarse en
la celda y, posteriormente, pulsar el botón Run (figura 14). Es recomendable ver el vídeo “Running Hello World on a Jupyter
Notebook”7 . En él se muestran los pasos para ejecutar su primer programa.
De igual forma, para interrumpir la ejecución se pulsa sobre el cuadrado. Para crear celdas nuevas, se pulsa sobre el botón con el
icono del signo +.
Elegir el tipo de celda. Por defecto, son de tipo Code. Dependiendo del tipo de celda elegido, Jupyter lo interpretará de diferente
manera.
Una vez introducido el código o texto en la celda, se debe ejecutar. Para ello, se pulsa sobre el icono en forma de flecha.
El código definido en cada celda de tipo Code es visible al resto de celdas de este tipo. Es decir, si se define una variable o una
función en una celda, se podrán utilizar en celdas posteriores.
Ejemplo
Por ejemplo, si se quiere crear una celda que contenga la función: def multiplica(a,b): return a*b y
después invocarla con los valores 3 y 4, multiplica(3,4), se haría como se muestra en la figura 15.
Lección 4 de 14
Variables:
Una variable es un nombre que referencia un valor de cualquier tipo de dato. Por ejemplo:
Una sentencia de asignación crea variables nuevas y las asocia a valores. Tiene la siguiente sintaxis:
nombre = valor
Por ejemplo:
Para mostrar el valor de una variable, se puede usar la función print(nombre_variable). Asimismo, se le puede pasar una lista de variables, separadas por “,”, que
serán impresas en orden, en la misma línea. Por ejemplo:
Las variables son de un tipo que coincide con el tipo del valor que referencian. El método type () indica el tipo de una variable. Por ejemplo:
type(mensaje)
type(n)
C O NT I NU A R
Python ofrece cinco tipos de datos “primitivos”8, denominados así porque constituyen la base para componer tipos de datos más complejos. Son:
INT F LO AT BO O L STR
INT F LO AT BO O L STR
Enteros.
INT F LO AT BO O L STR
Números reales.
INT F LO AT BO O L STR
INT F LO AT BO O L STR
Cadenas de texto.
INT F LO AT BO O L STR
Es un tipo de dato especial, que se corresponde con la ausencia de valor o valor nulo.
Atención:
Es importante destacar que hay una serie de restricciones a la hora de establecer nombres de variables9:
C O NT I NU A R
Antes de poder utilizar una variable, esta debe existir (porque se le ha asignado un valor en algún momento anterior en el código).
En el siguiente ejemplo se muestra cómo se inicia una variable con el valor 0 y posteriormente se utiliza su valor en una segunda operación aritmética: a su valor
se le suma 1 y el resultado se vuelve a guardar en la misma variable. Es decir, se puede utilizar una misma variable en ambos lados de una operación de
asignación (=). En el lado derecho se lee su valor actual y en el izquierdo se actualiza con el valor resultante de la operación):
x = 0
x = x + 1
Por ejemplo:
n1 = 1
n2 = 3
suma = n1 + n1
print(n1," + ", n2," = ", suma)
lado = 3
area = lado * lado
print ("El área de un cuadrado que mide ",lado, "cm por lado es ",area)
C O NT I NU A R
import keyword
print(keyword.kwlist)
C O NT I NU A R
4.2. Operadores
Los operadores son símbolos especiales que representan cálculos, como la suma o la multiplicación. Los valores a los cuales se aplican esos operadores reciben
el nombre de operandos.
El resultado de cada operación dependerá del tipo de dato de cada operando. Incluso se pueden mezclar tipos de datos diferentes, de manera que el tipo de dato
del resultado de la operación será el mismo que el del operando menos significativo, es decir, el más genérico.
Ejemplo
La suma de dos variables de tipo int producirá como resultado otro int. Sin embargo, la suma de un int y un float será
de tipo float.
i+j, suma.
i-j, resta.
i*j, multiplicación.
i/j, división de dos números. Si son enteros, el resultado es un entero, y si son reales, el resultado es un real.
i==j, operador booleano que devuelve True si i es igual a j y False en caso contrario.
i!=j, operador booleano que devuelve True si i es distinto de j y False en caso contrario.
i>j, operador booleano para comprobar si i es mayor que j, y de forma similar: >=, <, <=, respectivamente mayor o igual, menor y menor o igual.
Ejemplo
• x >0 and x <10 es verdadero solo cuando x es mayor que 0 y menor que 10.
• n%2 == 0 or n%3 == 0 es verdadero si el número es divisible por 2 o por 3.
• not (x>y) es verdadero si x es menor o igual que y.
Hay que tener en cuenta que cualquier número distinto de cero se interpreta como “verdadero”. Por ejemplo: 23 and True
O PE R A DO R E S BO O LE A N O S O PE R A DO R E S LÓ G I C O S
Algunos ejemplos de uso de estos operadores booleanos son:
7 == 7 #True
7 != 7 #False
7 > 7 #False
7 >=7 #True
10 > 1 #True
10 < 1 #False
10 <=1 #False
1 < 10 #True
O PE R A DO R E S BO O LE A N O S O PE R A DO R E S LÓ G I C O S
V. Estructuras de control
Una vez vistas las sintaxis que ofrece Python para componer expresiones, es momento de profundizar en
el desarrollo de algoritmos más complejos.
Para componer estos algoritmos, se utilizan estructuras o sentencias de control que permiten ejecutar conjuntos de expresiones en función de condiciones.
Para agrupar estos conjuntos de expresiones asociadas a una estructura de control, Python obliga a utilizar diferentes niveles de sangrado del código, de manera
que esos bloques se puedan diferenciar de manera muy visual. La profundidad y los caracteres utilizados para definir este sangrado no son relevantes en Python,
aunque sí se ha definido un estándar dentro de la norma PEP8 (norma que define un conjunto de buenas prácticas para la programación en Python), que establece
que los sangrados deben ser de cuatro espacios (se puede leer la norma completa aquí).
sentencia
sentencia
...
estructura_control: # cada sentencia de control acaba en “:”
sentencia
...
estructura_control:
sentencia
...
sentencia
...
sentencia
No existe un límite en el número de sentencias que pueden aparecer en cada bloque (o nivel de sangrado). No obstante, siempre
debe haber al menos una sentencia.
C O NT I NU A R
5.1. Condicionales
Las expresiones condicionales facilitan la codificación de estructuras que bifurcan la ejecución del código en varias ramas o caminos de ejecución según
condiciones definidas. Existen varias formas.
5.1.1. IF SIMPLE
Tiene la estructura:
if expresión_booleana:
ejecutar código
Por ejemplo:
Programa que muestra el mensaje “El número es positivo” si se escribe un número mayor a cero.
Conclusión:
Si la expresión a continuación de la palabra if se evalúa como True, el bloque sangrado a continuación se ejecutará por completo. En caso de ser False, la
ejecución continuará con la siguiente sentencia a continuación del if en el mismo nivel de sangrado.
C O NT I NU A R
5.1.2. IF-ELSE
La segunda forma de la sentencia if es la ejecución alternativa, en la cual existen dos posibilidades y la condición determina cuál de ellas sería ejecutada:
if expresión booleana:
ejecutar bloque 1
else:
ejecutar bloque 2
Por ejemplo:
Programa que solicita un número al usuario y muestra si está dentro del rango 10-20.
Programa que muestra el mensaje “El número es positivo” si se escribe un número mayor que cero y, en caso contrario, se muestra “El número es negativo”.
Conclusión:
Dado que la condición debe ser obligatoriamente verdadera o falsa, solo una de las alternativas será ejecutada. Las alternativas reciben el nombre de ramas, ya
que se trata de ramificaciones en el flujo de la ejecución.
C O NT I NU A R
5.1.3. IF-ELIF-ELSE
La tercera forma de la sentencia if es el condicional encadenado que permite que haya más de dos posibilidades o ramas:
if expresión booleana:
ejecutar bloque 1
elif otra expresión booleana:
ejecutar bloque 2
else:
ejecutar por defecto
Por ejemplo:
n1 = 10
n2 = 11
n3 = 12
if n1 > n2 and n1 > n3:
print (n1)
elif n2 > n1 and n2 > n3:
print (n2)
elif n3 > n1 and n3 > n2:
print (n3)
else:
print ("Son iguales")
Programa que muestra el mensaje “El número es positivo” si se escribe un número mayor que cero, “El número es cero” si el número es cero y “El número es
negativo” si el número es menor que cero.
• No hay un límite para el número de sentencias elif. Si hay una cláusula else, debe ir al final, pero tampoco es obligatorio que esta exista.
• Cada condición es comprobada en orden. Si la primera es falsa, se comprueba la siguiente y así sucesivamente. Si una de ellas es verdadera, se ejecuta la rama
correspondiente y la sentencia termina. Incluso si hay más de una condición que sea verdadera, solo se ejecuta la primera que se encuentra.
Saber más
Un condicional puede también estar anidado dentro de otro. Sin embargo, estos pueden ser difíciles de leer, por lo que
deben evitarse y hay que tratar de usar operadores lógicos que permitan simplificar las sentencias condicionales
anidadas.
C O NT I NU A R
5.2. Bucles
Los bucles permiten la ejecución repetitiva de un bloque de sentencias. Este bloque se ejecutará de manera secuencial mientras se cumplan las condiciones
definidas en la estructura de control del bucle.
Tras cada iteración, se evaluará de nuevo la condición para determinar si se debe o no repetir la ejecución del bloque.
Se define la estructura de control del bucle, con la expresión que define las condiciones de ejecución.
2
Cuando se define la última sentencia del bucle, se pueden añadir nuevas sentencias posteriores, fuera de este (al mismo nivel de
sangrado que el bucle), para que sean ejecutadas cuando este finalice.
C O NT I NU A R
5.2.1. WHILE
Los bucles de tipo while permiten definir una estructura de control condicional, generalmente una expresión booleana, de manera que las sentencias del bucle se
ejecutarán indefinidamente mientras sea cierta la expresión (True).
Tras cada iteración, la ejecución vuelve al inicio del bucle, donde se evalúa de nuevo la condición. Solo cuando esta condición sea False, el programa saldrá del
bucle y continuará por la siguiente sentencia en el mismo nivel de sangrado que el while.
Por ejemplo:
i = 10
while i<=50 :
print(i)
i += 1
Usando un while, programa que imprime una palabra al revés:
invertida = ""
cadena = "al revés"
cont = len(cadena)
indice = -1
while cont >= 1:
invertida += cadena[indice]
indice = indice + (-1)
cont -= 1
print (invertida)
numero = 5
factorial = 1
print ("Factorial de",numero)
while numero > 0:
factorial *= numero
numero -= 1
print ("es ",factorial)
C O NT I NU A R
5.2.2. FOR
El siguiente tipo de bucle es el for. Se repite a través de un conjunto conocido de elementos, de modo que ejecuta tantas iteraciones como elementos hay en el
conjunto. Es útil utilizar la función range para crear una secuencia de elementos sobre los que poder iterar. Range puede tomar uno o dos valores:
1 Si toma dos valores, genera todos los enteros desde la primera entrada hasta la segunda entrada-1. Por ejemplo: range (2, 5) = (2, 3, 4).
x = 101
for i in range(1, x):
print(i)
Usando un for, programa que muestra los números pares del 1 al 100:
Usando un for, programa que pregunta al usuario cuántos números necesita validar. Posteriormente, el usuario teclea cada uno y valida si son positivos,
negativos o cero:
Un ejercicio más, programa que imprime al revés la frase que escriba el usuario:
C O NT I NU A R
Por ejemplo, se puede construir un bucle while que solicite al usuario que introduzca palabras hasta que la palabra introducida sea “Fin”:
while True:
linea = input ("Introduce Fin para finalizar: ")
if (linea == "Fin"):
break
print (linea)
C O NT I NU A R
while True:
linea = input ("Introduce Fin para finalizar: ")
if len(linea) > 3:
continue
if (linea == "Fin"):
break
print (linea)
Lección 6 de 14
6.1. Tuplas
Una tupla es una secuencia de valores de cualquier tipo indexada por enteros. Las tuplas son inmutables —tienen una longitud fija y sus elementos no pueden
cambiarse— y son comparables. Sintácticamente, una tupla es una lista de valores separados por comas y encerradas entre paréntesis.
Ejemplo
t = ("a","b","c","d","e","f")
Para crear una tupla con un único elemento, es necesario incluir una coma al final.
p = (4,)
Otra forma de construir una tupla es usar la función interna tuple, que crea una tupla vacía si se invoca sin argumentos y, si se le proporciona como argumento una
secuencia (cadena, lista o tupla), genera una tupla con los elementos de la secuencia. Por ejemplo:
t = tuple()
print (t)
t = tuple("supercalifragilisticoespialidoso")
print (t)
No se pueden modificar los elementos de una tupla, pero se puede reemplazar una tupla por otra.
Se pueden comparar dos tuplas usando los caracteres de comparación ya vistos. De forma nativa, los comparadores comparan elemento a elemento de
cada tupla. Se comienza comparando el primer elemento de cada secuencia. Si es igual en ambas, pasa al siguiente elemento y así sucesivamente hasta
que encuentra uno que es diferente. A partir de ese momento, los elementos siguientes ya no se tienen en cuenta.
C O NT I NU A R
Tupla con los nombres de los meses del año. Se solicita al usuario que escriba un número y se muestra el mes del año que corresponde:
meses = ("Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Novie
numero = int(input("Escribe un número entre 1 y 12: "))
if( numero>=1 and numero <= 12):
print("El mes ",numero, "es: ", meses[numero-1])
else:
print(":(")
Tupla con números aleatorios del 1 al 10. Se solicita un número al usuario y se imprime cuantas veces se repite:
tupla = (2,3,2,1,3,4,7,8,9,7,6,5,5,6,7,8,9,10,4,3,2,1,6,4,5,3,6,6,6,6,6)
numero = int(input("Escribe un numero del 1 al 10: "))
contador= 0
for i in tupla:
if numero == i:
contador = contador + 1
print ("El número ", numero, " se repite ", contador, " veces.")
C O NT I NU A R
6.2. Listas
Al igual que las tuplas, las listas son secuencias de elementos de cualquier tipo, indexados mediante números enteros. La principal diferencia con las tuplas es
que las listas sí son mutables. Es decir, su contenido puede cambiarse, así como su longitud (se pueden añadir y borrar elementos).
El método más simple para crear una lista es encerrar los elementos entre corchetes. Por ejemplo:
La asignación de valores a una lista no retorna nada; sin embargo, si se usa el nombre de la lista, es posible ver el contenido de la variable. Por ejemplo:
Una lista que no contiene elementos recibe el nombre de lista vacía —se crea con unos corchetes vacíos []—. Por ejemplo:
t = []
t # Devuelve []
Para acceder a los elementos de una lista, se usa el operador corchete, que contiene una expresión que especifica el índice —los índices comienzan por 0—. Los
índices de una lista se caracterizan por:
Si un índice tiene un valor negativo, se cuenta hacia atrás desde el final de la lista.
Por ejemplo:
t = [10, 20, 30, 40]
t[2] # Devuelve 30
t[-2] # Devuelve 30
C O NT I NU A R
Recuerda:
Como se ha comentado, las listas son mutables, puesto que su estructura puede cambiarse después de haberlas creado. Por ejemplo:
Los elementos en una lista no tienen por qué ser todos del mismo tipo. Por ejemplo:
Cuando una lista está dentro de otra, se dice que está anidada. En una lista anidada, cada lista interna solo cuenta como un único elemento. Por ejemplo:
C O NT I NU A R
Operadores:
El operador + concatena listas.
a = [1, 2, 3]
b = [4, 5, 6]
c = a + b
print (c) # Devuelve [1, 2, 3, 4, 5, 6]
a = [1, 2, 3]
2 in a # True
5 in a # False
El operador in se puede usar para recorrer los elementos de una lista usando un bucle for, por ejemplo:
a = [1, 2, 3]
for x in a:
print (x)
El operador (slice) cuya sintaxis es [inicio:final:salto] permite seleccionar secciones de una lista.
C O NT I NU A R
Funciones
t = [1, 2, 3, 4, 5, 6]
sum (t) # Devuelve 21
t = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print ( max(t), min (t) ) # Devuelve 9 1
La función range () crea una secuencia de valores a partir del dado como parámetro. Es útil para los bucles de tipo for. Por ejemplo:
Para ver el contenido generado por range (), se debe usar el constructor list.
extend toma una lista como argumento y añade al final de la actual todos sus elementos.
t1 = [1, 2, 3, 4, 5, 6]
t2 = [7, 8, 9]
t1.extend(t2)
t1 # Devuelve [1, 2, 3, 4, 5, 6, 7, 8, 9]
t = ["d","e","a","c","x"]
t.sort()
t # Devuelve ['a', 'c', 'd', 'e', 'x']
t = [7,6,5,4,3,2,1]
t.sort()
t # Devuelve [1, 2, 3, 4, 5, 6, 7]
El método pop elimina un elemento de la lista referenciado en forma de índice. Devuelve el elemento que ha sido eliminado. Si no se proporciona un índice,
borra y devuelve el último elemento.
t = ["d","e","a","c","x"]
x = t.pop(1)
print (t) # Devuelve ['d', 'a', 'c', 'x']
print (x) # Devuelve e
t = ["d","e","a","c","x"]
t.remove("e")
print (t) # Devuelve ['d', 'a', 'c', 'x']
Saber más
C O NT I NU A R
En Python, dos listas son equivalentes si tienen los mismos elementos, pero no son idénticas. Sin
embargo, si dos listas son idénticas (es decir, sus referencias apuntan al mismo “objeto” en memoria, de
manera que, si se cambia una, el cambio se refleja en la otra), también son equivalentes.
Por tanto, la equivalencia no implica que sean idénticas. Para comprobar si dos variables son idénticas, se puede usar el operador is.
En este ejemplo, a y b son equivalentes, pero no idénticas:
a = [1, 2, 3]
b = [1, 2, 3]
a is b # Devuelve false
a = [1, 2, 3]
a = b
a is b # Devuelve true
Si a y b son idénticas, significa que la lista tiene dos referencias o nombres diferentes. Así, los cambios que se hagan usando cualquiera de los nombres
afectan a la misma lista.
a = [1, 2, 3]
b = a
b[0] = 45
print (a) # Devuelve [45, 2, 3]
En las operaciones que se realizan sobre las listas existen aquellas que modifican listas y otras que crean listas nuevas. Por ejemplo, el método append
modifica una lista, pero el operador + crea una lista nueva.
t1 = [2, 3]
t2 = [5]
t1.append(4)
print ( t1, t1+t2 ) # Devuelve [2, 3, 4] [2, 3, 4, 5]
C O NT I NU A R
Ejemplos con listas
Programa que solicita al usuario una palabra y guarda los caracteres en una lista sin repetirlos:
Lista vacía, se solicita al usuario valores para la lista. Al final, se muestra la suma y el promedio:
lista = []
total = int(input("¿Cúantos elementos tendrá la lista?: "))
for i in range(total):
numero = int(input("Escribe un numero: "))
lista.append(numero)
suma = sum(lista)
promedio = suma / len(lista)
print (lista)
print("La suma es ",suma)
print("El promedio es ",promedio)
C O NT I NU A R
Lista que contiene los valores de 3 elevado a la x, donde x es un número par y pertenece al rango del 1 a 100:
c = [3 ** x for x in range(1,101) if x % 2 == 0]
print (c)
c = [ x for x in range(1,101) if x % 3 == 0]
print (c)
C O NT I NU A R
6.3. Diccionarios
Un diccionario es una colección no ordenada de pares clave-valor donde la clave y el valor son objetos que pueden ser de (casi) cualquier tipo. Los diccionarios
permiten acceder y manipular valores concretos a través de sus claves.
La función dict () crea un diccionario nuevo sin elementos.
ejemplo = dict()
ejemplo # Devuelve {}
C O NT I NU A R
Para añadir elementos al diccionario, se pueden usar corchetes y usar acceso indexado a través de la clave. Por ejemplo:
ejemplo = dict()
ejemplo # Devuelve {}
ejemplo["primero"] = "Libro"
ejemplo # Devuelve {'primero': 'Libro'}
Otra forma de crear un diccionario es mediante una secuencia de pares clave-valor separados por comas y encerrados entre llaves. Por ejemplo:
ejemplo2 = {"primero":"Libro","segundo":34,"tercero":(3,4)}
ejemplo2 # Devuelve {'primero': 'Libro',
'segundo': 34, 'tercero': (3, 4)}
El orden de los elementos en un diccionario es impredecible, pero eso no es importante, ya que se usan las claves para buscar los valores correspondientes. En
este sentido, si la clave especificada no está en el diccionario, se obtiene una excepción de tipo KeyError.
Algunos métodos:
Función len
–
La función len devuelve el número de parejas clave-valor.
ejemplo2 = {"primero":"Libro","segundo":34,"tercero":(3,4)}
len (ejemplo2) #3
Operador in
–
El operador in permite comprobar si un valor existe como clave dentro del diccionario.
ejemplo2 = {"primero":"Libro","segundo":34,"tercero":(3,4)}
"primero" in ejemplo2 # True
Método values
–
Para ver si algo aparece como valor en un diccionario, se puede usar el método values, que devuelve los valores como una lista, y después usar el operador in sobre esa lista.
valores = ejemplo2.values()
"uno" in valores # False
Método get ()
–
El método get () toma una clave y un valor por defecto. Si la clave aparece en el diccionario get, devuelve el valor correspondiente. En caso contrario, devuelve el valor por
defecto.
Método keys ()
–
El método keys () crea una lista con las claves de un diccionario.
Método items ()
–
El método items () devuelve una lista de tuplas, cada una de las cuales es una pareja clave-valor sin ningún orden definido.
C O NT I NU A R
Se puede utilizar un diccionario como una secuencia en una sentencia for, de manera que se recorren todas las claves del diccionario. Por ejemplo:
El ejemplo anterior se podría haber realizado de una manera equivalente utilizando el método ítems (), que devuelve una lista de tuplas donde cada tupla contiene
dos elementos: clave y valor.
VII. Funciones
Una función es una secuencia de sentencias que realizan una operación y que reciben un
nombre.
Una vez que se ha definido una función, se puede llamar a la función por ese nombre y reutilizarla a lo largo del programa.
El resultado de la función se llama valor de retorno. Las funciones pueden retornar uno o varios valores, aunque no es obligatorio que lo hagan.
Proceso:
Para crear una función se utiliza la palabra reservada def. A continuación, aparece el nombre de la función, entre paréntesis los parámetros, y finaliza con :. Esta
línea se denomina cabecera de la función. El código de la función, o cuerpo, se define en líneas sucesivas, con un nivel más de sangrado con respecto a la
cabecera. El cuerpo puede contener cualquier número de sentencias. Para devolver el valor se usa la palabra reservada return.
Por ejemplo:
def palindromo(palabra):
palabra_al_reves = palabra[::-1]
print(palabra_al_reves)
if( palabra == palabra_al_reves ):
print("Es palindromo")
else:
print("No es palindromo")
palindromo("Aguila") # 'NO es palindromo'
palindromo("arenera") # 'es palindromo'
11Palindrome Definition.
C O NT I NU A R
Las reglas para los nombres de las funciones son las mismas que para las variables: se pueden usar letras, números y algunos signos de puntuación, pero el
primer carácter no puede ser un número. No se puede usar una palabra clave como nombre de una función y se debería evitar también tener una variable y una
función con el mismo nombre. Las funciones con paréntesis vacíos después del nombre indican que esta función no toma ningún argumento.
La sintaxis para llamar a una función definida consiste en indicar el nombre de la función junto a una expresión entre paréntesis denominados argumentos de la
función. El argumento es un valor o variable que se pasa a la función como parámetro de entrada.
Algunas características:
La definición de una función debe ser ejecutada antes de que la función se llame por primera vez, y no generan ninguna salida. Sin embargo,
las sentencias dentro de cada función son ejecutadas solamente cuando se llama a esa función.
En las funciones no se especifica el tipo de parámetro ni lo que se retorna. No obstante, en Python 3 se introdujo una nueva sintaxis que
permite indicar el tipo “esperado” de cada parámetro, en la cabecera de la definición de la función. Y se subraya “esperado” porque el intérprete
no evalúa el tipo de cada parámetro en tiempo de ejecución. Se trata simplemente de una convención para facilitar la comprensión del código
y, por tanto, está constituida como una buena práctica en el ámbito del desarrollo en Python.12
12Say yes more. Yes opens doors. No closes them. Yes pushes us. No keeps us safe at home. Imagine all the opportunities waiting for a yes.
Las definiciones de funciones no alteran el flujo de la ejecución de un programa debido a que las sentencias dentro de una función no son
ejecutadas. Sin embargo, una llamada a una función es como un desvío en el flujo de la ejecución. En vez de pasar a la siguiente sentencia, el
flujo salta al cuerpo de la función, ejecuta todas las sentencias que hay allí y después vuelve al punto donde lo dejó.
Los argumentos de una función solo existen en el ámbito de esta, y dejan de hacerlo cuando la ejecución de la función termina. Asimismo, se
puede pasar como parámetro cualquier expresión, que será evaluada justo antes de iniciar la ejecución de la función, y su resultado quedará
almacenado en el argumento correspondiente.
En el inicio de la ejecución, los parámetros proporcionados en la invocación pasan a ser referenciados por los argumentos definidos en la
cabecera de esta, para poder ser usados en el cuerpo:
Cuando se definen los argumentos de una función, estos pueden tener valores por defecto, que se utilizarán en caso de que se invoque la
función sin esos argumentos. Por ejemplo:
def ejemplo(a=3):
print (a)
ejemplo() # Devuelve 3
Una vez que se ha definido una función, puede usarse dentro de otra, lo cual facilita la descomposición de un problema y su resolución
mediante una combinación de llamadas a funciones. Por ejemplo:
Aquellas que producen resultados, con los que se querrá hacer algo.
def ejemplo1(a):
return 3 * a
b = ejemplo1(4)
print(b) # Devuelve 12
C O NT I NU A R
Es posible definir funciones que devuelvan múltiples resultados, los cuales se empaquetan en una tupla. Por ejemplo, función que recibe el número de segundos y
calcula la duración de horas, minutos y segundos:
def segundos_a_HMS(segundos):
hs = int(segundos / 3600)
min = int((segundos % 3600) / 60)
seg = int((segundos % 3600 ) % 60)
return (hs, min, seg)
(h, m, s) = segundos_a_HMS(3661)
print ("Son",h,"horas",m,"minutos",s,"segundos")
# Son 1 horas 1 minutos 1 segundos
Python proporciona un número importante de funciones internas que pueden usarse sin necesidad de tener que definirlas previamente. Se denominan built-in
functions 13:
Las funciones max y min dan respectivamente el valor mayor y menor de una lista.
La función len devuelve cuantos elementos hay en su argumento. Si el argumento es una cadena, devuelve el número de caracteres que hay
en la cadena.
Funciones que permiten convertir valores de un tipo a otro: int(), float(), y str().
La función chr tiene como parámetro un número entero que devuelve un carácter (cadena) cuyo código Unicode14 es el número entero
(parámetro). Por ejemplo, chr(97) devuelve el carácter (cadena) 'a'.
La función ord tiene como parámetro un carácter (cadena) que devuelve el valor ASCII de una cadena. Por ejemplo, ord ('a') devuelve el entero
97.
13Built-in functions.
14Unicode in Python.
C O NT I NU A R
En Python, el paso de argumentos a una función se hace por referencia, de manera que las modificaciones que se hagan sobre los argumentos se mantienen
después de la llamada y ejecución de la función, dentro de las variables proporcionadas como parámetro en la llamada.
for x in range(65,91):
print ("Carácter UNICODE de ",x ,'=' ,chr(x) )
Lección 8 de 14
VIII. Excepciones
Durante la ejecución de un programa, se pueden producir situaciones inesperadas que den lugar a un error. Son situaciones en las que, por norma general, la
continuación de la ejecución del programa de forma normal produciría resultados incorrectos.
Por eso, en esas ocasiones, es conveniente “lanzar” una excepción, de manera que se interrumpa la ejecución de las sentencias sucesivas de ese bloque y los
bloques exteriores hasta llegar a un bloque “padre” que disponga de lógica apropiada para gestionar ese error.
Una excepción se puede lanzar de forma voluntaria en cualquier punto de un programa, si se dan condiciones ante las que no se debe
continuar la ejecución.
Las excepciones se pueden capturar, para tratarse y, en caso de ser posible, proporcionar un flujo alternativo de ejecución.
Existen diferentes tipos de excepciones dentro del sistema y todas parten de una misma clase de error: el error de tipo Exception. Se pueden
definir otros tipos de excepciones, pero eso queda fuera del alcance de esta unidad.
C O NT I NU A R
Se pueden definir varios bloques except para un mismo try, de manera que se puedan tratar de forma diferente los diferentes tipos de
excepción que se pueden lanzar en el try.
Sintaxis
try:
animal = input("Elije tu animal preferido entre caballo, perro, gato:")
if animal not in ['caballo', 'perro', 'gato']:
throw Exception("Animal incorrecto")
print("Tu elección ha sido", animal)
except Exception as e: # Guardamos en la variable e la
excepción lanzada
print("Elección incorrecta,", e) # Imprimiría "Elección
incorrecta, Animal incorrecto"
Lección 9 de 14
Python dispone de una amplia variedad de módulos o librerías. Los módulos son programas que amplían las funciones y clases de Python para realizar tareas
específicas. Los módulos tienen extensión py. En la página web de Python, se puede encontrar el índice de módulos de Python.
Para poder utilizarlas, hay que importarlas previamente, lo cual se puede hacer de varias formas:
Importar todo el módulo mediante la palabra reservada import, de manera que para utilizar un elemento hay que usar el nombre del módulo
seguido de un punto (.) y el nombre del elemento que se desee obtener.
import random
for i in range(4):
x = random.random()
print (x)
Importar solo algunos elementos del módulo mediante la estructura from nombre_modulo import lista_elementos, de manera que los
elementos importados se usan directamente por su nombre. Por ejemplo, programa que genera cuatro números enteros aleatorios entre 1 y 10:
Programa que calcula el perímetro o área de un círculo. El usuario debe teclear el radio del círculo y seleccionar el cálculo que necesita:
Importar todo el módulo mediante la palabra reservada import y definir un alias mediante la palabra reservada as, de manera que para usar un
elemento hay que utilizar el nombre del módulo seguido de un punto (.) y el nombre del elemento que se desee obtener. Por ejemplo, usando el
módulo os15, programa que imprime el directorio actual y su contenido:
import os as te
print("Directorio actual: ", te.getcwd())
print("Directorios/ficheros: ", te.listdir(os.getcwd()))
Para conocer las operaciones disponibles de un módulo, se puede usar el comando dir.
import os
dir (os)
Lección 10 de 14
X. Gestión de archivos
F I C HE R O M O DO
F I C HE R O M O DO
Es otra cadena que indicará el modo de apertura del fichero. Los modos más destacados son:
Saber más
La función open retorna un objeto file, que expone una serie de métodos para manipular el descriptor de fichero asociado.
La operación más sencilla que se puede realizar sobre un archivo es leer su contenido. Para procesarlo línea por línea, es posible hacerlo de la siguiente forma:
fichero = open("cuna.txt")
for linea in fichero:
print(linea)
fichero.close()
C O NT I NU A R
Al terminar de trabajar con un archivo, se debe cerrar. Esto es especialmente importante cuando el fichero se abre en modo edición (w o a), ya que, según el
sistema, podrían no guardarse todos los cambios una vez finalizada la ejecución del programa. Para ello, se usa close.
fichero.close()
Además, usando la función readlines es posible recuperar de una sola vez todo el contenido del archivo estructurado en forma de líneas.
fichero= open("cuna.txt")
lineas = fichero.readlines()
print(lineas)
En este caso, la variable líneas tendrá una lista de cadenas con todas las líneas del archivo. Téngase en cuenta que es posible eliminar los saltos de línea.
lineas[0].rstrip()
C O NT I NU A R
f = open ('prueba.txt','w')
f.write('Primer archivo')
f.close()
Crear un archivo llamado “nuevo.txt” y guardar las líneas pares del archivo “cuna.txt” que se puede descargar en este enlace:
cuna.txt.zip
649 B
En ocasiones, es posible que un bloque de código termine de forma abrupta (mediante un error o excepción). Esto puede ser especialmente grave si ocurre en
mitad de una operación de escritura en un fichero abierto. En este caso, en el evento de una excepción durante la escritura de un dato en un fichero, haría que la
excepción se elevase a la rutina llamante, evitando que se ejecute la función close. Como se ha visto, esto podría causar que todo o parte del contenido añadido al
fichero se perdiera.
Para evitarlo, Python ofrece un mecanismo de protección denominado context managers17, que permite utilizar los recursos justo en el momento en el que son
necesarios.
17Context Managers.
C O NT I NU A R
Uno de los más utilizados está disponible a través de la sentencia with, que permite “encapsular” el acceso a un fichero, asegurando que se cierra en caso de
errores inesperados:
f = open ('prueba.txt','w')
try:
f.write('Primer archivo')
finally:
f.close()
Lección 11 de 14
XI. Resumen
En esta unidad, se ha introducido el lenguaje de programación Python. Se trata de un lenguaje de propósito general que dispone de potentes librerías para análisis de datos,
lo cual lo convierte en uno de los lenguajes más utilizados en el ámbito del big data.
Asimismo, se ha mostrado cómo instalar y utilizar la herramienta Jupyter Notebook. Esta herramienta permite desarrollar y ejecutar código Python de manera muy visual,
alternando código con secciones de lenguaje de marcas (Markup language). De esta manera, se pueden componer análisis completos donde intercalar gráficas,
imágenes, vídeos, así como cualquier otro componente web junto con el código.
Esto convierte a Jupyter Notebook en una de las herramientas preferidas por analistas y científicos de datos para presentar informes interactivos de cierta complejidad.
Gracias a Jupyter, se han podido explorar cómodamente, y de forma interactiva, las funcionalidades básicas de Python.
Se ha hecho un recorrido por los primeros pasos dentro del lenguaje, aprendiendo a asignar variables y a realizar operaciones aritméticas básicas.
Se ha aprendido que Python es un lenguaje de tipado dinámico, lo que implica que una variable puede contener datos de cualquier tipo y que esos tipos se definen en
tiempo de ejecución.
Se ha enseñado cómo utilizar las estructuras básicas de control de flujo en Python, como if-ese, for y while, y se ha visto la peculiar sintaxis de Python a la hora de definir
bloques de código, mediante sangrado.
Se ha trabajado con las estructuras de datos básicas del lenguaje, como las listas y los diccionarios. Es importante recordar que una lista es una colección de elementos
accesibles a través de un índice, mientras que un diccionario es una colección de datos referenciados por una clave.
Asimismo, se ha aprendido a trabajar con funciones y a entender su vital importancia a la hora de definir secciones de código reutilizable.
Se ha hecho hincapié en la potencia de la sintaxis de Python a la hora de facilitar la construcción de estructuras de datos complejas mediante listas por comprensión. En
una sola línea se pueden construir listas que en otros lenguajes implicarían el desarrollo de varios bloques anidados.
Por último, se ha visto el sistema de gestión de errores de Python, basado en excepciones. Las excepciones son un mecanismo muy habitual en los lenguajes de
programación actuales y permiten detener la ejecución del algoritmo en un punto en el que se produce una situación inesperada o errónea.
La ejecución de los ejercicios de la unidad se muestra en el cuaderno que se puede descargar en el siguiente enlace: UD2_Python.ipynb. Se recomienda abrir el cuaderno
con Jupyter Notebook, basta con iniciar el servicio "Jupyter Notebook" e importar el fichero “UD2_Python.ipynb” desde la opción Upload.
UD2_Python.zip
69.3 KB
Lección 12 de 14
ENUNCIADO
73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450
Se sabe que la secuencia de cuatro dígitos consecutivos de este número que computa el mayor producto es 9 x 9 x 8 x 9 = 5832.
DATOS
Desarrollar una función que, dado un número de dígitos consecutivos, obtenga la secuencia que calcule el mayor producto.
VER SOLUCIÓN
SOLUCIÓN
XIII. Glosario
Programa
–
Se trata de un conjunto de sentencias de un lenguaje de programación cuya ejecución produce un resultado.
Entorno de desarrollo
–
También denominado editor. Es una aplicación informática que permite crear y ejecutar programas para un determinado lenguaje de programación.
Jupyter Notebook
–
Entorno de desarrollo para Python.
Notebook
–
Tipo de archivo utilizado por Jupyter Notebook para editar código Python que permite integrar otros recursos como vídeos o imágenes.
Variable
–
Nombre que referencia una posición de memoria.
Expresión
–
Conjunto de valores o variables combinadas mediante un conjunto de operadores que representan un valor de un tipo de datos.
Estructura de control
–
Hace referencia a sentencias de un lenguaje que permiten estructurar el flujo de ejecución de un programa.
Bucle
–
Estructura de control de Python que permite repetir un conjunto de acciones un número de veces que depende de una condición determinada.
Condicional
–
Estructura de control de Python que permite ejecutar acciones alternativas de acuerdo con el valor de una expresión.
Estructura de datos
–
Hace referencia a una forma lógica determinada de almacenar la información.
Mutabilidad
–
Es una propiedad de las estructuras de datos en Python que indica si los datos pueden modificar su estructura y contenido una vez que se han definido.
Diccionario
–
Estructura de datos de Python que permite almacenar la información en forma de parejas clave-valor. Es un tipo de datos mutable.
Lista
–
Estructura de datos de Python que permite almacenar un conjunto de datos de diferentes tipos. Es un tipo de datos mutable.
Tupla
–
Estructura de datos de Python que permite almacenar un conjunto de datos de diferentes tipos. Es similar a las listas, pero no mutable.
Función
–
Es la unidad de estructuración de un programa en Python. Representa un conjunto de acciones que reciben un nombre y que pueden depender de un conjunto de parámetros
y devolver como resultado uno o más valores.
Módulo
–
También denominado librería, se trata de un conjunto de funciones o métodos que añaden nuevas funcionalidades a Python respecto a las que tiene de manera estándar.
Excepción
–
Situación de error que interrumpe la ejecución del programa en un punto dado, elevando el problema en la jerarquía del algoritmo hasta que un bloque la capture para
gestionarla.
Lección 14 de 14
XIV. Bibliografía
Marzal Varó, A., Gracia Luengo, I. y García Sevilla, P. Introducción a la programación con Python 3. Castelló de la Plana: Publicacions de la
Universitat Jaume I. Servei de Comunicació i Publicacions; 2014.
Rossum, G. Guía de aprendizaje de Python. Release 2.4.1a0, Fred L. Drake, Jr. 2005
Wachenchauzer, R., Manterola, M., Curia, M., Medrano, M. y Páez, N. Algoritmos de programación con Python. 2006-2019.