Mostrando entradas con la etiqueta PYTHON. Mostrar todas las entradas
Mostrando entradas con la etiqueta PYTHON. Mostrar todas las entradas

Proyecto Final: Asistente personal

 El objetivo es crear una aplicación que funcione como un asistente personal de escritorio, capaz de:

  • Gestionar tareas y recordatorios

  • Guardar notas

  • Consultar el tiempo o noticias

  • Enviar correos automáticos

  • Registrar eventos en una base de datos

  • Automatizar acciones (abrir apps, escribir texto, mover el ratón)

  • Generar informes PDF/Excel

  • Integrarse con un bot (Telegram opcional)

Todo desde una interfaz gráfica con Tkinter.

Arquitectura del Proyecto

asistente_personal/
│
├── main.py                # Interfaz principal (Tkinter)
├── db/
│   └── datos.db           # SQLite o TinyDB
├── modulos/
│   ├── tareas.py          # CRUD de tareas
│   ├── notas.py           # Gestor de notas
│   ├── recordatorios.py   # Recordatorios automáticos
│   ├── scraping.py        # Web scraping (tiempo, noticias…)
│   ├── correo.py          # Envío de emails
│   ├── automatizacion.py  # Control de teclado/ratón
│   ├── informes.py        # PDF/Excel
│   └── bot.py             # Bot de Telegram (opcional)
└── assets/
    └── iconos/            # Iconos para la interfaz

1. Módulo de Tareas (CRUD con SQLite o TinyDB)

Ejemplo con SQLite:

import sqlite3

conexion = sqlite3.connect("db/datos.db")
cursor = conexion.cursor()

cursor.execute("""
CREATE TABLE IF NOT EXISTS tareas (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    titulo TEXT,
    descripcion TEXT,
    estado TEXT
)
""")
conexion.commit()

def añadir_tarea(titulo, descripcion):
    cursor.execute("INSERT INTO tareas (titulo, descripcion, estado) VALUES (?, ?, ?)",
                   (titulo, descripcion, "pendiente"))
    conexion.commit()

def obtener_tareas():
    cursor.execute("SELECT * FROM tareas")
    return cursor.fetchall()

2. Módulo de Notas

def guardar_nota(titulo, contenido):
    with open(f"notas/{titulo}.txt", "w", encoding="utf-8") as f:
        f.write(contenido)

3. Módulo de Recordatorios (notificaciones + email opcional)

import time
from tkinter import messagebox

def recordatorio(mensaje, segundos):
    time.sleep(segundos)
    messagebox.showinfo("Recordatorio", mensaje)

4. Módulo de Web Scraping (tiempo, noticias…)

Ejemplo: obtener temperatura actual.

import requests
from bs4 import BeautifulSoup

def obtener_tiempo(ciudad):
    url = f"https://www.eltiempo.es/{ciudad}"
    html = requests.get(url).text
    soup = BeautifulSoup(html, "html.parser")
    temp = soup.find("span", class_="dato-temperatura").text
    return temp

5. Módulo de Envío de Correos

import smtplib
from email.mime.text import MIMEText

def enviar_correo(destino, asunto, mensaje):
    msg = MIMEText(mensaje)
    msg["Subject"] = asunto
    msg["From"] = "tu_correo@gmail.com"
    msg["To"] = destino

    with smtplib.SMTP("smtp.gmail.com", 587) as server:
        server.starttls()
        server.login("tu_correo@gmail.com", "tu_contraseña")
        server.send_message(msg)

6. Módulo de Automatización (PyAutoGUI)

import pyautogui

def abrir_navegador():
    pyautogui.hotkey("win")
    pyautogui.write("chrome")
    pyautogui.press("enter")

7. Módulo de Informes (PDF + Excel)

PDF con ReportLab:

from reportlab.pdfgen import canvas

def generar_informe():
    c = canvas.Canvas("informe.pdf")
    c.drawString(50, 800, "Informe del Asistente Personal")
    c.save()

8. Interfaz Principal (Tkinter)

import tkinter as tk
from modulos import tareas, scraping

ventana = tk.Tk()
ventana.title("Asistente Personal")
ventana.geometry("500x500")

def mostrar_tiempo():
    ciudad = entrada_ciudad.get()
    temp = scraping.obtener_tiempo(ciudad)
    label_resultado.config(text=f"Temperatura: {temp}")

entrada_ciudad = tk.Entry(ventana)
entrada_ciudad.pack()

boton_tiempo = tk.Button(ventana, text="Consultar tiempo", command=mostrar_tiempo)
boton_tiempo.pack()

label_resultado = tk.Label(ventana, text="")
label_resultado.pack()

ventana.mainloop()

ACTIVIDAD FINAL: “Entrega del Asistente Personal”

Requisitos mínimos

  1. Interfaz Tkinter con menú lateral

  2. Módulo de tareas (CRUD completo)

  3. Módulo de notas

  4. Módulo de recordatorios

  5. Consulta del tiempo o noticias por scraping

  6. Envío de correos

  7. Generación de un informe PDF

  8. Base de datos SQLite o TinyDB

  9. Entorno virtual (venv)

  10. Documentación con Doctest o README

Requisitos opcionales (para nota extra)

  • Bot de Telegram integrado

  • Automatización con PyAutoGUI

  • Exportación a Excel

  • Tema oscuro / diseño moderno (CustomTkinter)

  • API REST con Flask

Resultado esperado

Un asistente personal completo, modular, ampliable y profesional, que demuestra dominio de:

  • Python avanzado

  • Tkinter

  • Bases de datos

  • Web scraping

  • Automatización

  • Envío de correos

  • PDF/Excel

  • Buenas prácticas (venv, documentación, módulos)

Un proyecto perfecto para evaluación final o incluso para el portfolio del alumno.



< Anterior                                            Siguiente >

Distribución de Paquetes (Pip, PyPl)

 

¿Qué es Pip?

