Saltar al contenido
Volver al inicio 100 Días de Código en Python — Día 14: Proyecto Higher Lower (Mayor o Menor)

100 Días de Código en Python — Día 14: Proyecto Higher Lower (Mayor o Menor)

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

Este tutorial adapta pedagógicamente el Día 14, el último del nivel principiante. Todo el día es un proyecto que el estudiante debe construir solo. Aquí se organiza por las etapas de la solución del curso. Las secciones 📝 Ejercicio original del curso provienen de los archivos del curso. Los retos 🟢🟡🟠🔴, el proyecto extra y el proyecto integrador son creaciones de esta adaptación. Las correcciones al material original aparecen como 🛠️ Nota técnica.


Tabla de contenidos

  1. Antes de empezar: el método para resolver problemas grandes
  2. Etapa 1: Descomponer el juego en problemas pequeños
  3. Etapa 2: Datos: una lista de diccionarios
  4. Etapa 3: Formatear y mostrar las cuentas
  5. Etapa 4: Verificar la respuesta (tabla de decisiones)
  6. Etapa 5: Puntaje, repetición y "B pasa a ser A"
  7. 🚀 Proyecto del día: Higher Lower completo
  8. 🌟 Proyecto extra: Mayor o Menor, Colombia en Datos
  9. 🏆 Proyecto integrador del nivel principiante (Días 1–14): Mayor o Menor, Edición del Colegio
  10. 🤖 Programar con apoyo de IA
  11. 🛠️ Correcciones técnicas al material original
  12. 📋 Matriz de trazabilidad
  13. 📦 Evidencias de aprendizaje del Día 14

0. Antes de empezar

(Fuentes: 102 - Introduction & Program Requirements for the Higher Lower Game.md, 104 - Study Tip- Set Reminders in Your Calendar to Review.md)

El juego. Se muestran dos cuentas de Instagram, A y B, y debes adivinar cuál tiene más seguidores. Si aciertas, sumas un punto, la cuenta B pasa a ser la A y aparece una nueva B. Si fallas, el juego termina y ves tu puntaje final. Se basa en el juego web Higher or Lower, donde se comparan cantidades de búsquedas en Google.

Lo especial de hoy. Igual que en el Día 12, vuelas solo. El curso te da los datos y el arte, pero no los pasos: tú debes descomponer el problema.

El método del curso para resolver problemas grandes

Texto
flowchart LR
    A[Dividir el problema grande<br/>en problemas pequeños] --> B[Hacer una lista de tareas]
    B --> C[Elegir la tarea más fácil]
    C --> D[Dividirla en comentarios<br/>dentro del código]
    D --> E[Escribir código<br/>bajo los comentarios]
    E --> F[Ejecutar]
    F --> G{¿Funciona?}
    G -- No --> H[Corregir] --> F
    G -- Sí --> I[Tachar la tarea] --> C

"Esta es la verdadera habilidad de los programadores: tomar algo inmensamente complejo, dividirlo en problemas más pequeños y abordarlos del más fácil al más difícil."

Consejo de estudio de cierre del curso: si en algún ejercicio tuviste que mirar la solución, no fallaste. Asegúrate de entenderla y luego agenda en tu calendario rehacer ese ejercicio dentro de una semana, sin ayuda.

Prerequisito general: Días 1 a 13. En especial: listas de diccionarios (Día 9), funciones con return (Día 10), while con bandera (Días 6 y 7) y depuración (Día 13).


1. Etapa 1: Descomponer el juego

(Fuente: 103 - Solution & Walkthrough of the Higher Lower Game.md, primera parte)

🎯 Objetivo de aprendizaje

  • Observar un programa terminado y deducir todos los subproblemas que lo componen.

📝 Ejercicio original del curso: juega y haz tu lista

Enunciado: juega la versión final al menos 10 veces, observando qué pasa cuando aciertas, cuando fallas y qué se repite. Luego escribe tu lista de tareas.

