Quiz en terminal con Python: preguntas y puntuación

Actualizado el: 21/08/2026
Tempo de leitura: 3 minutos
Quiz interativo no terminal desenvolvido com Python

Un quiz para la terminal es un proyecto ideal para principiantes porque convierte conceptos básicos de Python en un programa interactivo completo. Las preguntas se guardan como datos, el usuario elige respuestas, el programa valida la entrada, calcula puntos y muestra un resultado final.

En esta guía construiremos un quiz en Python con preguntas de opción múltiple, respuestas mezcladas, validación, explicaciones, puntuación, repetición de partidas y carga opcional desde JSON.

Organizar los datos del quiz

Cada pregunta necesita un enunciado, una lista de opciones, la respuesta correcta y, opcionalmente, una explicación. Un diccionario representa una pregunta y una lista almacena el conjunto completo.

PREGUNTAS = [
    {
        "pregunta": "¿Qué palabra define una función en Python?",
        "opciones": ["class", "def", "return", "import"],
        "respuesta": "def",
        "explicacion": "Las funciones comienzan con def.",
    },
    {
        "pregunta": "¿Qué tipo almacena valores únicos?",
        "opciones": ["list", "tuple", "set", "str"],
        "respuesta": "set",
        "explicacion": "Un set mantiene elementos únicos.",
    },
]

Guardar la respuesta como texto evita problemas cuando se mezclan las opciones.

Mostrar una pregunta

def mostrar_pregunta(pregunta, numero, total):
    print()
    print(f"Pregunta {numero} de {total}")
    print(pregunta["pregunta"])

    for numero_opcion, opcion in enumerate(
        pregunta["opciones"],
        start=1,
    ):
        print(f"  {numero_opcion}. {opcion}")

enumerate() crea números para las opciones sin mantener un contador manual.

Leer y validar la respuesta

def leer_opcion(cantidad):
    while True:
        texto = input("Tu respuesta: ").strip()

        try:
            seleccion = int(texto)
        except ValueError:
            print("Introduce el número de una opción.")
            continue

        if 1 <= seleccion <= cantidad:
            return seleccion - 1

        print(f"Elige un número entre 1 y {cantidad}.")

La función devuelve un índice válido para la lista. Los datos incorrectos no terminan el programa.

Comprobar la respuesta

def es_correcta(pregunta, indice):
    seleccionada = pregunta["opciones"][indice]
    return seleccionada == pregunta["respuesta"]

Es una función pura: no solicita datos ni imprime. Eso facilita las pruebas.

Mezclar preguntas y opciones

import random


def preparar_preguntas(preguntas, generador=None):
    generador = generador or random.Random()
    preparadas = []

    for pregunta in preguntas:
        copia = {
            **pregunta,
            "opciones": list(pregunta["opciones"]),
        }
        generador.shuffle(copia["opciones"])
        preparadas.append(copia)

    generador.shuffle(preparadas)
    return preparadas

La copia evita modificar el orden original. Puedes usar una semilla fija durante pruebas.

Calcular el porcentaje

def calcular_porcentaje(puntos, total):
    if total == 0:
        return 0.0

    return puntos / total * 100

Quiz completo en Python

import random

PREGUNTAS = [
    {
        "pregunta": "¿Qué palabra define una función en Python?",
        "opciones": ["class", "def", "return", "import"],
        "respuesta": "def",
        "explicacion": "Las funciones comienzan con def.",
    },
    {
        "pregunta": "¿Qué tipo almacena valores únicos?",
        "opciones": ["list", "tuple", "set", "str"],
        "respuesta": "set",
        "explicacion": "Un set mantiene elementos únicos.",
    },
    {
        "pregunta": "¿Qué devuelve len([10, 20, 30])?",
        "opciones": ["2", "3", "30", "60"],
        "respuesta": "3",
        "explicacion": "len() devuelve la cantidad de elementos.",
    },
    {
        "pregunta": "¿Qué estructura maneja excepciones?",
        "opciones": ["if/else", "try/except", "for/in", "match/case"],
        "respuesta": "try/except",
        "explicacion": "try/except maneja errores durante la ejecución.",
    },
]


def preparar_preguntas(preguntas, generador=None):
    generador = generador or random.Random()
    preparadas = []

    for pregunta in preguntas:
        copia = {
            **pregunta,
            "opciones": list(pregunta["opciones"]),
        }
        generador.shuffle(copia["opciones"])
        preparadas.append(copia)

    generador.shuffle(preparadas)
    return preparadas


def mostrar_pregunta(pregunta, numero, total):
    print()
    print(f"Pregunta {numero} de {total}")
    print(pregunta["pregunta"])

    for numero_opcion, opcion in enumerate(pregunta["opciones"], start=1):
        print(f"  {numero_opcion}. {opcion}")


def leer_opcion(cantidad):
    while True:
        texto = input("Tu respuesta: ").strip()

        try:
            seleccion = int(texto)
        except ValueError:
            print("Introduce el número de una opción.")
            continue

        if 1 <= seleccion <= cantidad:
            return seleccion - 1

        print(f"Elige un número entre 1 y {cantidad}.")


def es_correcta(pregunta, indice):
    return pregunta["opciones"][indice] == pregunta["respuesta"]


def calcular_porcentaje(puntos, total):
    return puntos / total * 100 if total else 0.0