pip es el gestor de paquetes de Python. Permite:

  • Instalar librerías

  • Actualizarlas

  • Desinstalarlas

  • Consultar versiones

  • Crear archivos de dependencias

Es la herramienta que conecta Python con PyPI.

¿Qué es PyPI?

PyPI (Python Package Index) es el repositorio oficial donde se publican las librerías de Python. Es como la “App Store” de Python.

Ejemplos de paquetes en PyPI:

  • requests

  • flask

  • numpy

  • pandas

  • beautifulsoup4

1. Instalar paquetes con pip

pip install requests

Instalar una versión específica:

pip install flask==2.3.2

Actualizar:

pip install --upgrade requests

Desinstalar:

pip uninstall requests

2. Ver paquetes instalados

pip list

Buscar un paquete:

pip search nombre

3. Crear un archivo de dependencias (requirements.txt)

Guardar las librerías instaladas:

pip freeze > requirements.txt

Instalar desde ese archivo:

pip install -r requirements.txt

Perfecto para proyectos colaborativos.

4. Crear tu propio paquete Python

Aquí empieza lo interesante: Tus alumnos pueden convertir su código en un paquete instalable.

Estructura básica

mi_paquete/
    mi_paquete/
        __init__.py
        funciones.py
    pyproject.toml
    README.md

5. Archivo pyproject.toml (moderno y recomendado)

Ejemplo mínimo:

[project]
name = "mi_paquete"
version = "0.1.0"
description = "Un paquete de ejemplo"
authors = [
    { name="Tu Nombre", email="tu@mail.com" }
]
readme = "README.md"
requires-python = ">=3.8"

6. Crear el paquete (build)

Instalar herramientas de empaquetado:

pip install build

Construir el paquete:

python -m build

Esto genera:

  • un archivo .tar.gz

  • un archivo .whl (wheel)

7. Instalar tu paquete localmente

pip install dist/mi_paquete-0.1.0-py3-none-any.whl

8. Subir el paquete a PyPI

Instalar Twine:

pip install twine

Subir:

