Saltar al contenido
Inicio 100 Días de Código en Python — Día 46: La máquina del tiempo musical

100 Días de Código en Python — Día 46: La máquina del tiempo musical

Nivel: Grado décimo Área: Tecnología e Informática Modalidad: Tutorial práctico Fuente: Curso "100 Days of Code: The Complete Python Pro Bootcamp" (Angela Yu, App Brewery). Contenido del Día 46 (nivel intermedio+).

Este tutorial adapta pedagógicamente el Día 46. Las secciones 📝 Ejercicio original del curso provienen de los archivos del curso (lecciones 337 a 344). El curso ofrece dos rutas: YouTube Music (gratuita) y Spotify (solo con cuenta Premium). Las soluciones oficiales están en los gists enlazados en cada paso. Los retos 🟢🟡🟠🔴, la ruta sin cuentas de la sección 4, el proyecto extra y el proyecto integrador son creaciones de esta adaptación. Las correcciones al material original aparecen como 🛠️ Nota técnica.

Nota sobre las verificaciones: el 26 de septiembre de 2026, con Python 3.14, requests 2.34 y beautifulsoup4 4.15, se comprobó la estructura del sitio de práctica Bakeboard Hot 100. No se crearon cuentas de Google ni de Spotify, así que los pasos de YouTube Music y Spotify se presentan según las instrucciones del curso, sin ejecutarlos.

🔐 Cuentas y seguridad (adaptación para el aula):

  1. Las rutas de YouTube Music y Spotify requieren una cuenta personal. Crear cuentas depende de la edad mínima que exige cada servicio en tu país: si eres menor de edad, hazlo solo con autorización y acompañamiento de un adulto responsable.
  2. En la ruta de YouTube Music, el archivo browser.json contiene las cookies de tu sesión: quien lo tenga puede actuar como tú en tu cuenta de Google. No lo compartas, no lo subas a Internet y no lo generes en computadores compartidos del colegio.
  3. Por eso, en el aula se recomienda la ruta sin cuentas de la sección 4, que practica lo mismo (scraping, listas, búsqueda y generación de archivos). Las rutas con cuenta pueden hacerse en casa o como demostración del docente.

Tabla de contenidos

  1. Antes de empezar: viajar en el tiempo con música
  2. Paso 1: extraer el Hot 100 de una fecha
  3. Ruta A — YouTube Music (pasos 2 a 4)
  4. Ruta B — Spotify (pasos 2 a 4)
  5. Ruta C para el aula: una lista de reproducción sin cuentas
  6. 🚀 Proyecto del día: la máquina del tiempo musical
  7. 🌟 Proyecto extra: el observatorio de la radio escolar
  8. 🏆 Proyecto integrador del bloque (Días 45 a 51) — Etapa 2
  9. 🧩 Comprueba lo aprendido
  10. 🤖 Programar con apoyo de IA
  11. 🛠️ Correcciones técnicas al material original
  12. 📋 Matriz de trazabilidad
  13. 📦 Evidencias de aprendizaje del Día 46

0. Antes de empezar: viajar en el tiempo con música

(Fuente: 337 - Day 46 Goals- what you will make by the end of the day.md)

La profesora recibió de una amiga una cinta mezclada con los éxitos de la época en que estudiaban juntas. Escucharla la "transportó" a esos años. De ahí nace el proyecto: una máquina del tiempo musical que, dada una fecha, arme una lista de reproducción con las 100 canciones más escuchadas de esa semana.

Billboard publica cada semana el Hot 100, y su sitio permite consultar semanas pasadas. El plan del curso:

  1. Con Beautiful Soup, extraer los 100 títulos de la fecha elegida.
  2. Con la API de un servicio de música, crear una lista de reproducción privada.
  3. Buscar cada canción y agregarla a la lista.

Idea de regalo de la profesora: la lista del día en que conociste a alguien importante, o del día en que empezó una amistad.

