Versión imprimible multipagina. Haga click aquí para imprimir.
Recursos más avanzados
1 - Instalación y configuración del entorno
Instalación de un intérprete
- https://docs.python.org/3/using (según el sistema operativo)
En Linux tenemos que instalar también python-dev si se van a instalar algunas librerías.
Instalación de un editor
- https://code.visualstudio.com/docs/python/python-tutorial (Visual Studio Code)
Extensiones de Visual Studio Code
1.1 - Ejercicio de depuración
Depurar
Objetivo
En este ejercicio, los estudiantes deberán depurar un programa Python que intenta realizar una búsqueda binaria en una lista ordenada de números. El programa tiene varios errores, y los alumnos deberán utilizar las herramientas de debug de VS Code para identificar y corregir estos problemas.
Instrucciones
- Crea un nuevo archivo Python (
debug_binsearch.py
) en un nuevo proyecto en VS Code. - Pega el siguiente código, que tiene varios errores intencionados:
# debug_binsearch.py
# Este programa tiene errores. Tu tarea es usar el debug de VS Code para encontrarlos y corregirlos.
def binary_search(arr, x):
low = 0
high = len(arr)
while low <= high:
mid = (low + high) / 2 # Error intencionado
mid_val = arr[mid] # Error intencionado
if mid_val < x:
low = mid + 1
elif mid_val > x:
high = mid - 1
else:
return mid # Encuentra el valor
return -1 # Valor no encontrado
if __name__ == "__main__":
arr = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
x = input("Ingrese un número para buscar en la lista: ") # Error intencionado
# Realizar búsqueda binaria
result = binary_search(arr, x)
if result != -1:
print(f"El número {x} está en la posición {result} de la lista.")
else:
print(f"El número {x} no se encuentra en la lista.")
- Coloca breakpoints en las líneas que consideres relevantes para encontrar los errores.
- Inicia el debug (puedes hacerlo presionando F5 o yendo a la barra lateral de “Run and Debug”).
- Observa las variables, la salida y el flujo del programa para identificar los errores.
- Corrige los errores que encuentres y reinicia el debug para confirmar que el programa funciona correctamente.
Errores a Corregir
mid = (low + high) / 2
calculamid
como un número de punto flotante. Debe ser un entero para indexar la lista. Puede corregirse comomid = (low + high) // 2
.high = len(arr)
debería serhigh = len(arr) - 1
para evitar el acceso fuera de rango.- El valor ingresado
x
es una cadena. Debe ser convertido a un entero antes de pasarlo a la funciónbinary_search
.
if __name__ == "__main__"
Por supuesto, el bloque if __name__ == "__main__":
es un patrón común en programas Python.
Cuando ejecutas un script en Python, el intérprete asigna un valor especial a la variable __name__
. Este valor será "__main__"
si el script se está ejecutando como programa principal. Pero si el script se importa como un módulo en otro script, el valor de __name__
será el nombre del archivo del script (sin la extensión .py
).
En otras palabras, if __name__ == "__main__":
permite diferenciar entre los dos escenarios: ¿se está ejecutando este archivo Python como programa principal o se está importando en otro script como un módulo?
¿Para qué se usa?
Este bloque se usa principalmente por dos razones:
Modularidad: Al poner el código bajo este bloque, te aseguras de que ese código solo se ejecute cuando el script sea el programa principal. Esto permite que otros scripts importen funciones y clases de este script sin ejecutar todo el código inmediatamente al importarlo.
Organización del Código: Al colocar el “código de arranque” del script bajo este bloque, se separa claramente la definición de funciones y clases del código que realmente inicia la lógica del programa. Esto hace que el código sea más legible y mantenible.
Un ejemplo
Supongamos que tienes un script llamado mi_script.py
con el siguiente contenido:
# Definición de una función
def imprimir_saludo(nombre):
print(f"Hola, {nombre}.")
# Código de arranque
if __name__ == "__main__":
imprimir_saludo("Alice")
Si ejecutas mi_script.py
directamente (python mi_script.py
), verás la salida Hola, Alice.
porque el script se está ejecutando como programa principal y, por lo tanto, __name__
es igual a "__main__"
.
Ahora, si importas mi_script.py
en otro script:
import mi_script
mi_script.imprimir_saludo("Bob")
Verás la salida Hola, Bob.
pero no verás Hola, Alice.
Esto es porque al importar mi_script
, la variable __name__
en mi_script.py
no es "__main__"
, por lo que el bloque if __name__ == "__main__":
no se ejecuta.
2 - Entrada y Salida
Ejercicio Práctico: Calculadora de Índice de Masa Corporal (IMC)
Objetivo
El objetivo de este ejercicio es crear un programa en Python que calcule el Índice de Masa Corporal (IMC) de una persona. El programa deberá pedir la altura en metros y el peso en kilogramos, calcular el IMC y mostrar un mensaje con el resultado.
Fórmula del IMC
El IMC se calcula con la siguiente fórmula:
Instrucciones
- Crea un nuevo archivo Python y nómbralo
calculadora_imc.py
. - Utiliza la función
input()
para obtener el peso y la altura del usuario. Asegúrate de convertir estas entradas a números flotantes para poder hacer cálculos con ellos. - Usa la fórmula del IMC para calcular el índice.
- Utiliza la función
print()
para mostrar el IMC calculado. Asegúrate de que el resultado se muestre con dos decimales.
Código de ejemplo
# Obtener peso del usuario
peso = float(input("Por favor, introduce tu peso en kilogramos: "))
# Obtener altura del usuario
altura = float(input("Por favor, introduce tu altura en metros: "))
# Calcular IMC
imc = peso / (altura ** 2)
# Mostrar el resultado
print(f"Tu Índice de Masa Corporal (IMC) es: {imc:.2f}")
Ampliación
- Agrega validaciones para asegurarte de que el usuario no introduzca números negativos o cero.
- Extiende el programa para que, además de mostrar el IMC, indique si el usuario está bajo de peso, en su peso ideal o tiene sobrepeso, según la escala de IMC.
3 - Clases
Ejercicios
Ejercicio 1: Clase Persona
Crea una clase llamada Persona
que tenga un atributo nombre
y un método saludar
que imprima “Hola, soy [nombre]”.
Ejercicio 2: Clase Librería
Descripción:
La clase Libreria
tendrá un conjunto de libros disponibles y permitirá realizar ciertas operaciones como añadir libros, quitar libros y listar los libros disponibles.
Código:
class Libreria:
def __init__(self):
self.libros = []
def agregar_libro(self, titulo):
self.libros.append(titulo)
print(f"Se ha agregado el libro '{titulo}'.")
def quitar_libro(self, titulo):
if titulo in self.libros:
self.libros.remove(titulo)
print(f"Se ha quitado el libro '{titulo}'.")
else:
print(f"El libro '{titulo}' no está en la librería.")
def listar_libros(self):
if self.libros:
print("Libros disponibles en la librería:")
for libro in self.libros:
print(f"- {libro}")
else:
print("La librería está vacía.")
# Instanciamos la libreria
mi_libreria = Libreria()
# Añadimos algunos libros
mi_libreria.agregar_libro("1984")
mi_libreria.agregar_libro("Cien años de soledad")
# Listamos los libros
mi_libreria.listar_libros()
# Quitamos un libro
mi_libreria.quitar_libro("1984")
# Listamos de nuevo los libros
mi_libreria.listar_libros()
Tareas:
Tarea 1: Método para buscar un libro
Añade un método llamado buscar_libro
que tome un título como parámetro y diga si el libro está o no en la librería.
Tarea 2: Contador de libros
Añade un método llamado contar_libros
que devuelva el número total de libros en la librería.
4 - Decoradores
¿Qué es un Decorador en Python?
Un decorador es una función que toma una función como entrada y devuelve una nueva función. Se usan para modificar el comportamiento de las funciones o clases de una manera limpia, reutilizable y legible.
Sintaxis
La sintaxis básica para usar un decorador es preceder la definición de una función con el símbolo @
seguido del nombre del decorador.
@decorador
def mi_funcion():
pass
¿Cómo Funcionan?
Veamos un ejemplo sencillo de cómo funciona un decorador. Supongamos que deseamos medir el tiempo que toma la ejecución de una función.
import time
def timer_decorator(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"{func.__name__} se ejecutó en {end_time - start_time} segundos")
return result
return wrapper
@timer_decorator
def mi_funcion(n):
suma = 0
for i in range(n):
suma += i
return suma
Cuando llamamos a mi_funcion
, en realidad estamos llamando a wrapper
, que a su vez llama a mi_funcion
, permitiéndonos hacer cosas antes y después de que se ejecute mi_funcion
sin modificar su código.
Utilidad
Separación de Responsabilidades: Los decoradores ayudan a seguir el principio de separación de responsabilidades al extraer la lógica que no está directamente relacionada con la tarea de una función.
Reusabilidad: Una vez que tienes un decorador, puedes usarlo en múltiples funciones.
Modificación Dinámica: Permiten modificar el comportamiento de una función o clase sin tener que modificar su código fuente.
Legibilidad: Mejoran la legibilidad al etiquetar las funciones con su comportamiento adicional.
5 - Errores y Excepciones
Documentación
Notebook Base
The try-except block
When you think an error may occur, you can write a try-except
block to handle the exception that might be raised.
The try block tells Python to try running some code, and the except block tells Python what to do if the code results in a particular kind of error.
Ejemplo: Handling the ZeroDivisionError exception
try:
print(5/0)
except ZeroDivisionError:
print("You can't divide by zero!")
Ejemplo: Handling the FileNotFoundError exception
from pathlib import Path
path = Path("siddhartha.txt")
try:
contents = path.read_text()
except FileNotFoundError:
msg = f"Can’t find file: {path.name}."
print(msg)
else
block
prompt = "How many tickets do you need? "
num_tickets = input(prompt)
try:
num_tickets = int(num_tickets)
except ValueError:
print("Please try again.")
else:
print("Your tickets are printing.")
Knowing which exception to handle
It can be hard to know what kind of exception to handle when writing code. Try writing your code without a try block, and make it generate an error. The traceback will tell you what kind of exception your program needs to handle.
6 - Información en archivos. Texto, CSV, JSON, HTML, XML
En este bloque vamos a ver cómo se trabaja con distintos formatos de archivos con Python.
6.1 - Archivos de texto
Documentación
Notebook Base
6.2 - Archivos CSV
El formato de archivos CSV
CSV significa “Comma-Separated Values” (Valores Separados por Comas), y es un formato de archivo que almacena datos tabulares en forma de texto. Un archivo CSV esencialmente consta de una o más filas, y cada campo en la fila está separado por una coma. Este es un ejemplo muy simple:
Nombre,Edad,Correo
Alice,30,alice@email.com
Bob,45,bob@email.com
Charlie,25,charlie@email.com
La primera fila a menudo contiene encabezados que describen qué datos se encuentran en cada columna. Sin embargo, esto no es estrictamente necesario. Los archivos CSV son muy flexibles y pueden ser abiertos o editados con un simple editor de texto o con software más avanzado como una hoja de cálculo.
Formato muy usado en la ciencia de datos y en IoT debido a su simplicidad, eficiencia y versatilidad. Su capacidad para almacenar datos de manera estructurada pero simple lo convierte en una opción popular para una variedad de aplicaciones.
6.3 - Archivos JSON
Documentación
Notebook Base
¿Qué es JSON?
JSON (JavaScript Object Notation) es un formato de intercambio de datos ligero y de fácil lectura para humanos. Está basado en un subconjunto del lenguaje de programación JavaScript y es muy similar a los diccionarios en Python. Aunque fue originado en JavaScript, se ha convertido en un formato estándar para el intercambio de datos entre diferentes lenguajes y aplicaciones.
¿Por qué es importante JSON en Python?
- Interoperabilidad: JSON es un formato ampliamente aceptado para el intercambio de datos en aplicaciones web.
- Facilidad de Uso: La sintaxis de JSON es sencilla y fácil de leer/escribir.
- Estructura de Datos Anidados: Permite anidar arrays y objetos, lo cual es especialmente útil para almacenar datos más complejos.
Bibliotecas para manipular JSON en Python
La biblioteca estándar de Python incluye el módulo json
, que permite codificar y decodificar datos en formato JSON.
json.dump() / json.dumps()
: Para escribir datos en JSON.json.load() / json.loads()
: Para leer datos en JSON.
Ejercicios Propuestos
Ejercicio 1: Leer y modificar datos JSON
- Leer un archivo JSON que contiene una lista de productos. Cada producto debe tener un
nombre
,precio
ycantidad_en_stock
. - Incrementar el
precio
de cada producto en un 10%. - Guardar los datos modificados en un nuevo archivo JSON.
Ejercicio 2: Análisis de Datos JSON
- Leer un archivo JSON que contiene datos sobre diversas ciudades, incluyendo el
nombre
,población
, yaltitud
. - Encontrar y mostrar la ciudad con la mayor y la menor población.
- Guardar esta información en un nuevo archivo JSON titulado
analisis_ciudades.json
.
Estos elementos deberían proporcionar una base sólida para enseñar la manipulación de archivos JSON en Python. Puedes adaptar los ejemplos y ejercicios según las necesidades de tus alumnos.
7 - Proyecto 2
Visualizador de canales de TDT a partir de un archivo JSON
En este repositorio https://github.com/LaQuay/TDTChannels tienes información sobre canales de TDT de España en formato JSON.
Usa el archivo https://www.tdtchannels.com/lists/tv.json para crear un visualizador de los canales de TDT.
Si lo quieres ver en el navegador, necesitarás una extensión para ver archivos m3u
.
Variante: uso de streamlit
no podrás ejecutarlo en colab, sino en tu equipo. Para ejecutarlo en colab, tendrías que usar alguna herramienta como ngrok.
Aquí tienes un ejemplo de aplicación que usa streamlit https://github.com/lmorillas/streamlit-tdt/
Para ejecutar en tu equipo, tienes que
- clonar el repositorio
$ git clone c
* crear entorno virtual
```bash
$ cd streamlit-tdt
$ python3 -m venv env
$ source env/bin/activate
- instalar dependencias
$ pip install -r requirements.txt
- ejecutar la aplicación
$ streamlit run tdt.py
Modifica el programa
- Que muestre los canales
- Que permita otras búsquedas directas.
Ejercicios propuestos
- Añade una caja de búsqueda para filtrar los canales por nombre.
text_search = st.text_input("Buscar canal de TV", value="")