twine upload dist/*

Necesitas una cuenta en PyPI.

ACTIVIDAD PRÁCTICA: “Crea y publica tu propia librería”

Objetivo: que tus alumnos creen un paquete real y lo instalen con pip.

Enunciado

  1. Crea una carpeta calculadora_avanzada

  2. Dentro, crea un módulo con funciones:

    • sumar(a, b)

    • restar(a, b)

    • multiplicar(a, b)

    • dividir(a, b)

  3. Añade un pyproject.toml con metadatos

  4. Crea un README.md

  5. Construye el paquete

  6. Instálalo localmente con pip

  7. (Opcional) Publícalo en PyPI

Solución propuesta (estructura)

calculadora_avanzada/funciones.py

def sumar(a, b):
    return a + b

def restar(a, b):
    return a - b

def multiplicar(a, b):
    return a * b

def dividir(a, b):
    if b == 0:
        raise ValueError("No se puede dividir entre cero")
    return a / b

calculadora_avanzada/__init__.py

from .funciones import sumar, restar, multiplicar, dividir

pyproject.toml

[project]
name = "calculadora-avanzada"
version = "0.1.0"
description = "Una calculadora simple para FP"
readme = "README.md"
requires-python = ">=3.8"

Resultado esperado

  • Los alumnos crean su propio paquete

  • Lo instalan con pip

  • Entienden cómo funciona PyPI

  • Aprenden buenas prácticas de distribución




< Anterior                                            Siguiente >

Pruebas y Documentación (Doctest)

 

¿Qué es Doctest?

doctest permite escribir pruebas dentro de los docstrings de tus funciones. Es decir, los ejemplos que pones en la documentación se ejecutan automáticamente para comprobar que el código funciona como dices.

Esto ayuda a:

  • Documentar funciones con ejemplos reales

  • Detectar errores rápidamente

  • Enseñar buenas prácticas

  • Crear tests sin frameworks complicados

1. Ejemplo básico de doctest

def sumar(a, b):
    """
    Suma dos números.

    >>> sumar(2, 3)
    5
    >>> sumar(-1, 1)
    0
    """
    return a + b

Para ejecutar los tests:

python -m doctest archivo.py

Si todo está bien, no muestra nada. Si falla, muestra el error.

2. Doctest con cadenas

def mayusculas(texto):
    """
    Convierte un texto a mayúsculas.

    >>> mayusculas("hola")
    'HOLA'
    """
    return texto.upper()

3. Doctest con listas

def pares(lista):
    """
    Devuelve los números pares de una lista.

    >>> pares([1,2,3,4,5])
    [2, 4]
    """
    return [n for n in lista if n % 2 == 0]

4. Ignorar espacios o formatos (ELLIPSIS)

A veces no importa el resultado exacto:

def info():
    """
    >>> info()  # doctest: +ELLIPSIS
    'Versión...'
    """
    return "Versión 1.2.3"

5. Ejecutar doctest desde el propio archivo

Al final del archivo:

if __name__ == "__main__":
    import doctest
    doctest.testmod()

Así, al ejecutar:

python archivo.py

se ejecutan los tests automáticamente.

6. Ventajas de Doctest para tus alumnos

  • Aprenden a documentar funciones

  • Aprenden a escribir pruebas sin frameworks

  • Ven ejemplos reales funcionando

  • Es perfecto para ejercicios pequeños

  • Se integra muy bien con FP y proyectos educativos

ACTIVIDAD PRÁCTICA: “Biblioteca de utilidades con Doctest”

Objetivo: crear un módulo con varias funciones documentadas y probadas.

Enunciado

Crea un archivo utilidades.py con las siguientes funciones:

  1. es_primo(n)

    • Devuelve True si n es primo

    • Incluye 3 doctests

  2. invertir(texto)

    • Devuelve el texto al revés

    • Incluye 2 doctests

  3. media(lista)

    • Devuelve la media de una lista

    • Incluye 2 doctests

Al final del archivo, añade:

if __name__ == "__main__":
    import doctest
    doctest.testmod()

Solución propuesta

def es_primo(n):
    """
    Determina si un número es primo.

    >>> es_primo(2)
    True
    >>> es_primo(15)
    False
    >>> es_primo(17)
    True
    """
    if n < 2:
        return False
    for i in range(2, int(n**0.5) + 1):
        if n % i == 0:
            return False
    return True


def invertir(texto):
    """
    Invierte un texto.

    >>> invertir("hola")
    'aloh'
    >>> invertir("Python")
    'nohtyP'
    """
    return texto[::-1]


def media(lista):
    """
    Calcula la media de una lista de números.

    >>> media([1,2,3])
    2.0
    >>> media([10, 20])
    15.0
    """
    return sum(lista) / len(lista)


if __name__ == "__main__":
    import doctest
    doctest.testmod()

Resultado esperado

  • Los alumnos ejecutan el archivo

  • Doctest valida automáticamente todos los ejemplos

  • Si algo falla, doctest lo muestra




< Anterior                                            Siguiente >

Entornos Virtules (venv)

 

¿Qué es un entorno virtual?

Un entorno virtual es una carpeta que contiene:

  • Una instalación independiente de Python

  • Sus propias librerías

  • Sus propias versiones de paquetes

Esto permite:

  • Tener proyectos con dependencias distintas

  • Evitar conflictos entre versiones

  • Mantener el sistema limpio

  • Reproducir proyectos fácilmente

1. Crear un entorno virtual

Desde la terminal:

python -m venv mi_entorno

Esto crea una carpeta llamada mi_entorno/ con todo lo necesario.

2. Activar el entorno virtual

Windows

mi_entorno\Scripts\activate

Linux / macOS

source mi_entorno/bin/activate

Cuando está activo, verás algo así:

(mi_entorno) C:\proyecto>

3. Instalar paquetes dentro del entorno

Una vez activado:

pip install requests
pip install flask

Solo se instalan dentro del entorno, no en el sistema.

4. Ver paquetes instalados

pip list

5. Desactivar el entorno virtual

deactivate

6. Eliminar un entorno virtual

Simplemente borra la carpeta:

rm -r mi_entorno

7. Crear un archivo de dependencias (requirements.txt)

Para guardar las librerías instaladas:

pip freeze > requirements.txt

Contenido típico:

flask==2.3.2
requests==2.31.0

8. Instalar dependencias desde requirements.txt

pip install -r requirements.txt

Perfecto para compartir proyectos.

ACTIVIDAD PRÁCTICA: “Proyecto aislado con Flask”

Objetivo: que tus alumnos creen un entorno virtual y un proyecto real con dependencias.

Enunciado

  1. Crea una carpeta llamada proyecto_flask

  2. Dentro, crea un entorno virtual venv

  3. Actívalo

  4. Instala Flask

  5. Crea un archivo app.py con un servidor básico

  6. Genera un requirements.txt

  7. Desactiva el entorno

Solución propuesta

1. Crear carpeta

mkdir proyecto_flask
cd proyecto_flask

2. Crear entorno virtual

python -m venv venv

3. Activarlo

Windows:

venv\Scripts\activate

Linux/macOS:

source venv/bin/activate

4. Instalar Flask

pip install flask

5. Crear app.py

from flask import Flask

app = Flask(__name__)

@app.route("/")
def inicio():
    return "Hola desde Flask en un entorno virtual!"

if __name__ == "__main__":
    app.run(debug=True)

6. Crear requirements.txt

pip freeze > requirements.txt

7. Desactivar entorno

deactivate

Resultado esperado

  • Un proyecto completamente aislado

  • Flask instalado solo dentro del entorno

  • Un servidor web funcionando

  • Dependencias guardadas en requirements.txt



< Anterior                                            Siguiente >

TinyDB

 

¿Qué es TinyDB?

TinyDB es una base de datos NoSQL, basada en archivos JSON, que funciona sin servidor y con una sintaxis muy intuitiva.

Características:

  • No requiere instalación de servidor

  • Guarda los datos en un archivo .json

  • Consultas muy fáciles con sintaxis tipo Python

  • Perfecta para proyectos pequeños y medianos

  • Ideal para integrarla con Tkinter, bots, automatización, etc.

1. Instalación

pip install tinydb

2. Crear o abrir una base de datos

from tinydb import TinyDB

db = TinyDB("usuarios.json")

Esto crea un archivo JSON si no existe.

3. Insertar datos

db.insert({"nombre": "Ana", "edad": 22, "email": "ana@mail.com"})

Insertar varios:

python
db.insert_multiple([
    {"nombre": "Luis", "edad": 30},
    {"nombre": "Marta", "edad": 25}
])

4. Consultar datos

from tinydb import Query

Usuario = Query()

resultado = db.search(Usuario.nombre == "Ana")
print(resultado)

Obtener todos:

python
print(db.all())

5. Actualizar datos

db.update({"edad": 23}, Usuario.nombre == "Ana")

Actualizar solo un campo:

python
db.update({"email": "nuevo@mail.com"}, Usuario.nombre == "Ana")

6. Eliminar datos

db.remove(Usuario.nombre == "Luis")

Eliminar todos:

db.truncate()

7. Tablas múltiples

TinyDB permite crear tablas como si fueran colecciones:

productos = db.table("productos")
productos.insert({"nombre": "Teclado", "precio": 20})

8. Ventajas frente a SQLite o MySQL

TinyDBSQLite/MySQL
Muy fácilMás complejo
JSON legibleBinario / servidor
Ideal para apps pequeñasIdeal para apps grandes
No requiere SQLRequiere SQL
Perfecto para prototiposPerfecto para producción

ACTIVIDAD PRÁCTICA: “Gestor de tareas con TinyDB”

Objetivo: crear un CRUD completo usando TinyDB.

Enunciado

Crea un programa que:

  1. Use TinyDB para guardar tareas

  2. Cada tarea debe tener:

    • id

    • título

    • descripción

    • estado (pendiente / completada)

  3. Permita mediante un menú:

    • Añadir tarea

    • Listar tareas

    • Buscar por título

    • Marcar como completada

    • Eliminar tarea

  4. Guarde todo en tareas.json

Solución propuesta

from tinydb import TinyDB, Query

db = TinyDB("tareas.json")
Tarea = Query()

def añadir_tarea():
    titulo = input("Título: ")
    descripcion = input("Descripción: ")
    db.insert({
        "titulo": titulo,
        "descripcion": descripcion,
        "estado": "pendiente"
    })
    print("Tarea añadida.")

def listar_tareas():
    tareas = db.all()
    for t in tareas:
        print(f"{t.doc_id}. {t['titulo']} - {t['estado']}")

def buscar_tarea():
    titulo = input("Título a buscar: ")
    resultado = db.search(Tarea.titulo == titulo)
    print(resultado)

def completar_tarea():
    id_tarea = int(input("ID de la tarea: "))
    db.update({"estado": "completada"}, doc_ids=[id_tarea])
    print("Tarea completada.")

def eliminar_tarea():
    id_tarea = int(input("ID de la tarea: "))
    db.remove(doc_ids=[id_tarea])
    print("Tarea eliminada.")

while True:
    print("\n--- MENÚ ---")
    print("1. Añadir tarea")
    print("2. Listar tareas")
    print("3. Buscar tarea")
    print("4. Completar tarea")
    print("5. Eliminar tarea")
    print("6. Salir")

    opcion = input("Opción: ")

    if opcion == "1":
        añadir_tarea()
    elif opcion == "2":
        listar_tareas()
    elif opcion == "3":
        buscar_tarea()
    elif opcion == "4":
        completar_tarea()
    elif opcion == "5":
        eliminar_tarea()
    elif opcion == "6":
        break
    else:
        print("Opción no válida.")

Resultado esperado

  • Un gestor de tareas totalmente funcional

  • Datos guardados en un archivo JSON

  • CRUD completo sin necesidad de SQL

  • Perfecto para integrarlo con Tkinter o bots



< Anterior                                            Siguiente >

MySQL / PyMySQL

 

¿Qué es MySQL?

MySQL es un sistema de gestión de bases de datos relacional (RDBMS):

  • Muy rápido

  • Multicliente

  • Ideal para aplicaciones web

  • Usado por empresas de todos los tamaños

  • Requiere servidor (local o remoto)

Python se conecta a MySQL mediante librerías como:

  • PyMySQL (la más sencilla)

  • mysql-connector-python

  • SQLAlchemy (ORM)

Aquí trabajaremos con PyMySQL.

1. Instalación de PyMySQL

pip install pymysql

2. Conectarse a MySQL

import pymysql

conexion = pymysql.connect(
    host="localhost",
    user="root",
    password="tu_contraseña",
    database="mi_base"
)

cursor = conexion.cursor()

3. Crear una base de datos (opcional)

cursor.execute("CREATE DATABASE IF NOT EXISTS mi_base")

4. Crear una tabla

cursor.execute("""
CREATE TABLE IF NOT EXISTS usuarios (
    id INT AUTO_INCREMENT PRIMARY KEY,
    nombre VARCHAR(50),
    edad INT,
    email VARCHAR(100)
)
""")
conexion.commit()

5. Insertar datos

cursor.execute(
    "INSERT INTO usuarios (nombre, edad, email) VALUES (%s, %s, %s)",
    ("Ana", 22, "ana@mail.com")
)
conexion.commit()

6. Insertar varios registros

datos = [
    ("Luis", 30, "luis@mail.com"),
    ("Marta", 25, "marta@mail.com")
]

cursor.executemany(
    "INSERT INTO usuarios (nombre, edad, email) VALUES (%s, %s, %s)",
    datos
)
conexion.commit()

7. Consultar datos

Obtener todos

cursor.execute("SELECT * FROM usuarios")
for fila in cursor.fetchall():
    print(fila)

Obtener uno

cursor.execute("SELECT * FROM usuarios WHERE id = %s", (1,))
print(cursor.fetchone())

8. Actualizar datos

cursor.execute(
    "UPDATE usuarios SET edad = %s WHERE nombre = %s",
    (23, "Ana")
)
conexion.commit()

9. Eliminar datos

cursor.execute("DELETE FROM usuarios WHERE id = %s", (2,))
conexion.commit()

10. Cerrar conexión

conexion.close()

11. Convertir resultados en diccionarios (más cómodo)

cursor = conexion.cursor(pymysql.cursors.DictCursor)

cursor.execute("SELECT * FROM usuarios")
fila = cursor.fetchone()

print(fila["nombre"])

ACTIVIDAD PRÁCTICA: “CRUD completo con MySQL + PyMySQL”

Objetivo: que tus alumnos creen un sistema CRUD real conectado a MySQL.

Enunciado

Crea un programa que:

  1. Se conecte a MySQL

  2. Cree una tabla clientes con:

    • id

    • nombre

    • ciudad

    • telefono

  3. Permita mediante un menú:

    • Añadir cliente

    • Mostrar todos

    • Buscar por ciudad

    • Actualizar teléfono

    • Eliminar cliente

  4. Use funciones para cada operación

  5. Maneje errores (try/except)

Solución propuesta

import pymysql

conexion = pymysql.connect(
    host="localhost",
    user="root",
    password="tu_contraseña",
    database="empresa"
)

cursor = conexion.cursor()

cursor.execute("""
CREATE TABLE IF NOT EXISTS clientes (
    id INT AUTO_INCREMENT PRIMARY KEY,
    nombre VARCHAR(50),
    ciudad VARCHAR(50),
    telefono VARCHAR(20)
)
""")
conexion.commit()

def añadir_cliente():
    nombre = input("Nombre: ")
    ciudad = input("Ciudad: ")
    telefono = input("Teléfono: ")
    cursor.execute(
        "INSERT INTO clientes (nombre, ciudad, telefono) VALUES (%s, %s, %s)",
        (nombre, ciudad, telefono)
    )
    conexion.commit()

def mostrar_clientes():
    cursor.execute("SELECT * FROM clientes")
    for fila in cursor.fetchall():
        print(fila)

def buscar_por_ciudad():
    ciudad = input("Ciudad: ")
    cursor.execute("SELECT * FROM clientes WHERE ciudad = %s", (ciudad,))
    print(cursor.fetchall())

def actualizar_telefono():
    nombre = input("Nombre del cliente: ")
    nuevo_tel = input("Nuevo teléfono: ")
    cursor.execute(
        "UPDATE clientes SET telefono = %s WHERE nombre = %s",
        (nuevo_tel, nombre)
    )
    conexion.commit()

def eliminar_cliente():
    nombre = input("Nombre del cliente a eliminar: ")
    cursor.execute("DELETE FROM clientes WHERE nombre = %s", (nombre,))
    conexion.commit()

while True:
    print("\n--- MENÚ ---")
    print("1. Añadir cliente")
    print("2. Mostrar clientes")
    print("3. Buscar por ciudad")
    print("4. Actualizar teléfono")
    print("5. Eliminar cliente")
    print("6. Salir")

    opcion = input("Opción: ")

    if opcion == "1":
        añadir_cliente()
    elif opcion == "2":
        mostrar_clientes()
    elif opcion == "3":
        buscar_por_ciudad()
    elif opcion == "4":
        actualizar_telefono()
    elif opcion == "5":
        eliminar_cliente()
    elif opcion == "6":
        break
    else:
        print("Opción no válida.")

conexion.close()

Resultado esperado

Un sistema CRUD completo conectado a MySQL, perfecto para:

  • Integrarlo con Tkinter

  • Crear APIs

  • Conectar con aplicaciones web

  • Usarlo como proyecto final



< Anterior                                            Siguiente >

SQLite3

 

¿Qué es SQLite3?

SQLite es una base de datos:

  • Integrada (no necesita servidor)

  • Muy rápida

  • Basada en un solo archivo .db

  • Perfecta para proyectos pequeños y medianos

Python incluye el módulo sqlite3 por defecto.

1. Crear una base de datos y conectarse

import sqlite3

conexion = sqlite3.connect("mi_base.db")
cursor = conexion.cursor()

Si el archivo no existe, se crea automáticamente.

2. Crear una tabla

cursor.execute("""
CREATE TABLE IF NOT EXISTS usuarios (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    nombre TEXT,
    edad INTEGER,
    email TEXT
)
""")

conexion.commit()

3. Insertar datos

cursor.execute("INSERT INTO usuarios (nombre, edad, email) VALUES (?, ?, ?)",
               ("Ana", 22, "ana@mail.com"))

conexion.commit()

El uso de ? evita inyecciones SQL.

4. Insertar varios registros a la vez

datos = [
    ("Luis", 30, "luis@mail.com"),
    ("Marta", 25, "marta@mail.com")
]

cursor.executemany("INSERT INTO usuarios (nombre, edad, email) VALUES (?, ?, ?)", datos)
conexion.commit()

5. Consultar datos

Obtener todos los registros

cursor.execute("SELECT * FROM usuarios")
filas = cursor.fetchall()

for fila in filas:
    print(fila)

Obtener un solo registro

cursor.execute("SELECT * FROM usuarios WHERE id = ?", (1,))
print(cursor.fetchone())

6. Actualizar datos

cursor.execute("UPDATE usuarios SET edad = ? WHERE nombre = ?", (23, "Ana"))
conexion.commit()

7. Eliminar datos

cursor.execute("DELETE FROM usuarios WHERE id = ?", (2,))
conexion.commit()

8. Cerrar la conexión

conexion.close()

9. Convertir resultados en diccionarios (más cómodo)

conexion.row_factory = sqlite3.Row
cursor = conexion.cursor()

cursor.execute("SELECT * FROM usuarios")
fila = cursor.fetchone()

print(fila["nombre"])

10. Integración con Tkinter, bots, scraping…

SQLite es ideal para:

  • Guardar usuarios de una app Tkinter

  • Registrar logs de un bot

  • Guardar datos de scraping

  • Crear inventarios

  • Crear sistemas CRUD completos

ACTIVIDAD PRÁCTICA: “Gestor de usuarios con SQLite”

Objetivo: que tus alumnos creen un CRUD completo (Crear, Leer, Actualizar, Borrar).

Enunciado

Crea un programa que:

  1. Cree una base de datos usuarios.db

  2. Tenga una tabla usuarios con:

    • id

    • nombre

    • edad

    • email

  3. Permita mediante un menú:

    • Añadir usuario

    • Mostrar todos

    • Buscar por nombre

    • Actualizar email

    • Eliminar usuario

  4. Use funciones para cada operación

Solución propuesta

import sqlite3

conexion = sqlite3.connect("usuarios.db")
cursor = conexion.cursor()

cursor.execute("""
CREATE TABLE IF NOT EXISTS usuarios (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    nombre TEXT,
    edad INTEGER,
    email TEXT
)
""")
conexion.commit()

def añadir_usuario():
    nombre = input("Nombre: ")
    edad = int(input("Edad: "))
    email = input("Email: ")
    cursor.execute("INSERT INTO usuarios (nombre, edad, email) VALUES (?, ?, ?)",
                   (nombre, edad, email))
    conexion.commit()

def mostrar_usuarios():
    cursor.execute("SELECT * FROM usuarios")
    for fila in cursor.fetchall():
        print(fila)

def buscar_por_nombre():
    nombre = input("Nombre a buscar: ")
    cursor.execute("SELECT * FROM usuarios WHERE nombre = ?", (nombre,))
    print(cursor.fetchall())

def actualizar_email():
    nombre = input("Nombre del usuario: ")
    nuevo_email = input("Nuevo email: ")
    cursor.execute("UPDATE usuarios SET email = ? WHERE nombre = ?", (nuevo_email, nombre))
    conexion.commit()

def eliminar_usuario():
    nombre = input("Nombre del usuario a eliminar: ")
    cursor.execute("DELETE FROM usuarios WHERE nombre = ?", (nombre,))
    conexion.commit()

while True:
    print("\n--- MENÚ ---")
    print("1. Añadir usuario")
    print("2. Mostrar usuarios")
    print("3. Buscar por nombre")
    print("4. Actualizar email")
    print("5. Eliminar usuario")
    print("6. Salir")

    opcion = input("Opción: ")

    if opcion == "1":
        añadir_usuario()
    elif opcion == "2":
        mostrar_usuarios()
    elif opcion == "3":
        buscar_por_nombre()
    elif opcion == "4":
        actualizar_email()
    elif opcion == "5":
        eliminar_usuario()
    elif opcion == "6":
        break
    else:
        print("Opción no válida.")

conexion.close()

Resultado esperado

Un gestor de usuarios totalmente funcional, perfecto para:

  • Integrarlo con Tkinter

  • Añadir validaciones

  • Exportar a Excel o PDF

  • Usarlo como base de un proyecto final



< Anterior                                            Siguiente >

Tkinter

 

¿Qué es Tkinter?

Tkinter es el módulo oficial de Python para crear interfaces gráficas. Permite construir:

  • Ventanas

  • Botones

  • Etiquetas

  • Entradas de texto

  • Listas

  • Cuadros de diálogo

  • Menús

  • Formularios completos

Y todo con muy pocas líneas de código.

1. Crear una ventana básica

import tkinter as tk

ventana = tk.Tk()
ventana.title("Mi primera ventana")
ventana.geometry("300x200")

ventana.mainloop()

2. Widgets básicos

Etiquetas (Label)

label = tk.Label(ventana, text="Hola Tkinter")
label.pack()

Botones (Button)

def saludar():
    print("Hola!")

boton = tk.Button(ventana, text="Saludar", command=saludar)
boton.pack()

Entradas de texto (Entry)

entrada = tk.Entry(ventana)
entrada.pack()

3. Obtener y mostrar datos

def mostrar():
    texto = entrada.get()
    label.config(text=f"Has escrito: {texto}")

entrada = tk.Entry(ventana)
entrada.pack()

boton = tk.Button(ventana, text="Mostrar", command=mostrar)
boton.pack()

label = tk.Label(ventana, text="")
label.pack()

4. Layouts: pack, grid, place

pack (simple)

label.pack()

grid (ideal para formularios)

tk.Label(ventana, text="Nombre:").grid(row=0, column=0)
tk.Entry(ventana).grid(row=0, column=1)

place (posiciones absolutas)

boton.place(x=50, y=100)

5. Cuadros de diálogo

from tkinter import messagebox

messagebox.showinfo("Información", "Operación completada")

6. Listbox (listas)

lista = tk.Listbox(ventana)
lista.pack()

lista.insert(0, "Python")
lista.insert(1, "Java")
lista.insert(2, "C++")

7. Menús

menu = tk.Menu(ventana)
ventana.config(menu=menu)

archivo = tk.Menu(menu, tearoff=0)
menu.add_cascade(label="Archivo", menu=archivo)
archivo.add_command(label="Salir", command=ventana.quit)

ACTIVIDAD PRÁCTICA: “Gestor de tareas con Tkinter”

Objetivo: que tus alumnos creen una aplicación gráfica funcional con:

  • Entrada de texto

  • Botón para añadir tareas

  • Listbox para mostrarlas

  • Botón para eliminar tareas

  • Mensajes de confirmación

Enunciado

Crea una aplicación con Tkinter que permita:

  1. Escribir una tarea en un Entry

  2. Añadirla a una lista (Listbox)

  3. Eliminar la tarea seleccionada

  4. Mostrar mensajes de error si no hay tarea seleccionada

  5. Guardar las tareas en un archivo tareas.txt al cerrar

Solución propuesta

import tkinter as tk
from tkinter import messagebox

def añadir_tarea():
    tarea = entrada.get()
    if tarea.strip() == "":
        messagebox.showwarning("Error", "No puedes añadir una tarea vacía.")
        return
    lista.insert(tk.END, tarea)
    entrada.delete(0, tk.END)

def eliminar_tarea():
    try:
        indice = lista.curselection()[0]
        lista.delete(indice)
    except:
        messagebox.showwarning("Error", "Selecciona una tarea para eliminar.")

def guardar_tareas():
    with open("tareas.txt", "w", encoding="utf-8") as f:
        for i in range(lista.size()):
            f.write(lista.get(i) + "\n")
    ventana.quit()

ventana = tk.Tk()
ventana.title("Gestor de Tareas")
ventana.geometry("300x400")

entrada = tk.Entry(ventana)
entrada.pack(pady=10)

boton_añadir = tk.Button(ventana, text="Añadir tarea", command=añadir_tarea)
boton_añadir.pack()

lista = tk.Listbox(ventana)
lista.pack(expand=True, fill="both", padx=10, pady=10)

boton_eliminar = tk.Button(ventana, text="Eliminar tarea", command=eliminar_tarea)
boton_eliminar.pack()

boton_guardar = tk.Button(ventana, text="Guardar y salir", command=guardar_tareas)
boton_guardar.pack(pady=10)

ventana.mainloop()

Resultado esperado

  • Una ventana con un gestor de tareas funcional

  • Añadir y eliminar tareas fácilmente

  • Guardado automático al salir



< Anterior                                            Siguiente >

Control de Teclado y Ratón

 La librería más usada para controlar teclado y ratón es:

pyautogui

Permite:

  • Mover el ratón

  • Hacer clic

  • Escribir texto

  • Pulsar teclas

  • Tomar capturas de pantalla

  • Detectar posiciones del cursor

1. Instalación

pip install pyautogui

2. Control del ratón

Obtener la posición actual

import pyautogui

print(pyautogui.position())

Mover el ratón

pyautogui.moveTo(500, 300, duration=1)  # x, y, tiempo

Clics

pyautogui.click()              # clic izquierdo
pyautogui.doubleClick()        # doble clic
pyautogui.rightClick()         # clic derecho

Arrastrar

pyautogui.dragTo(800, 400, duration=1)

3. Control del teclado

Escribir texto

pyautogui.write("Hola mundo", interval=0.1)

Pulsar teclas

pyautogui.press("enter")
pyautogui.press("tab")
pyautogui.hotkey("ctrl", "c")   # combinación de teclas

4. Capturas de pantalla

imagen = pyautogui.screenshot()
imagen.save("captura.png")

5. Localizar elementos en pantalla

PyAutoGUI puede buscar imágenes en la pantalla para automatizar clics.

boton = pyautogui.locateOnScreen("boton.png")
pyautogui.click(boton)

Muy útil para bots que interactúan con interfaces gráficas.

Consejos de seguridad

  • Usa pyautogui.FAILSAFE = True para detener el script moviendo el ratón a la esquina superior izquierda.

  • Añade pausas entre acciones:

pyautogui.PAUSE = 0.5

ACTIVIDAD PRÁCTICA: “Bot que abre una aplicación y escribe un mensaje”

Objetivo: que tus alumnos creen un bot que:

  1. Abra el menú de inicio

  2. Escriba el nombre de una aplicación (por ejemplo, “Bloc de notas”)

  3. La abra

  4. Escriba un texto automáticamente

  5. Guarde el archivo

Pistas

  • Usa pyautogui.hotkey("win") para abrir el menú

  • Usa write() para escribir

  • Usa press("enter") para abrir la app

  • Usa hotkey("ctrl", "s") para guardar

Solución propuesta (Windows)

import pyautogui
import time

pyautogui.PAUSE = 0.5
pyautogui.FAILSAFE = True

# 1. Abrir menú inicio
pyautogui.hotkey("win")
time.sleep(1)

# 2. Escribir "Bloc de notas"
pyautogui.write("notepad")
pyautogui.press("enter")
time.sleep(1)

# 3. Escribir texto
pyautogui.write("Hola, este texto fue escrito automáticamente con Python.", interval=0.05)

# 4. Guardar archivo
pyautogui.hotkey("ctrl", "s")
time.sleep(1)

pyautogui.write("mensaje_automatico.txt")
pyautogui.press("enter")

Resultado esperado

  • Se abre el Bloc de notas

  • Se escribe el mensaje automáticamente

  • Se guarda el archivo sin intervención humana



< Anterior                                            Siguiente >


Bots y Envío de Correos

 Python permite crear bots que interactúan con:

  • páginas web

  • redes sociales

  • formularios

  • correos electrónicos

  • APIs

Y también permite enviar emails automáticos usando smtplib.

Vamos por partes.

1. Envío de correos con Python (smtplib)

Python incluye un módulo estándar para enviar emails.

Enviar un correo básico

import smtplib
from email.mime.text import MIMEText

mensaje = MIMEText("Hola, este es un mensaje automático.")
mensaje["Subject"] = "Notificación"
mensaje["From"] = "tu_correo@gmail.com"
mensaje["To"] = "destino@mail.com"

with smtplib.SMTP("smtp.gmail.com", 587) as servidor:
    servidor.starttls()
    servidor.login("tu_correo@gmail.com", "tu_contraseña")
    servidor.send_message(mensaje)

Nota: Para Gmail, es necesario usar contraseñas de aplicación.

2. Enviar correos con HTML

html = """
<h1>Informe Diario</h1>
<p>Todo funciona correctamente.</p>
"""

mensaje = MIMEText(html, "html")

3. Enviar archivos adjuntos

from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders

msg = MIMEMultipart()
msg["Subject"] = "Archivo adjunto"
msg["From"] = "tu_correo@gmail.com"
msg["To"] = "destino@mail.com"

# Adjuntar archivo
with open("informe.pdf", "rb") as f:
    parte = MIMEBase("application", "octet-stream")
    parte.set_payload(f.read())

encoders.encode_base64(parte)
parte.add_header("Content-Disposition", "attachment; filename=informe.pdf")
msg.attach(parte)

4. Bots con Python

Hay muchos tipos de bots:

  • Bots web (con Selenium)

  • Bots de Telegram

  • Bots de Discord

  • Bots de correo

  • Bots de automatización interna

Vamos a ver los más útiles para FP.

Bot con Selenium (automatización web)

Ejemplo: iniciar sesión automáticamente.

python
from selenium import webdriver
from selenium.webdriver.common.by import By
import time

driver = webdriver.Chrome()
driver.get("https://example.com/login")

driver.find_element(By.ID, "usuario").send_keys("admin")
driver.find_element(By.ID, "password").send_keys("1234")
driver.find_element(By.ID, "login").click()

time.sleep(3)
driver.quit()

Bot de Telegram (muy usado en FP)

Instalación

pip install python-telegram-bot

Bot que responde mensajes

from telegram.ext import Updater, CommandHandler

def start(update, context):
    update.message.reply_text("Hola, soy tu bot!")

updater = Updater("TOKEN_DEL_BOT")
dispatcher = updater.dispatcher

dispatcher.add_handler(CommandHandler("start", start))

updater.start_polling()
updater.idle()

5. Integrar Bots + Email

Aquí es donde se vuelve interesante: Un bot puede enviar correos automáticos cuando ocurre un evento.

Ejemplos:

  • Bot que avisa por email cuando detecta un precio bajo

  • Bot que envía un informe diario

  • Bot que notifica errores en un sistema

  • Bot que envía un correo cuando recibe un comando

ACTIVIDAD PRÁCTICA: “Bot de alertas que envía correos”

Objetivo: crear un bot que monitoriza una web y envía un correo si detecta un cambio.

Enunciado

Crea un programa que:

  1. Acceda a una página web con Selenium

  2. Extraiga un precio o dato con BeautifulSoup

  3. Si el valor baja de un umbral, envíe un correo automático

  4. Registre la alerta en un archivo de texto

  5. Se ejecute cada X minutos (con time.sleep)

Pistas

  • Usa driver.page_source

  • Usa soup.find()

  • Usa smtplib para enviar el correo

  • Usa un bucle while True

Solución propuesta (simplificada)

import time
import smtplib
from email.mime.text import MIMEText
from selenium import webdriver
from selenium.webdriver.common.by import By
from bs4 import BeautifulSoup

URL = "https://example.com/producto"
UMBRAL = 50  # precio mínimo para alertar

def enviar_alerta(precio):
    mensaje = MIMEText(f"ALERTA: El precio ha bajado a {precio}€")
    mensaje["Subject"] = "Alerta de precio"
    mensaje["From"] = "tu_correo@gmail.com"
    mensaje["To"] = "destino@mail.com"

    with smtplib.SMTP("smtp.gmail.com", 587) as servidor:
        servidor.starttls()
        servidor.login("tu_correo@gmail.com", "tu_contraseña")
        servidor.send_message(mensaje)

def monitorizar():
    driver = webdriver.Chrome()
    driver.get(URL)

    html = driver.page_source
    driver.quit()

    soup = BeautifulSoup(html, "html.parser")
    precio = float(soup.find("span", class_="precio").text.replace("€", ""))

    if precio < UMBRAL:
        enviar_alerta(precio)
        with open("alertas.txt", "a") as f:
            f.write(f"Alerta enviada. Precio: {precio}\n")

while True:
    monitorizar()
    time.sleep(300)  # cada 5 minutos

Resultado esperado

  • Si el precio baja, recibes un email automático

  • Se registra la alerta en un archivo

  • El bot sigue funcionando en segundo plano




< Anterior                                            Siguiente >

Web Scraping (BeautifulSoup, Selenium)

 Existen dos enfoques principales:

  • BeautifulSoup → para analizar HTML estático

  • Selenium → para interactuar con páginas dinámicas (JavaScript)

Vamos paso a paso.

1. Web Scraping con BeautifulSoup

Ideal para páginas estáticas donde el contenido ya está en el HTML.

Instalación

pip install requests beautifulsoup4

Ejemplo básico: extraer títulos de una web

import requests
from bs4 import BeautifulSoup

url = "https://example.com"
respuesta = requests.get(url)

soup = BeautifulSoup(respuesta.text, "html.parser")

titulos = soup.find_all("h2")

for t in titulos:
    print(t.text)

Selección de elementos

Por etiqueta

soup.find("p")
soup.find_all("a")

Por clase

soup.find_all("div", class_="producto")

Por id

soup.find(id="precio")

Con selectores CSS

soup.select("div.item > a.link")

2. Web Scraping con Selenium

Selenium permite controlar un navegador real (Chrome, Firefox…) y es ideal para páginas con JavaScript.

Instalación

pip install selenium

Ejemplo básico: abrir una página y extraer texto

from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://example.com")

titulo = driver.find_element(By.TAG_NAME, "h1").text
print(titulo)

driver.quit()

Interacciones comunes

Escribir en un campo

driver.find_element(By.ID, "busqueda").send_keys("python")

Hacer clic

driver.find_element(By.CLASS_NAME, "boton").click()

Esperas (muy importante)

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.CLASS_NAME, "resultado"))
)

3. Diferencias entre BeautifulSoup y Selenium

CaracterísticaBeautifulSoupSelenium
VelocidadMuy rápidoMás lento
JavaScriptNo lo ejecuta
InteracciónNoSí (clics, formularios…)
Uso idealWeb estáticaWeb dinámica

ACTIVIDAD PRÁCTICA: “Scraper de precios con Selenium + BeautifulSoup”

Objetivo: que tus alumnos construyan un scraper real que:

  1. Abra una página de productos con Selenium

  2. Espere a que cargue el contenido dinámico

  3. Obtenga el HTML final

  4. Use BeautifulSoup para extraer:

    • Nombre del producto

    • Precio

    • Enlace

  5. Guarde los datos en un archivo JSON

Pistas

  • Usa driver.page_source para obtener el HTML final

  • Usa soup.find_all() para recorrer productos

  • Usa json.dump() para guardar los datos

Solución propuesta

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup
import json
import time

driver = webdriver.Chrome()
driver.get("https://example.com/productos")

# Esperar a que carguen los productos
WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.CLASS_NAME, "producto"))
)

# Obtener HTML final
html = driver.page_source
driver.quit()

# Analizar con BeautifulSoup
soup = BeautifulSoup(html, "html.parser")
productos_html = soup.find_all("div", class_="producto")

productos = []

for p in productos_html:
    nombre = p.find("h2").text.strip()
    precio = p.find("span", class_="precio").text.strip()
    enlace = p.find("a")["href"]

    productos.append({
        "nombre": nombre,
        "precio": precio,
        "enlace": enlace
    })

# Guardar en JSON
with open("productos.json", "w", encoding="utf-8") as f:
    json.dump(productos, f, indent=4, ensure_ascii=False)

print("Scraping completado. Datos guardados en productos.json")

Resultado esperado

Un archivo productos.json con contenido como:

[
    {
        "nombre": "Teclado Mecánico",
        "precio": "29.99€",
        "enlace": "/producto/teclado"
    },
    {
        "nombre": "Ratón Inalámbrico",
        "precio": "14.50€",
        "enlace": "/producto/raton"
    }
]



< Anterior                                            Siguiente >