La lista que construye el curso (compárala con la tuya después de hacer la tuya):

  1. Mostrar el arte: el logo y el "VS".
  2. Generar cuentas al azar a partir de los datos.
  3. Dar formato a los datos de la cuenta para mostrarlos.
  4. Pedir al usuario que adivine.
  5. Verificar si acertó, obteniendo los seguidores de cada cuenta y usando un if.
  6. Darle retroalimentación.
  7. Llevar el puntaje.
  8. Hacer que el juego se repita.
  9. Que la cuenta B pase a ser la A en la siguiente ronda.
  10. "Limpiar" la pantalla entre rondas.

"Si llegaste hasta aquí y lograste identificar todos los problemas que necesitas resolver, ya puedes considerarte exitoso."

Retos adicionales (creados para esta adaptación)

  • 🟢 Reto 1: ordena tu lista de la tarea más fácil a la más difícil y justifica el orden.
  • 🟡 Reto 2: convierte tu lista en un diagrama de flujo.
  • 🟠 Reto 3: para la tarea más difícil de tu lista, escribe los comentarios que pondrías en el código (sin código todavía), como recomienda el curso.
  • 🔴 Reto 4: juega la versión web original y haz una lista de las diferencias con la versión del curso. ¿Qué funcionalidades agregarías y cuánto trabajo crees que costaría cada una?

2. Etapa 2: Datos: una lista de diccionarios

📖 Explicación conceptual

El archivo inicial del curso trae game_data.py, con una variable data: una lista de diccionarios (Día 9). Todos los diccionarios tienen las mismas cuatro claves:

Python
data = [
    {
        "name": "Nombre de la cuenta",
        "follower_count": 215,          # en millones
        "description": "Futbolista",
        "country": "Portugal",
    },
    # ... más cuentas
]

El curso dice, por ejemplo, que Cristiano Ronaldo tenía 215 millones de seguidores "al menos en el momento en que recopilé los datos". Estos datos cambian con el tiempo. Además, los archivos game_data.py y art.py del curso no están incluidos entre los materiales suministrados, así que tendrás que crear tu propio conjunto de datos (ver la nota técnica).

Importar de otros archivos (Días 4 y 7):

Python
from game_data import data
from art import logo, vs
import random

Elegir cuentas al azar:

Python
account_a = random.choice(data)
account_b = random.choice(data)
if account_a == account_b:
    account_b = random.choice(data)

🛠️ Nota técnica (verificada): con if, la cuenta se vuelve a elegir una sola vez, y puede volver a salir repetida. En una simulación con 5 cuentas, alrededor del 4 % de las rondas mostraron la misma cuenta dos veces. Corrección: usar while account_a == account_b:.

Retos adicionales (creados para esta adaptación)

  • 🟢 Reto 1: crea un game_data.py propio con al menos 10 elementos de un tema que te interese, con la misma estructura de cuatro claves.
  • 🟡 Reto 2: imprime el nombre de todas las cuentas recorriendo la lista con un for.
  • 🟠 Reto 3: encuentra, con un bucle y sin usar max, la cuenta con más seguidores de tus datos (Día 5).
  • 🔴 Reto 4: ¿qué pasa si dos cuentas tienen exactamente el mismo número de seguidores? Busca si ocurre en tus datos y piensa qué debería hacer el juego (ver la Etapa 4).

3. Etapa 3: Formatear y mostrar las cuentas

📝 Ejercicio original del curso: format_data

El curso lo resuelve así: primero escribe el código para la cuenta A. Al notar que tendría que repetirlo para la cuenta B, lo convierte en una función con return y docstring:

Python
def format_data(account):
    """Recibe los datos de una cuenta y devuelve un texto listo para imprimir."""
    account_name = account["name"]
    account_descr = account["description"]
    account_country = account["country"]
    return f"{account_name}, {account_descr}, de {account_country}"

Uso: print(f"Compara A: {format_data(account_a)}."), luego print(vs) y después print(f"Contra B: {format_data(account_b)}.").