Lo nuevo hoy: combinar scraping (Día 45) con API autenticadas (Días 33 a 38) y leer documentación de librerías por tu cuenta, "como un desarrollador de verdad" (palabras del curso).

Prerequisitos: Beautiful Soup (Día 45), requests y encabezados HTTP (Días 33 a 37), manejo de excepciones (Día 30), datetime (Día 32), variables de entorno (Día 35).


1. Paso 1: extraer el Hot 100 de una fecha

(Fuente: 338-step-1-scraping-the-billboard-hot-100.md)

🎯 Objetivo de aprendizaje

Construir una URL a partir de una fecha escrita por el usuario, descargar la página con un encabezado User-Agent y extraer 100 títulos en una lista.

📖 Explicación conceptual

El sitio de práctica. Billboard puede cambiar su HTML o poner un muro de pago en cualquier momento, así que el curso creó un clon: Bakeboard Hot 100 (appbrewery.github.io/bakeboard-hot-100/), sin anuncios. No tiene todas las fechas, pero sí bastantes, que se eligen en su calendario.

Las URL siguen un patrón (pista 1 del curso):

Texto
https://appbrewery.github.io/bakeboard-hot-100/2026-04-18/
https://www.billboard.com/charts/hot-100/2000-08-12

La fecha va al final con formato AAAA-MM-DD. Si el usuario escribe la fecha en ese formato, basta con pegarla a la URL base.

Encabezados (pista 2): al hacer una petición conviene enviar un encabezado User-Agent, que le dice al servidor qué navegador hace la petición. Para este proyecto es el único que hace falta:

Python
header = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36"}
response = requests.get(URL, headers=header)

Puedes ver los encabezados de tu propio navegador en sitios como WhatIsMyBrowser. El tema se profundiza en el Día 47.

Datos verificados de Bakeboard (26/09/2026):

  • Tiene 103 fechas, desde 1959 hasta el 18 de abril de 2026 (incluida 2000-08-12, la fecha del ejemplo del curso).
  • Con una fecha que no existe en el sitio, el servidor responde 404 y la página no trae canciones.
  • Cada título está en un h3 con clase chart-entry__title y el artista, en un span con clase chart-entry__artist. (Compruébalo tú en DevTools: así es como se trabaja con un sitio real.)

📝 Ejercicio original del curso: paso 1

  1. Elegir una fecha disponible en Bakeboard (por ejemplo, 2026-04-18).
  2. Crear un proyecto nuevo en PyCharm con main.py.
  3. Con input(), preguntar: "Which year do you want to travel to? Type the date in this format YYYY-MM-DD:".
  4. Con requests y Beautiful Soup, extraer los 100 títulos de esa fecha en una lista de Python.

🔍 Antes de programar

  • ¿Qué parte de la URL cambia según la fecha y qué parte es fija?
  • ¿Qué pasa si el usuario escribe 18/04/2026? ¿Y una fecha que no está en el sitio?
  • ¿Cuántos elementos debe tener tu lista? ¿Cómo lo compruebas?
  • Además del título, ¿qué otro dato te servirá después para buscar la canción sin confundirla con otra del mismo nombre?

⚠️ Errores frecuentes

Error Qué ocurre Solución
Fecha con formato incorrecto o inexistente Respuesta 404 y lista vacía, sin error de Python Valida con datetime.strptime(fecha, "%Y-%m-%d") y revisa response.status_code o response.raise_for_status() (Día 33)
Títulos con espacios y saltos de línea alrededor "\n Choosin' Texas\n" getText(strip=True) o .strip()
Selector copiado del sitio real de Billboard para usarlo en Bakeboard (o al revés) Lista vacía Cada sitio tiene su propio HTML: inspecciona el que estás usando
Olvidar el User-Agent en el sitio real Algunos sitios responden distinto o bloquean la petición Agrega el encabezado

