MCQ-XeLaTeX Full Documentation

Date

2019-02-07 (updated 2023-04-21)

LaTeX documentation of mcq.sty

The package can be called with any latex class, but recommended classes are article (for Multiple Choice Questions and Optical Mark Recognition). It also support the exam class(for open questions, see below An exam class example:):

\documentclass{article}
\usepackage{mcq}

To install, download it: mcq.sty. Then, put it somewhere. For example, in ubuntu:

$ mkdir -p ~/texmf/tex/latex/mcq
$ cd ~/texmf/tex/latex/mcq
$ wget https://www.dlfer.xyz/var/mcq.sty
$ texhash

Package options:

bubblesheet

Print a cover sheet with the grid of bubbles (to be filled) for student UID and answers.

dsa

Use OpenDyslexic font, a typeface for Dyslexia. It has to be installed on the system. On ubuntu linux, for example:

$ sudo apt install fonts-opendyslexic
extrasheet

Print a second bubblesheet after the first, just in case, if the students are considered not careful enough in filling the bubbles (and therefore a high percentage will do a mistake).

namedheader

Print a named header, useful for when a multi-page document has to be returned by students, and therefore they need to write their own name on each sheet.

noblankpage

Do not print a blank page after the bubblesheet page. Usefule if one does not print on duplex printers.

sol

With this option, an explicit graphic mark will highlight the (correct) answers. Userful for proof-reading the exam document, but absolutely to remove befor generating the real production document.

ttf

Use the TTF version of Linux Libertine instead of the default OTF version.

doexe

when generating copies for the individual sheets, include not only exerm style questions, but also open-answer questions \begin{exe}...\end{exe}

Preamble commands:

\puntigiusta{<number>}

Number of points (float or signed integer) assigned to a correct answer. Typical value: n - 1, where n is the number of answers. Dafault value: 1.

\puntisbagliata{<number>}

Number of points (float or signed integer) assigned to a wrong answer. Typical value: -1. Default value: 0.

\puntiempty{<number>}

Number of points (float or signed integer) assigned to a ungiven answer. Typical value: 0. Default value: 0.

\formulavoto{<python expression in x and y>}

Formula to aggregate x = <MCQ_MARK> and y = <OPTIONAL_MARK>. The exam might consist of a Multiple-Choice part, followed by some open questions or exercises. The mark of the MCQ part will be computed automatically, and denoted by <MCQ_MARK>. The mark of the open-ended part needs to be given by your grading. This formula is simply the way to sum the two parts, in python syntax.

\UIDdigits{number}

Number of UID digits. Default value: 6.

\headline{text}

Headline of the page (with info about the exam).

\englishinfo

Choose English language, instead of Italian, for the front sheet info.

\variantlabel{ABC}

Optional label to prepend to the permutation code of each sheet.

\moodlecategory{categoryname/subcategory}

Optional category name, in case a GIFT export is planned.

Environments and list of questions:

Just after the \begin{document}, one of the two following commands should appear:

\nomeesame

Write \Cognomename: \dotfill \Nomename: \dotfill \Firmaname:\dotfill, or an analogue.

\bubblesheet[optional number of columns]{number of questions}{number of anwsers}

Print a cover page with fillable bubbles, to be fed to a document scanner and OMR.

Then, there will be all questions/exercises, grouped in some environments. The top (numbered or *-numbered) environment is esercizi, which surrounds the list of questions, each given by an exerm or exe. The exe type does not have any features. The exerm environment is a multiple choice question: its anwers are enumerated as in the following example:

% here a normal section of exercises
\begin{esercizi}{Title of the section}

  \begin{exerm}[optional text]
  Body of the question.
  \begin{rispm}[2]
    % the optional argument is the number of columns of the answers.
  \risp[=]
  \risp
  \risp
  \risp
  \end{rispm}
  \end{exerm}

  ... continued

\end{esercizi}

% here an unnumbered section of exercises
\begin{esercizi*}{Title of the unnumbered section}

  \begin{exerm}
  Body of the question.
  \begin{rispm}
  \risp[=]
  \risp
  \risp
  \risp
  \end{rispm}
  \end{exerm}

  ... continued

\end{esercizi}

