» Home Page
MCQ-XeLaTeX: Domande a Scelta Multipla (Multiple Choice Question) per la matematica.

Ho scritto un sistema per la creazione, gestione e correzione automatica (con un lettore ottico) di test a risposta multipla, che potrebbe essere utile per chi, come me, insegna matematica (all'università o alle scuole superiori). E' ancora un prototipo, ma dovrebbe essere già utilizzabile da chiunque abbia un po' di dimestichezza con il\(\LaTeX\) e con i computer. E' pensato per la matematica, ma può essere usato anche per altre materie. L'unico vincolo è conoscere il\(\LaTeX\).

Questa pagina è per una documentazione un po' più completa. Per chi non ha tempo per leggere e vuole provare a capire con un esempio concreto, qui c'è la pagina sintetica, con i dettagli per l'installazione.

La versione descritta in questa pagina è un parzialmente obsoleta. Nuove funzionalità sono indicate in questa pagina (in inglese).

MCQ-XeLaTeX & mcq.{py,sty}: Domande a Scelta Multipla (Multiple Choice Question) per la matematica.

I test a scelta multipla possono essere uno strumento molto utile per la didattica. Se usati bene, aiutano gli studenti ad autovalutarsi e a capire la natura dei propri errori (a patto che ci sia un sistema che dia loro alcune indicazioni relative all'errore commesso, il cosiddetto "feedback"), e permettono al docente di localizzare e quantificare le difficoltà degli studenti prima della valutazione finale (se è possibile analizzare, anche in modo grossolano, alcuni indicatori statistici sulle domande poste). Last, but not least, consentono di stimolare e verificare (in modo parziale e superficiale, ma comunque utile) i risultati di apprendimento in modo relativamente semplice e rapido.

Un sistema per la creazione, gestione e somministrazione di test a scelta multipla per la matematica purtroppo non c'era (che fosse semplice e rapido nelle correzioni, basato su\(\LaTeX\), poco costoso e che desse sia indicatori statistici che feedback per gli studenti). Ho scritto quindi questo prototipo, che ho usato nelle lezioni di geometria 1 per qualche anno; con la recente aggiunta delle funzioni OMR (Optical Mark Recognition) e la ampia disponibilità di piattaforme e-learning (moodle) sembra ora sufficientemente utile da poter essere anche provato da altri.

Le singole parti del sistema, ovviamente, possono anche essere utilizzate stand-alone. Per esempio, l'OMR (che utilizza un sistema di chiamate a procedure remote RPC) potrebbe anche essere utilizzato solo per la scansione di schede con bolle, senza aver bisogno della valutazione o di gestione di esercizi. Basta usare mcq.sty per stampare il form da scansionare ("bubblesheet"), e utilizzare solo la procedura di OMR.

Cos'è

Un sistema per:

Prerequisiti

Occorre innanzitutto un computer con una distrubuzione TeX recente (z.B. TeXlive 2011), python (importante: usare python 2.*, e non python 3, però!) e una connessione a internet, oltre alla capacità di lavorare su terminale non grafico. In teoria non dipende dal sistema operativo, posto che i requisiti siano soddisfatti.

Come funziona

Testo\(\LaTeX\):

Per prima cosa occorre creare gli esercizi: un file\(\LaTeX\) ("file.tex") con il pacchetto "mcq.sty".

Importante: il file deve essere compilato con il comando "xelatex" (sufficientemente recente). Il font "linux libertine" deve essere installato (per ragioni varie, occorre installare la versione TTF, non la versione indicata dal default), per poter avere a disposizione tutte le funzionalità. Dato che si usa "xelatex", è necessario che il file .tex sia codificato con l'encoding UTF8.

Un esempio (commentato) di testo è il seguente (file.tex):

\documentclass[a4paper]{article}
\usepackage[italian]{babel}
\usepackage{mathpazo}

%===================================================================
\usepackage[bubblesheet,sol]{mcq}
% l'opzione "bubblesheet" serve a creare la pagina con le bolle per l'OMR,
% l'opzione "sol" serve a mostrare nel pdf sia le soluzioni che i feedback
% delle soluzioni (importante: "sol" è da usare solo nella preparazione del test, non nel test vero)

% per avere *due copie* del bubblesheet, usare l'opzione "extrasheet":
% \usepackage[bubblesheet,extrasheet]{mcq}
% in questo modo è possibile che i candidati rovinino una copia, e usino la seconda di riserva.

\headline{Geometria I - Test 2011-07-12 (14:00-14:30, U1-08)}

\puntigiusta{3} % punti assegnati per ogni risposta giusta
\puntisbagliata{-1} % punti assegnati per ogni risposta  sbagliata
\puntiempty{0} % punti assegnati per ogni mancata risposta


\begin{document}
\bubblesheet[2]{10}{4}
% questo serve per aggiungere la scheda iniziale con le bolle da riempire,
% per 10 domande da 4 risposte l'una ABCD, poste su 2 colonne.
% il [2] è opzionale; il default è 1.


\begin{esercizi*}{Domande a scelta multipla}

\begin{exerm}
Se $A\subset X$ è un sottoinsieme di uno spazio topologico $X$,
allora $x\in X$ è un punto di accumulazione per
$A$ in $X$ se:
\begin{rispm}[1] 
% il parametro opzionale "1" significa che le risposte
% saranno disposte su una colonna (il default è 1). 
\risp[=] 
% questa è la risposta giusta
In ogni intorno aperto $U$ di $x$ in $X$ ci sono
punti di $A$ diversi da $x$.
\risp In ogni intorno aperto $U$ di $x$ in $X$ ci sono punti di $A$.
\fb{Si devono avere punti diversi da $x$: in questo caso un punto
isolato non è di accumulazione, ma verifica la proprietà.}
% questo è il "feedback"; viene usato solamente per la somministrazione
% dinamica del test (moodle e html), non per il pdf. 
\risp Ogni intorno aperto $U$ di $x$ in $A$ è non-vuoto.
\fb{Se $x\in A$, allora ogni intorno aperto di $x$ in $A$
è non vuoto, ma questo non vuol dire che $x$ è di accumulazione
(potrebbe essere isolato).}
\risp Per ogni intorno $U$ di $x$ in $X$ si ha $U\cap A \neq \emptyset$.
\fb{Se $x\in A$ è un punto isolato, allora $U\cap A\neq \emptyset$,
dato che contiene $x$; ma non è di accumulazione.}
\end{rispm}
\end{exerm}

....

\end{esercizi*}
\end{document}

Il formato è abbastanza semplice. I comandi "\fb{...}" servono ad aggiungere dei commenti di feedback, che sono molto importanti se si vuole utilizzare poi le domande in un contesto dinamico (moodle o html+css+MathJax, si veda sotto).

Compilando (due volte) il file

~$ xelatex file.tex 
...
~$ xelatex file.tex
...

si dovrebbe ottenere un pdf come questo.

Se invece di attivare le opzioni "bubblesheet" e "sol" si richiama il pacchetto semplicemente con

\usepackage{mcq}

allora dopo la (doppia) compilazione il pdf dovrebbe essere come questo.

Dopo un po' di compilazioni, modifiche degli esercizi e correzioni, il testo d'esame dovrebbe essere pronto.

A questo punto può essere esportato per MOODLE o in XHTML, con i due comandi

mcq.py --gift file.tex > file.gift

oppure

mcq.py --xhtml file.tex > file.html

rispettivamente (naturalmente occorre prima scaricare lo script mcq.py (vedi sotto)). Per moodle, seguire la documentazione per importare domande in formato GIFT del sito di moodle. Per l'xhtml, guardare gli esempi (solo per conoscitori di CSS+xhtml+MathJax, per il momento).

Supponiamo invece che si voglia somministrare il test su carta, cercando di minimizzare il rischio che si copi (ma mantenendo invariato l'insieme di domande).

Per stampare copie multiple del test, con esercizi e soluzioni permutate, occorre utilizzare "mcq.py" con l'opzione "-n". Per esempio, per averne 40 copie distinte :

~$ mcq.py -n 40 file.tex

Viene generato il file "file_exam.tex", che a sua volta deve essere bi-compilato con "xelatex"; questo genera "file_exam.pdf" che deve essere stampato su una stampante (fronte/retro) di qualità decente e contiene le 40 copie (distinte).

Importante: quando si stampa, occorre evitare riscalamenti del foglio (cioè, bisogna stamparlo al 100% della sua dimensione).

Per la correzione, si procede in due modi. Nel modo manuale (senza OMR) o in modo automatico (con OMR).

Con l'OMR, si utilizzi uno scanner con feeder automatico per convertire in PDF le pagine con i bubblesheet compilate dagli studenti. Dovrebbero essere almeno a 150 DPI, le immagini. Ma molto meglio a 200-300 DPI, così da minimizzare gli artefatti e quindi gli errori di riconoscimento. Supponiamo che i file siano s1.pdf s2.pdf s3.pdf (ognuno con 20 schede). Allora con il comando (occorre essere collegati a internet)

~$ mcq.py --omr=file.tex s1.pdf s2.pdf s2.pdf > output.txt

si genera il file "output.txt", che riporta, in ogni riga, l'etichetta (a 4 cifre) del compito, la matricola e le risposte, nel formato

<etichetta>:      :<matricola>:<risposte>:

Dovrebbe comparire anche un file omr-output.pdf con dettagli sul procedimento di optical mark reading.

Nel secondo campo della riga, lasciato vuoto, si dovrebbe aggiungere a mano Cognome+Nome, oppure farlo in modo automatico se c'è un elenco matricola-nomecognome da utilizzare. Per test ripetuti (come i compitini) è possibile riutilizzare un file output.txt precedente, cui sono stati aggiunti i nomi, con il comando

~$  mcq.py --uid=output_precedente.txt output.txt > output2.txt

Se si ha invece un file CSV, con delimitatore ";", per esempio, in cui la matricola è nella colonna 1 e il nome nella colonna 4, si può usare il formato

~$ mcq.py --uid="uidfile.txt:1;4" output.txt > output2.txt

Il formato è <NOMEFILE>:<colonna MATRICOLA><DELIMITATORE><colonna NOME>. (Osservazione: nel nome del file non ci devono essere ":", e occorre mettere tra virgolette l'argomento di --uid. Sia i numeri delle colonne che il delimitatore devono essere lunghi un carattere.)

A proposito del formato dei file dei risultati "output.txt", se inseriti a mano, la stringa delle risposte deve essere lunga quanto il numero di domande, con al posto $i$ la lettera corrispondente alla risposta scelta dallo studente per la domanda $i$-esima, se è stata selezionata, altrimenti la cifra "0". Maiuscole e minuscole sono equivalenti.

Alla fine il file "output2.txt" completato con i nomi, per 10 domande, dovrebbe essere come questo:

7yFH:Verdi, Giuseppe    :736220:D0ABC0ACD0:
xE72:Rossi, Paolo       :735221:DA0CBBA0CB:
6FB2:Bianchi, Michele   :739223:0AADC00C0B:
H63z:Neri, Valentina    :735333:BDACCABCCD:

Per la correzione vera e propria, occorre eseguire il comando

~$ mcq.py --db=$(TODO)_exam.db output2.txt > risultati.txt

sostituendo alla variabile $(TODO) il nome del file tex (senza estensione) che abbiamo usato all'inizio. Per esempio, nel caso sopra, il nome era "file.tex", quindi il comando è

~$ mcq.py --db=file_exam.db output2.txt > risultati.txt

Nel file "risultati.txt" ci sono i numeri di matricola e i voti aggregati. Verrà creato anche un "file_exam.csv" un po' più completo (le cui ultime due colonne sono da ignorare, per il momento).

Un'ultima interessante possibilità è il calcolo di alcuni indici statistici sulle risposte:

~$ mcq.py --stats=file_exam_stats.db file.tex >file_stats.tex

Occorre poi compilare "file_stats.tex" con xelatex qualche volta, per avere una versione del compito annotata con indici statistici (utili per verificare se ci sono stati errori nell'elaborazione o nella creazione del test).

Gli indici di facilità ($f$) e di discriminazione ($d$) sono definiti come segue:

Sia $U$ l'insieme del $27\%$ degli studenti con voto finale più alto, e $L$ l'insieme del $27\%$ degli studenti con voto finale più basso. Fissata una domanda, sia $n_U$ il numero degli studenti in $U$ che ha risposto correttamente e $n_L$ il numero di studenti in $L$ che ha risposto correttamente. Sia $k=|U|=|L|$ il numero di elementi di $U$ o, equivalentemente, di $L$. Allora \[ \text{discrimination index: } d = \dfrac{n_U - n_L}{k} \] In altre parole, è la differenza tra la percentuale di risposte corrette in $U$ con la percentuale di risposte corrette in $L$: se è negativo c'è qualche problema (per esempio, un errore nell'inserimento della risposta corretta), ma valori da $20\%,30\%$ in poi sono considerati buoni.

L'indice di facilità di una domanda è, invece, semplicemente la percentuale di studenti che ha risposto correttamente. Per $f<30\%$ la domanda è difficile, per $f>75\%$ la domanda è facile, mentre se è compresa tra $30\%$ e $75\%$ è soddisfacente.

(Approfondimenti)

Alcune altre opzioni (di mcq.sty e di mcq.py) sono documentate internamente al programma "mcq.py". Basta eseguirlo con l'opzione "help":

~$ mcq.py --help

È possibile, per esempio, creare il testo di un compito scegliendo a caso un certo numero di domande tra un insieme di domande archiviate semplicemente in un insieme di file (una o più domande per ogni file). Per esempio, per scegliere a caso 14 domande tra un insieme di esercizi archiviati nei file file1.tex file2.tex file3.tex, si esegue il comando

~$ mcq.py --choose= 14 file1.tex file2.tex file3.tex > c.tex

In modo un po' più articolato, per scegliere 5 domande tra quelle contenute in file il cui nome inizia per "c", e 9 domande tra quelle contenute in file il cui nome inizia per "q", si esegue

~$ mcq.py --choose=5 c*.tex > tmp1.tex
~$ mcq.py --choose=9 q*.tex > tmp2.tex

Per unirle in un terzo file "file.tex":

~$ mcq.py --choose=14 tmp1.tex tmp2.tex > file.tex

Opzionale: è possibile creare test misti, formati da una prima parte a risposta multipla e una seconda parte a risposta aperta, da correggere in modo tradizionale; in questo caso nel file delle risposte occorre aggiungere a mano in ogni riga, dopo gli ultimi due punti, il voto della parte tradizionale; è anche possibile scegliere quale formula usare per combinare i due voti (somma, media, media geometria, etc. etc.). Si veda "mcq.py --help".

C'è una funzione (un po' sperimentale) di scelta casuale tra *varianti* di un esercizio. Un esercizio può avere più varianti, e quando si generano le copie permutate della lista di esercizi, ogni volta verrà generato (pseudo-casualmente) un esercizio scelto tra le varianti (vedere mcq.py --help per un esempio).

Il modo migliore che ho trovato per ricordare tutte queste opzioni è di utilizzare il Makefile seguente (opzionale):

TODO=file

pdf: $(TODO).pdf

exam:
        mcq.py -n 80  $(TODO).tex 
        xelatex $(TODO)_exam.tex

omr:
        mcq.py --omr=$(TODO) scan/$(TODO)*.pdf > $(TODO)_raw.txt
        mcq.py --uid=c3.txt $(TODO)_raw.txt > $(TODO)_full.txt

val:
        mcq.py --db=$(TODO)_exam.db $(TODO).txt > $(TODO)_exam.txt
        mcq.py --stats $(TODO)_exam_stats.db $(TODO).tex > $(TODO)_stats.tex

xhtml:
        mcq.py --xhtml $(TODO).tex > $(TODO).html

gift:
        mcq.py --gift $(TODO).tex > $(TODO).gift

FORCE:

.SUFFIXES:

.SUFFIXES: .tex .dvi .ps  .ind .pdf


$(TODO).pdf: FORCE
        xelatex  --synctex=1 $(TODO)

clean:
        rm -f *.{aux,log,dvi}

Licenza d'Uso (EULA)

Si può usare il sofware linkato in questa pagina a scopo di prova e valutazione del medesimo, as-it-is, senza nessuna garanzia, alle seguenti ulteriori condizioni. Scaricando il software si accettano automaticamente questi termini e condizioni.

Licenza Creative Commons
Questo opera è distribuito con licenza Creative Commons Attribuzione - Non commerciale - Non opere derivate 3.0 Unported.
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

(E' vero che la CC non sarebbe una licenza per software, ma non è nemmeno davvero software in senso tradizionale, questo sistema. E' una forma strana di ibrido).

Download