Retos adicionales (creados para esta adaptación)

  • 🟢 Reto 1: extrae también el artista de cada canción y guarda una lista de tuplas (título, artista).
  • 🟡 Reto 2: valida la fecha: si el formato es incorrecto, vuelve a preguntar; si el sitio responde 404, informa "No hay datos para esa fecha" y vuelve a preguntar.
  • 🟠 Reto 3: calcula qué artista tiene más canciones en el Hot 100 de esa fecha (diccionario de conteo, Día 9).
  • 🔴 Reto 4 — Pensamiento computacional: el usuario quiere la lista de su fecha de nacimiento, pero Bakeboard no tiene esa semana. Diseña un algoritmo que encuentre la fecha disponible más cercana. ¿De dónde sacas la lista de fechas disponibles sin hacer 103 peticiones? (Pista: el propio HTML de la página las contiene; búscalas.)

2. Ruta A — YouTube Music (pasos 2 a 4)

(Fuentes: 339-step-2-youtube-music-re-use-your-browser-s-requests-to-authenticate.md, 340-step-3-youtube-music-create-a-playlist.md, 341-step-4-youtube-music-search-and-add-songs-to-the-playlist.md)

🎯 Objetivo de aprendizaje

Autenticarse con la librería ytmusicapi, crear una lista privada y agregarle canciones buscándolas por nombre y artista.

📖 Explicación conceptual

YouTube Music no tiene una clave de API sencilla. La librería ytmusicapi (no oficial) funciona "tomando prestada" la sesión de tu navegador: cuando has iniciado sesión, el navegador envía cookies y encabezados de autenticación en cada petición. Se copian esos encabezados y ytmusicapi los convierte en un archivo browser.json.

Paso 2 — Autenticación (según el curso):

  1. Necesitas una cuenta de Google.
  2. Instala ytmusicapi en el proyecto.
  3. Usa Firefox (con Chrome es más complicado copiar los encabezados).
  4. En Firefox, abre music.youtube.com con sesión iniciada → DevTools (Ctrl + Mayús + I) → pestaña Network (Red) → filtra por browse (recarga si no aparece nada) → clic derecho sobre una petición browse?... de music.youtube.com → Copy Value → Copy Request Headers.
  5. En la terminal, dentro de la carpeta del proyecto:
    • Windows o Linux: ytmusicapi browser, pegar los encabezados y terminar con Ctrl + Z (Windows) o Ctrl + D (Linux), según indique el programa, y luego Enter.
    • Mac: pbpaste | ytmusicapi browser (la terminal de Mac corta los textos largos al pegarlos).
  6. Comprobar que funciona:
Python
   from ytmusicapi import YTMusic

   yt = YTMusic("browser.json")
   playlists = yt.get_library_playlists()
   print(f"Found {len(playlists)} playlists in your library.")

Las cookies caducan. Si tras un tiempo deja de funcionar, repite el proceso para obtener un browser.json nuevo.

Paso 3 — Crear la lista: con el método create_playlist() de la documentación, crear una lista privada llamada {fecha} Billboard 100 (por ejemplo, 2000-08-12 Billboard 100). Mejora opcional: antes de crearla, revisar con get_library_playlists() si ya existe una con el mismo title, para no duplicarla.

Paso 4 — Buscar y agregar: para cada canción, buscar título y artista con yt.search(..., filter="songs"), tomar el primer resultado y agregarlo con yt.add_playlist_items(). Algunas canciones no se encontrarán o darán error: envolver cada búsqueda en try/except para saltarlas y continuar.

⚠️ Errores frecuentes

Error Causa probable Solución (según el curso)
Error de "missing headers" No estabas en music.youtube.com (solo en youtube.com), no usaste Firefox o copiaste una petición equivocada Inicia sesión en YouTube Music, usa Firefox y elige una petición browse?... normal (no de anuncios ni de analítica)
En Mac, pegar no hace nada La terminal cortó el texto pbpaste | ytmusicapi browser
Funcionaba ayer y hoy no Las cookies caducaron Genera de nuevo browser.json
Listas duplicadas al ejecutar varias veces Cada ejecución crea una lista nueva Implementa la verificación del paso 3