The difference of esercizi and esercizi* is the same as the \section and \section* commands.

The two questions/exercises types are exerm and exe: the first is a Multiple Choice Question, the second is a normal exercise.

More precisely, in exerm the question with answers can be formatted as in the following full example:

\begin{exerm}[Optional text]
\qtitle{Optional command for the title of the question: it is
 not shown in the PDF}
% the qtitle can be used to assign a unique ID to questions,
% so that they can be kept in a Question Bank.
Here write the text of the question.

  \begin{rispm}[4] % The answers will be on 4 columns.
                   % The default value is 1.
  \risp[=] Correct answer
    % it will be graded as correct, with a number of points
    % given by \puntigiusta{number} command defined above
    \fb{Very well!}  % This feedback is very important, for questions
                     % converted to GIFT or HTML (interactive).
  \risp Wrong answer
    % it will be graded as wrong, if checked, with a number
    % of points given by \puntisbagliata{number} command
    \fb{No, you are wrong, since ...}
        % This feedback is very important, for questions
        % converted to GIFT or HTML (interactive).
  \risp[0.5] Kind of wrong answer.
    % It will be graded as an answer with a manual value,
    % given by the float 0.5.
    \fb{Almost correct! In fact ... (explanation)}
          % This feedback is very important, for questions
          % converted to GIFT or HTML (interactive).
  \risp[-10] Very wrong answer.
    % It will be graded with -10 points (signed integer).
    \fb{Very bad! You do not get it since (explanation)}
          % This feedback is very important, for questions
          % converted to GIFT or HTML (interactive).
  \end{rispm}
  \fb{General Feedback}
\end{exerm}

The other exercise type is a simple environment, that can be also used as follows:

\begin{exe}[Optional text]
Text of the exercise
\end{exe}
\begin{sol}
Solution
\end{sol}

Open answer questions can be used also to generate essay questions for MOODLE, with textarea solutions (visible with the sol mcq option and removed in the moodle exported version):

\begin{exe}[comment]
\qtitle{Eventual tag of the question, it is only for MOODLE}
How much is $1+1$?
\blank{$2$}
\end{exe}

The GIFT output will be:

::Eventual tag of the question, it is only for MOODLE::
How much is $1+1$?
{}

Questions with variants:

Instead of just permuting the questions and the answers, it can randomly choose variants (with different numerical values, or different questions and different answers) of the questions.

The syntax is as in the following example:

\begin{exerm}
  \begin{varianti}
  %% this is an exercise with two variants (randomly select just one of the two).
  \varitem

    $1+2=$?
    \begin{rispm}
      \risp[=]  3
      \risp  2
      \risp  1
      \risp  0
    \end{rispm}

  \varitem

    $2+3=$?
    \begin{rispm}
      \risp[=]  5
      \risp  4
      \risp  3
      \risp  2
    \end{rispm}

  \end{varianti}
\end{exerm}

The same can be done with \begin{exe} ... \end{exe} type exercises.

When exportin in moodle GIFT format, all the variants will be sequentially exported.

Other commands:

\begin{sol} ... \end{sol}

It is a proof-like environment, for solutions of exercises.

\WarningSign

Default: the string ★★!!★★``.

\OrnamentalBreak

An ornamental break (centered).

\blank{Text of the solution}

Will draw a blank line with space for a solution (until the end of the line).

\blankarea[optional number of rows]{Text of the solution}

Will draw a blank area with space for a solution.

When compiled with the sol option:

\usepackage[sol]{mcq}

the blank areas/lines will be filled with the texts of the solutions. Otherwise, they will be white or filled with squares. The default number of rows is 10, if omitted. Otherwise, it can be any positive integer.

LaTeX variables:

can be redefined with \renewcommand, and are meant for internal use):

\geninfo

Definition of the text giving the instructions/info about the test/exam.

\ansinfo

Text to write before the bubblesheet answers.

\uidname

Name of the UID. Default: Matricola.

\Cognomename

Name of FamilyName. Default: Cognome.

\Nomename

Name of GivenName. Default: Nome.

\Firmaname

Name of the signature. Default: Firma.

\SolName

Name of the solution. Default: Soluzione.

