Cómo crear un quiz interactivo en Python

Publicado el: 11/07/2026
Tempo de leitura: 3 minutos
Quiz interativo no terminal desenvolvido com Python

Un quiz interactivo es un proyecto práctico para aprender a organizar datos, validar respuestas, recorrer colecciones, calcular puntuaciones y guardar preguntas en archivos. La primera versión puede funcionar completamente en el terminal, pero una buena estructura permite reutilizar la lógica después en Tkinter, una página web o una aplicación móvil.

Antes de comenzar, conviene revisar los diccionarios en Python, las listas, la función input(), las funciones y el módulo random.

La documentación oficial del módulo json explica cómo leer y escribir archivos JSON. La documentación oficial de random describe cómo mezclar opciones y seleccionar elementos.

Representar una pregunta

Podemos guardar cada pregunta en un diccionario:

pregunta = {
    "texto": "¿Cuál es la capital de España?",
    "opciones": ["Madrid", "Barcelona", "Valencia", "Sevilla"],
    "correcta": 0,
    "explicacion": "Madrid es la capital de España.",
}

El índice correcto es cero porque las listas de Python comienzan en cero. La interfaz mostrará las opciones desde uno para que sean más naturales para el usuario.

Crear un banco de preguntas

preguntas = [
    {
        "texto": "¿Qué palabra define una función en Python?",
        "opciones": ["func", "def", "function", "method"],
        "correcta": 1,
        "explicacion": "Las funciones se definen con def.",
    },
    {
        "texto": "¿Qué tipo almacena pares clave-valor?",
        "opciones": ["list", "tuple", "dict", "set"],
        "correcta": 2,
        "explicacion": "dict relaciona claves con valores.",
    },
]

Mantén las preguntas separadas de la lógica del juego. Así podrás editarlas sin tocar las funciones principales.

Mostrar una pregunta

def mostrar_pregunta(pregunta, numero):
    print(f"\nPregunta {numero}: {pregunta['texto']}")
    for indice, opcion in enumerate(pregunta["opciones"], start=1):
        print(f"  {indice}. {opcion}")

enumerate evita crear un contador manual y permite empezar la numeración en uno.

Leer una respuesta válida

def leer_respuesta(cantidad_opciones):
    while True:
        texto = input("Respuesta: ").strip()
        if not texto.isdigit():
            print("Escribe el número de una opción.")
            continue

        respuesta = int(texto)
        if not 1 <= respuesta <= cantidad_opciones:
            print("La opción está fuera del rango.")
            continue

        return respuesta - 1

La función devuelve un índice compatible con la lista de opciones.

Evaluar la respuesta

def evaluar(pregunta, respuesta):
    correcta = pregunta["correcta"]
    acierto = respuesta == correcta
    return {
        "acierto": acierto,
        "respuesta_correcta": pregunta["opciones"][correcta],
        "explicacion": pregunta.get("explicacion", ""),
    }

Devolver un diccionario con los detalles permite que distintas interfaces decidan cómo presentarlos.

Crear una partida completa

def jugar(preguntas):
    puntos = 0
    resultados = []

    for numero, pregunta in enumerate(preguntas, start=1):
        mostrar_pregunta(pregunta, numero)
        respuesta = leer_respuesta(len(pregunta["opciones"]))
        resultado = evaluar(pregunta, respuesta)
        resultados.append(resultado)

        if resultado["acierto"]:
            puntos += 1
            print("¡Correcto!")
        else:
            print(
                "Incorrecto. Respuesta correcta:",
                resultado["respuesta_correcta"],
            )

        if resultado["explicacion"]:
            print(resultado["explicacion"])

    return puntos, resultados

Mostrar el resultado final

def mostrar_resultado(puntos, total):
    porcentaje = puntos / total * 100 if total else 0
    print("\nRESULTADO")
    print(f"Aciertos: {puntos}/{total}")
    print(f"Porcentaje: {porcentaje:.1f}%")

    if porcentaje >= 90:
        print("Excelente resultado.")
    elif porcentaje >= 70:
        print("Buen trabajo.")
    elif porcentaje >= 50:
        print("Vas por buen camino.")
    else:
        print("Repasa el contenido y vuelve a intentarlo.")

Mezclar el orden

import random


def preparar_partida(preguntas, cantidad=None):
    copia = preguntas.copy()
    random.shuffle(copia)
    if cantidad is not None:
        copia = copia[:cantidad]
    return copia

Trabajamos con una copia para no modificar permanentemente el banco original.

Mezclar opciones sin perder la respuesta correcta

def mezclar_opciones(pregunta):
    pares = list(enumerate(pregunta["opciones"]))
    random.shuffle(pares)

    nuevas_opciones = [texto for _, texto in pares]
    indice_original = pregunta["correcta"]
    nueva_correcta = next(
        indice
        for indice, (original, _) in enumerate(pares)
        if original == indice_original
    )

    copia = pregunta.copy()
    copia["opciones"] = nuevas_opciones
    copia["correcta"] = nueva_correcta
    return copia

No mezcles únicamente la lista de textos porque el índice correcto dejaría de apuntar a la respuesta adecuada.

Cargar preguntas desde JSON

import json
from pathlib import Path


def cargar_preguntas(ruta):
    contenido = Path(ruta).read_text(encoding="utf-8")
    datos = json.loads(contenido)
    if not isinstance(datos, list):
        raise ValueError("El archivo debe contener una lista")
    return datos

Un archivo puede tener esta estructura:

[
  {
    "texto": "¿Cuánto es 2 + 2?",
    "opciones": ["3", "4", "5", "6"],
    "correcta": 1,
    "explicacion": "Dos más dos es cuatro."
  }
]

Validar el banco de preguntas

def validar_pregunta(pregunta):
    campos = {"texto", "opciones", "correcta"}
    if not campos.issubset(pregunta):
        raise ValueError("Faltan campos obligatorios")
    if not isinstance(pregunta["opciones"], list):
        raise ValueError("Las opciones deben ser una lista")
    if len(pregunta["opciones"]) < 2:
        raise ValueError("Debe haber al menos dos opciones")
    correcta = pregunta["correcta"]
    if not isinstance(correcta, int):
        raise ValueError("correcta debe ser un entero")
    if not 0 <= correcta < len(pregunta["opciones"]):
        raise ValueError("Índice correcto inválido")

Valida todas las preguntas al iniciar. Es mejor detenerse con un mensaje claro que fallar a mitad de la partida.

Añadir categorías y dificultad

{
    "texto": "¿Qué función obtiene la longitud?",
    "opciones": ["size", "count", "len", "length"],
    "correcta": 2,
    "categoria": "Python",
    "dificultad": "facil"
}

Después puedes filtrar:

def filtrar_preguntas(preguntas, categoria=None, dificultad=None):
    resultado = preguntas
    if categoria:
        resultado = [p for p in resultado if p.get("categoria") == categoria]
    if dificultad:
        resultado = [p for p in resultado if p.get("dificultad") == dificultad]
    return resultado

Guardar puntuaciones

from datetime import datetime


def crear_registro(nombre, puntos, total):
    return {
        "nombre": nombre.strip(),
        "puntos": puntos,
        "total": total,
        "fecha": datetime.now().isoformat(timespec="seconds"),
    }

Guarda varios registros en JSON o SQLite. No recolectes información personal innecesaria.

Temporizador opcional

En terminal puedes medir el tiempo total con time.monotonic(). Para limitar cada pregunta necesitarías una interfaz o entrada no bloqueante dependiente del sistema. No uses threads complejos solo para un proyecto inicial; primero construye una versión confiable sin límite.

Pruebas

def test_evaluar_correcta():
    pregunta = {
        "texto": "Prueba",
        "opciones": ["A", "B"],
        "correcta": 1,
    }
    resultado = evaluar(pregunta, 1)
    assert resultado["acierto"] is True


def test_validacion_indice_invalido():
    pregunta = {
        "texto": "Prueba",
        "opciones": ["A", "B"],
        "correcta": 5,
    }
    try:
        validar_pregunta(pregunta)
        assert False
    except ValueError:
        assert True

Mejoras posibles

Puedes añadir preguntas de verdadero o falso, varias respuestas correctas, imágenes, pistas, tabla de posiciones, importación CSV, modo de estudio y una interfaz gráfica. Mantén siempre el banco separado de la lógica.

Errores frecuentes

Los errores habituales son mezclar opciones sin actualizar el índice correcto, confiar en JSON sin validarlo, modificar la lista original, dividir por cero cuando no hay preguntas y guardar respuestas correctas como texto ambiguo. También conviene evitar una función enorme que haga preguntas, calcule puntos, lea archivos y guarde resultados.

Conclusión

Un quiz interactivo enseña a modelar datos y a separar responsabilidades. Guarda cada pregunta en un diccionario, valida el banco, crea funciones para mostrar, leer y evaluar, y utiliza JSON para editar contenido sin tocar el programa. Con esa base puedes añadir categorías, dificultad, puntuaciones y nuevas interfaces de forma segura.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Jogo de adivinhação de números desenvolvido com Python
    Proyectos
    Foto de perfil de Leandro Hirt da Academify

    Cómo crear un juego de adivinar números con Python

    Crea un juego de adivinar números con Python usando random, validación, intentos, niveles, pistas, puntuación, récords y pruebas.

    Ler mais

    Tempo de leitura: 3 minutos
    11/07/2026
    Projeto de jogo da velha desenvolvido em Python como exercício de lógica de programação
    Proyectos
    Foto de perfil de Leandro Hirt da Academify

    Cómo crear un juego de tres en raya con Python

    Crea un juego de tres en raya con Python usando listas, funciones, validación, detección de victoria, marcador, pruebas y una

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    texto Tkinter com uma interface gráfica dele ao lado
    Proyectos
    Foto de perfil de Leandro Hirt da Academify

    Cómo crear tu primera aplicación con Tkinter

    Crea tu primera aplicación con Tkinter: ventanas, ttk, formularios, grid, eventos, archivos, threads, estilos y separación de lógica.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    Sistema de lembretes e alarmes desenvolvido com Python
    Proyectos
    Foto de perfil de Leandro Hirt da Academify

    Cómo crear un sistema de recordatorios con alarma en Python

    Crea recordatorios con alarma en Python usando datetime, JSON, threads, zonas horarias, sonidos, recurrencia y pruebas controladas.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    Foto de uma pessoa usando uma calculadora
    Proyectos
    Foto de perfil de Leandro Hirt da Academify

    Cómo crear una calculadora en Python paso a paso

    Crea una calculadora en Python con funciones, menú, validación, Decimal, historial, pruebas y una base segura para añadir Tkinter.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    Conversor de moedas desenvolvido com Python
    Proyectos
    Foto de perfil de Leandro Hirt da Academify

    Cómo crear un conversor de monedas con Python

    Crea un conversor de monedas con Python, Requests, Decimal, validación, caché, manejo de errores y tasas de referencia confiables.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026