From 95c305cfe98b74ff3ffa01f28e56229fa6c26c56 Mon Sep 17 00:00:00 2001 From: "David A. Madore" Date: Wed, 3 Jun 2020 20:28:32 +0200 Subject: Start preparing multiple-choice test. --- controle-2020qcm.tex | 271 +++++++++++++++++++++++++++++++++++++++++++++++++ misc/randomize-test.pl | 179 ++++++++++++++++++++++++++++++++ 2 files changed, 450 insertions(+) create mode 100644 controle-2020qcm.tex create mode 100755 misc/randomize-test.pl diff --git a/controle-2020qcm.tex b/controle-2020qcm.tex new file mode 100644 index 0000000..8d80361 --- /dev/null +++ b/controle-2020qcm.tex @@ -0,0 +1,271 @@ +%% This is a LaTeX document. Hey, Emacs, -*- latex -*- , get it? +\documentclass[12pt,a4paper]{article} +\usepackage[francais]{babel} +\usepackage[utf8]{inputenc} +\usepackage[T1]{fontenc} +%\usepackage{ucs} +\usepackage{times} +% A tribute to the worthy AMS: +\usepackage{amsmath} +\usepackage{amsfonts} +\usepackage{amssymb} +\usepackage{amsthm} +% +\usepackage{mathrsfs} +\usepackage{wasysym} +\usepackage{url} +% +\usepackage{graphics} +\usepackage[usenames,dvipsnames]{xcolor} +\usepackage{tikz} +\usetikzlibrary{arrows,automata,positioning} +\usepackage{hyperref} +% +\newenvironment{qcm}{\relax}{\relax} +\newenvironment{qvar}{\relax}{\relax} +\newcounter{quescnt} +\newenvironment{question}% +{\stepcounter{quescnt}\bigskip\noindent\textbf{Question~\arabic{quescnt}.}\par\nobreak} +{\relax} +\newcounter{answcnt}[quescnt] +\newcommand\answer{% +\stepcounter{answcnt}\smallskip\textbf{(\Alph{answcnt})}~} +\let\rightanswer=\answer +% +\DeclareUnicodeCharacter{00A0}{~} +\DeclareUnicodeCharacter{03B5}{$\varepsilon$} +% +\DeclareMathSymbol{\tiret}{\mathord}{operators}{"7C} +\DeclareMathSymbol{\traitdunion}{\mathord}{operators}{"2D} +% +\newif\ifcorrige +\corrigefalse +% +% +% NOTE: compile dot files with +% dot2tex --figonly -f tikz --tikzedgelabels --graphstyle=automaton file.dot > file.tex +\tikzstyle{automaton}=[>=stealth',initial text={},thick,every loop/.style={min distance=7mm,looseness=5}] +\tikzstyle{state}=[] +\tikzstyle{final}=[accepting by arrow] +% +% +% +\begin{document} +\ifcorrige +\title{INF105\\Contrôle de connaissances — Corrigé\\{\normalsize Théorie des langages}} +\else +\title{INF105\\Contrôle de connaissances\\{\normalsize Théorie des langages}} +\fi +\author{} +\date{(date à remplir)} +\maketitle + +\pretolerance=8000 +\tolerance=50000 + +\vskip1truein\relax + +\noindent\textbf{Consignes.} + +Ce contrôle de connaissances est un QCM (questionnaire à choix +multiples). Chaque question admet une unique réponse correcte. Les +questions sont totalement indépendantes les unes des autres. La +sélection des questions et l'ordre ont été tirés aléatoirement et +n'obéissent donc à aucune logique particulière. + +La réponse est attendue sous forme d'une liste de numéros de question +suivie de la réponse proposée : par exemple, « \verb=1A 2B 4D= » pour +signifier que la réponse proposée à la question 1 est (A), la réponse +proposée à la question 2 est (B), et la réponse proposée à la +question 4 est (D). + +Une réponse incorrecte sera (deux fois) plus fortement pénalisée +qu'une absence de réponse : il est donc préférable de ne pas répondre +à une question que de répondre aléatoirement. + +\medbreak + +Durée : (à remplir) + +\vfill + +{\tiny\noindent +\immediate\write18{sh ./vc > vcline.tex} +Git: \input{vcline.tex} +\immediate\write18{echo ' (stale)' >> vcline.tex} +\par} + +\pagebreak + +\begin{qcm} + + +% +% +% + +\begin{qvar} + +\begin{question} + +Quelle est la couleur du cheval blanc d'Henri IV ? + +\rightanswer +Blanc + +\answer +Noir + +\answer +Bleu à pois roses + +\end{question} + +\begin{question} + +Quelle est la couleur du cheval noir de Charlemagne ? + +\rightanswer +Noir + +\answer +Blanc + +\answer +Bleu à pois roses + +\end{question} + +\end{qvar} + + +% +% +% + +\begin{question} + +Qui est enterré dans le tombeau de Grant ? + +\rightanswer +Grant + +\answer +Charlemagne + +\answer +Obi-Wan Kenobi + +\end{question} + + +% +% +% + +\begin{question} + +Combien fait $2+2$ ? + +\rightanswer +$4$ + +\answer +$696\,729\,600$ + +\answer +$e^{\pi\sqrt{163}}$ + +\end{question} + + +% +% +% + +\begin{question} + +David Madore est-il... ? + +\rightanswer +l'auteur de ces questions + +\answer +un arbre + +\answer +une application Android + +\answer +le fils caché de la reine d'Angleterre + +\end{question} + + +% +% +% + +\begin{question} + +Complétez les vers : « Ô rage ! ô désespoir ! ô vieillesse ennemie ! / +N'ai-je donc tant vécu que pour cette... ? » + +\rightanswer +infamie + +\answer +alchimie + +\answer +momie + + +\end{question} + + +% +% +% + +\begin{question} + +La réponse correcte à cette question est-elle... ? + +\rightanswer +celle-ci + +\answer +une autre que celle-ci + +\answer +inexistante + +\answer +toutes à la fois + +\end{question} + + +% +% +% + +\begin{question} + +Un quart d'heure avant sa mort, il était encore... ? + +\rightanswer +en vie + +\answer +mort + +\end{question} + + +\end{qcm} +% +% +% +\end{document} diff --git a/misc/randomize-test.pl b/misc/randomize-test.pl new file mode 100755 index 0000000..2db3998 --- /dev/null +++ b/misc/randomize-test.pl @@ -0,0 +1,179 @@ +#! /usr/local/bin/perl -w + +use strict; +use warnings; + +use Digest::SHA qw(sha256); + +use Getopt::Std; + +my %opts; + +getopts("c:N:n:", \%opts); + +my @preamble = (); +my @postamble = (); +my @questions = (); +my $nbvarid = 0; + + +### READ INPUT FILE + +if ( 1 ) { ## Keep following variables local + +my $in_preamble = 1; +my $in_postamble = 0; +my $in_qvar = 0; +my $curqn; +my $listref = \@preamble; +my $varid; +LINELOOP: +while ($_ = <>) { + if ( $_ =~ m/\\begin\{qcm\}/ ) { + die "wrong placement" unless $in_preamble; + die "bad format" unless $_ eq "\\begin\{qcm\}\n"; + $in_preamble = 0; + $listref = undef; + next LINELOOP; + } elsif ( $_ =~ m/\\end\{qcm\}/ ) { + die "wrong placement" if $in_preamble; + die "bad format" unless $_ eq "\\end\{qcm\}\n"; + $in_postamble = 0; + $listref = \@postamble; + next LINELOOP; + } elsif ( $_ =~ m/\\begin\{qvar\}/ ) { + die "wrong placement" if $in_preamble || $in_postamble || $in_qvar || defined($curqn); + die "bad format" unless $_ eq "\\begin\{qvar\}\n"; + $in_qvar = 1; + $varid = ($nbvarid++); + next LINELOOP; + } elsif ( $_ =~ m/\\end\{qvar\}/ ) { + die "wrong placement" if $in_preamble || $in_postamble || (!$in_qvar) || defined($curqn); + die "bad format" unless $_ eq "\\end\{qvar\}\n"; + $in_qvar = 0; + $varid = undef; + next LINELOOP; + } elsif ( $_ =~ m/\\begin\{question\}/ ) { + die "wrong placement" if $in_preamble || $in_postamble || defined($curqn); + die "bad format" unless $_ eq "\\begin\{question\}\n"; + my %qn = (); + $varid = ($nbvarid++) unless $in_qvar; + $qn{varid} = $varid; + $qn{question} = []; + $qn{answers} = []; + push @questions, \%qn; + $listref = $qn{question}; + $curqn = \%qn; + next LINELOOP; + } elsif ( $_ =~ m/\\end\{question\}/ ) { + die "wrong placement" if $in_preamble || $in_postamble || !defined($curqn); + die "bad format" unless $_ eq "\\end\{question\}\n"; + $listref = undef; + $curqn = undef; + next LINELOOP; + } elsif ( $_ =~ m/\\(right)?answer/ + && $_ !~ /\\newcommand/ && $_ !~ /\\let\\rightanswer/ ) { + die "wrong placement" if $in_preamble || $in_postamble || !defined($curqn); + die "bad format" unless $_ eq "\\answer\n" || $_ eq "\\rightanswer\n"; + die "this is impossible" unless ref($curqn) eq "HASH" && defined $curqn->{answers}; + die "right answer should come first" unless ($_ eq "\\rightanswer\n") == (scalar(@{$curqn->{answers}}) == 0); + my @ans = (); + push @{$curqn->{answers}}, \@ans; + $listref = \@ans; + ## no next LINELOOP here: include \answer in answer itself! + } + die "this is impossible" if $in_preamble && $in_postamble; + die "this is impossible" if $in_preamble && ($listref ne \@preamble); + die "this is impossible" if $in_postamble && ($listref ne \@postamble); + push @{$listref}, $_ if defined($listref); +} + +} + +# printf STDERR "nbvarid=%d (total=%d)\n", $nbvarid, scalar(@questions); + + +### RANDOMIZE + +my $commonseed = $opts{N} // ""; +my $seed = $opts{n} // ""; +my $nbqn = $opts{c} // int(($nbvarid+1)/2); + +my @questab = (); +my @quesanstab = (); + +if ( 1 ) { ## Keep following variables local + +my @hashlist; + +for ( my $i=0 ; $i $nbqn; + my $i = $prequestab[$k]; + my $qn = $questions[$i]; + my $varid = $qn->{varid}; + if ( defined($varid) ) { + if ( defined($varid_punch{$varid}) ) { + next PREQUESLOOP; + } else { + $varid_punch{$varid} = $i; + } + } + push @questab, $i; +} + +for ( my $i=0 ; $i{answers}; + for ( my $j=0 ; $j{question}} ) { + print $l; + } + for ( my $kk=0 ; $kk[$kk]; + my $a = $qn->{answers}->[$j]; + foreach my $l ( @{$a} ) { + print $l; + } + push @correct, sprintf("%d%s", $k+1, chr(ord("A")+$kk)) if $j==0; + } + print "\\end\{question\}\n\n"; +} + +print "\\end\{qcm\}\n\n"; + +printf "\%\% === %s ===\n", join(" ", @correct); +printf "\\ifcorrige\\bigskip\\noindent\\textbf{Corrigé.} %s\\fi\n", join(" ", @correct); + +foreach my $l ( @postamble ) { + print $l; +} -- cgit v1.2.3