Lección del curso: "cuando te repites, crea una función". Y no muestres follower_count, porque eso revelaría la respuesta.

⚠️ Errores frecuentes

  • Claves mal escritas: account["Name"] produce KeyError. El curso recomienda copiar y pegar las claves.
  • Imprimir dentro de la función: si format_data imprime en lugar de devolver, no se puede usar dentro de una f-string (Día 10).

Retos adicionales (creados para esta adaptación)

  • 🟢 Reto 1: cambia el formato a Nombre (descripción, país).
  • 🟡 Reto 2: ajusta el artículo según el país (de Colombia, de Estados Unidos) o evita el problema reformulando la frase.
  • 🟠 Reto 3: agrega una clave "categoria" a tus datos y muéstrala con un emoji (⚽ deportes, 🎵 música…) usando un diccionario de emojis.
  • 🔴 Reto 4: escribe format_data(account, mostrar_seguidores=False), con un parámetro por defecto, para poder reutilizarla en la pantalla final mostrando los seguidores.

4. Etapa 4: Verificar la respuesta

📖 La tabla de decisiones del curso

La lógica "¿acertó?" depende de dos cosas: qué eligió el usuario y cuál cuenta tiene más seguidores. El curso la dibuja como una tabla de 2 × 2:

El usuario elige A El usuario elige B
A tiene más ✅ Correcto ❌ Incorrecto
B tiene más ❌ Incorrecto ✅ Correcto

De la versión larga a la corta (el curso muestra las dos):

Python
# Versión larga (fácil de perderse)
if a_followers > b_followers and guess == "a":
    return True
elif ...  # cuatro casos

# Versión corta del curso
def check_answer(user_guess, a_followers, b_followers):
    """Recibe la elección del usuario y los seguidores; devuelve True si acertó."""
    if a_followers > b_followers:
        return user_guess == "a"
    else:
        return user_guess == "b"

return user_guess == "a" devuelve directamente el resultado de la comparación: True o False. El curso admite que "es un poco alucinante" y recomienda seguirlo con el depurador.

La entrada se normaliza con .lower() para aceptar tanto A como a.

🛠️ Nota técnica (verificada):

  • Empate: si ambas cuentas tienen los mismos seguidores, el else da como correcta solo la B.
  • Entrada inválida: si el usuario escribe c, se toma como respuesta incorrecta y el juego termina.

Mejoras: decide una regla justa para los empates (por ejemplo, que ambas respuestas sean correctas) y valida la entrada con el kit del Día 13 (pedir_opcion).

Retos adicionales (creados para esta adaptación)

  • 🟢 Reto 1: escribe las 4 pruebas de la tabla de decisiones y 2 pruebas de empate, llamando check_answer con valores fijos.
  • 🟡 Reto 2: implementa una regla para los empates y pruébala.
  • 🟠 Reto 3: escribe una versión de check_answer en una sola línea con operadores lógicos. ¿Es más legible o menos?
  • 🔴 Reto 4: agrega un modo "difícil" en el que el usuario, además de elegir, debe estimar la diferencia de seguidores. Gana 2 puntos si su estimación está a menos del 20 % del valor real.

5. Etapa 5: Puntaje, repetición y "B pasa a ser A"

📖 Explicación conceptual

Retroalimentación y puntaje: score = 0 antes del bucle. Si acierta: score += 1 y "¡Correcto! Puntaje actual: X". Si falla: "Lo siento, es incorrecto. Puntaje final: X".

¿Qué parte se repite? El curso lo analiza así: el puntaje inicial no se repite; elegir cuentas, mostrarlas, preguntar y verificar sí se repiten. La bandera game_should_continue = True se vuelve False cuando el usuario falla.

"B pasa a ser A" (la parte más ingeniosa). Jugando a ser el computador (Día 13):

Python
account_b = random.choice(data)     # ANTES del bucle: solo la primera vez