def jugar_quiz(preguntas, generador=None):
    preparadas = preparar_preguntas(preguntas, generador)
    puntos = 0

    for numero, pregunta in enumerate(preparadas, start=1):
        mostrar_pregunta(pregunta, numero, len(preparadas))
        indice = leer_opcion(len(pregunta["opciones"]))

        if es_correcta(pregunta, indice):
            puntos += 1
            print("¡Correcto!")
        else:
            elegida = pregunta["opciones"][indice]
            print(f"Elegiste: {elegida}")
            print(f"Respuesta correcta: {pregunta['respuesta']}")

        explicacion = pregunta.get("explicacion")
        if explicacion:
            print(explicacion)

    porcentaje = calcular_porcentaje(puntos, len(preparadas))
    print()
    print(f"Puntuación: {puntos}/{len(preparadas)}")
    print(f"Porcentaje: {porcentaje:.1f}%")

    if porcentaje == 100:
        print("¡Puntuación perfecta!")
    elif porcentaje >= 70:
        print("¡Muy buen trabajo!")
    elif porcentaje >= 50:
        print("Buen comienzo. Revisa las explicaciones.")
    else:
        print("Sigue practicando e inténtalo otra vez.")

    return puntos


def quiere_repetir():
    while True:
        respuesta = input("¿Jugar de nuevo? [s/n]: ").strip().lower()

        if respuesta in {"s", "si", "sí"}:
            return True
        if respuesta in {"n", "no"}:
            return False

        print("Escribe s o n.")


def main():
    print("Quiz de Python")

    while True:
        jugar_quiz(PREGUNTAS)

        if not quiere_repetir():
            print("¡Gracias por jugar!")
            break


if __name__ == "__main__":
    main()

Cargar preguntas desde JSON

Separar las preguntas del código permite actualizar el contenido sin modificar la lógica.

[
  {
    "pregunta": "¿Qué palabra define una función?",
    "opciones": ["class", "def", "return", "import"],
    "respuesta": "def",
    "explicacion": "Las funciones comienzan con def."
  }
]
import json
from pathlib import Path


def cargar_preguntas(ruta):
    ruta = Path(ruta)

    with ruta.open("r", encoding="utf-8") as archivo:
        preguntas = json.load(archivo)

    if not isinstance(preguntas, list):
        raise ValueError("La raíz del JSON debe ser una lista.")

    return preguntas

Validar datos externos

def validar_preguntas(preguntas):
    requeridos = {"pregunta", "opciones", "respuesta"}

    for numero, pregunta in enumerate(preguntas, start=1):
        faltantes = requeridos - pregunta.keys()

        if faltantes:
            raise ValueError(
                f"Pregunta {numero}: faltan {sorted(faltantes)}"
            )

        if pregunta["respuesta"] not in pregunta["opciones"]:
            raise ValueError(
                f"Pregunta {numero}: la respuesta no está en las opciones"
            )

Probar la lógica

from quiz import calcular_porcentaje, es_correcta


def test_calcular_porcentaje():
    assert calcular_porcentaje(4, 5) == 80.0
    assert calcular_porcentaje(0, 0) == 0.0


def test_es_correcta():
    pregunta = {
        "opciones": ["list", "set"],
        "respuesta": "set",
    }

    assert es_correcta(pregunta, 1) is True
    assert es_correcta(pregunta, 0) is False

Errores frecuentes

  • Guardar solamente una letra de respuesta y después mezclar opciones.
  • No validar los campos del JSON.
  • Convertir la entrada sin manejar ValueError.
  • Usar variables globales para toda la puntuación y el estado.
  • Mezclar preguntas, salida, entrada y cálculo en un único bucle grande.
  • Aceptar números fuera del rango disponible.

Ideas para mejorar

  • Añadir categorías y niveles de dificultad.
  • Seleccionar una cantidad limitada de preguntas.
  • Guardar récords en JSON o SQLite.
  • Añadir tiempo máximo por pregunta.
  • Soportar preguntas de verdadero o falso.
  • Crear una versión gráfica.

Conclusión

Un quiz en Python reúne estructuras de datos, bucles, validación, funciones, aleatoriedad, archivos y pruebas en un proyecto accesible. Separar los datos de la lógica facilita ampliar el juego sin volverlo difícil de mantener.

Lecturas relacionadas

Documentación oficial

Consulta la documentación de Python sobre el módulo json y la referencia del módulo random utilizado para mezclar preguntas y opciones.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Búsqueda en PDF con Python y RAG
    Proyectos
    Foto de perfil de Leandro Hirt da Academify

    Guía PDF con Python y RAG

    Aprende a consultar PDF con Python y RAG, recuperación semántica, evaluación y seguridad.

    Ler mais

    Tempo de leitura: 7 minutos
    23/07/2026
    Integração do ChatGPT com código Python em projeto prático
    Proyectos
    Foto de perfil de Leandro Hirt da Academify

    OpenAI API con Python: integración y seguridad

    Integra la API de OpenAI con Python usando Responses API, variables de entorno, validación, reintentos, control de costes, pruebas y

    Ler mais

    Tempo de leitura: 5 minutos
    12/07/2026
    Calendário mensal gerado automaticamente com Python
    Proyectos
    Foto de perfil de Leandro Hirt da Academify

    Calendario mensual en Python con calendar

    Genera un calendario mensual con Python usando calendar y datetime, valida fechas, añade eventos y exporta a TXT, HTML o

    Ler mais

    Tempo de leitura: 4 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

    Tres en raya con Python: lógica y validación

    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

    Tkinter en Python: crea una app de escritorio

    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

    Recordatorios con alarma en Python: datetime y sonido

    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