🛠️ Nota técnica y de seguridad (adaptación): browser.json equivale a tener tu sesión abierta. Si usas Git (Día 70), agrégalo al .gitignore igual que el archivo .env. Si crees que alguien lo copió, cierra la sesión de Google en todos los dispositivos para invalidar las cookies. Además, ytmusicapi es una librería no oficial: Google puede cambiar su sistema en cualquier momento y hacer que deje de funcionar.


3. Ruta B — Spotify (pasos 2 a 4)

(Fuentes: 342-step-2-spotify-create-an-app-y-authenticate.md, 343-step-3-spotify-search-for-the-songs-from-step-1.md, 344-step-4-spotify-create-and-add-to-your-playlist.md)

🎯 Objetivo de aprendizaje

Entender el flujo OAuth y usar la librería Spotipy para autenticarse, buscar canciones por URI y crear una lista privada.

📖 Explicación conceptual

Según el curso, la API web de Spotify ahora está restringida a suscriptores Premium. YouTube Music es la alternativa gratuita.

OAuth permite que una aplicación (nuestro programa) actúe sobre la cuenta de un usuario sin conocer su contraseña: el usuario inicia sesión en la página de Spotify, autoriza permisos concretos (scopes) y Spotify entrega al programa un token temporal. Es lo que ocurre cuando una app te dice "Continuar con Google" o "Iniciar sesión con Spotify".

Paso 2 — Crear la app y autenticarse (según el curso):

  1. En el Developer Dashboard de Spotify, aceptar los términos, verificar el correo si hace falta y crear una app.
  2. Copiar el Client ID y el Client Secret (guárdalos en .env, nunca en el código, Día 35).
  3. Con la documentación de Spotipy, autenticarse usando el Authorization Code Flow (clase spotipy.oauth2.SpotifyOAuth), pasando el Client ID y el Secret directamente al constructor.
  4. Usar http://example.com como Redirect URI, registrándola también en el Dashboard.
  5. Pedir el scope playlist-modify-private para poder crear listas privadas.
  6. Al ejecutar, se abre una página de autorización (clic en Agree), luego se llega a example.com: hay que copiar la URL completa de la barra de direcciones y pegarla en la consola de PyCharm. Se crea un archivo token.txt (o .cache) con el token.
  7. Obtener el id del usuario con current_user() (es un diccionario: busca la clave "id"). Si aparece el error 403 "User not registered in the Developer Dashboard", revisa que pasaste un nombre de usuario en el flujo de autorización.

Paso 3 — Buscar las canciones: crear una lista de URI de Spotify (identificadores del tipo spotify:track:...). La consulta "track: {name} year: {YYYY}" limita la búsqueda a un año. Algunas canciones no están en Spotify: usar manejo de excepciones para saltarlas. pprint() ayuda a leer los resultados, que son diccionarios grandes y anidados.

Paso 4 — Crear y llenar la lista: crear una lista privada "AAAA-MM-DD Billboard 100" con el id del usuario y agregarle las URI usando el id de la lista que devuelve la creación.