while game_should_continue:
    account_a = account_b           # la B anterior pasa a ser la nueva A
    account_b = random.choice(data) # nueva B
    while account_a == account_b:   # (mejora de esta adaptación)
        account_b = random.choice(data)
    ...
Momento account_a account_b
Antes del bucle — X (al azar)
Ronda 1 X Y (nueva)
Ronda 2 (si acertó) Y Z (nueva)

Limpiar la pantalla: justo después de la respuesta del usuario, print("\n" * 20) y volver a imprimir el logo.

⚠️ Errores frecuentes

  • score = 0 dentro del bucle: el puntaje se reinicia en cada ronda. Es el acumulador reiniciado del Día 5.
  • Elegir la cuenta A al azar dentro del bucle: se pierde el efecto "B pasa a ser A".
  • La primera account_b dentro del bucle: en la primera ronda, account_a = account_b produce NameError.

Retos adicionales (creados para esta adaptación)

  • 🟢 Reto 1: muestra en cada ronda el número de ronda además del puntaje.
  • 🟡 Reto 2: evita que ninguna cuenta se repita en toda la partida, llevando una lista de cuentas ya usadas.
  • 🟠 Reto 3: cuando el usuario falle, muestra los seguidores de A y B para que vea por cuánto se equivocó.
  • 🔴 Reto 4: ¿qué pasa si se acaban las cuentas disponibles (Reto 2)? Diseña el final "¡Completaste todas las cuentas!" y pruébalo con un conjunto de datos de solo 4 elementos.

6. 🚀 Proyecto del día: Higher Lower completo

(Fuentes: 102 y 103, proyecto oficial del curso original)

Requisitos funcionales

  1. Logo al inicio y después de cada ronda.
  2. Compara A: [cuenta], el arte "VS" y Contra B: [cuenta], sin mostrar los seguidores.
  3. Pregunta "¿Quién tiene más seguidores? Escribe 'A' o 'B'", sin importar mayúsculas.
  4. Si acierta: puntaje + 1, mensaje y nueva ronda en la que B pasa a ser A.
  5. Si falla: mensaje con el puntaje final y fin del juego.

Restricciones técnicas

Módulos propios (game_data.py, art.py), una lista de diccionarios, funciones con return (format_data, check_answer), un while con bandera y un acumulador.

Pruebas

(Usa un game_data.py de prueba con valores que controles.)

Caso Datos Resultado esperado
A tiene más y elige a A = 100, B = 50 Correcto, puntaje 1
A tiene más y elige B (mayúscula) A = 100, B = 50 Incorrecto, fin
Empate A = 70, B = 70 Según tu regla (el curso da correcta solo la B)
Entrada c — Curso: termina el juego. Mejorada: vuelve a preguntar
2 rondas acertadas — La B de la ronda 1 aparece como A en la ronda 2
Conjunto de datos de 2 elementos — Con while, A y B nunca son la misma cuenta

🧪 Prueba y depuración

Este código tiene cuatro errores:

Python
score = 0
game_should_continue = True
while game_should_continue:
    account_a = account_b
    account_b = random.choice(data)
    print(f"Compara A: {format_data(account_a)}.")
    print(vs)
    print(f"Contra B: {format_data(account_b)}.")
    guess = input("¿Quién tiene más seguidores? 'A' o 'B': ")
    a_follower_count = account_a["follower_count"]
    b_follower_count = account_b["followers"]
    is_correct = check_answer(guess, a_follower_count, b_follower_count)
    if is_correct:
        score = 1
        print(f"¡Correcto! Puntaje actual: {score}.")
    else:
        print(f"Lo siento, es incorrecto. Puntaje final: {score}.")

(Pistas: una variable que no existe en la primera ronda, un .lower() que falta, una clave equivocada y un acumulador que no acumula. Y aunque no es un error de sintaxis: ¿cuándo termina el juego?)

