Banco de preguntas (plantilla qbank)

Proyecto creado con qbank-init. Contiene todo lo necesario para escribir preguntas de opción múltiple con qbank, comprobarlas y exportarlas a AMC (exámenes en papel) y a Moodle. Sustituye las preguntas de ejemplo por las tuyas y borra este párrafo.

1. Qué hay aquí

preguntas/ Una pregunta por fichero JSON: L-NN-Descripcion.json (NN = lección o tema, dos cifras; 00 vale). Sin espacios ni : en el nombre.
nueva_pregunta.py Guion para escribir una pregunta en Python y guardarla como JSON en preguntas/.
config.py Preámbulo LaTeX propio (el de AMC ya carga babel en español), textos de la opción por defecto y cuántos casos imprime la vista profe con setup.
scripts/ Generadores de AMC y Moodle que usa el Makefile; no hace falta tocarlos.
Makefile make lint, make tabla, make patrones, make amc, make lectura, make amc-student, make moodle, make clean.
build/ Todo lo generado (PDF, XML, .tex). No se versiona.
prompts/ Instrucciones para escribir preguntas con ayuda de una IA: PROMPT-qbank-generico.org (proceso y reglas, remite a la Guía y al Manual) y PROMPT-proyecto.org (las decisiones de tu banco, con huecos por rellenar).
CLAUDE.md Punto de entrada para Claude Code (u otro agente): remite a prompts/ y resume entorno y órdenes. Rellena sus huecos o bórralo si no usas una IA.

Los ficheros de preguntas/ que no sigan la convención L-NN- también se procesan; solo quedan fuera cuando se filtra con LECCION.

2. Requisitos

  • Python 3.9 o superior con calcprop-qbank 0.8.0 o posterior (la versión que trae qbank-init): pip install calcprop-qbank (o pip install -U calcprop-qbank para actualizar una anterior). Si usas un entorno virtual, actívalo antes de make, o pasa el intérprete: make amc PYTHON=/ruta/al/venv/bin/python. Cada objetivo comprueba primero que ese intérprete tenga qbank 0.8 o posterior (un python3 del sistema puede cargar uno antiguo); si no, se para con un mensaje que dice eso mismo.
  • GNU make (en Linux suele estar; en macOS viene con las herramientas de línea de órdenes, xcode-select --install). Todos los objetivos, incluido make clean, necesitan Python.
  • En Windows, el Makefile usa órdenes de un shell POSIX (sh, test, grep, rm): lánzalo desde Git Bash o MSYS2 con su make, o trabaja dentro de WSL (y entonces Python y LaTeX se instalan también dentro de WSL). Un make de Windows que use cmd.exe no sirve. Escribe la ruta del intérprete con barras normales: make lint PYTHON.venv/Scripts/python.exe=. Si un script falla con UnicodeEncodeError al escribir en la terminal, define PYTHONUTF8=1. Auto Multiple Choice no existe para Windows (sí para Linux y, vía MacPorts, macOS): fuera de WSL, usa solo make lint, make tabla y make moodle.
  • Para los PDF y el XML: pdflatex con los paquetes automultiplechoice (AMC) y moodle (en TeX Live: tlmgr install moodle, con sudo en BasicTeX/MacTeX; MiKTeX instala los paquetes por su cuenta la primera vez que hacen falta; AMC se instala con el programa Auto Multiple Choice). El preámbulo carga además babel en español. Los .tex de Moodle compilan también con xelatex (LATEX_MOODLE en el Makefile); con pdflatex, scripts/fix_moodle_xml.py corrige después la declaración de codificación del XML. Sin LaTeX puedes igualmente escribir preguntas y pasar make lint y make tabla; make a secas (= make all) lanza los tres exportadores y sí necesita LaTeX.

Todos los comandos se lanzan desde esta carpeta (la que contiene el Makefile).