🛠️ Nota técnica: Spotify anunció en 2025 cambios en las reglas de las Redirect URI de las apps nuevas: se exige HTTPS, salvo las direcciones de loopback escritas como IP (por ejemplo http://127.0.0.1:8888/callback), y ya no se acepta localhost. Si el Dashboard rechaza http://example.com, consulta la guía actual de Spotify y usa una dirección permitida. Además, las condiciones de la API pueden cambiar: consulta siempre la documentación vigente antes de empezar.

🛠️ Nota técnica (análisis de esta adaptación): el filtro year: usa el año de la fecha elegida, pero muchas canciones del Hot 100 de una semana se publicaron el año anterior (una canción de noviembre de 1999 puede estar de moda en agosto de 2000). Con ese filtro, esas canciones no se encuentran. Buscar por título y artista es más preciso.

⚠️ Errores frecuentes

Error Causa probable Solución
INVALID_CLIENT: Invalid redirect URI La Redirect URI del código no coincide exactamente con la del Dashboard Copia la misma dirección en ambos lugares
IndexError al tomar el primer resultado La búsqueda no encontró nada try/except IndexError, o verifica que la lista de resultados no esté vacía
Credenciales en el código subidas a Internet Cualquiera puede usar tu app .env + .gitignore; si ocurrió, regenera el Client Secret
Pedir la autorización en cada ejecución No se guarda el token Usa cache_path y reutiliza el archivo

Retos adicionales para las rutas A y B (creados para esta adaptación)

  • 🟢 Reto 1: cuenta cuántas canciones no se encontraron e imprime sus títulos al final.
  • 🟡 Reto 2: agrega a la descripción de la lista el texto "Creada con Python el …" con la fecha actual.
  • 🟠 Reto 3: en lugar de agregar las canciones una por una, agrúpalas y agrégalas en lotes (consulta en la documentación cuántas admite cada llamada). ¿Por qué es mejor para el servidor?
  • 🔴 Reto 4: cuando la búsqueda devuelve varios resultados, escribe una función que elija el que mejor coincide con el título y el artista del Hot 100 (por ejemplo, comparando textos en minúsculas y sin signos). Pruébala con canciones que tengan versiones en vivo o remixes.

4. Ruta C para el aula: una lista de reproducción sin cuentas

(Adaptación pedagógica; no existe en el curso original.)

🎯 Objetivo

Obtener el mismo resultado práctico (poder escuchar las canciones de una fecha) sin cuentas, sin cookies y sin tokens, reutilizando el HTML de los Días 41 a 44.

📖 La idea

Un programa en Python puede escribir un archivo HTML. Si para cada canción creamos un enlace de búsqueda en YouTube, obtenemos una "lista de reproducción" en forma de página web que cualquiera puede abrir:

Python
from urllib.parse import quote_plus

consulta = quote_plus("Choosin' Texas Ella Langley")
enlace = f"https://www.youtube.com/results?search_query={consulta}"
  • quote_plus convierte el texto al formato de una URL: "Choosin' Texas Ella Langley" → "Choosin%27+Texas+Ella+Langley" (verificado; los espacios pasan a + y el apóstrofo a %27).
  • El programa no hace ninguna petición a YouTube: solo escribe enlaces. Quien abre la página decide en qué canción hacer clic.

📝 Actividad

Escribe una función crear_pagina(fecha, canciones) que reciba la fecha y la lista de tuplas (título, artista) del paso 1 y genere hot100_{fecha}.html con:

  • La plantilla HTML completa del Día 42 (lang, charset, title).
  • Un h1 con el título "Máquina del tiempo: {fecha}".
  • Una lista ordenada con cada canción como enlace de búsqueda.
  • Una hoja de estilos (puede ser interna, Día 43) que dé un aspecto de "cinta de casete".

🔍 Antes de programar

  • ¿Qué partes de la página son fijas y cuáles cambian con cada canción?
  • ¿Qué pasa si un título contiene < o &? (Pista: busca html.escape en la documentación de Python.)
  • ¿Con qué encoding debes escribir el archivo para que las tildes se vean bien?

5. 🚀 Proyecto del día: la máquina del tiempo musical

(Integra los pasos 1 a 4 del curso: 338 a 344.)

Problema

Dada una fecha, obtener las 100 canciones más populares de esa semana y convertirlas en algo que se pueda escuchar.

Contexto

Un regalo para un familiar: la música de la semana en que se graduó, se casó o nació alguien de la familia.

Objetivo

Un programa que pida una fecha, extraiga el Hot 100 y cree la lista de reproducción por la ruta elegida (A, B o C).

Requisitos funcionales

  1. Pedir y validar la fecha.
  2. Extraer títulos y artistas (el curso pide títulos; el artista mejora la búsqueda).
  3. Crear la lista (ruta A o B) o la página (ruta C) con el nombre AAAA-MM-DD Billboard 100.
  4. Informar cuántas canciones se agregaron y cuáles no se encontraron.
  5. No duplicar la lista si el programa se ejecuta dos veces con la misma fecha.

Restricciones técnicas

  • Credenciales (si las hay) en .env, nunca en el código.
  • Manejo de excepciones en la búsqueda de cada canción.
  • Código organizado en funciones: pedir_fecha(), obtener_hot100(fecha), crear_lista(...).

Planificación

  1. Comprender el flujo completo. 2. Entradas: la fecha. 3. Procesos: validar → descargar → extraer → buscar → agregar. 4. Salidas: lista o página, y un resumen. 5. Dividir en funciones. 6. Diseñar un diagrama de flujo. 7. Implementar por versiones. 8. Probar. 9. Corregir. 10. Mejorar.

Construcción paso a paso

  • Versión 1: fecha fija en el código; imprime los 100 títulos.
  • Versión 2: fecha con input() y validación; títulos y artistas.
  • Versión 3: autenticación (A o B) o función que escribe el HTML (C), probada con 3 canciones antes de las 100.
  • Versión 4: búsqueda y agregado con try/except, y conteo de fallos.
  • Versión final: control de duplicados y resumen final.

Pruebas

Caso Entrada Resultado esperado
Fecha válida disponible 2000-08-12 100 canciones extraídas
Formato inválido 12/08/2000 Mensaje de error y nueva pregunta
Fecha sin datos 2026-04-19 "No hay datos para esa fecha" (el sitio responde 404, verificado)
Ejecutar dos veces Misma fecha No se crea una segunda lista
Canción inexistente Título inventado agregado a la lista Se reporta como "no encontrada" y el programa continúa

🧪 Prueba y depuración

Este fragmento tiene cuatro problemas. Explica cada uno:

Python
date = input("¿A qué fecha quieres viajar? (AAAA-MM-DD): ")
response = requests.get("https://appbrewery.github.io/bakeboard-hot-100/" + date)
soup = BeautifulSoup(response.text, "html.parser")
songs = soup.find_all("h3", class_="chart-entry__title").getText()
for song in songs:
    result = yt.search(song, filter="songs")
    yt.add_playlist_items(playlist_id, [result[0]["videoId"]])

(Pistas: qué pasa si la fecha no existe y nadie revisa response.status_code; qué devuelve find_all; qué pasa si result está vacío; qué dato falta en la búsqueda. Curiosamente, la URL sin barra final sí funciona: el servidor responde con una redirección 301 a la dirección con barra y requests la sigue automáticamente, verificado.)

⭐ Extensión del proyecto

  • Permitir varias fechas y crear una lista combinada sin canciones repetidas (conjuntos, set).
  • Agregar a la página de la ruta C la posición de cada canción y resaltar el top 10 con CSS.
  • Guardar un historial (JSON, Día 30) con las fechas ya procesadas.

6. 🌟 Proyecto extra: el observatorio de la radio escolar

(Proyecto creado para esta adaptación; no existe en el curso original.)

Situación

La emisora escolar quiere un segmento semanal: "¿Qué cambió en el ranking?". Necesitan comparar el Hot 100 de dos semanas disponibles en Bakeboard.

Requisitos

  1. Pedir dos fechas y extraer ambos rankings (título, artista y posición).
  2. Reportar: canciones nuevas (están en la segunda y no en la primera), canciones que salieron, las 3 que más subieron y las 3 que más bajaron.
  3. Generar el guion del segmento en un archivo .txt con un texto listo para leer al aire.
  4. Hacer como máximo una petición por fecha y esperar un segundo entre ellas.

Decisiones que debes tomar (y justificar)

  • ¿Cómo identificas que dos canciones son "la misma"? ¿Solo por el título? ¿Qué pasa si dos artistas tienen canciones con el mismo nombre?
  • ¿Qué estructura de datos usas: listas, diccionarios, conjuntos? ¿Por qué?
  • ¿Cómo presentas los resultados para que se entiendan escuchándolos (radio) y no leyéndolos?

Casos de prueba

  • Comparar una fecha consigo misma: no debe haber canciones nuevas ni canciones que salieron.
  • Dos semanas consecutivas (por ejemplo, 2026-04-11 y 2026-04-18) y dos muy lejanas (1970-08-01 y 2026-04-18): ¿los resultados tienen sentido?

7. 🏆 Proyecto integrador del bloque (Días 45 a 51) — Etapa 2

(Proyecto creado para esta adaptación. La situación problema está en el Día 45; la versión final, en el Día 51.)

Etapa 2 (hoy): de los datos a una página web

  1. Toma la información que extrajo lector.py (etapa 1) de tu sitio del bloque web.
  2. Escribe generar_reporte.py, que produzca un archivo reporte.html con:
    • Un resumen (número de enlaces, imágenes y encabezados).
    • Una tabla o lista con los enlaces y una indicación de si son internos o externos.
    • Una sección de alertas de accesibilidad (imágenes sin alt), resaltada con CSS.
  3. Usa html.escape para cualquier texto que venga de la página analizada.
  4. Entregable: generar_reporte.py y reporte.html abierto en el navegador (captura).

8. 🧩 Comprueba lo aprendido

Conceptuales

  1. ¿Por qué el curso creó Bakeboard en lugar de usar solo Billboard?
  2. ¿Para qué sirve el encabezado User-Agent?
  3. ¿Qué problema resuelve OAuth? ¿Qué es un scope?
  4. ¿Por qué browser.json debe tratarse como una contraseña?
  5. ¿Por qué se usa try/except al buscar cada canción?

Análisis de código

Python
fechas_validas = []
for texto in ["2000-08-12", "2000-13-01", "12-08-2000"]:
    try:
        datetime.strptime(texto, "%Y-%m-%d")
        fechas_validas.append(texto)
    except ValueError:
        print(f"Formato inválido: {texto}")

¿Qué imprime y qué contiene fechas_validas al final?

Predicción

Python
from urllib.parse import quote_plus
print(quote_plus("Rock & Roll 100%"))

Escribe tu predicción y luego ejecútalo.

Depuración

Python
canciones = [h3.getText() for h3 in soup.find_all("h3")]
print(canciones[0])      # imprime "\n   Choosin' Texas\n  "
if "Choosin' Texas" in canciones:
    print("Encontrada")  # nunca se imprime

¿Por qué no se imprime "Encontrada"? Corrígelo.

Modificación

Cambia tu programa para que el nombre de la lista incluya el día de la semana (por ejemplo, "Sábado 12 de agosto de 2000 — Billboard 100"). Pista: strftime.

Creación

Crea un programa que reciba una fecha y un artista, y diga en qué posición estaba cada canción de ese artista en el Hot 100 de esa fecha (o que no tenía canciones en el ranking).


9. 🤖 Programar con apoyo de IA

Ciclo de trabajo: formula el problema → inténtalo tú → consulta a la IA → lee y entiende → prueba → compara con la documentación oficial → modifica → explica con tus palabras.

Actividad 1 — Documentación contra respuestas de la IA. Pide a una IA el código para autenticarse con Spotipy. Compara el nombre de las clases, los parámetros y la Redirect URI con la documentación actual de Spotipy y con la guía de Spotify. ¿La IA propone http://localhost? ¿Qué dice hoy la documentación de Spotify sobre eso?

Actividad 2 — Seguridad. Pregúntale a una IA: "¿Es seguro compartir mi archivo browser.json con un compañero para que pruebe mi código?". Evalúa si la respuesta explica qué contiene el archivo. Escribe tú una explicación de tres líneas para un compañero que no sepa qué son las cookies.

Actividad 3 — Leer resultados anidados. Pide a una IA que te explique la estructura del diccionario que devuelve una búsqueda de Spotify o de ytmusicapi. Luego compruébalo con pprint sobre un resultado real (o sobre el ejemplo de la documentación). ¿La IA acertó en los nombres de las claves?


10. 🛠️ Correcciones técnicas al material original

Archivo Afirmación o comportamiento del curso Observación Tratamiento
342 Redirect URI http://example.com Spotify anunció en 2025 que las apps nuevas deben usar HTTPS (o una IP de loopback como http://127.0.0.1) y que no se acepta localhost. Hay que consultar la guía vigente Nota técnica de la sección 3
343 Consulta "track: {name} year: {YYYY}" Las canciones publicadas el año anterior a la fecha elegida no se encuentran; buscar por título y artista es más preciso Nota técnica de la sección 3
339 ytmusicapi "toma prestada" la sesión del navegador Es correcto, pero implica un riesgo de seguridad que el curso no destaca: browser.json da acceso a la cuenta de Google Aviso inicial; nota de la sección 2
338 El paso 1 solo pide los títulos Sin el artista, la búsqueda confunde canciones con el mismo nombre Reto 1 de la sección 1; proyecto del día
337 "Cualquier fecha de los últimos 20 años" en Billboard Bakeboard tiene 103 fechas concretas (1959–2026) y responde 404 con las demás (verificado) Sección 1; pruebas del proyecto

11. 📋 Matriz de trazabilidad

Contenido original Archivo de origen Concepto desarrollado Ejercicio original Reto adicional Proyecto relacionado
Cinta mezclada, máquina del tiempo, Billboard Hot 100, plan en tres pasos, idea de regalo 337 Sección 0 — — Sección 5
Elegir ruta, Bakeboard, input() con formato de fecha, scraping de 100 títulos, URL histórica, encabezado User-Agent 338 Sección 1 Paso 1 Retos 1–4 de la sección 1 Secciones 5 y 6
ytmusicapi, browser.json, Firefox, Copy Request Headers, ytmusicapi browser, pbpaste, get_library_playlists 339 Sección 2 Paso 2 (YouTube Music) Retos de las rutas A y B Sección 5
create_playlist, lista privada, evitar duplicados 340 Sección 2 Paso 3 (YouTube Music) Retos de las rutas A y B Sección 5
search con filter="songs", add_playlist_items, try/except 341 Sección 2 Paso 4 (YouTube Music) Retos de las rutas A y B Sección 5
Premium, Developer Dashboard, Client ID y Secret, OAuth, Spotipy, SpotifyOAuth, Redirect URI, playlist-modify-private, token.txt, current_user 342 Sección 3 Paso 2 (Spotify) Retos de las rutas A y B Sección 5
URI de canciones, consulta track: y year:, excepciones, pprint 343 Sección 3 Paso 3 (Spotify) Retos de las rutas A y B Sección 5
Crear lista privada con el id del usuario, agregar canciones con el id de la lista 344 Sección 3 Paso 4 (Spotify) Retos de las rutas A y B Sección 5
(No existe en el curso original) — Sección 4 — Ruta C: página HTML con enlaces de búsqueda Sección 5
(No existe en el curso original) — — — Observatorio de la radio escolar Sección 6
(No existe en el curso original) — — — Asistente automático, etapa 2 Sección 7

12. 📦 Evidencias de aprendizaje del Día 46

  • Programa del paso 1 con validación de la fecha y manejo del error 404.
  • Lista de tuplas (título, artista) impresa para una fecha elegida.
  • Según la ruta: captura de la lista creada en YouTube Music o Spotify, o el archivo hot100_{fecha}.html de la ruta C abierto en el navegador.
  • Resumen de canciones agregadas y no encontradas.
  • El guion del observatorio de la radio escolar (proyecto extra).
  • Etapa 2 del proyecto integrador: reporte.html.
  • Cuaderno de errores: fecha mal escrita, 404 silencioso, getText sobre una lista, títulos con espacios, búsqueda sin artista, Redirect URI que no coincide, credenciales o browser.json expuestos.