⭐ Extensión del proyecto

  • Guardar el récord de la sesión y un menú "¿Jugar otra vez?".
  • Limpiar la pantalla de verdad con os.system("cls" if os.name == "nt" else "clear").
  • Mostrar al final la lista de cuentas en las que acertaste.

7. 🌟 Proyecto extra: Mayor o Menor, Colombia en Datos

Situación

Reutiliza exactamente el mismo motor del juego, pero con datos de Colombia para repasar Ciencias Sociales, por ejemplo: la población de los departamentos, la altura de montañas o volcanes, o la longitud de los ríos.

Requisitos

  1. Investigar los datos en fuentes oficiales (por ejemplo DANE, IGAC o IDEAM) y citar la fuente y el año en un comentario al inicio de datos_colombia.py.
  2. Mantener la estructura de lista de diccionarios, adaptando las claves (por ejemplo, "nombre", "valor", "unidad" y "region").
  3. Cambiar solo los textos y los datos: la lógica (check_answer, "B pasa a ser A") no debería cambiar.
  4. Al final de cada ronda, mostrar el valor real de ambos elementos, porque el objetivo es aprender.

⚠️ Este tutorial no trae datos listos a propósito: buscar, verificar y citar la información es parte del ejercicio. Usa siempre fuentes oficiales y fechas recientes.

Pregunta de análisis

¿Cuántas líneas de la lógica tuviste que cambiar? Si fueron muchas, ¿qué podrías haber diseñado mejor en tu versión original?


8. 🏆 Proyecto integrador del nivel principiante

Proyecto integrador creado para esta adaptación. Con el Día 14 termina el nivel principiante del curso; el Día 15 inicia el intermedio. Este proyecto integra los Días 1 a 14.

Mayor o Menor: Edición del Colegio

Situación problema

El consejo estudiantil quiere un juego para la semana cultural que ponga a prueba el conocimiento de los estudiantes sobre temas del colegio y de Colombia, con varias categorías y un modo para dos jugadores.

Pregunta orientadora

¿Cómo construir un programa completo, robusto y extensible combinando todo lo aprendido en el nivel principiante?

Requerimientos

# Requerimiento Conceptos (día)
1 Módulo de datos con al menos 3 categorías, cada una una lista de diccionarios, organizadas en un diccionario {categoria: lista}. Los datos deben estar investigados y con la fuente citada Anidamiento (4, 9), módulos (7)
2 Menú de categorías generado con for Bucles (5)
3 Validación de todas las entradas con el kit del Día 13 try/except, funciones (10, 13)
4 Sin repetir elementos durante una partida Listas, in, remove (4, 7)
5 Regla definida para los empates Condicionales (3)
6 Modo dos jugadores: turnos alternos con %; cada jugador tiene 3 vidas; gana quien sume más puntos % (3), diccionario de jugadores (9)
7 Constantes globales para las vidas, los puntos y el número de categorías; sin global Ámbito (12)
8 Récord de la sesión y "¿jugar otra vez?" while, acumuladores (5, 6)
9 Todas las funciones con docstring y return (10)
10 Bitácora de depuración con al menos 3 bugs encontrados durante el desarrollo Depuración (13)

Etapas de desarrollo (con el método del curso)

  1. Jugar la versión del Día 14 y escribir tu lista de tareas del proyecto integrador.
  2. Ordenar las tareas de la más fácil a la más difícil.
  3. Para cada tarea: comentarios → código → ejecutar → corregir → tachar.
  4. Pruebas finales con una tabla de al menos 12 casos.

Entregables

  • Código en al menos 4 archivos: principal, datos, arte y entradas.py.
  • Lista de tareas y diagrama de flujo.
  • Tabla de pruebas y bitácora de depuración.
  • Demostración en clase y una reflexión escrita: ¿qué aprendiste en los 14 días? ¿Qué concepto necesitas repasar antes del nivel intermedio? (Aplica el consejo del curso: agenda ese repaso en tu calendario.)

