I believe the following should do more or less what you want. I assume there is always exactly one correct answer per question (otherwise, we'll probably have to change the input syntax because of the freeform answer, which is currently not part of the input). The correct answer must be indicated with a preceding [x] or [X] as follows:
\question{La velocità di \SI{1,00e2}{m/s} espressa in \si{km/h} è:}{
{\SI{36}{km/h}.}
[X]{\SI{360}{km/h}.}
{\SI{27,8}{km/h}.}
{\SI{3,60e8}{km/h}.}
}
Spaces are ignored before and after the [x] or [X], therefore this kind of input is also legal:
\question{La velocità di \SI{1,00e2}{m/s} espressa in \si{km/h} è:}{
{\SI{36}{km/h}.}
[X] {\SI{360}{km/h}.}
{\SI{27,8}{km/h}.}
{\SI{3,60e8}{km/h}.}
}
If none of the proposed answers has such a mark for a given question, the freeform answer (with no corresponding line in the above input) is assumed to be the correct one.
Whether a check mark next to the correct answer for each question is printed depends on the use of \ShowCorrectAnswers and \HideCorrectAnswers (see the screenshots below). These commands respect TeX grouping rules (i.e., they act locally). Alternatively, you can:
load the sebmcq package with show-correct-answers=true or show-correct-answers=false, or
use \sebmcqSetup{show-correct-answers=true} or \sebmcqSetup{show-correct-answers=false}.
The \sebmcqSetup command respects grouping and accepts the following options. They can also be passed in the \usepackage{sebmcq} call and in the optional argument of the questionnaire environment.
questionnaire-env (initially: enumerate). This is the environment used by questionnaire in order to print all questions. It has to accept an \item command that works the same way as in enumerate.
shuffle-questions (initially: false); the value can be true or false. If you use the option with no value, it means true.
shuffle-answers (initially: false). The value is interpreted in the same way as for shuffle-questions.
show-correct-answers (initially: false). Ditto regarding the value.
after-answer-num-skip=〈skip〉 determines the horizontal space between each answer number/letter and the corresponding answer.
answer-number-format=〈code〉 allows one to completely change the formatting of answer numbers (alph, Alph, roman, Roman, arabic; custom TikZ code to draw a circle or rectangle around it, etc). Any occurrence of #1 in the 〈code〉 argument will be replaced by the proposed answer number (an integer).
The examples below show how to use these options.
The sebmcq.sty style file
% sebmcq.sty --- Multiple choice questions. Can print questions and proposed
% answers in a random order. Optionally show the correct
% answers.
%
% See <https://tex.stackexchange.com/a/529060/73317> for more information.
%
% Copyright (C) 2020 Florent Rougon, Enrico Gregorio
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
% of this license or (at your option) any later version.
% The latest version of this license is in
% http://www.latex-project.org/lppl.txt
% and version 1.3 can be found in the LICENSE file present in this
% distribution.
%
% This work has the LPPL maintenance status `maintained'.
%
% The Current Maintainer of this work is Florent Rougon.
%
% This work consists of only one file: sebmcq.sty.
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
\RequirePackage{expl3}
\RequirePackage{xparse}
\RequirePackage{l3keys2e}
\RequirePackage{amssymb} % for the \checkmark
\ProvidesExplPackage{sebmcq}{2020-03-14}{0.6}
{Multiple choice questions}
\str_new:N \l_questionnaire_env_str
\seq_new:N \l__sebmcq_questions_seq
\tl_new:N \l__sebmcq_answers_tl
\tl_new:N \l__sebmcq_correctness_code_tl
\tl_new:N \l__sebmcq_answer_tl
\bool_new:N \l_sebmcq_shuffle_questions_bool
\bool_new:N \l_sebmcq_shuffle_answers_bool
\bool_new:N \l_sebmcq_show_correct_answers_bool
\bool_new:N \l__sebmcq_has_correct_answer_bool % parsing stage
\bool_new:N \l__sebmcq_correct_answer_marked_bool % rendering stage
\skip_new:N \l_sebmcq_after_answer_num_skip % horizontal skip
\msg_new:nnn { sebmcq } { invalid-answer-opt-arg }
{ Invalid~input~inside~brackets~before~answer:~'#1'. }
\msg_new:nnn { sebmcq } { empty-answer-opt-arg }
{ Empty~input~inside~brackets~before~answer. }
\msg_new:nnn { sebmcq } { question-cmd-used-outside-of-questionnaire-env }
{ \question command~used~outside~of~questionnaire~environment. }
% This is assumed to be illegal
\msg_new:nnn { sebmcq } { several-correct-answers }
{ Several~answers~have~been~marked~as~correct~for~a~question. }
\cs_new_protected:Npn \__sebmcq_read_answer_with_optarg:wn [#1]#2
{
\tl_if_empty:nTF {#1}
{ \msg_error:nn { sebmcq } { empty-answer-opt-arg } }
{
\str_if_in:nnTF { xX } {#1}
{
\bool_if:NTF \l__sebmcq_has_correct_answer_bool
{ \msg_error:nn { sebmcq } { several-correct-answers } }
{
\bool_set_true:N \l__sebmcq_has_correct_answer_bool
\tl_put_right:Nn \l__sebmcq_answers_tl
{ { { \correct } {#2} } }
}
}
{ \msg_error:nnn { sebmcq } { invalid-answer-opt-arg } {#1} }
}
\__sebmcq_read_answers:w % recurse
}
\cs_new_protected:Npn \__sebmcq_read_answer_without_optarg:n #1
{
% Incorrect answer
\tl_put_right:Nn \l__sebmcq_answers_tl { { { } {#1} } }
\__sebmcq_read_answers:w % recurse
}
\cs_new_protected:Npn \__sebmcq_read_answers:w
{
\peek_meaning_ignore_spaces:NTF \q_stop
{ \use_none:n }
{
\peek_meaning_ignore_spaces:NTF [
{ \__sebmcq_read_answer_with_optarg:wn }
{ \__sebmcq_read_answer_without_optarg:n }
}
}
\cs_new_protected:Npn \__sebmcq_maybe_mark_correct_answer:
{
% Little trick in the boolean expression: this allows us to automatically
% mark the freeform answer as correct if none of the explicitly given
% answers was declared as correct.
\bool_if:nT
{
\bool_if_p:N \l_sebmcq_show_correct_answers_bool &&
! \bool_if_p:N \l__sebmcq_correct_answer_marked_bool
}
{
\makebox[0pt][r] { \checkmark \skip_horizontal:n { 0.7em } }
% No other answer will be marked as correct for this question.
\bool_set_true:N \l__sebmcq_correct_answer_marked_bool
}
}
% Default function for formatting the question number
\cs_new_protected:Npn \sebmcq_format_question_number_default:n #1
{
\fbox { \makebox[\height]{ \int_to_Alph:n {#1} } }
}
% #1: empty means the answer is incorrect
% #2: answer number
% #3: answer text
\cs_new_protected:Npn \__sebmcq_print_proposed_answer:nnn #1#2#3
{
\tl_if_empty:nF {#1} { \__sebmcq_maybe_mark_correct_answer: }
\__sebmcq_format_question_number:n {#2}
\skip_horizontal:n { \l_sebmcq_after_answer_num_skip } {#3} \\[0.5ex]
}
\cs_generate_variant:Nn \__sebmcq_print_proposed_answer:nnn { VnV }
\cs_generate_variant:Nn \__sebmcq_format_question_number:n { x }
% Based on egreg's code: <https://tex.stackexchange.com/a/519972/73317>
% #1: question text; #2: proposed answers
\cs_new_protected:Npn \__sebmcq_read_question:nn #1#2
{
\tl_clear:N \l__sebmcq_answers_tl
\bool_set_false:N \l__sebmcq_has_correct_answer_bool
\__sebmcq_read_answers:w #2 \q_stop
\seq_put_right:Nx \l__sebmcq_questions_seq
{
{ \exp_not:n {#1} } % { question }
{ \exp_not:n \exp_after:wN { \l__sebmcq_answers_tl } } % { answers }
}
}
\seq_new:N \l__sebmcq_oq_answers_seq
% #1: question
% #2: answers, each of which being of the form
% { { \correct or empty } { answer text } }
\cs_new_protected:Npn \__sebmcq_output_question:nn #1#2
{
\seq_set_split:Nnn \l__sebmcq_oq_answers_seq { } {#2}
\bool_if:NT \l_sebmcq_shuffle_answers_bool
{ \seq_shuffle:N \l__sebmcq_oq_answers_seq }
\item {#1} \\[2ex] % question text
\bool_set_false:N \l__sebmcq_correct_answer_marked_bool
\seq_indexed_map_inline:Nn \l__sebmcq_oq_answers_seq
{
\seq_set_split:Nnn \l_tmpa_seq { } {##2}
\seq_pop_left:NN \l_tmpa_seq \l__sebmcq_correctness_code_tl
\seq_pop_left:NN \l_tmpa_seq \l__sebmcq_answer_tl
\__sebmcq_print_proposed_answer:VnV
\l__sebmcq_correctness_code_tl {##1}
\l__sebmcq_answer_tl
}
\__sebmcq_maybe_mark_correct_answer:
\__sebmcq_format_question_number:x
{ \int_eval:n { \seq_count:N \l__sebmcq_oq_answers_seq + 1 } }
\skip_horizontal:n { \l_sebmcq_after_answer_num_skip }
\hbox_to_wd:nn { 9em } { \hrulefill }
}
\cs_new_protected:Npn \__sebmcq_output_question:n #1
{ \__sebmcq_output_question:nn #1 }
\cs_new_protected:Npn \__sebmcq_output_questionnaire:
{
\bool_if:NT \l_sebmcq_shuffle_questions_bool
{ \seq_shuffle:N \l__sebmcq_questions_seq }
% I didn't use \seq_map_inline:Nn here because it would fail with l3kernel
% older than 2020-03-14 (this is due to a bug in \seq_shuffle:N
% <https://github.com/latex3/latex3/issues/687>, fixed in this commit:
% <https://github.com/latex3/latex3/commit/42c70c63fd83324c5792dd14538a39dd7e388a55>).
\seq_map_function:NN \l__sebmcq_questions_seq \__sebmcq_output_question:n
}
\NewDocumentCommand \question { }
{
\msg_error:nn { sebmcq } { question-cmd-used-outside-of-questionnaire-env }
}
\NewDocumentEnvironment { questionnaire } { O{} }
{
\keys_set:nn { sebmcq } {#1}
\cs_set_eq:NN \question \__sebmcq_read_question:nn
\tl_clear:N \l__sebmcq_questions_seq
\use:c { \str_use:N \l_questionnaire_env_str }
}
{
\__sebmcq_output_questionnaire:
\use:c { end \str_use:N \l_questionnaire_env_str }
}
\NewDocumentCommand \ShowCorrectAnswers { }
{
\bool_set_true:N \l_sebmcq_show_correct_answers_bool
}
\NewDocumentCommand \HideCorrectAnswers { }
{
\bool_set_false:N \l_sebmcq_show_correct_answers_bool
}
% Set the default question number formatter
\cs_new_eq:NN \__sebmcq_format_question_number:n
\sebmcq_format_question_number_default:n
\keys_define:nn { sebmcq }
{
after-answer-num-skip .skip_set:N = \l_sebmcq_after_answer_num_skip ,
after-answer-num-skip .value_required:n = true,
after-answer-num-skip .initial:n = { 0.9em },
%
answer-number-format .code:n = {
\cs_set_protected:Npn \__sebmcq_format_question_number:n ##1 {#1} },
answer-number-format .value_required:n = true,
%
questionnaire-env .code:n = {
\str_set:Nn \l_questionnaire_env_str {#1} },
questionnaire-env .value_required:n = true,
questionnaire-env .initial:n = { enumerate },
%
show-correct-answers .bool_set:N = \l_sebmcq_show_correct_answers_bool,
show-correct-answers .initial:n = { false },
show-correct-answers .default:n = { true },
%
shuffle-questions .bool_set:N = \l_sebmcq_shuffle_questions_bool,
shuffle-questions .initial:n = { false },
shuffle-questions .default:n = { true },
%
shuffle-answers .bool_set:N = \l_sebmcq_shuffle_answers_bool,
shuffle-answers .initial:n = { false },
shuffle-answers .default:n = { true },
}
\NewDocumentCommand \sebmcqSetup { m }
{
\keys_set:nn { sebmcq } {#1}
}
% Process LaTeX2e-style package options. This uses l3keys2e, see
% <https://tex.stackexchange.com/a/371754/73317> for explanations.
\ProcessKeysPackageOptions { sebmcq }
\endinput
First example
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{lmodern} % or whatever you want
% To make small pages for the screenshots:
\usepackage[paperwidth=15cm, paperheight=11cm,
hmargin=2cm, vmargin=1cm]{geometry}
\usepackage[italian]{babel}
\usepackage{siunitx} % only for the examples
\usepackage{xparse} % only for the 'test' environment
\usepackage[shuffle-questions, shuffle-answers]{sebmcq} % your new package :-)
\pagestyle{empty}
\sisetup{output-decimal-marker={,}}
\ExplSyntaxOn
\NewDocumentEnvironment { test } { m +b }
{ \prg_replicate:nn { #1 } { #2 \clearpage } }
{ }
\ExplSyntaxOff
\ShowCorrectAnswers
\begin{document}
\begin{test}{4}
\begin{questionnaire}
% Mark the correct answer with either [x] or [X]. If no mark is present, the
% correct answer is assumed to be the freeform one.
\question{La velocità di \SI{1,00e2}{m/s} espressa in \si{km/h} è:}{
{\SI{36}{km/h}.}
[X]{\SI{360}{km/h}.}
{\SI{27,8}{km/h}.}
{\SI{3,60e8}{km/h}.}
}
\question{In fisica nucleare si usa l'angstrom
(simbolo: $\SI{1}{\angstrom} = \SI{1e-10}{m}$) e il fermi o femtometro
($\SI{1}{fm} = \SI{1e-15}{m}$). Qual è la relazione tra queste due
unità di misura?}{
[x]{$\SI{1}{\angstrom}=\SI{1e5}{fm}$.}
{$\SI{1}{\angstrom}=\SI{1e-5}{fm}$.}
{$\SI{1}{\angstrom}=\SI{1e-15}{fm}$.}
{$\SI{1}{\angstrom}=\SI{1e3}{fm}$.}
}
\end{questionnaire}
\end{test}
\end{document}
Sample output:

Sample output with \ShowCorrectAnswers commented out, or with \HideCorrectAnswers:

Second example
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{lmodern} % or whatever you want
% To make small pages for the screenshots:
\usepackage[paperwidth=15cm, paperheight=12cm,
hmargin=2cm, vmargin=1cm]{geometry}
\usepackage[italian]{babel}
\usepackage{siunitx} % for the examples
\usepackage{tikz} % for \myCircled
\usepackage{sebmcq}
\sebmcqSetup{
shuffle-questions, shuffle-answers, show-correct-answers=true,
answer-number-format={\myCircled{#1}}, after-answer-num-skip=1.5em,
}
\pagestyle{empty}
\sisetup{output-decimal-marker={,}}
\newcommand*{\myCircled}[1]{%
\begin{tikzpicture}[baseline=(number.base)]
\node[circle, draw=green!10!gray, fill=blue!30!green!10] (number) {#1};
\end{tikzpicture}%
}
\begin{document}
\begin{questionnaire}
\question{La velocità di \SI{1,00e2}{m/s} espressa in \si{km/h} è:}{
{\SI{36}{km/h}.}
[X] {\SI{360}{km/h}.}
{\SI{27,8}{km/h}.}
{\SI{3,60e8}{km/h}.}
}
\question{In fisica nucleare si usa l'angstrom (simbolo:
$\SI{1}{\angstrom} = \SI{1e-10}{m}$) e il fermi o femtometro
($\SI{1}{fm} = \SI{1e-15}{m}$). Qual è la relazione tra queste due unità di
misura?}{
[X] {$\SI{1}{\angstrom}=\SI{1e5}{fm}$.}
{$\SI{1}{\angstrom}=\SI{1e-5}{fm}$.}
{$\SI{1}{\angstrom}=\SI{1e-15}{fm}$.}
{$\SI{1}{\angstrom}=\SI{1e3}{fm}$.}
}
\end{questionnaire}
\end{document}
Sample output (the value 1.5em passed to option after-answer-num-skip is probably too large; this is only to demonstrate its effect):

Third example
This is a small variant of the previous example. This time, the answer-number-format key isn't set with \sebmcqSetup, but in the optional argument of the questionnaire environment.
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{lmodern} % or whatever you want
% To make small pages for the screenshots:
\usepackage[paperwidth=15cm, paperheight=11cm,
hmargin=2cm, vmargin=1cm]{geometry}
\usepackage[italian]{babel}
\usepackage{siunitx} % for the examples
\usepackage{tikz} % for \myCircled
\usepackage{sebmcq}
\sebmcqSetup{shuffle-questions, shuffle-answers, show-correct-answers}
\pagestyle{empty}
\sisetup{output-decimal-marker={,}}
\begin{document}
% Use a specific answer number format for this questionnaire
\begin{questionnaire}[answer-number-format={%
\tikz[baseline=(number.base)]
\node[rectangle, rounded corners=1pt, draw=none, fill=gray!40] (number)
{#1};%
}]
\question{La velocità di \SI{1,00e2}{m/s} espressa in \si{km/h} è:}{
{\SI{36}{km/h}.}
[X] {\SI{360}{km/h}.}
{\SI{27,8}{km/h}.}
{\SI{3,60e8}{km/h}.}
}
\question{In fisica nucleare si usa l'angstrom (simbolo:
$\SI{1}{\angstrom} = \SI{1e-10}{m}$) e il fermi o femtometro
($\SI{1}{fm} = \SI{1e-15}{m}$). Qual è la relazione tra queste due unità di
misura?}{
[X] {$\SI{1}{\angstrom}=\SI{1e5}{fm}$.}
{$\SI{1}{\angstrom}=\SI{1e-5}{fm}$.}
{$\SI{1}{\angstrom}=\SI{1e-15}{fm}$.}
{$\SI{1}{\angstrom}=\SI{1e3}{fm}$.}
}
\end{questionnaire}
\end{document}

Fourth example
This is a small variant of the previous examples with \alph-style numbering for the proposed answers (LaTeX2e's \alph command can't be used here, because the proposed answer number is not a counter when represented by #1 in the argument of answer-number-format).
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{lmodern} % or whatever you want
% To make small pages for the screenshots:
\usepackage[paperwidth=15cm, paperheight=11cm,
hmargin=2cm, vmargin=1cm]{geometry}
\usepackage[italian]{babel}
\usepackage{siunitx} % for the examples
\usepackage{tikz} % for \mySquared
\usepackage{expl3} % for \int_to_alph:n
\usepackage{sebmcq}
\sebmcqSetup{
shuffle-questions, shuffle-answers, show-correct-answers,
answer-number-format={\mySquared{#1}},
}
\pagestyle{empty}
\sisetup{output-decimal-marker={,}}
\ExplSyntaxOn
% Borrow \int_to_alph:n from expl3
\cs_new_eq:NN \inttoalph \int_to_alph:n
\ExplSyntaxOff
\newcommand*{\mySquared}[1]{%
\begin{tikzpicture}[baseline=(number.base)]
\node[rectangle, rounded corners=1pt, draw=none, fill=gray!40] (number)
{\inttoalph{#1}};
\end{tikzpicture}%
}
\begin{document}
\begin{questionnaire}
\question{In fisica nucleare si usa l'angstrom (simbolo:
$\SI{1}{\angstrom} = \SI{1e-10}{m}$) e il fermi o femtometro
($\SI{1}{fm} = \SI{1e-15}{m}$). Qual è la relazione tra queste due unità di
misura?}{
[X] {$\SI{1}{\angstrom}=\SI{1e5}{fm}$.}
{$\SI{1}{\angstrom}=\SI{1e-5}{fm}$.}
{$\SI{1}{\angstrom}=\SI{1e-15}{fm}$.}
{$\SI{1}{\angstrom}=\SI{1e3}{fm}$.}
}
\end{questionnaire}
\end{document}

sebmcq.sty) for your convenience. – frougon Feb 19 '20 at 18:25sebmcq.styfile provided in this answer (respecting your statement, TTBOMK). Should you be unhappy about that, feel free to edit the answer. :-) – frougon Feb 19 '20 at 18:26answer-number-formatto modify the numbering style. If you don't use this option, you still have A, B, C, D, etc. numbering inside squares. – frougon Feb 20 '20 at 23:41questionnaireenvironment. With this update, neither questions nor answers are shuffled by default anymore, but the new optionsshuffle-questionsandshuffle-answersallow you to choose what you want. – frougon Mar 13 '20 at 19:36sebmcq.styto explain a technical choice I made yesterday and avoid some problems in the future (the question and answer texts are now wrapped in braces to prevent\bfseriesand friends from leaking to the following text; this also prevents\itemfrom picking up an unwanted optional argument from an opening bracket that might start the question text). You don't need to change your.texfiles, just update the.sty. – frougon Mar 14 '20 at 15:44.styfile. But just a curiosity? :-) Where can I put the code to generate image with\begin{figure}usinggraphicx? Into or out thequestionnaireI have mistakes. – Sebastiano Mar 14 '20 at 16:00figureortableinside the questionnaire because they create a float, but you can use\includegraphicswhich merely creates a box, like any text character. TeX doesn't make any difference! Ditto for atikzpicture, by the way (atikzpictureis also a box, but in some cases with a\raiseor\lowercommand in front of it, which in rare circumstances can cause little problems—this is when options likebaselineandoverlayare used, IIRC). – frougon Mar 14 '20 at 16:14baselineandoverlayare explained in PGF bug 345. – frougon Mar 14 '20 at 16:19sebmcq.sty:\l_sebmcq_after_answer_num_skipwas declared withdimtype instead ofskip, which would have prevented one from effectively using stretchable glue for theafter-answer-num-skipoption (so, probably no change for what you've written so far). No need to thank me, I've just been stupid forgetting to update the type after doing a search & replace on the variable name! – frougon Mar 14 '20 at 22:55