3. Flujo de trabajo

  1. Escribe la pregunta. Dos caminos equivalentes:
    • En Python: copia nueva_pregunta.py con otro nombre en esta misma carpeta, edita NOMBRE, SETUP y PREGUNTA, ejecútalo (python mi_pregunta.py, con el mismo intérprete que tenga qbank: el entorno activado o la ruta completa, igual que PYTHON) hasta que lo que imprime y el lint te convenzan, y guarda con --guardar: deja el JSON en preguntas/.
    • Directamente en JSON, copiando una de las preguntas de ejemplo de preguntas/ (los campos, más abajo).
  2. Compruébala: make lint (o make lint LECCION=3 para una sola lección); antes de dar la pregunta por buena, también make patrones (más lento: busca lo que un alumno podría acertar sin leer el enunciado). Un ERROR significa que la pregunta está rota (p. ej. una variante con todas las opciones correctas); un AVISO hay que leerlo y decidir; un INFO es información. make tabla PREGUNTA=L-01-Nombre (con o sin .json) añade la tabla de mundos: el valor de cada cuestión en cada combinación de supuestos (con setup aleatorio usa un solo sorteo, así que si los supuestos llevan precond sobre los números solo verás los mundos que ese sorteo admite; la vista completa es la de make amc).
  3. Revísala en PDF: make amc genera build/amc/<pregunta>.pdf, la vista del profesor (cómo leerla, más abajo). Es lo que conviene repasar entero antes de dar una pregunta por buena. make lectura genera build/lectura/L-NN-lectura.pdf, un documento por lección para leer las preguntas: un ejemplo por mundo, las alternativas agrupadas por hueco con su V/F y su exp debajo, y las excluidas con su motivo (más abajo). Es el que conviene dar a quien las revise.
  4. Exporta:
    • make amc-student → build/amc-student/<pregunta>.pdf con todas las variantes de la pregunta tal como las verá el alumno. Es el modo catálogo de AMC: las casillas correctas salen rellenas y la cabecera dice «Catálogo provisional» (también en la vista profe de make amc); en el examen real salen vacías. Para usar las preguntas en un examen AMC: copia build/amc-student/<pregunta>.tex (y _catalogo.tex, que es un \input por cada pregunta de preguntas/, también las cinco de ejemplo si no las has borrado) junto al .tex del examen, haz \input{_catalogo} (o \input{<pregunta>}) en el preámbulo y, dentro de \onecopy, pon \insertgroup[1]{<pregunta>} donde deba ir cada pregunta: el [1] es imprescindible (sin él AMC inserta todas las variantes) y conviene \shufflegroup{<pregunta>} antes para que cada copia reciba una variante distinta.
    • make moodle → build/moodle/<pregunta>-moodle.xml (y un PDF de revisión con las mismas variantes y sus explicaciones) por pregunta, y build/moodle/_banco.xml con todas (incluidas las cinco de ejemplo, si siguen en preguntas/). En Moodle: Banco de preguntas → Importar → Formato Moodle XML; cada pregunta llega como una categoría con todas sus variantes, lista para una «pregunta aleatoria» del cuestionario. Cada variante es una pregunta cloze con un bloque de casillas por parte; el exportador da a cada bloque un peso igual al número de opciones que ve el alumno menos uno (3 puntos para tres huecos más la opción por defecto), y Moodle lo puntúa como una opción múltiple con varias respuestas (las correctas marcadas suman, las incorrectas marcadas restan, sin bajar de cero). La nota que fijes a la pregunta en el cuestionario reescala la suma de sus bloques. Si al compilar aparece «N «<» escapados dentro de bloques cloze», es un arreglo automático del XML que Moodle necesita, no un error. Los XML se entregan en UTF-8. El <penalty>0.10</penalty> de cada pregunta lo pone el paquete moodle: es la penalización por reintento, que Moodle solo aplica en los comportamientos con varios intentos (interactivo, adaptativo).

make solo recompila lo que ha cambiado; make clean borra build/.

4. Cómo leer el PDF de make amc (vista profe)

La vista profe no lista las variantes del alumno: tiene una entrada por mundo (cada combinación de Supuesto sorteados), que muestra todas las cuestiones de cada hueco (no solo la que le tocaría al alumno), en el orden de los huecos y con la casilla marcada en las correctas, y cada explicación (exp) en cursiva tras una raya junto a su cuestión. Las cuestiones rechazadas por su precondición se listan al final en «Exclusiones», con la condición que no se cumplió. Sin setup, las entradas se etiquetan <pregunta>-N (N numera los mundos; en make amc-student el mismo sufijo numera variantes, que son otra cosa) y make amc dice cuántos mundos hay. Con setup aleatorio no se imprimen todas las instancias: el script explora config.N_SORTEOS_PROFE sorteos y guarda un caso por cada combinación distinta de enunciado (sin contar los números) y patrón de marcas, hasta config.MAX_CASOS_PROFE casos, etiquetados mundoM-casoK (M numera los enunciados distintos, K los patrones de marcas dentro de cada uno), y make amc dice cuántos mundos y casos salen. Así ves cada rama de la pregunta una vez. Con setup, por tanto, aquí «mundo» cuenta también los textos sorteados distintos (una pregunta sin Supuesto que sortea cuatro tratados da cuatro «mundos»).

La vista de lectura (make lectura) tiene la misma información con otro formato, pensado para leer: cada pregunta empieza con su tabla de mundos y una nota con cuántas opciones ve el alumno; cada ejemplo lleva el enunciado en un recuadro y, debajo, «Hueco 1, 2, …» con todas sus alternativas (el alumno recibe una de cada hueco), V en verde o F en rojo, la exp en gris debajo («la misma retroalimentación que la anterior» si se repite) y las excluidas por su precondición en gris claro con el motivo. Con setup, una pregunta puede pedir ejemplos para todas las combinaciones de valores de algunas variables: "lectura": {"cubrir": ["ctx", "rech"]} en su JSON (los valores deben ser discretos; lint lo comprueba). Sin esa clave, un ejemplo por mundo más config.EXTRAS_LECTURA sorteos con enunciado distinto.

La vista profe no incluye la opción por defecto: su valor depende de qué cuestión le toque al alumno en cada hueco. Para comprobarla, mira las variantes de make amc-student en las que todas las opciones reales son falsas: allí sale marcada.