\squarebox

The character for the symbol appearing on the left of each possible item-answer. Check that the characters is included in the font Linux Libertine first.

\variantlabel

A label (possibly empty) to prepend to each permutation code.

Further commands:

Other commands can be included in the [optional] file mcq_commands.tex. If it exists, it is included and processed automatically. If it does not exists, nothing is done (read the logs to see what happended).

MCQ w/Bubblesheet example:

An example of MCQ exam with bubblesheet (try to compile it with or without the sol package option):

%===================================================================
\documentclass[twoside,a4paper,leqno]{article}
%===================================================================
\usepackage{mathpazo} % I like it.
\usepackage[bubblesheet]{mcq}
\englishinfo %% this if you want English sentences.
\usepackage{polyglossia}
\setdefaultlanguage{english} %% it needs to be *after* mcq.

%===================================================================
\headline{Multiple Choice questions on Logic (2013-12-31)}
%% this is the "name" of the exam
%  http://www.math.ucla.edu/\char`~tao/java/MultipleChoice/logic.txt

\puntigiusta{6} % points for a correct answer
\puntisbagliata{-1} % points for a wrong answer
\puntiempty{0} % points for non-response.

%===================================================================
\begin{document}
\bubblesheet[2]{14}{7}
% [number of columns] {number of questions} {number of answers}

\begin{esercizi*}{}

\begin{exerm}[Optional text]
  \qtitle{This is an unseen title}
  Let $X$ and $Y$ be statements.  If we know that $X$ implies $Y$, then
  we can also conclude that
  \begin{rispm}[2]
    \risp $X$ is true, and $Y$ is also true.
      \fb{%
      This is a feedback comment (optional). Useful only in the conversion
      to HTML or for dynamical formats on MOODLE.
      }
    \risp[-2]
      $Y$ cannot be false.
      \fb{This was terribly wrong.}
    \risp[3] If $Y$ is true, then $X$ is true.
      \fb{Kind of true?}
    \risp[=]
      If $Y$ is false, then $X$ is false.
    \risp If $X$ is false, then $Y$ is false.
    \risp $X$ cannot be false.
    \risp[3.1415]
      At least one of $X$ and $Y$ is true.
  \end{rispm}
\end{exerm}

\begin{exerm}
  Let $X$ and $Y$ be statements.  If we want to DISPROVE the claim that
  "Both $X$ and $Y$ are true", we need to show that
  \begin{rispm}
    \risp[=]  At least one of $X$ and $Y$ are false.
    \risp $X$ and $Y$ are both false.
    \risp[0.5] $X$ is false.
      \fb{This will indeed disprove "Both $X$ and $Y$ are true", but $X$ does
      not need to be false in order to disprove the above statement.}
    \risp[0.5] $Y$ is false.
      \fb{This will indeed disprove "Both $X$ and $Y$ are true", but $Y$ does
      not need to be false in order to disprove the above statement.}
    \risp $X$ does not imply $Y$, and $Y$ does not imply $X$.
    \risp Exactly one of $X$ and $Y$ are false.
    \risp $X$ is true if and only if $Y$ is false.
  \end{rispm}
\end{exerm}


(..omissis..)

\end{esercizi*}

\end{document}

An exam class example:

Some commands taken from the exam latex class:

\documentclass{exam}

\pointpoints{point}{points}
\bonuspointspoints{bonus point}{bonus points}
\qformat{Format specification}
\bonusqformat{Format specification}

\chqword{Exercise:}
\chpword{Points:}
\chbpword{Bonus points:}
\chtword{Total}

An example of an exam with blankareas and no bubblesheet (try to compile it with or without the sol option):

%===================================================================
\documentclass[twoside,a4paper,leqno,addpoints]{exam}
%===================================================================
\usepackage{mathpazo}
\usepackage[noblankpage,sol]{mcq}