Criterios técnicos de funcionamiento

  • Ninguna entrada del usuario detiene el programa.
  • Los elementos no se repiten durante una partida y el juego maneja bien el caso en que se agotan.
  • En el modo de dos jugadores, los turnos, las vidas y los puntajes se calculan correctamente (verificados con una partida documentada paso a paso).
  • No aparece la palabra global y las constantes están en mayúsculas.

9. 🤖 Programar con apoyo de IA

El curso dice: "no importa tanto el código, sino la habilidad de descomponer". Esa es justamente la parte que no conviene delegar a una IA.

Actividad: comparar descomposiciones.

  1. Haz tu lista de tareas del Higher Lower sin ayuda.
  2. Pide a una IA: "Descompón en tareas pequeñas un juego de consola tipo Higher or Lower".
  3. Compara las tres listas: la tuya, la del curso (Etapa 1) y la de la IA. ¿Qué tarea olvidó cada una? ¿Alguna consideró los empates o las cuentas repetidas?
  4. Verificación de datos: si pides a una IA datos de seguidores o de población, contrástalos con una fuente oficial. Las IA pueden inventar cifras que parecen reales.

10. 🛠️ Correcciones técnicas al material original

Archivo Comportamiento del curso Observación (verificada) Tratamiento
103 if account_a == account_b: vuelve a elegir una sola vez La cuenta puede repetirse igual (≈ 4 % de las rondas con 5 cuentas en una simulación). Se corrige con while Nota técnica en la Etapa 2 y pruebas
103 check_answer con else para B En un empate solo la B cuenta como correcta Nota técnica en la Etapa 4
103 Sin validación de la entrada Escribir c o dejarlo vacío termina el juego como si fuera un error del jugador Nota técnica y kit del Día 13
102 Seguidores "al momento de recopilar los datos" Los datos quedan desactualizados con el tiempo Etapa 2 y proyecto extra (citar la fuente y la fecha)
102 Archivos game_data.py y art.py No están incluidos entre los materiales suministrados Se pide crear un conjunto de datos propio

11. 📋 Matriz de trazabilidad

Contenido original Archivo de origen Concepto desarrollado Ejercicio original Reto adicional Proyecto relacionado
Juego, método de descomposición, archivos iniciales 102 Sección 0 y Etapas 1–2 Jugar 10 veces y hacer la lista de tareas Retos 1–4 de la Etapa 1 Secciones 6, 7 y 8
Lista de problemas del curso 103 Etapa 1 Comparar con la propia lista Retos de la Etapa 1 Sección 8
Arte, datos, random.choice, cuentas distintas 103 Etapa 2 Importar y elegir cuentas Retos 1–4 de la Etapa 2 Secciones 6 y 7
format_data 103 Etapa 3 Función de formato Retos 1–4 de la Etapa 3 Secciones 6 y 7
Tabla de 2 × 2, check_answer, .lower() 103 Etapa 4 Verificar la respuesta Retos 1–4 de la Etapa 4 (empates) Secciones 6 y 8
Puntaje, bandera, B pasa a ser A, limpiar la pantalla 103 Etapa 5 Repetición del juego Retos 1–4 de la Etapa 5 Secciones 6 y 8
Consejo de estudio: agendar repasos 104 Sección 0 — Reflexión del integrador Sección 8
(No existe en el curso original) — — — Mayor o Menor: Colombia en Datos Sección 7
(No existe en el curso original) — — — Mayor o Menor: Edición del Colegio (Días 1–14) Sección 8

12. 📦 Evidencias de aprendizaje del Día 14

  • Tu lista de tareas y tu diagrama, hechos antes de ver la solución.
  • Higher Lower funcionando con tu propio conjunto de datos y la tabla de pruebas.
  • Depuración resuelta: los 4 errores y la pregunta sobre cuándo termina el juego.
  • Proyecto extra (con datos citados) o integrador del nivel principiante.
  • Plan de repaso: una lista de los ejercicios de los Días 1 a 14 en los que necesitaste ayuda, con la fecha en que los vas a rehacer (consejo del curso).