5. La mecánica en tres frases (lo que más confunde al empezar)

  • Una lista de Cuestion no son «las opciones que se muestran juntas»: en cada variante se sortea una de la lista. El alumno ve tantas opciones como elementos-Cuestion consecutivos haya (sueltos o listas), más la opción por defecto si export.last_choice es true.
  • Una lista de Supuesto son mundos alternativos: se sortea uno y su fórmula pasa a ser hipótesis; la semantica de cada Cuestion se evalúa contra esas hipótesis. Un Supuesto suelto con enunciado: "" es un axioma (añade su fórmula sin texto).
  • Patrón recomendado: tres elementos-Cuestion consecutivos + "export": {"last_choice": true}. Así siempre hay cuatro opciones y al menos una correcta y una incorrecta, sea cual sea la combinación.

Las cinco preguntas de preguntas/ ilustran, en este orden: mundos y axioma (L-01-ParidadSumaProducto), setup con seed e instances (L-01-FuncionMonotona), dos partes con precond (L-02-MatrizInvertible), semántica lambda sobre los datos con pareja verdadera/falsa (L-02-ComparacionNumerica) y una pregunta en prosa, sin fórmulas, con mundos de texto y un setup que sortea países y décadas (L-03-PoliticaArancelaria). GuiaDiseno.org (en el repositorio de qbank) desarrolla todo esto.

6. Caracteres y símbolos en los textos

Los textos son LaTeX. En español puedes teclear tal cual á é í ó ú ñ ¿ ¡ y las comillas tipográficas “ ”. Tres cosas rompen la exportación y lint las señala: el % sin barra como ERROR (make se para) y las otras dos como AVISO (make sigue, pero el PDF de Moodle falla o sale mal: corrígelas igualmente):

  • El símbolo % en LaTeX empieza un comentario: escrito tal cual, se pierde el resto de la línea y el PDF sale vacío o roto. Escribe siempre \% («un 25 \% del valor»), y fuera de los dólares si hay fórmula (al $5$\,\%, no $5\%$). En Python, dentro de una cadena cruda (r"un 25 \% del valor") o como \\%.
  • Las comillas angulares «» no existen en la codificación que usa el paquete moodle (make moodle da «Command \guillemetleft unavailable»), y las rectas "…" salen como ”…”: escribe ``así'' (dos acentos graves para abrir, dos apóstrofos para cerrar).
  • El símbolo de grado °: escribe $180^\circ$.

Si make amc o make moodle dan «ERROR en <pregunta>», el motivo está en el .log que indican (busca la primera línea que empieza por !).

Figuras. El enunciado admite \includegraphics{fig.pdf} (los documentos AMC cargan graphicx; la ruta es relativa a build/amc/). Para Moodle el paquete moodle necesita un PNG y compilar con pdflatex -shell-escape, cosa que estos scripts no hacen: la FAQ del Manual explica cómo adaptarlos.

7. Campos de una pregunta

Nivel superior del JSON (o argumentos de ProblemaTipo en Python):

nombre Igual que el nombre del fichero sin .json; sin : ni espacios.
componentes La lista plana de textos, Supuesto y Cuestion (sueltos o en listas de alternativas).
setup Código Python (cadena) que se ejecuta antes de cada variante, o null. Usa np.random, no random: seed siembra los dos, pero la vista profe (make amc, nueva_pregunta.py) solo siembra numpy en cada sorteo.
seed Entero, solo si setup sortea valores: hace reproducible la pregunta.
export {"last_choice": true, "cols": 2, "instances": N}; ver abajo.
lectura Opcional: {"cubrir": ["var", …]}, variables del setup cuyas combinaciones de valores debe mostrar make lectura.

Supuesto y Cuestion (en JSON, objetos con "tipo"; en Python, las clases del mismo nombre):

enunciado Texto LaTeX; admite @{variable} para interpolar valores del setup.
semantica Fórmula calcprop como cadena: "v('A')", "alguno(v('A'), v('B'))", "True", "False", o "lambda ns: ns['x'] > 0".
precond Condición para que el componente pueda aparecer; mismo formato. Por defecto "True".
exp Solo Cuestion: explicación que Moodle muestra tras responder; admite @{variable}. Opcional.

Campo export:

last_choice Añade la opción por defecto («Ninguna de las anteriores» / «Las demás opciones son falsas»), correcta solo si las demás son falsas.
cols Columnas en que se disponen las opciones en AMC.
instances Solo con setup aleatorio: cuántas instancias (recorridos con números distintos) se generan. Objetivo: ≥ 60 variantes (lint lo calcula); con pocos valores posibles se repiten, mira make amc-student.

8. Más documentación

En la web de qbank (mbujosab.github.io/calcprop-qbank) o en su repositorio, en este orden: Tutorial.ipynb (ejemplos progresivos), la Guía de diseño (GuiaDiseno.org, cómo diseñar buenas preguntas) y el Manual (Manual.org, referencia completa de la API y del formato JSON); la Guía y el Manual están también en PDF (GuiaDiseno.pdf, Manual.pdf). Si escribes preguntas con ayuda de una IA, empieza por prompts/.