\usepackage[italian]{babel}
\headline{Analisi 2 - Scritto \#3  -- 2019-02-25, 1430-1630, aula U2-07}
%===================================================================
\usepackage{xspace}
\newcommand{\quindi}{\fontspec[Scale=1.0]{Junicode}\char"2234\xspace}
%===================================================================
\begin{document}

\nomeesame

\norme{\itshape\small
Norme per la prova:
\begin{compactenum}
\item Scrivere cognome, nome e numero di matricola negli appositi spazi.
\item Consegnare \emph{solo} il presente fascicolo.
\item Rispondere alle domande utilizzando gli appositi spazi.
\item Tempo: 120 minuti.
\item I punti di ciascun esercizio sono indicati tra parentesi.
\item I punti \emph{bonus} valgono soltanto se le parti precedenti
nell'esercizio sono state valutate con punteggio pieno.
\end{compactenum}
}

\begin{questions}
\question[3]
Il limite
\begin{equation*}
\lim_{(x,y) \to (0,0)}\, \frac{x \, {|y|}^\alpha}{x^2 + y^2}
\end{equation*}
esiste se  e solo se  $\alpha \in $
\blank{$(1,+\infty)$}

\question[3]
Sia $T$ il triangolo in $\mathbb{R}^2$ di vertici $\left(1,1\right)$,
$\left(2,2\right)$ e $\left(1, 3\right)$.

Calcolare l'integrale $\displaystyle \int_T xy\, dx\, dy =$
\blank{$\frac{8}{3}$}

(..omissis..)

\OrnamentalBreak

\question[8]
Sia $f_n(x) = \dfrac{\sin^2 nx}{n}$, e $f(x) = \lim_n f_n(x)$,
dove esiste.

Determinare in quali punti di $\mathbb{R}$ la successione
$f_n$ converge puntualmente a $f$.

\blankarea[5]{%
$\forall x\in \mathbb{R}$, $\left|{\sin^2 nx}\right|\leq 1$, e quindi
$\lim_n -\frac{1}{n} \leq \lim_n f_n(x) \leq \lim_n \frac{1}{n} $,
\quindi $\lim_n f_n(x) = 0 $, $\forall x\in \mathbb{R}$.
}
\end{questions}

\clearpage
\fillwithdottedlines{\stretch{1}}

\begin{center}
\combinedpointtable[h]
\end{center}

\end{document}

Documentation of the CLI

The Command Line Interface, which runs simply by:

$ mcq.py

has can be summarized by the following graph. Full documentation and use instructions are shown in the interface itself.

digraph {

welcome [shape = box, label="Welcome\n[prompt = ' mcq->>']" ] ;
open [shape = oval , label = "Open a XeLaTeX file\n(uiFileNavigator)\n[prompt = '(File)mcq[folder]->> ']" ] ;
create [shape = oval , label = "Create from guided template \n (newfileloop)\n[prompt='(New)mcq[default] >']" ] ;
exit [shape = box, label="Exit" ];

active [shape = box, label = "Active File= 'file.tex'\n (uiMasterFile)\n[prompt='(Work)mcq[folder]->> '" ];


welcome -> open   [label = " o "];
welcome -> create [label = " c " ] ;
welcome -> exit   [label = " q " ];

open -> active;
create -> active;
         }

After this, several commands are available, each with their own help (see below, prepending do_ with the commands: for example, do_x will give the help for the command x in the CLI.

class mcq.uiMasterFile(term=None)

Main Commands (type ? <command> for help):

status                 : show MCQ-XeLaTex status
make                   : compile the main TeX file <main>.tex (with XeLaTeX)
exam <n>               : gen <n> exam permuted copies -> *_exam.{tex,pdf}
omr <scanfiles*.pdf>   : get the OMR  answers file <main>_answers.txt
open <file>            : open and view/edit <file> with appropriate program
uid [<file>][:<specs>] : align UIDs with names, following specs  (in-place)
mark [<file>]          : evaluate and mark, via answers file (default given)
makestats              : generate a STATS file <main>_stats.pdf
export <filename.gift> : export to filename.gift, in GIFT moodle format (.txt ext appended)
export <filename.html> : export to filename.html, in HTML format
! <shell commands>     : execute directly shell commands
x                      : clear the status and go to main menu
q                      : quit (without clearing the status)

Important

Quitting the CLI keeps a persistent status, found in pickle objects saved in the home directory. Next time mcq.py is run, it will start from where left.

Assuming the exam file name is f.tex, the following hierarchy of files will be generated, among others. The commands are on the arrows.

digraph {

main [label="Main file: f.tex"];
xml [label="f.pos\n f.lbl\n f.pdf"] ;
exam [label="f_exam.pdf\n(DEBUG: f_exam.tex, f_exam.sols, f.xml)"] ;

gift [ label="f.gift" ];
html [ label="f.html" ];


answers [label="f_answers.txt\n f_answers.pdf"] ;
esse3 [label="esse3.py\n ->  f.uid",shape = box ] ;

marked [label="f_exam.txt\nf_exam.csv"] ;

stats [ label = "f_stats.pdf" ] ;

end [ shape = box , label = "Exit" ];

main -> xml [ label = " make " ];

main -> gift [ label = "export f.gift"];
main -> html [ label = "export f.html"];


xml -> main [ label = " check and remake " ];

xml -> exam [label = " exam " ];

exam -> answers [ label = " omr " ] ;
exam -> answers [ label = " (manual typing) " ]
esse3 -> answers  [label = " uid " ];
answers -> answers [ label = " check PDF and fix TXT " ] ;

answers -> marked [ label = " mark " ];

marked -> stats  [ label = " makestats " ];

stats -> main [ label = " check stats\n and fix f.tex " ];

stats -> end [label = " x " ];
}

Managing and using a Question Bank with Random Choices

A question bank is simply a folder where there are TeX files with mcq.sty questions in them. Operating on question banks allows to generate random questions for a test:

You can use the commands listed below to choose random questions
from the Question Bank.

Main Commands (type `? <command>` for help):
qbank [<directory>]  : show or set the Question Bank Directory
load <commandsfile>  : load a commandsfile
lsbank               : list files in the Question Bank Directory
ls  <arg>            : list files
add <n> from <files> : add <n> questions from the list of files
                        (separated by space, wildcard `*` acceptable).
del <n> | all        : remove n-th question, or all the quesitons
make                 : generate `<main>.pdf`
open                 : open the file (e.g. for viewing, open main.pdf)
random all|<n>       : draw all or just exercise <n>, and create <main>.tex
status               : show status of the chosen questions
rehash               : reload the full set of questions from the qbank
next                 : Accept the random choice and proceed.
x                    : Exit (without accepting)

A typical session, which can be saved in a txt file and loaded with the command load is as follows:

add 1 from c*-2018.tex
add 3 from c*-2019.tex
add 1 from richiami.tex
add 1 from derivate.tex
add 1 from integrali.tex
add 1 from successioni.tex
add 1 from fourier.tex
add 1 from curvesup.tex
add 1 from forme.tex
add 1 from eqdiff.tex
add 1 from lebes.tex
add 1 from lebes2.tex
add 1 from hilbert.tex

Exporting to other formats: HTML and GIFT

The commandline:

$ mcq.py --gift filename.tex > questions.gift

will convert all the questions in filename.tex to the GIFT moodle format, ready to be imported in MOODLE as questions. The two main types (exerm and exe) correspond to multiple choice questions or essays, in moodle.

The preamble command \moodlecategory{categoryname} will trigger the following behavour: for each group of questions, all the questions in a single environment \begin{esercizi}{sectioname}.. or \begin{esercizi*}{sectionname} will be categorized under the moodle GIFT category:

$CATEGORY: categoryname/sectionname

or, if the sectionname is empty,:

$CATEGORY: category

to facilitate categorized GIFT importing into MOODLE question banks.

Exactly the same function is provided by the export filename.gift in the command line user interface.

When things go wrong

(TODO)

Advanced usage: command line options

(TODO)


mcq as a python module: mcq CLASSES

class mcq.Esercizio(testo, type='EXERM', numero_colonne=1, risposte=None, src='', fb=None, coda='')

Bases: object

Base class for exercises

latex_perm(perm)

return a latex representation of the exercise, with permuted answers.

latex_withstats(stats)

return a latex (unpermuted) representation of the exercise, together with statistical data annotations.

class mcq.MultiEsercizio(s)

Bases: object

class mcq.Risposta(testo, giusta=False, punti=None, fb=None, src='')

Bases: object

class mcq.myTerm(output=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>, prompt='mcq-> ', number_of_columns=79)

Bases: object

class mcq.ExamFile(abspath)

Bases: object

show_status()

Check the poset of dependencies

view(arg)

View status, log, …

class mcq.uiShell(name, term=None)

Bases: cmd.Cmd

emptyline()

Called when an empty line is entered in response to the prompt.

If this method is not overridden, it repeats the last nonempty command entered.

do_shell(args)

Shell (direct) commands

do_open(args)

USAGE:

->> open <file>

Open PDF/TXT/CVS/… file with the appropriate program (according to system configuration / mime-types / OS… )

EXAMPLES:

->> open main_answers.pdf
->> open main_answers.txt
precmd(line)

Hook method executed just before the command line is interpreted, but after the input prompt is generated and issued.

do_EOF(args)

EndOfFile (equivalent to Quit)

do_x(args)

Exit (interrupting everything and not saving)

help_help()

help

do_q(args)

Quit (saving status)

completedefault(text, line, begidx, endidx)

Method called to complete an input line when no command-specific complete_*() method is available.

By default, it returns an empty list.

class mcq.uiFileNavigator(term=None)

Bases: mcq.uiShell

do_ls(args)

USAGE:

->> ls [<path>]

Return the list of .TeX files or directories containing TeX files or directories. If the optional argument <path> is missing, the current dir will be listed.

  • If <path> is a directory, its content will be listed.

  • If <path> is a file, just this file will be listed.

do_cd(arg)

USAGE:

->> cd [<dir>]

Change working directory to directory <arg>. With no <dir> argument, it will go to the Home Directory.

do_load(args)

USAGE:

->> load <mainfile>

This commands simply loads the MCQ-XeLaTeX file <mainfile>. Use ls, cd and tab-completion to locate the file, first.

EQUIVALENT EXAMPLES:

->> load main.tex
->> load main
->> load mai<TAB>
class mcq.uiMasterFile(term=None)

Bases: mcq.uiShell

Main Commands (type ? <command> for help):

status                 : show MCQ-XeLaTex status
make                   : compile the main TeX file <main>.tex (with XeLaTeX)
exam <n>               : gen <n> exam permuted copies -> *_exam.{tex,pdf}
omr <scanfiles*.pdf>   : get the OMR  answers file <main>_answers.txt
open <file>            : open and view/edit <file> with appropriate program
uid [<file>][:<specs>] : align UIDs with names, following specs  (in-place)
mark [<file>]          : evaluate and mark, via answers file (default given)
makestats              : generate a STATS file <main>_stats.pdf
export <filename.gift> : export to filename.gift, in GIFT moodle format (.txt ext appended)
export <filename.html> : export to filename.html, in HTML format
! <shell commands>     : execute directly shell commands
x                      : clear the status and go to main menu
q                      : quit (without clearing the status)
do_x(args)

USAGE:

->> x

Clear the status and go to main menu. Use with caution: you need to re-load a main MCQ-XeLaTeX file after.

do_q(args)

Quit, saving the status.

do_status(args)

Show the status of the job.

do_make(args)

USAGE:

->> make

Compile (XeLaTeX-ing) the TeX file <main>.tex, and generates some internal files necessary for the OMR scan:

OUTPUT: <main>.pdf INTERNAL: <main>.lbl, <main>.pos

do_export(args)

USAGE:

->> export <outputfile>

It exports all the questions in the main TeX to <outputfile>, in a format depending on the <outputfile> extension. If the extension is .gift, the format is MOODLE GIFT. (.txt ext appended) If the extension is .html or .htm, the format is HTML.

EXAMPLES:

->> export file.gift
->> export file.html
do_exam_nolatex(args)

UNDOCUMENTED (DANGEROUS) FUNCTION: USAGE exam_nolatex <n>

do_exam(args, DOLATEX=True)

USAGE:

exam <n>

Generate <n> exam copies of <main>.tex, permuting the questions and the anwsers if <n> is at least 2. It will save the output in file <main>_exam.tex and then compile it to obtain <main>_exam.pdf, where <main>.tex is the name of the main TeX file. If <n>=1, then it will not permute questions and answers. If <n> >= 2, the permutations will be pseudo-random, with a constant seed, so that each run will give exactly the same permutations. So, if a mistake in <main>.tex needs to be fixed, it is possible to re-generate the answer keys by XeLaTeX-ing <main>.tex and re-running exam <n> as many times necessary:

OUTPUT: <main>_exam.pdf
INTERNAL: <main>_exam.tex, <main>.xml, <main>_exam.db
HUMAN-READABLE DEBUG: <main>_exam.sols
do_omr(args)

USAGE:

omr <scanfiles*.pdf>

Parse the scanned bubblesheets in <scanfiles*.pdf>, and save the list of answers in <main>_answers.txt. The argument is a list of PDF files (wildcard * is accepted).

EXAMPLES:

->> omr scan/c1-s1.pdf scan/c1-s2.pdf scan/c2-s1.pdf
->> omr scan/c1-*.pdf scan/c2-S*.pdf

The annotated PDF file <main>_answers.pdf is created. It is possible to visually check the errors in the Optical Marks Recognition, and (more likely) the mistakes of the humans on the bubblesheets. A RED circle means it is an out-of place mark, a YELLOW circle means it is a (probably) ignorable out-of-place mark, a GREEN circle means the mark was identified correctly. The OMR is based on a client-server model (a remote OMR service), therefore it is necessary to be connected to internet, and to wait some time. If running multiple times on different PDF sets, the different answers files can be simply manually merged.

The format of the output, written in <main>_answers.txt is the format required by the subsequent mark process:

<CODE>:<NAME>:<UID>:<ANSWERS>:<OPTIONAL_MARK>

with empty column name and empty <OPTIONAL_MARK>. The string <ANSWERS> is a string of length = number of questions, with a `` 0 `` for a missed answer, one of ABCD… for a given answer, and a `` * `` for a multiple answer found. One needs to manually check <main>_answers.pdf to possibly correct the output <main>_answers.txt.

WARNING: Please scan the bubblesheets in GRAYSCALE format, not BW, to minimize OMR errors.

OUTPUT:

<main>_answers.txt  <main>_answers.pdf
do_uid(args)

USAGE:

->> uid [<UIDfile>][:<UIDcol><delim><NAMEcol>]

Add Names to the answers list <main>_answers.txt, from a <UIDfile>. The file <UIDfile> is a CSV file, with delimiter <delim> (default is the colon :)

EXAMPLES OF DEFAULT LINES:

:Verdi, Giuseppe:762809:
1F5G:Peano, Giuseppe:012345:

After the optional argument <UIDfile> there is an optional specification of which columns contain the UID and the NAME, and which character is the delimiter (for example, :, ; or ,):

<UIDfile>[:<UIDcol><delim><NAMEcol>]

EXAMPLE:

If the file main.uid contains lines such as:

012345;Rossi,Giuseppe

the columns specifications are <UIDcol>=1 <delim>=; <NAMEcol>=2 and therefore one has to type:

`uid main.uid:1;2`

Omitting the optional ‘spec’ argument gives the default: filename.uid correponds to filename.uid:3:2, i.e., the third and second columns contain UID and name, with delimiter :.

The default format is the output of ‘esse3.py –uid Table.xls’, the multi-tool available at www.dlfer.xyz/var/ (cf. the documentation there).

If <UIDfile> is empty, the default is <main>.uid (if it exists), where <main>.tex is the main MCQ-XeLaTeX file.

OUTPUT:

none; the file <main>_answers.txt is modified in-place.
do_mark(args)

USAGE:

mark [<answersfile>]

Take the optional argument <answersfile>, and give marks according to the answer keys generated by exam.

Default answersfile: <main>_answers.txt. The general format of the answers lines is the following:

FXZH:Verdi, Giuseppe:193146:ADba:30
<CODE>:<NAME>:<UID>:<ANSWERS>:<OPTIONAL_MARK>

where <CODE> is the code of the permutation, <NAME> is the name, <UID> the User Identification number, and <ANSWERS> is a string of length = number of questions, where the k-th character is the given answer (a case-insensitive letter), or 0 if no answer was given. The optional field <OPTIONAL_MARK> is a number, which can be given to assess other forms of exercises in the exam. In general it is not used, so the line reads as:

FXZH:Verdi, Giuseppe:193146:ADba:

The output files are <main>_exam.csv and <main>_exam.txt. The format of the CSV version is:

FXZH;Verdi, Giuseppe;193146;15.0;14.0;29.0
<CODE>;<NAME>;<UID>;<MCQ_MARK>;<OPTIONAL_MARK>;<TOTAL>

where <CODE>,<NAME>,<UID>, and <OPTIONAL_MARK> are as above. The new field <MCQ_MARK> is the sum of the numerical values of the given answers, and <TOTAL> is the combination of <MCQ_MARK> with <OPTIONAL_MARK> using the formula formulavoto defined in the <main>.tex file (python syntax), where x stands for <MCQ_MARK> and y stands for <OPTIONAL_MARK>.

EXAMPLE:

If in the <main>.tex file there is a:

\formulavoto{x+2*y}

then in the result list the total mark will be:

<TOTAL>=<MCQ_MARK> + 2 *<OPTIONAL_MARK>

The output file <main>_exam.txt is an anonymous version, with just the <CODE> and <TOTAL> columns, used to publish results on-line.

OUTPUT:

<main>_exam.csv, <main>_exam.txt
do_makestats(args)

USAGE:

->> makestats

Generate the statistics file (after marking). Each question will have the following indices for item analysis.

The FACILITY INDEX $f$ is the percentage of students who gave the right answer: if $f$< 30%, the question is too hard, if $f$>75%, the question is too easy.

The DISCRIMINATION INDEX $d$ is the number of 27% top students who gave the correct answer, minus the number of 27% bottom students who gave the correct answer, divided by the number of 27% students). If $d$>25%, it os OK. If $d$<20%, or worse, $d$ is negative, probably there is a mistake in the answer keys.

OUTPUT:

<main>_stats.pdf
do_pdfx(args)

USAGE:

->> pdfx

Attempt to convert the <main>_exam.pdf PDF file to a PDFX version, more suitable for error-free printing, using ghostscript, if installed. It tries to set a proper GS_FONTPATH.

class mcq.uiChooser(dbvars={}, term=None)

Bases: mcq.uiShell

do_make(args)

USAGE:

->> make

Compile (XeLaTeX-ing) the TeX file generated file.

OUTPUT:

<file>.pdf
do_add(args)

USAGE:

->> add <n> from file1.tex f2.tex ... f2*.tex
do_ls(args)

USAGE:

->> ls [<path>]

Return the list of .TeX files or directories containing TeX files or directories. If the optional argument <path> is missing, the current dir will be listed. If <path> is a directory, its content will be listed. If <path> is a file, just this file will be listed.

do_lsbank(args)

USAGE:

->> ls

Return the list of .TeX files in the Question Bank Directory.

do_qbank(args)

USAGE:

qbank <directory>

This commands define the Question Bank = <directory> Use ls, cd and tab-completion to locate the file, first.

do_cd(arg)

USAGE:

->> cd [<dir>]

Change working directory to directory <arg>. With no <dir> argument, it will go to the Main File Directory.

do_status(args)

status: print the current status of all chosen questions form the databank

do_rehash(args=None)

Restart and rehash all

do_random(args)

USAGE:

->> random [all]|[<n>] [n_2] ...

Random choose either all questions (if no argument or all is given). Otherwise random choose just the n-th question.

EXAMPLES:

->> random all
->> random
->> random 3
->> random 3 5 7
do_del(args)

del <n>|all: delete the n-th question from the list, or all

do_q(args)

q: quit from the procedure.

do_next(args)

Next: all finished, proceed to the Work Menu.

do_load(args)

USAGE:

->> load <commandsfile>

Load a file with add|del|random|qbank|… commands, one per line (same syntax as the UI shell)”

EQUIVALENT EXAMPLES:

->> load commandsfile.txt
->> load command<TAB>

JUNKYARD

default_combina_voti ARGOMENTO:

mcq.default_combina_voti(x, y)

Return the formula for the two parts, default of:

\formulavoto{x+y}
mcq.check_safe_dvipdfmx()

Check that the dvipdfmx correcly works with pstricks, for the output of 2Dbarcodes