diff --git a/CreateDocAndTest.sh b/CreateDocAndTest.sh new file mode 100644 index 0000000..ddee551 --- /dev/null +++ b/CreateDocAndTest.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# usefull to generate all the documentation + +# create the doc and test pdf file +amc2moodle.sh -h > ./doc/usage.txt +cd test +pdflatex QCM.tex +cd ../doc +pdflatex -output-directory=.. amc2moodle.tex +cd .. + +# run amc2moodle on the QCM.tex test +amc2moodle.sh -i ./test/QCM.tex -o ./test/QCM.xml -k -c amc + diff --git a/README.md b/README.md new file mode 100644 index 0000000..df2ccc1 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +amc2moodle, is conversion tool to recast multiple choice quiz written with the LaTeX format used by automuliplechoice 1.0.3 into the moodle XML quiz format. + +It is based on LaTeXML for a first step conversion of the LaTeX file into XML. Then a set of transformation is applied in python and with XSLT stylesheet to conform to moodle XML format. Most of LaTeX possibilities are supported (equations, tables, graphics, user defined commands). The question can then be imported in the moodle question bank using category tags. + +The automuliplechoice LaTeX format is convienient and can be used for preparing test and avoiding moodle web gui for multiple choice questions. + +For more information, installation, usage, dependancies and to see the limitations, please have a look on amc2moodle.pdf. diff --git a/amc2moodle.pdf b/amc2moodle.pdf new file mode 100644 index 0000000..4484151 Binary files /dev/null and b/amc2moodle.pdf differ diff --git a/amc2moodle.sh b/amc2moodle.sh new file mode 100644 index 0000000..a886e6c --- /dev/null +++ b/amc2moodle.sh @@ -0,0 +1,189 @@ +#!/bin/bash + +# This file is part of amc2moodle, a convertion tool to recast quiz written +# with the LaTeX format used by automuliplechoice 1.0.3 into the +# moodle XML quiz format. +# Copyright (C) 2016 Benoit Nennig, benoit.nennig@supmeca.fr + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +# path to the python and xslt file. Watchout no space before = +src="/home/bn/Enseignement/Moodle/amc2moodle/src" + +# peut-être judicieux de tout faire en python.. + +# ==================================================================== +# init variable +keep=0 # 0: delete temp file, 1: keep temp file +unset filein +unset fileout + + + +# ==================================================================== +# function giving usage +function usage() { echo "Usage: $0 input_file [-i input_file -o output_file -c catname -k -h -s]"; } + +usage() +{ +cat << EOF + + + Usage: \\ + $0 input_Tex_file [-i input_Tex_file \\ + -o output_file -c catname -k -h ] + + This script converts a tex file of AMC questions into an xml file + suitable for moodle import. Only question and questionmult + environnement are ready! + + OPTIONS: + -h Show this message + -k Keep temp file (useful for debuging) + -i Input Tex file + -o output XML file [default input_file.xml] + -c Use \element{label} as category tag as a + subcategorie root_cat_name + +EOF +} + +remarques() +{ +cat << EOF + + File converted. Check below for errors... + + For import into moodle : + -------------------------------- + - Go to the course admistration\question bank\import + - Choose 'moodle XML format' + - In the option chose : 'choose the closest grade if not listed' + in the 'General option' + (Moodle used tabulated grades like 1/2, 1/3 etc...) + . +EOF +} + + +# function to init the requiered variable +function init() { + # get absolute name of the input file + filein=$(readlink -m $OPTARG) # do not check existance! + # remove the end to get the path + pathin="${filein%/*}/" + # keep basename + filein="${filein##*/}" + catname=$filein + catflag=0 + #fileout=$(basename "$filein") # remove path + fileout=$filein + fileout="${fileout%.*}.xml" #remove extension + pathout=$pathin +} + + + +# ==================================================================== +# Arguments parsing +# Si paramètres optionnels +while getopts ":i:o:c:kh" opt; do + case $opt in + + i) # input file + init + ;; + o) # output file, if not same basemabe + fileout=$(readlink -m $OPTARG) # do not check existance! + # remove the end to get the path + pathout="${fileout%/*}/" + # keep basename + fileout="${fileout##*/}" + ;; + k) # output file, if not same basemabe + keep=1 + ;; + c) # category + catname=$OPTARG + catflag=1 + ;; + + h) # print help message + usage + exit 0 + ;; + + \?) # invalid option + echo "Invalid option. See usage." + usage + exit 1 + ;; + + esac +done + +# si qu'un seul argument +if [ "$#" = "1" ] ; then + echo run with the defaut parameters + OPTARG=$1 + init +fi + +# si rien erreur +if [ -z "$1" ]; then + echo Argument missing. See usage. + usage + exit 0 +fi + + +# check +echo "Parameters :" +echo "------------------------------------------" +echo " >path input :"$pathin +echo " >path output :"$pathout +echo " >file input :"$filein +echo " >file output :"$fileout +echo " >keep temp :"$keep +echo " >use categorie :"$catflag +echo " >catname :"$catname +#filetemp=$fileout "t" +#echo $filetemp +# ==================================================================== +# conversion script call + +# appel latexml +filetemp=tex2xml.xml +echo " > Running LateXML conversion... " +latexml --noparse --nocomment --path=$src --dest=$pathout/$filetemp $pathin/$filein +# appel bareme.py [bareme + transformation + ecriture outpu] +echo " > Running python conversion... " +#echo $src/grading.py $pathin $filetemp $pathout $fileout $keep $catname $catflag +# moche cette longue liste... à changer +python $src/grading.py $pathin $filetemp $pathout $fileout $keep $catname $catflag +# suppression fichiers temp +if [ "$keep" = "0" ]; then + echo " > Delete temp file :" $pathout$filetemp + rm $pathout$filetemp +fi +# pretty indent (not mandatory) +# voir comment améliorer ce qui est fait par lxml! +xmlindent $pathout/$fileout -o $pathout/$fileout +# return exit code ! + +# print a help message for the importation in moodle +remarques + + diff --git a/doc/amc2moodle.tex b/doc/amc2moodle.tex new file mode 100644 index 0000000..d3ccd44 --- /dev/null +++ b/doc/amc2moodle.tex @@ -0,0 +1,218 @@ +% This file is part of amc2moodle, a convertion tool to recast quiz written +% with the LaTeX format used by automuliplechoice 1.0.3 into the +% moodle XML quiz format. +% Copyright (C) 2016 Benoit Nennig, benoit.nennig@supmeca.fr +% +% This program is free software: you can redistribute it and/or modify +% it under the terms of the GNU General Public License as published by +% the Free Software Foundation, either version 3 of the License, or +% (at your option) any later version. +% +% This program is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this program. If not, see . + +\documentclass[a4paper]{article} + +%######################################################################### +\usepackage{verbatim} +\usepackage[utf8]{inputenc} +\usepackage[T1]{fontenc} +%\usepackage[francais]{babel} +\usepackage{lmodern} +%\usepackage[hmargin=3cm, vmargin=1cm, includeheadfoot]{geometry} +\usepackage{amsmath,amssymb} +\usepackage{color} +\usepackage{graphicx} +\usepackage{subfigure} +\usepackage{framed} +\usepackage{hyperref} +\usepackage[final]{pdfpages} +\hypersetup{pdfborder = 0 0 0} +\usepackage{breakurl} + +%######################################################################### +\title{\texttt{amc2moodle}} + +\author{B. Nennig\footnote{\url{benoit.nennig@supmeca.fr}}} + +\newcommand{\elem}[1]{\texttt{<#1>}} +\newcommand{\py}{\texttt{grading.py}~} +\newcommand{\amc}{\texttt{amc2moodle}} + + +\begin{document} +%######################################################################### +%=================================================================== +\maketitle + +%=================================================================== +\begin{abstract} + \input{../README.md} +\end{abstract} + + +% ======================================================================== +\tableofcontents +% ======================================================================== +\newpage +\section{Install} +% ======================================================================== +Dependencies : +\begin{itemize} + \item install python [tested with 2.7] and lxml library + \item install \texttt{PythonMagick} [tested with version 0.9.7-2] (ubuntu : sudo apt-get install python-pythonmagick). Useful to convert image files (*.eps, *.pdf, ...) into png. + \item install \texttt{LateXML}\footnote{\url{http://dlmf.nist.gov/LaTeXML}} [tested with version 0.8.1] from package (ubuntu : sudo apt-get install latexml) or from source. If you choose to compile it, please check on : + \url{http://dlmf.nist.gov/LaTeXML/get.html} that all the dependencies are installed. This program does the first step of the conversion into XML. + \item install \texttt{xmlindent} [optional]. This program can be used to indent well the XML file (ubuntu : sudo apt-get install xmlindent). If not present just comment the call in the end of \texttt{amc2moodle.sh}. +\end{itemize} + + + +Install : +\begin{itemize} + \item Create a link in /usr/bin or add to the execution \amc~ root path the folder. + \item Set the \texttt{src} folder in the \texttt{amc2moodle.sh} script or modify it to take into account an environment variable. +\end{itemize} + + +Note : The project \texttt{TeX2Quiz}, \url{https://github.com/hig3/tex2quiz}, is a similar project to translate multiple choice quiz into moodle XML, without connexion with AMC. + + +\section{Usage} +% ======================================================================== +\subsection{Command line call} +%----------------------------------------------------------------------- +Here is recall the \amc~-h output. Note that, ``\textbackslash'', stands for a line break. +%\begin{verbatim} +\verbatiminput{usage.txt} +%\end{verbatim} + + + +\subsection{Code structure} +%----------------------------------------------------------------------- +The command line calls a shell script \texttt{amc2moodle.sh}. This script then call +\begin{itemize} +\item \texttt{LateXML} with \texttt{automuliplechoice.sty.ltxml}. The package has been made using \texttt{note} element in LateXML and most of AMC environment or command names are pass through attribute (in french for the moment). User command can be added in the .tex file. This first step is used to get an XML file \texttt{tex2xml.xml}. Thanks to \texttt{LateXML}, most \LaTeX possibilities are supported in the conversion to moodle. Note that option passed to \texttt{automuliplechoice.sty} package are ignored. + +\item \py with \texttt{lxml} is used to add data like grade, image conversion and additional attributes to ease XSLT stylesheet transformation. For the moment, 3 layers of XSLT are use i) \texttt{transform\_ns.xslt} to remove the namespace added by \texttt{LateXML}, ii) \texttt{transform2html.xslt} to recast the image element, convert into html text style, tables and extract raw tex equations (instead of mathml). The html are embedded into CDATA markup. +Note that image elements will appear twice i) in \elem{img} elements present in the CDATA markup to html moodle rendering and ii) in \elem{file} element in order to embedded the image file as text (base64). This elements are present at \elem{questiontext} level or answer \elem{answer} level. +The last XSLT transform, performed by \texttt{transform.xslt} is used change the element name and conform to moodle XML format. +\end{itemize} +Note that i) moodle fill the missing element like feedback (see \ref{sec:feed}); ii) the global structure have been obtained by looking few questions created directly in moodle. +% + +\subsection{What you can do} +% ======================================================================== +\begin{itemize} +\item Convert \texttt{question} and \texttt{questionmult} environments. +\item You don't need to remove questionnaires part \textbackslash \texttt{exemplaire} or \textbackslash \texttt{onecopy}. But if this part contains undefined commands, remove/comment it! +\item Put in-line equations like $x^2$ or use equation environment (or \$\$ delimiters). For the moment eqnarray or the amsmath environments multline, align are not supported. The choice have been made to keep equation in tex and use mathjax filter of moodle for rendering. In my opinion, it is better for modifying question after importation. +\item Include image, in all format supported by \texttt{PythonMagick}. \amc will convert it in .png for moodle export. The image will be embedded as text (base64) in the output xml file. The folder is '/' in moodle. The image can be in an another folder than the tex file. +\item Include Table, with the tabular environment. In the present form, \amc put border around each cell. +\item Use italic, typerwritter, bold, emphasize\dots +\item Automatically add an answer like ``there is no good answer'' if there is no good answer. +\item Use user's command defined in the \LaTeX~file. +\item \texttt{\textbackslash usepackage[utf8]\{inputenc\}} for accents +\item Use packages that are supported by \texttt{LateXML}. See the list at \url{http://dlmf.nist.gov/LaTeXML/manual/included.bindings/}. Instead you need to add a binding to \texttt{LateXML}. +\end{itemize} + +\subsection{What you cannot do}\label{sec:cannot} +% ======================================================================== +\begin{itemize} +\item Use underscore in question name field ! +\item Use verbatim. This environment is not supported by \texttt{automultiplechoice} 1.0.3. Use \texttt{alltt} package instead. +\item Use font size (easy to add) +\item Use amsmath environments like align, aligned\dots Because \texttt{tex} attribute of \elem{equation}, provided by \texttt{LateXML} output, doesn't contains really the raw tex equation. +\item Change border of table +\item Use command like \texttt{\textbackslash raggedright}, text align is not fully supported. this add align information into the \texttt{class} attribute of \elem{note} and the string matching break down. Note that \texttt{\textbackslash raggedright} is bypassed. %in\texttt{/src/automultiplechoice.sty.ltxml} +\item Use \texttt{multicol}, it use is bypass \texttt{automultiplechoice.sty.ltxml} for choices layout. But it should be possible to use it elsewhere (create newcommand). +\item Translate equation into mathml, but it can be easily changed +\item Use AMC numeric question +\item Only the main commands of the package \texttt{automultiplechoice.sty} are supported in french. The english keywords support is on-going. The list of supported keywords can be seen in \texttt{/src/automultiplechoice.sty.ltxml} +\item You cannot remove the add of "None of these answers are correct" choice at the end of each multiple question. + + +\end{itemize} + +\section{Grading strategy} +% ======================================================================== +In moodle 3, if the total grade is negative then the total grade for this question will be zero. The grading strategy is different from AMC especially for question with multiple answers. In this case, AMC affects a grade for each checked good answer and each non-checked wrong answer. The total grade of the question depend on the number of choice. + +In Moodle and here, only checked item leads to a grade, positive or negative. The grading is compute in the \py script. +The defaut grading parameter are set in \py script to +\begin{verbatim} +# Multiple :: e :incohérence, b: bonne, m: mauvaise, p: planché +amc_bs = {'e':-1,'b':1,'m':-0.5} +amc_bm = {'e':-1,'b':1,'m':-0.5, 'p':-1} +# defaut question grade in moodle +moo_defautgrade = 1. +\end{verbatim} +This value can be changed (as in AMC) with the tex command +\begin{verbatim} +\baremeDefautS{e=-0.5,b=1,m=-0.5} % never put b<1, +\baremeDefautM{e=-0.5,b=1,m=-0.25,p=-0.5} % never put b<1, +\end{verbatim} +or at the question level with the tex command \texttt{bareme}. +The gade $g_i$ in \% is then computed as +$g_i = 100\cdot c_i / N_i$ where $i$ stand for the good or the wrong answer. Here, $N_i$ is the total number of the good or the wrong answer and $c_i$ the coefficient (\texttt{m}, \texttt{b}\dots). It important to set b=1 to get 100\% if all the good answers are found. The \texttt{e} parameter is not used here, because it is not possible to tick 2 answers in moodle for one-answer-question. The only case where incoherent can be used is if the ``\emph{there isn't any correct answer''} answer is ticked with another question but it is not implemented. + +Another difference is that moodle 3 use tabulated grade like : 1/2, 1/3, 1/4, 1/5, 1/6, 1/7, 1/8, 1/9, 1/10 and their multiple. If your grade are not conform to that you must use : 'Nearest grade if not listed' in import option in the moodle question bank. But check at least that the sum of good answer give 100\% ! + + + + + +\section{Categories} +% ======================================================================== +By default, the imported questions are all created in \texttt{$course$/filein} . When the flag \texttt{-c} is used, the AMC command \texttt{element} is used to create subcategories and the argument following \texttt{-c catname} is used instead of \texttt{filein}. +Each question is then placed in \texttt{$course$/catname/elementName}. +This part is set in \py. + +\section{Feedback}\label{sec:feed} +% ======================================================================== +Feedback are present, in a certain way, in \texttt{automuliplechoice} with the \textbackslash\texttt{explain} command. This part is not yet implemented in \amc. However it could be easy to add it at the response or question level as other fields and bypass them for real \texttt{automuliplechoice} test. + + +\section{Import in Moodle} +% ======================================================================== + + +\section{Example} +% ======================================================================== +A complete example to illustrate the possibilities of \amc, is given in \texttt{/test/QCM.tex}, an extract is given below to illustrate the syntax +\begin{verbatim} +\element{cat1}{ % use category and sub-category to classify questions + \begin{questionmult}{QLabel} + \bareme{e=-0.5,b=1,m=-1.,p=-0.5} % never put b<1, + Quel fruit possède un noyau ? + \begin{reponses} + \mauvaise{La pomme} + \mauvaise{La tomate} + \mauvaise{le Kiwi} + \end{reponses} + \end{questionmult} +} +\end{verbatim} +\includepdf[pages=-,scale=.95,nup=1x2,landscape, +pagecommand={\thispagestyle{plain}},linktodoc=false, +addtotoc={1,subsection,1,AMC example,sec:exQCM}]{../test/QCM.pdf} + + +\section{To do list} +% ======================================================================== +All the points listed in sec.~\ref{sec:cannot} can be push on this list, among them +\begin{itemize} +\item Add mathml support +\item Add other equation environnement in raw tex +\item All multi-langage support of \texttt{automultiplechoice.sty} and really implement all the \texttt{automultiplechoice.sty} command! +\item Add AMC numeric question support +\item Add a support for listing or verbatim environment. For the moment, \texttt{alltt} seems to be supported. +\item Add a support for feedback with \textbackslash\texttt{explain} command +\end{itemize} +\end{document} diff --git a/src/automultiplechoice.sty.ltxml b/src/automultiplechoice.sty.ltxml new file mode 100644 index 0000000..76810a9 --- /dev/null +++ b/src/automultiplechoice.sty.ltxml @@ -0,0 +1,128 @@ +package LaTeXML::Package::pool; # to put new subs & variables in common pool +use LaTeXML::Package; # to load these definitions +use strict; # good style +use warnings; + +# def les notes, comparer avec les arguemens optionnels etc +# comment ajouter des tags? +# comment imposer de neester les environenements? +# ici pas de mise en forme, jsute des changement de case. +# \usepackage[francais,bloc,completemulti]{automultiplechoice} + +DefMacro('\@ifundefined{}{}{}',''); + +DefMacro('\cleargroup',''); +DefMacro('\AMCcleardoublepage',''); +DefMacro('\AMCform',''); +DefMacro('\AMCformBegin',''); +DefMacro('\AMCnobloc',''); + + +# Load "anotherpackage" +# RequirePackage('anotherpackage'); +# +# A simple macro, just like in TeX +#DefMacro('\thesection', '\thechapter.\roman{section}'); + + +# A constructor defines how a control sequence generates XML: + +# =================================================================== +# TRADUCTION ET EQUIVALENCE +# a faire voir automultiplechoice.sty... + +# =================================================================== +# BAREME +# % e=incohérence; b=bonne; m=mauvaise; p planché (on ne descent pas en dessous) +DefConstructor('\bareme{}',"#1"); # dans question +DefConstructor('\scoring{}',"#1"); # dans question + +DefConstructor('\baremeDefautS{}',"#1"); # début document +DefConstructor('\scoringDefaultS{}',"#1"); # début document + +DefConstructor('\baremeDefautM{}',"#1"); #début document +DefConstructor('\scoringDefaultM{}',"#1"); #début document + +DefConstructor('\exemplaire{}{}',""); # on supprime la partie construction du sujet si présente +DefConstructor('\onecopy{}{}',""); + +DefConstructor('\element{}{}',"#1#2"); # on cree les categories + + + +# =================================================================== +# QUESTIONS +# question simple +DefEnvironment('{question}{}',"#body"); +# question multiple +DefEnvironment('{questionmult}{}',"#body");# ajouter un test pour si aucune réponse correcte +# Dans le cas où la question posée est juste informative et ne doit pas contribuer à la note de l'étudiant, on utilisera la commande \QuestionIndicative, comme dans l'exemple suivant : +DefConstructor('\QuestionIndicative',"e=0,b=0,m=0"); # pas testé + +DefEnvironment('{examcopy}[]',""); # alternative to onecopy, # on supprime la partie construction du sujet si présente + +# question numérique à faire.... + +# =================================================================== +# REPONSE +# Pas exploité, simple copie +DefEnvironment('{reponses}','#body'); #FR +DefEnvironment('{choices}','#body'); #EN + +DefEnvironment('{reponseshoriz}','#body'); +DefEnvironment('{choiceshoriz}','#body'); + +DefConstructor('\bonne{}',"#1"); # possible child bareme +DefConstructor('\correctchoice{}',"#1"); # possible child bareme + +DefConstructor('\mauvaise{}','#1'); +DefConstructor('\wrongchoice{}','#1'); + +# =================================================================== +# MISE EN FORME PAPIER +#DefMacro('\raggedright',''); +#DefMacro('\raggedleft',''); +DefEnvironment('{multicols}{}',"#body"); # on supprime la mise en forme sur plusieurs colonnes pour les réponses, possible side effect in table + +DefConstructor('\AMCBoxedAnswers',""); # on ne gère pas les pb de saut de colonne (lié à multicols) + +DefConstructor('\AMCidsPosition{}',""); +DefConstructor('\AMCboxDimensions{}',""); # dimension box à cocher +DefConstructor('\AMCboxColor{}',""); # couleur case +DefConstructor('\AMCtext{}{}',""); # Text par défaut question etc... +DefConstructor('\AMCboxStyle{}',""); # couleur case + + +DefConstructor('\melangegroupe{}',""); # mélange +DefConstructor('\shufflegroup{}',""); # mélange + +DefConstructor('\restituegroupe{}',""); # restitution +DefConstructor('\insertgroup{}',""); # restitution + +DefConstructor('\cleargroup{}',""); # purge +DefConstructor('\copygroup{}{}',""); # copy + +DefConstructor('\champnom{}',""); # copy +DefConstructor('\namefield{}',""); # copy + + +DefConstructor('\AMCrandomseed{}',""); +DefConstructor('\setdefaultgroupmode{}',""); +DefConstructor('\AMCaddpagesto{}',""); + +DefConstructor('\setgroupmode{}{}',""); +DefConstructor('\setdefaultgroupmode{}',""); + + + + + + + +# il en manque ... + +# \AMCinterBrep # longueur +# \AMCinterIrep # longueur + +# Don't forget this, so perl knows the package loaded. +1; diff --git a/src/grading.py b/src/grading.py new file mode 100644 index 0000000..0f7e08f --- /dev/null +++ b/src/grading.py @@ -0,0 +1,414 @@ +# -*- coding: utf-8 -*- +""" + This file is part of amc2moodle, a convertion tool to recast quiz written + with the LaTeX format used by automuliplechoice 1.0.3 into the + moodle XML quiz format. + Copyright (C) 2016 Benoit Nennig, benoit.nennig@supmeca.fr + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +usage : + python grading.py $pathin $filein $pathout $fileout $keep $catname $catflag + pathin, path to input xml file + filein, input xml filename + pathout, path to output xml file + fileout, output xml filename + keep, keep intermediate file plug in deb... + catname, output xml filename + catflag, output xml filename + +part of amc2moodle : + call xslt stylesheet and complete the require xml element + compute the grade according to the amc way + convert non png img into png and embedded them in the output_file + +warning : + the grade are not computed exactly as in amc, see amc2moodle.pdf + +""" +import sys +from lxml import etree +from PythonMagick import Image +import base64 + +# ====================================================================== +# fonction pour le traitement des fichiers images +# ====================================================================== + +def basename(s): + """fonction pour extraire le nom (sans extension et sans path) + s : nom complet + name : nom du fichier + """ + start=s.split('.')[-2] + path = start.split('/') + if len(path)>1: + name=path[-1] + else: + name=path + + return name + + + +def EncodeImg(Ii,pathin,pathout): + """ fonction qui encode un png en base64 + Ii : l'element xml ou il faut la brancher + pathin et pathout les chemins des fichiers """ + print Ii.attrib + ext=Ii.attrib['ext'] + img_name = Ii.attrib['name'] + pathF=Ii.attrib['pathF'] +'/' + + # si ce n'est pas du png on converti en png + if (Ii.attrib['ext'] != 'png'): + im = Image(pathF+ img_name +'.' + ext) + img_name = img_name + ".png" + im.write(pathF + img_name) + else: + img_name = Ii.attrib['name']+'.'+ext + + img_file = open( pathF + img_name, "rb") + Ii.attrib.update({'name':img_name,'path':'/','encoding':"base64"}) + Ii.text=base64.b64encode(img_file.read()) + + + + +# ====================================================================== +# M A I N +# ====================================================================== + +# ====================================================================== +# récupération des arguments +# ====================================================================== + +# usage : python grading.py $pathin $filein $pathout $fileout $keep $catname $catflag +if len(sys.argv)!=8: + print "Problem with the number of imput args, check calling seq. in amc2moodle.sh ." + exit() + + +# 1st arg is the program name +pathin = sys.argv[1] # path to input xml file +filein = pathin+sys.argv[2] # input xml filename +pathout = sys.argv[3] # path to output xml file +fileout = pathout+sys.argv[4] # output xml filename +keep = int(sys.argv[5]) # keep intermediate file plug in deb... +catname = sys.argv[6] # output xml filename +catflag = int(sys.argv[7]) # output xml filename +deb=0 # set to 1 to write intermediate xml file and write verbose output + +""" +====================================================================== +# on définie les valeurs par défaut +====================================================================== +e=incohérence; b=bonne; m=mauvaise; p planché (on ne descent pas en dessous) +Elles peuvent etre spécifier dans le fichier .tex avec +\baremeDefautS{e=-0.5,b=1,m=-0.5} +\baremeDefautM{e=-0.5,b=0.5,m=-0.25,p=-0.5} +ou au niveau de la question +""" +amc_autocomplete=1 # ajout amc_aucune si obligatoire" +amc_aucune = u"aucune de ces réponses n'est correcte" +amc_bs = {'e':-1,'b':1,'m':-0.5} # Simple :: e :incohérence, b: bonne, m: mauvaise, p: planché +amc_bm = {'e':-1,'b':1,'m':-0.5, 'p':-1} # Multiple :: e :incohérence, b: bonne, m: mauvaise, p: planché +moo_defautgrade = 1. # valeur par défaut de la note de la question + + +# file out for debug pupose +filetemp0 = pathout + "temp0.xml" +filetemp = pathout + "temp.xml" + +# path to xslt stylesheet +filexslt_ns = sys.path[0] + "/transform_ns.xslt" # 1. remove namespace +filexslt_pre = sys.path[0] + "/transform2html.xslt" # 2. convert to html, tab, figure, equations +filexslt = sys.path[0] + "/transform.xslt" # 3. remane element and finish the job + + + +############################################################################ +# Pré traitement +# on parse le fichier xml +# Elements are lists +# Elements carry attributes as a dict +xml = open(filein, 'r') +tree0 = etree.parse(xml) + +# on supprime le namespace [a terme faire autrement] +xslt_ns = open(filexslt_ns, 'r') +xslt_ns_tree= etree.parse(xslt_ns) +transform_ns = etree.XSLT(xslt_ns_tree) +# applique tranformation +tree = transform_ns(tree0) +# on modifie les element graphic pour gérer les chemins, le taille et la mise en forme. +# +Ilist = tree.xpath(".//graphics") # que sur attributs ici +# conversion des notations d'alignement +align={'ltx_align_right':'right','ltx_align_left':'left','ltx_centering':'center'} +# ext extension, path:chemin img, dim [width/height],size, dimension en point + +for Ii in Ilist: + img_name=Ii.attrib['graphic'] + ext=img_name.split('.')[-1] + + # not all attrib are mandatory... check if they exist before use it + # try for class + if 'class' in Ii.attrib: + img_align=Ii.attrib['class'] + else: + img_align='ltx_centering' # default value center ! + # try for option + if 'options' in Ii.attrib: + img_options=Ii.attrib['options'] + img_size = img_options.split('=')[-1] # il reste pt, mais cela ne semble pas poser de pb + img_dim = img_options.split('=')[0] + else: + img_options='' + img_size='200pt' + img_dim='width' + + + img_path = pathin+'/'+img_name[0:img_name.rfind('/')] + name = basename(img_name) + Ii.attrib.update({'ext':ext,'dim':img_dim,'size':img_size,'pathF':img_path,'align':align[img_align],'name':name}) + #print Ii.attrib + +#path +#ext +# dim = width or height +# size : +#width options="height=216.81pt" +#alig <-> class + +# remise en forme + html + math + image + tableau +xslt_pre = open(filexslt_pre, 'r') +xslt_pre_tree= etree.parse(xslt_pre) +transform_pre = etree.XSLT(xslt_pre_tree) +# applique tranformation +tree = transform_pre(tree) +if (deb==1): + #print(etree.tostring(tree, pretty_print=True)) + # ecriture + xmltemp0 = open(filetemp0, 'w') + tree.write(xmltemp0, pretty_print=True) + xmltemp0.close() + + +############################################################################ +# Recherche barème par défaut +# attribut amc_baremeDefautS et amc_baremeDefautM +# on cherche s'il existe un barème par défaut pour question simple +bars = tree.xpath("//*[@class='amc_baremeDefautS']") # que sur attributs ici +# bar[0].text contient la chaine de caractère +if len(bars)>0: + # on découpe bar[0].text et on affecte les nouvelles valeurs par défaut + amc_bs=dict(item.split("=") for item in bars[0].text.strip().split(",")) + print "baremeDefautS :", amc_bs + if (float(amc_bs['b'])<1): print "warning the grade the good answser in question will be < 100%, put b=1" + +# on cherche s'il existe un barème par défaut pour question multiple +barm = tree.xpath("//*[@class='amc_baremeDefautM']") +# bar[0].text contient la chaine de caractère +if len(barm)>0: + # on découpe bar[0].text et on affecte les nouvelles valeurs par défaut + amc_bm=dict(item.split("=") for item in barm[0].text.strip().split(",")) + print "baremeDefautM :", amc_bm + if (float(amc_bm['b'])<1): print " -> warning the grade of the good answser(s) in questionmult may be < 100%, put b=1" + + +############################################################################ +# Prise en compte des catégories +# $course$/filein/amc_element_tag +Clist = tree.xpath("//*[@class='amc_categorie']") +for Ci in Clist: + if (catflag==1): + Ci.text = "$course$/"+catname.split('.')[0]+"/"+ Ci.text + else: + Ci.text = "$course$/"+catname.split('.')[0] + + + +############################################################################ +# Application du barème dans chaque question +# + vérf barème locale : attribut amc_bareme +# on suppose que le bareme est au même niveau que des element amc_bonne ou amc_mauvaise + +# Question simple +# ========================================================================== +#Qlist = tree.xpath("//text[@class='amc_question']") +Qlist = tree.xpath("//*[@class='amc_question']") +# calcul nombre de question totale +Qtot = len(Qlist) +for Qi in Qlist: + # est qu'il y a une bareme local cherche dans les child + #barl = Qi.xpath("./text[@class='amc_bareme']") + barl = Qi.xpath("bareme") + # Par défaut on a le bareme global + amc_bl = amc_bs + # si il y a une bareme local, on prend celui-la + if len(barl)>0: + amc_bl=dict(item.split("=") for item in barl[0].text.strip().split(",")) + print "bareme local :", amc_bl + if (float(amc_bl['b'])<1.): print " ->warning the grade of the good answser(s) may be < 100%, put b=1" + + + # inclusion des images dans les questions + Ilist = Qi.xpath("./questiontext/file") + for Ii in Ilist: + Ii=EncodeImg(Ii,pathin,pathout) + + + # bonne cherche dans les child + Rlist = Qi.xpath("./*[starts-with(@class, 'amc_bonne')]") + for Ri in Rlist: + frac = etree.SubElement(Ri, "fraction") # body pointe vers une case de tree + frac.text = str(float(amc_bl['b'])*100.) + # inclusion des images dans les réponses + RIlist = Ri.xpath("file") + for Ii in RIlist: + Ii=EncodeImg(Ii,pathin,pathout) + + # Mauvaise cherche dans les child + Rlist = Qi.xpath("./*[starts-with(@class, 'amc_mauvaise')]") + for Ri in Rlist: + frac = etree.SubElement(Ri, "fraction") # body pointe vers une case de tree + frac.text = str(float(amc_bl['m'])*100.) + # inclusion des images dans les réponses + RIlist = Ri.xpath("file") + for Ii in RIlist: + Ii=EncodeImg(Ii,pathin,pathout) + + # e:incohérente n'a pas trop de sens en ligne car on ne peut pas cocher plusieurs cases. + + # on ajoute le champ 1.0000000 + Dgrade = etree.SubElement(Qi, "defaultgrade") + Dgrade.text = str(moo_defautgrade) + + +# Question multiple +# ========================================================================== +#Qlist = tree.xpath("//text[@class='amc_questionmult']") +Qlist = tree.xpath("//*[@class='amc_questionmult']") +# calcul nombre de question au total +Qtot += len(Qlist) +for Qi in Qlist: + # est qu'il y a une bareme local cherche dans les child + #barl = Qi.xpath("./text[@class='amc_bareme']") + #barl = Qi.xpath("./*[@class='amc_bareme']") + barl = Qi.xpath("bareme") + # Par défaut on a le bareme global + amc_bml = amc_bm + # si il y a une bareme local, on prend celui-la + if len(barl)>0: + amc_bml=dict(item.split("=") for item in barl[0].text.strip().split(",")) + print "bareme local :", amc_bml + if (float(amc_bml['b'])<1): print " ->warning the grade of the good answser(s) may be < 100%, put b=1" + + # inclusion des images dans les questions + Ilist = Qi.xpath("./questiontext/file") + for Ii in Ilist: + Ii=EncodeImg(Ii,pathin,pathout) + + # on compte le nombre de réponse NR + #Rlistb = Qi.xpath("./text[@class='amc_bonne']") + Rlistb = Qi.xpath("./*[starts-with(@class, 'amc_bonne')]") + NRb = len(Rlistb) + + #Rlistm = Qi.xpath("./text[@class='amc_mauvaise']") + Rlistm = Qi.xpath("./*[starts-with(@class, 'amc_mauvaise')]") + NRm = len(Rlistm) + + + # ===================================================================== + # Ajouter les réponses "aucune réponse" + # Si déjà une bonne réponse on en ajoute une mauvaise + if ( (amc_autocomplete==1) & (NRb>0) ): + aucune = etree.SubElement(Qi, 'note', attrib={'class':'amc_mauvaise'} ) + aucunec = etree.SubElement(aucune, 'note' ) + aucunec.text = amc_aucune + NRm+=1 + Rlistm.append(aucune) + + # Si pas de bonne on en ajoute une bonne + if ( (amc_autocomplete==1) & (NRb==0) ): + aucune = etree.SubElement(Qi, 'note', attrib={'class':'amc_bonne'} ) + aucunec = etree.SubElement(aucune, 'note' ) + aucunec.text = amc_aucune + NRb+=1 + Rlistb.append(aucune) + + # ===================================================================== + # ajout d'un champ fraction au reponse + # bonne cherche dans les Qi childs + for Ri in Rlistb: + frac = etree.SubElement(Ri, "fraction") # body pointe vers une case de tree + frac.text = str(float(amc_bml['b'])*100./NRb) + RIlist = Ri.xpath("file") + for Ii in RIlist: + Ii=EncodeImg(Ii,pathin,pathout) + + # Mauvaise cherche dans les Qi childs + for Ri in Rlistm: + frac = etree.SubElement(Ri, "fraction") # body pointe vers une case de tree + frac.text = str(float(amc_bml['m'])*100./NRm) + RIlist = Ri.xpath("file") + for Ii in RIlist: + Ii=EncodeImg(Ii,pathin,pathout) + + + # incohérente pas trop de sens en ligne car on ne peut pas cocher plusieurs cases. + + # on ajoute le champ 1.0000000 + Dgrade = etree.SubElement(Qi, "defaultgrade") + Dgrade.text = str(moo_defautgrade) + + +# on affiche +if (deb==1): + #print(etree.tostring(tree, pretty_print=True,encoding="utf-8")) + # Ecriture fichier output intermediaire (grading edit) + # ouverture + xmltemp = open(filetemp, 'w') + # ecriture + tree.write(xmltemp, pretty_print=True,encoding="utf-8") + xmltemp.close() + + +############################################################################ +# Reformatage à partir de xslt +# chargement +xslt = open(filexslt, 'r') +xslt_tree= etree.parse(xslt) +transform = etree.XSLT(xslt_tree) +# applique tranformation +result_tree = transform(tree) +if (deb==1): + print(etree.tostring(result_tree, pretty_print=True,encoding="utf-8")) + + +############################################################################ +# écriture fichier out +xmlout = open(fileout, 'w') +result_tree.write(xmlout, pretty_print=True,encoding="utf-8") +xmlout.close() + +# fermeture des fichiers +xslt_pre.close() +xslt.close() + + +xml.close() + +print " > "+str(Qtot)+" questions converted..." diff --git a/src/transform.xslt b/src/transform.xslt new file mode 100644 index 0000000..2d90a94 --- /dev/null +++ b/src/transform.xslt @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/transform2html.xslt b/src/transform2html.xslt new file mode 100644 index 0000000..f1978ca --- /dev/null +++ b/src/transform2html.xslt @@ -0,0 +1,302 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <![CDATA[ + + ]]> + + + + + + + + + <![CDATA[ + + ]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ + + +

+
+ + + +
+ +
+
+ + + + + + + + \(\) + + + $$\begin{equation} + + \end{equation}$$ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + +

+ text-align:; + + + @@PLUGINFILE@@/.png + + + + + +

+
+ +
+ + + + diff --git a/src/transform_ns.xslt b/src/transform_ns.xslt new file mode 100644 index 0000000..84a020d --- /dev/null +++ b/src/transform_ns.xslt @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/Figures/other/4.png b/test/Figures/other/4.png new file mode 100644 index 0000000..4f9a1b7 Binary files /dev/null and b/test/Figures/other/4.png differ diff --git a/test/Figures/other/4r.png b/test/Figures/other/4r.png new file mode 100644 index 0000000..9a2cc66 Binary files /dev/null and b/test/Figures/other/4r.png differ diff --git a/test/Figures/other/schema_interpL.png b/test/Figures/other/schema_interpL.png new file mode 100644 index 0000000..affc9c1 Binary files /dev/null and b/test/Figures/other/schema_interpL.png differ diff --git a/test/Figures/tinymonk.pdf b/test/Figures/tinymonk.pdf new file mode 100644 index 0000000..a414453 Binary files /dev/null and b/test/Figures/tinymonk.pdf differ diff --git a/test/Figures/tinymonk.png b/test/Figures/tinymonk.png new file mode 100644 index 0000000..d9f4d38 Binary files /dev/null and b/test/Figures/tinymonk.png differ diff --git a/test/QCM.pdf b/test/QCM.pdf new file mode 100644 index 0000000..fa0d555 Binary files /dev/null and b/test/QCM.pdf differ diff --git a/test/QCM.tex b/test/QCM.tex new file mode 100644 index 0000000..2254bce --- /dev/null +++ b/test/QCM.tex @@ -0,0 +1,211 @@ +\documentclass[a4paper]{article} +%review + + +%######################################################################### +\usepackage[utf8]{inputenc} +%\usepackage[T1]{fontenc} +%\usepackage[francais]{babel} +%\usepackage{lmodern} +\usepackage[hmargin=4cm, vmargin=2cm, includeheadfoot]{geometry} +\usepackage{alltt} +\usepackage{multicol} +\usepackage{amsmath,amssymb} +\usepackage{color} +\usepackage{graphicx} +\usepackage[francais,bloc,completemulti]{automultiplechoice} % Mandatory for conversion + + + +% exemple de commande utilisateur +\providecommand{\abs}[1]{\lvert#1\rvert} +%######################################################################### +% Entête +%######################################################################### + + + +\title{Test de conversion AMC vers moodle} +\author{BN} + + + +%######################################################################### +% Document +%######################################################################### +\begin{document} + +% +% B A R E M E +% e=incohérence; b=bonne; m=mauvaise; p planché (on ne descent pas en dessous) +\baremeDefautS{e=-0.5,b=1,m=-0.5}% never put b<1, +\baremeDefautM{e=-0.5,b=1,m=-0.25,p=-0.5}% never put b<1, + + + + +%question : environnement, text question +%element{label}{groupe} :commande, encapsule la commande pour lui donner un groupe +%reponses : environnement +%bonne : commande +%mauvaise : commande +% B A R E M E +% e=incohérence; b=bonne; m=mauvaise; p planché (on ne descent pas en dessous) +%\baremeDefautS{e=-0.5,b=1,m=-0.5} +%\baremeDefautM{e=-0.5,b=0.5,m=-0.25,p=-0.5} +% ajouter aucune de ces réponses n'est correcte +%\usepackage[francais,bloc,completemulti]{automultiplechoice} + +%=================================================================== +% simple +\element{cat1}{ +\begin{question}{Qsimple:img} +On souhaite faire passer \textit{exactement}, par $N$ points donnés, un \texttt{polynôme} de degré \textbf{strictement} égal à $N-1$. Pour trouver les coefficients on doit résoudre un \emph{problème} + \begin{center} + \includegraphics[width=0.5\textwidth]{./Figures/other/schema_interpL.png} + \end{center} + + \begin{reponses} + \bonne{d'interpolation} + \mauvaise{de moindre carré} + \mauvaise{de Thelonius Sphere Monk + \begin{flushright} + \includegraphics[height=2cm]{./Figures/tinymonk.pdf} + \end{flushright} + \begin{flushleft} + \includegraphics[height=3cm]{./Figures/tinymonk.pdf} + \end{flushleft} + } + \end{reponses} +\end{question} +} + +% +%=================================================================== +% questions à réponse multiple +% pas de bonne réponse, on doit ajouter un champ "aucune de ces réponses n'est correcte" +\element{cat1}{ +\begin{questionmult}{Qmult:Aucune} \bareme{e=-0.5,b=1,m=-1.,p=-0.5} % never put b<1, +Quel fruit possède un noyau? + \begin{reponseshoriz} + \mauvaise{La pomme} + \mauvaise{La tomate} + \mauvaise{le Kiwi} +% \mauvaise{En allant à $$ \int_0^2 x \mathrm{d} x $$ la ligne} + \end{reponseshoriz} +\end{questionmult} +} +% +% il y a des bonne réponses et un tableau, verbatim, macro +\element{cat2}{ +\begin{questionmult}{Qmult:TabVerbMacro} +Quels sont les opérations qui donnent un chiffre présent dans le tableau? + \begin{center} + \begin{tabular}{ccc} + \hline + 12 & 2 & $2^3$ \\ + \multicolumn{2}{c}{Deux} & \includegraphics[height=16pt]{./Figures/other/4.png} \\ + \hline + \end{tabular} + \end{center} + \begin{reponses} + \bonne{ Ou en \texttt{C} using \texttt{alltt} package +\begin{alltt} +int s=-2; \\ +for (int i=0;i<4; i++)\{ \\ + s=i*i+s; \\ +\} +\end{alltt} +% \begin{verbatim}%L'environnement verbatim pose en effet des problèmes avec AMC +% int s=0 +% for(int i;i=0; i<4){ +% s++ +% } +% \end{verbatim} + } + \bonne{$\abs{-10-2}$ (math inline and newcommand)} + \mauvaise{la réponse en image \includegraphics[height=16pt]{./Figures/other/4r.png}} + \mauvaise{$6\times 6$} + \mauvaise{Avec une équation $$ \int_0^2 x \mathrm{d} x $$ } % works + \bonne{Avec une équation matricielle + \begin{equation} + \mathrm{det} \begin{pmatrix}1 & 2 \\ -1 & 10 \end{pmatrix} = \begin{vmatrix}1 & 2 \\ -1 & 10 \end{vmatrix} + \end{equation} + } +% \mauvaise{Avec une autre équation utilisant \texttt{aligned} amsmath environnemnt +% \begin{equation}\left\{\begin{aligned}\displaystyle t_{0}&\displaystyle=1/\sqrt{3}\\ \displaystyle t_{i+1}&\displaystyle=\frac{\sqrt{t_{i}^{2}+1}-1}{t_{i}}\end{aligned}\right.. +% \end{equation} +% } + \end{reponses} +\end{questionmult} +} + + +% test with englisg keywords +% example from http://home.gna.org/auto-qcm/auto-multiple-choice.en/latex.shtml#latex.simple +\element{english}{ +\begin{question}{prez} + Among the following persons, which one has ever been a President of the French Republic? + \begin{choiceshoriz} + \correctchoice{René Coty} + \wrongchoice{Alain Prost} + \wrongchoice{Marcel Proust} + \wrongchoice{with an image \includegraphics[height=16pt]{./Figures/other/4r.png}} + \end{choiceshoriz} +\end{question} +} + +\element{english}{ +\begin{questionmult}{pref} \scoring{e=-0.5,b=1,m=-.25,p=-0.5} + Among the following cities, which ones are French prefectures? + \begin{choices} + \correctchoice{Poitiers} + \wrongchoice{Sainte-Menehould} + \correctchoice{Avignon} + \end{choices} +\end{questionmult} +} + +% ################################################################# +% C R E A T I O N D E S C O P I E S +% ################################################################# +\exemplaire{1}{ % nombre de sujet différent + + %debut de l'en-tête des copies : + + \vspace*{.5cm} + \begin{minipage}{.4\linewidth} + \centering\large\bf Test + \end{minipage} + \champnom{\fbox{ + \begin{minipage}{.5\linewidth} + Nom et prénom : + + \vspace*{.5cm}\dotfill + \vspace*{1mm} + \end{minipage} + }} + + \begin{flushleft} +Certaine question peuvent sembler étrange, c'est le but ! + \begin{center} + \Large{\textsc{QCM using AMC Latex Format}}\\ + \normalsize + \end{center} + \end{flushleft} + + + + % mélange et catégorie (groupe dans ACM) + \cleargroup{BigGroupe} + \copygroup{cat1}{BigGroupe} + \copygroup{cat2}{BigGroupe} + \copygroup{english}{BigGroupe} + \melangegroupe{BigGroupe} + \restituegroupe{BigGroupe} +} + + + + +\end{document} diff --git a/test/QCM.xml b/test/QCM.xml new file mode 100644 index 0000000..d750b56 --- /dev/null +++ b/test/QCM.xml @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + +

+ + +

+ + + + $course$/amc/cat1 + + + + true + + Qsimple:img + + + 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exactement, par + \(N\) + points donnés, un polynôme de degré strictement égal à + \(N-1\) + . Pour trouver les coefficients on doit résoudre un problème +

+ + + + + +]]>
+
+ + 100.0 + + + -50.0 + + +

+

+]]>
iVBORw0KGgoAAAANSUhEUgAAABYAAAAXCAMAAAA4Nk+sAAAJJGlDQ1BpY2MAAHjalZVnUJNZF8fv8zzphUASQodQQ5EqJYCUEFoo0quoQOidUEVsiLgCK4qINEUQUUDBVSmyVkSxsCgoYkE3yCKgrBtXERWUF/Sd0Xnf2Q/7n7n3/OY/Z+4995wPFwCCOFgSvLQnJqULvJ3smIFBwUzwg8L4aSkcT0838I96Pwyg5XhvBfj3IkREpvGX4sLSyuWnCNIBgLKXWDMrPWWZDy8xPTz+K59dZsFSgUt8Y5mjv/Ho15xvLPqa4+vNXXoVCgAcKfoHDv+B/3vvslQ4gvTYqMhspk9yVHpWmCCSmbbcCR6Xy/QUJEfFJkT+UPC/Sv4HpUdmpy9HbnLKBkFsdEw68/8ONTIwNATfZ/HW62uPIUb//85nWd+95HoA2LMAIHu+e+GVAHTuAED68XdPbamvlHwAOu7wMwSZ3zzU8oYGBEABdCADFIEq0AS6wAiYAUtgCxyAC/AAviAIrAN8EAMSgQBkgVywDRSAIrAH7AdVoBY0gCbQCk6DTnAeXAHXwW1wFwyDJ0AIJsArIALvwTwEQViIDNEgGUgJUod0ICOIDVlDDpAb5A0FQaFQNJQEZUC50HaoCCqFqqA6qAn6BToHXYFuQoPQI2gMmob+hj7BCEyC6bACrAHrw2yYA7vCvvBaOBpOhXPgfHg3XAHXwyfgDvgKfBsehoXwK3gWAQgRYSDKiC7CRriIBxKMRCECZDNSiJQj9Ugr0o30IfcQITKDfERhUDQUE6WLskQ5o/xQfFQqajOqGFWFOo7qQPWi7qHGUCLUFzQZLY/WQVugeehAdDQ6C12ALkc3otvR19DD6An0ewwGw8CwMGYYZ0wQJg6zEVOMOYhpw1zGDGLGMbNYLFYGq4O1wnpgw7Dp2AJsJfYE9hJ2CDuB/YAj4pRwRjhHXDAuCZeHK8c14y7ihnCTuHm8OF4db4H3wEfgN+BL8A34bvwd/AR+niBBYBGsCL6EOMI2QgWhlXCNMEp4SyQSVYjmRC9iLHErsYJ4iniDOEb8SKKStElcUggpg7SbdIx0mfSI9JZMJmuQbcnB5HTybnIT+Sr5GfmDGE1MT4wnFiG2RaxarENsSOw1BU9Rp3Ao6yg5lHLKGcodyow4XlxDnCseJr5ZvFr8nPiI+KwETcJQwkMiUaJYolnipsQUFUvVoDpQI6j51CPUq9RxGkJTpXFpfNp2WgPtGm2CjqGz6Dx6HL2IfpI+QBdJUiWNJf0lsyWrJS9IChkIQ4PBYyQwShinGQ8Yn6QUpDhSkVK7pFqlhqTmpOWkbaUjpQul26SHpT/JMGUcZOJl9sp0yjyVRclqy3rJZskekr0mOyNHl7OU48sVyp2WeywPy2vLe8tvlD8i3y8/q6Co4KSQolCpcFVhRpGhaKsYp1imeFFxWommZK0Uq1SmdEnpJVOSyWEmMCuYvUyRsryys3KGcp3ygPK8CkvFTyVPpU3lqSpBla0apVqm2qMqUlNSc1fLVWtRe6yOV2erx6gfUO9Tn9NgaQRo7NTo1JhiSbN4rBxWC2tUk6xpo5mqWa95XwujxdaK1zqodVcb1jbRjtGu1r6jA+uY6sTqHNQZXIFeYb4iaUX9ihFdki5HN1O3RXdMj6Hnppen16n3Wl9NP1h/r36f/hcDE4MEgwaDJ4ZUQxfDPMNuw7+NtI34RtVG91eSVzqu3LKya+UbYx3jSONDxg9NaCbuJjtNekw+m5qZCkxbTafN1MxCzWrMRth0tie7mH3DHG1uZ77F/Lz5RwtTi3SL0xZ/Wepaxls2W06tYq2KXNWwatxKxSrMqs5KaM20DrU+bC20UbYJs6m3eW6rahth22g7ydHixHFOcF7bGdgJ7Nrt5rgW3E3cy/aIvZN9of2AA9XBz6HK4ZmjimO0Y4ujyMnEaaPTZWe0s6vzXucRngKPz2viiVzMXDa59LqSXH1cq1yfu2m7Cdy63WF3F/d97qOr1Vcnre70AB48j30eTz1Znqmev3phvDy9qr1eeBt653r3+dB81vs0+7z3tfMt8X3ip+mX4dfjT/EP8W/ynwuwDygNEAbqB24KvB0kGxQb1BWMDfYPbgyeXeOwZv+aiRCTkIKQB2tZa7PX3lwnuy5h3YX1lPVh68+EokMDQptDF8I8wurDZsN54TXhIj6Xf4D/KsI2oixiOtIqsjRyMsoqqjRqKtoqel/0dIxNTHnMTCw3tir2TZxzXG3cXLxH/LH4xYSAhLZEXGJo4rkkalJ8Um+yYnJ28mCKTkpBijDVInV/qkjgKmhMg9LWpnWl05c+xf4MzYwdGWOZ1pnVmR+y/LPOZEtkJ2X3b9DesGvDZI5jztGNqI38jT25yrnbcsc2cTbVbYY2h2/u2aK6JX/LxFanrce3EbbFb/stzyCvNO/d9oDt3fkK+Vvzx3c47WgpECsQFIzstNxZ+xPqp9ifBnat3FW560thROGtIoOi8qKFYn7xrZ8Nf674eXF31O6BEtOSQ3swe5L2PNhrs/d4qURpTun4Pvd9HWXMssKyd/vX779Zblxee4BwIOOAsMKtoqtSrXJP5UJVTNVwtV11W418za6auYMRB4cO2R5qrVWoLar9dDj28MM6p7qOeo368iOYI5lHXjT4N/QdZR9tapRtLGr8fCzpmPC49/HeJrOmpmb55pIWuCWjZfpEyIm7J+1PdrXqtta1MdqKToFTGade/hL6y4PTrqd7zrDPtJ5VP1vTTmsv7IA6NnSIOmM6hV1BXYPnXM71dFt2t/+q9+ux88rnqy9IXii5SLiYf3HxUs6l2cspl2euRF8Z71nf8+Rq4NX7vV69A9dcr9247nj9ah+n79INqxvnb1rcPHeLfavztuntjn6T/vbfTH5rHzAd6Lhjdqfrrvnd7sFVgxeHbIau3LO/d/0+7/7t4dXDgw/8HjwcCRkRPox4OPUo4dGbx5mP559sHUWPFj4Vf1r+TP5Z/e9av7cJTYUXxuzH+p/7PH8yzh9/9UfaHwsT+S/IL8onlSabpoymzk87Tt99ueblxKuUV/MzBX9K/FnzWvP12b9s/+oXBYom3gjeLP5d/Fbm7bF3xu96Zj1nn71PfD8/V/hB5sPxj+yPfZ8CPk3OZy1gFyo+a33u/uL6ZXQxcXHxPy6ikLxyKdSVAAABp1BMVEUtLS0xMTEyMjI1NTU3NzdXV1djY2NbW1tYWFhcXFxERERCQkI/Pz9BQUEeHh4XFxcVFRUUFBQwMDA2NjZWVlZQUFBNTU1SUlJ3d3dISEgkJCQbGxsdHR0aGhogICBJSUksLCxHR0d4eHglJSUhISEnJyc0NDQrKys7OztAQECNjY26urqurq5mZmYvLy8oKCgiIiI8PDxLS0udnZ2ampp+fn5qamoYGBhycnI5OTlfYF9RUVEpKSmIiIiqqqpOTk5FRUU6OjpVVVVzc3OMjIyDg4NtbW1ZWVlMTEw+Pj5GRkZhYWFkZGR0dHR8fHxoaGhUVFSJiYmVlZV2dnZwcHB9fX1ra2tiYmKPj4+QkJCKioqioqKYmJhpaWmRkZGAgIB7e3uXl5epqanW1tWcnJylpaWHh4dsbGxvb2+CgoKOjo6BgYGEhITFxcXa2tqvr6+GhoZ/f396enpeXl5ubm7X19fU1NSFhYVlZWWoqKjBwcFnZ2eUlJSmpqbPz89aWlq4uLinp6ddXV28vLzLy8sQEBASEhJxcXHT09Ojo6Obm5tPT0+SkpLMKjgtAAAACXBIWXMAAABIAAAASABGyWs+AAAB+UlEQVQozw3OaUPScBwA4N/+G4gcAzaujYEbxwYkZ4UbzBiiEngVCggmdiAoZXlVFhZqQueHjrfPqwcAQzih088YZo0ms9lCkFab3W4HoDDa4bS43B6GANbL+Ug/Z7VNmTDM8UjwBIxBvz8UIsM0IUpAoQjpY6OxB/NxKZFMBlMk509ngBKRjws7Hz56nMWSFIaCqRDHUYDhonchyMhKLh/lVVpBajjlJ6es8CnOrJcXnxQUxBMWDdQgCwgvLuEJrbS8slp+OpNOVKpVJPLTSHFtjRKV9Y1NnZbfMooVoWxGAMSz5zVGpbTtnbpcbsgMqlSbOVCNu8uxVpKlyu29Fx7dVt1Fa8I+SKVO6+DlqzSLv37TPez1j44LRIQAZ3sweLsjv5No3cn7vQ+n8XVdEUuC3Iv1zs6PmqLj4vLjp1r386pFEmmQD3orx+dyA6texb58PaydZg0KkiB+5NnOXiwNTUKjf/3t+mwwf5X2c+CaXW9s6apGF2HA1dnu9+VWbiSxoLpGzkzBidwVfVQimVYnVlo0MrAgqoAQLuIFev/SGbjZ3QjcdgSw21LeBRLT0pm5u+aw0R/+uG9vbsB4Yg0jQsKEiNsxGjnc/M9fv4//wGQy9vo4zBwxWfKjv1E1FG7d39RhMh5PUjwk8EhEYIqsqob525N//wGSrmVMh8fhcAAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNi0wMy0yNVQyMToyNjoyNyswMTowMFMPRA8AAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTYtMDMtMjVUMjE6MjY6MjcrMDE6MDAiUvyzAAAAKHRFWHRwZGY6SGlSZXNCb3VuZGluZ0JveAAyMi4wMDYxeDIzLjAwNjQrMCswAmrbSwAAACB0RVh0cGRmOlZlcnNpb24AUERGLTEuMyAgMSAwIG9iaiA8PCCHWNy9AAAAAElFTkSuQmCCiVBORw0KGgoAAAANSUhEUgAAABYAAAAXCAMAAAA4Nk+sAAAJJGlDQ1BpY2MAAHjalZVnUJNZF8fv8zzphUASQodQQ5EqJYCUEFoo0quoQOidUEVsiLgCK4qINEUQUUDBVSmyVkSxsCgoYkE3yCKgrBtXERWUF/Sd0Xnf2Q/7n7n3/OY/Z+4995wPFwCCOFgSvLQnJqULvJ3smIFBwUzwg8L4aSkcT0838I96Pwyg5XhvBfj3IkREpvGX4sLSyuWnCNIBgLKXWDMrPWWZDy8xPTz+K59dZsFSgUt8Y5mjv/Ho15xvLPqa4+vNXXoVCgAcKfoHDv+B/3vvslQ4gvTYqMhspk9yVHpWmCCSmbbcCR6Xy/QUJEfFJkT+UPC/Sv4HpUdmpy9HbnLKBkFsdEw68/8ONTIwNATfZ/HW62uPIUb//85nWd+95HoA2LMAIHu+e+GVAHTuAED68XdPbamvlHwAOu7wMwSZ3zzU8oYGBEABdCADFIEq0AS6wAiYAUtgCxyAC/AAviAIrAN8EAMSgQBkgVywDRSAIrAH7AdVoBY0gCbQCk6DTnAeXAHXwW1wFwyDJ0AIJsArIALvwTwEQViIDNEgGUgJUod0ICOIDVlDDpAb5A0FQaFQNJQEZUC50HaoCCqFqqA6qAn6BToHXYFuQoPQI2gMmob+hj7BCEyC6bACrAHrw2yYA7vCvvBaOBpOhXPgfHg3XAHXwyfgDvgKfBsehoXwK3gWAQgRYSDKiC7CRriIBxKMRCECZDNSiJQj9Ugr0o30IfcQITKDfERhUDQUE6WLskQ5o/xQfFQqajOqGFWFOo7qQPWi7qHGUCLUFzQZLY/WQVugeehAdDQ6C12ALkc3otvR19DD6An0ewwGw8CwMGYYZ0wQJg6zEVOMOYhpw1zGDGLGMbNYLFYGq4O1wnpgw7Dp2AJsJfYE9hJ2CDuB/YAj4pRwRjhHXDAuCZeHK8c14y7ihnCTuHm8OF4db4H3wEfgN+BL8A34bvwd/AR+niBBYBGsCL6EOMI2QgWhlXCNMEp4SyQSVYjmRC9iLHErsYJ4iniDOEb8SKKStElcUggpg7SbdIx0mfSI9JZMJmuQbcnB5HTybnIT+Sr5GfmDGE1MT4wnFiG2RaxarENsSOw1BU9Rp3Ao6yg5lHLKGcodyow4XlxDnCseJr5ZvFr8nPiI+KwETcJQwkMiUaJYolnipsQUFUvVoDpQI6j51CPUq9RxGkJTpXFpfNp2WgPtGm2CjqGz6Dx6HL2IfpI+QBdJUiWNJf0lsyWrJS9IChkIQ4PBYyQwShinGQ8Yn6QUpDhSkVK7pFqlhqTmpOWkbaUjpQul26SHpT/JMGUcZOJl9sp0yjyVRclqy3rJZskekr0mOyNHl7OU48sVyp2WeywPy2vLe8tvlD8i3y8/q6Co4KSQolCpcFVhRpGhaKsYp1imeFFxWommZK0Uq1SmdEnpJVOSyWEmMCuYvUyRsryys3KGcp3ygPK8CkvFTyVPpU3lqSpBla0apVqm2qMqUlNSc1fLVWtRe6yOV2erx6gfUO9Tn9NgaQRo7NTo1JhiSbN4rBxWC2tUk6xpo5mqWa95XwujxdaK1zqodVcb1jbRjtGu1r6jA+uY6sTqHNQZXIFeYb4iaUX9ihFdki5HN1O3RXdMj6Hnppen16n3Wl9NP1h/r36f/hcDE4MEgwaDJ4ZUQxfDPMNuw7+NtI34RtVG91eSVzqu3LKya+UbYx3jSONDxg9NaCbuJjtNekw+m5qZCkxbTafN1MxCzWrMRth0tie7mH3DHG1uZ77F/Lz5RwtTi3SL0xZ/Wepaxls2W06tYq2KXNWwatxKxSrMqs5KaM20DrU+bC20UbYJs6m3eW6rahth22g7ydHixHFOcF7bGdgJ7Nrt5rgW3E3cy/aIvZN9of2AA9XBz6HK4ZmjimO0Y4ujyMnEaaPTZWe0s6vzXucRngKPz2viiVzMXDa59LqSXH1cq1yfu2m7Cdy63WF3F/d97qOr1Vcnre70AB48j30eTz1Znqmev3phvDy9qr1eeBt653r3+dB81vs0+7z3tfMt8X3ip+mX4dfjT/EP8W/ynwuwDygNEAbqB24KvB0kGxQb1BWMDfYPbgyeXeOwZv+aiRCTkIKQB2tZa7PX3lwnuy5h3YX1lPVh68+EokMDQptDF8I8wurDZsN54TXhIj6Xf4D/KsI2oixiOtIqsjRyMsoqqjRqKtoqel/0dIxNTHnMTCw3tir2TZxzXG3cXLxH/LH4xYSAhLZEXGJo4rkkalJ8Um+yYnJ28mCKTkpBijDVInV/qkjgKmhMg9LWpnWl05c+xf4MzYwdGWOZ1pnVmR+y/LPOZEtkJ2X3b9DesGvDZI5jztGNqI38jT25yrnbcsc2cTbVbYY2h2/u2aK6JX/LxFanrce3EbbFb/stzyCvNO/d9oDt3fkK+Vvzx3c47WgpECsQFIzstNxZ+xPqp9ifBnat3FW560thROGtIoOi8qKFYn7xrZ8Nf674eXF31O6BEtOSQ3swe5L2PNhrs/d4qURpTun4Pvd9HWXMssKyd/vX779Zblxee4BwIOOAsMKtoqtSrXJP5UJVTNVwtV11W418za6auYMRB4cO2R5qrVWoLar9dDj28MM6p7qOeo368iOYI5lHXjT4N/QdZR9tapRtLGr8fCzpmPC49/HeJrOmpmb55pIWuCWjZfpEyIm7J+1PdrXqtta1MdqKToFTGade/hL6y4PTrqd7zrDPtJ5VP1vTTmsv7IA6NnSIOmM6hV1BXYPnXM71dFt2t/+q9+ux88rnqy9IXii5SLiYf3HxUs6l2cspl2euRF8Z71nf8+Rq4NX7vV69A9dcr9247nj9ah+n79INqxvnb1rcPHeLfavztuntjn6T/vbfTH5rHzAd6Lhjdqfrrvnd7sFVgxeHbIau3LO/d/0+7/7t4dXDgw/8HjwcCRkRPox4OPUo4dGbx5mP559sHUWPFj4Vf1r+TP5Z/e9av7cJTYUXxuzH+p/7PH8yzh9/9UfaHwsT+S/IL8onlSabpoymzk87Tt99ueblxKuUV/MzBX9K/FnzWvP12b9s/+oXBYom3gjeLP5d/Fbm7bF3xu96Zj1nn71PfD8/V/hB5sPxj+yPfZ8CPk3OZy1gFyo+a33u/uL6ZXQxcXHxPy6ikLxyKdSVAAABp1BMVEUtLS0xMTEyMjI1NTU3NzdXV1djY2NbW1tYWFhcXFxERERCQkI/Pz9BQUEeHh4XFxcVFRUUFBQwMDA2NjZWVlZQUFBNTU1SUlJ3d3dISEgkJCQbGxsdHR0aGhogICBJSUksLCxHR0d4eHglJSUhISEnJyc0NDQrKys7OztAQECNjY26urqurq5mZmYvLy8oKCgiIiI8PDxLS0udnZ2ampp+fn5qamoYGBhycnI5OTlfYF9RUVEpKSmIiIiqqqpOTk5FRUU6OjpVVVVzc3OMjIyDg4NtbW1ZWVlMTEw+Pj5GRkZhYWFkZGR0dHR8fHxoaGhUVFSJiYmVlZV2dnZwcHB9fX1ra2tiYmKPj4+QkJCKioqioqKYmJhpaWmRkZGAgIB7e3uXl5epqanW1tWcnJylpaWHh4dsbGxvb2+CgoKOjo6BgYGEhITFxcXa2tqvr6+GhoZ/f396enpeXl5ubm7X19fU1NSFhYVlZWWoqKjBwcFnZ2eUlJSmpqbPz89aWlq4uLinp6ddXV28vLzLy8sQEBASEhJxcXHT09Ojo6Obm5tPT0+SkpLMKjgtAAAACXBIWXMAAABIAAAASABGyWs+AAAB+UlEQVQozw3OaUPScBwA4N/+G4gcAzaujYEbxwYkZ4UbzBiiEngVCggmdiAoZXlVFhZqQueHjrfPqwcAQzih088YZo0ms9lCkFab3W4HoDDa4bS43B6GANbL+Ug/Z7VNmTDM8UjwBIxBvz8UIsM0IUpAoQjpY6OxB/NxKZFMBlMk509ngBKRjws7Hz56nMWSFIaCqRDHUYDhonchyMhKLh/lVVpBajjlJ6es8CnOrJcXnxQUxBMWDdQgCwgvLuEJrbS8slp+OpNOVKpVJPLTSHFtjRKV9Y1NnZbfMooVoWxGAMSz5zVGpbTtnbpcbsgMqlSbOVCNu8uxVpKlyu29Fx7dVt1Fa8I+SKVO6+DlqzSLv37TPez1j44LRIQAZ3sweLsjv5No3cn7vQ+n8XVdEUuC3Iv1zs6PmqLj4vLjp1r386pFEmmQD3orx+dyA6texb58PaydZg0KkiB+5NnOXiwNTUKjf/3t+mwwf5X2c+CaXW9s6apGF2HA1dnu9+VWbiSxoLpGzkzBidwVfVQimVYnVlo0MrAgqoAQLuIFev/SGbjZ3QjcdgSw21LeBRLT0pm5u+aw0R/+uG9vbsB4Yg0jQsKEiNsxGjnc/M9fv4//wGQy9vo4zBwxWfKjv1E1FG7d39RhMh5PUjwk8EhEYIqsqob525N//wGSrmVMh8fhcAAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNi0wMy0yNVQyMToyNjoyNyswMTowMFMPRA8AAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTYtMDMtMjVUMjE6MjY6MjcrMDE6MDAiUvyzAAAAKHRFWHRwZGY6SGlSZXNCb3VuZGluZ0JveAAyMi4wMDYxeDIzLjAwNjQrMCswAmrbSwAAACB0RVh0cGRmOlZlcnNpb24AUERGLTEuMyAgMSAwIG9iaiA8PCCHWNy9AAAAAElFTkSuQmCC-50.0 +
+ 1.0 +
+ + + $course$/amc/cat1 + + + + false + + Qmult:Aucune + + + + + + -33.3333333333 + + + -33.3333333333 + + + -33.3333333333 + + + aucune de ces réponses n'est correcte100.0 + + 1.0 + + + + $course$/amc/cat2 + + + + false + + Qmult:TabVerbMacro + + + iVBORw0KGgoAAAANSUhEUgAAACsAAAAzCAYAAAAO2PE2AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAPYQAAD2EBqD+naQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAASdSURBVGiBzZlbaB1VFIa/fZq0pa0xJlpKWhsraoO0TVOhRbzE3hBrQSKCVB8EIyXGFysU7JNPKgUFLw/FhwgipghVvIBFbQUfilSokkbTKtFSL9WI0caS5FjT/D7sPWafk5k5Zy4x+WExe/Zas+afvdesNXs2kgBtBr0H2iKJuSSgZf+1XUc32DNQP2g3aNEsk1wAehlUBN3nk33JIxvIMGg/qHkWiLaA+jwuAyATKD8KIRvIBOgtUPv/RLQTNFrGYbM/smdjyPrSB3oEVJ8zQQO6G/RJyD17puzQItBklWQDuehmoxvUlIHkYufjm4j7DIEaAnsDagO+ID0E9AFfAicDkfi93NAYlgIbPNkCXBHj+wGJg/69diUc1Wpl0s3AOOgC6K+E1x8un4kaoDnDqMbBALVOkmIC6C7vLAD1GUnNBN6XOFPeOVfJHgjrLBAf4FVgBBjI5qIUg8CRMEXGkT0GtDkZSu+mFK9IKEKn4+ne9oOCWgGCNYJLeWSQIqgxOi+jb5M7/VgwzxFF8E5e6a43voigc8kcfi9o8Ijekmdu3h1HtuBuWiXGgA7gD69vT9KYjMOJOGUBuFS9ry5sZfXRkJhRBP4B+uMMEpB9DXjdtf2itDAFr1D0S1yMMygAk5X9nAYec+1WYK+ny41sbAhAVSNbBO4HRoGrgHeBGzx9TWp2ZThdyaCKkX0C+9VngF7sd89yT/93anZlmKhkUGFkP2CqTO8Btrn2lZ7NeDpq01ExHGPIDgOdrr0OeMbT+RmgmI7adFRMoTVEPtGjwK/YF6gXWODpfLLnvHYROAR8hc3Hm3IlC+jE9Eryhlehng2pNMOefqvgRcEuQaPXXyv4Okn16qq8ZkOfl140JKh3N1wpGA9x/IJHKkpWCX5MQvapSmRDwmAfcN61n8ZO/3fYNHgE+BD4IWSGGoF24HZ3XF/FrJZgTRU2Ojb1dH0C443OJsGSCiO4UXBUMJH1I2Yg4cgeojTOj3ttA7QAG7Ev0puufy12RZ0Z1xvD/LiSW0NJ6moDVmO/rppce73r3wDUObsLHtnRPIgGXFqwFSjSYGTqtMNJJVyGjdFh7IPlhlZiyBZg+p+T6rDKHUdirRJiR5wyA9lmd/w53eXh2GEM86OUBexcpsA17vhTusvDUQdsjVLmMLJF4Ld0LsIR+dJkINvqtT9L5yIc9xhDIUyRgexNwDzXPprORTiWAveGKTLE7GLgLtc+m85FNPZF9KsxfYk8JegUDGYttWFyZ3m5NaACdhkcGieziE8l7vA7ChKTlP61mCtoN4ab/Y5gNFPG7YyjJHYDskkywhj2/+YgcIocV4wh2GkMa4OTYNEfR3YceBt4FRtHJQtMlxNXYr+YVmMT8Dbg6hzIGuBJ4EEAt7ZRT8jb+CeoC3R5yj2uG0GPgw6DxjJkhQnQtf4O4/4yg19A63LcQVwI2g56DnQyBeEDPtm9nuIM6Lo8tztDyDeBHnIzGrW76EsRtMxIwhgeBnqwOxnbpZKfATMOt/N4K3Abdp20HFgBLPHMng/IdmB/De6U5k7ONYY6LOkVQH1Atgk4L+W7Rskb/wJ+MRR3+5VIKgAAAABJRU5ErkJggg==122 + \(2^{3}\) + Deux

+ + + + + + + +]]>
+
+ + C using alltt package +

+int s=-2;
for (int i=0;i<4; i++){
s=i*i+s;
} +

+]]>
33.3333333333 +
+ + 33.3333333333 + + +

]]>
iVBORw0KGgoAAAANSUhEUgAAACsAAAAzCAYAAAAO2PE2AAAAh3pUWHRSYXcgcHJvZmlsZSB0eXBlIGV4aWYAAHjaVY7bDYVACET/qcISeC0s5XiNJnZg+UJWs97zAZMJDMB+nQcsBSGDNu8WZphoaPCaouNAEImRqmcdPF0oFU8bhIew6I46B/XxX5pYt8PV3ZpttnGm8y4knDUPQaVivREzhH/vR/9+LXyBG0fHLEd7vP7vAAAJ6WlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNC40LjAtRXhpdjIiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iCiAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjQzIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iNTEiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iMSIKICAgdGlmZjpJbWFnZUhlaWdodD0iNTEiLz4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/PuJV59YAAAAEc0JJVAgICAh8CGSIAAAEZ0lEQVRo3s2ZXYhVVRTHf/vOnZxGy3GUkjG0ESEbmokQHKLAtC/pk6AChRDJPpyXgoiglx5FiLSi7GVCMIke+rCHBFPpayQFx7laMQYxjqUx2ag4mpON8+/BdafN4Zw5596773Q3bPa69+yzzm8v1l577b2dJGq5OEcj0CRxMuccTzrHfc7R5hzX1hhoM7Ab6ATIA0uBl7wO54HfgBPAEeBb4DuJP6YYtAX4EmgDZtnfmgsaBSmlHgV1g9aAWiRRrQpaBBrwvv2yrogCtCUDbLQeBr0OuhfUEBC0A/R75FsbfdiFoLEygIv1L9BO0IugtjIhZ4KeB52J0d89AWudt1cAG63HQe+DXgCtBN0IysUA1oFWgD6wASfp+0wSrhi6nKMdKACuSnPmInAMqAeusdqY8d0eiTujI/08oHVD1n5J5CIj2FCja8Ns4D838OLbV8CyGoMdB+pzMQ+qYN1fgHVAf7kKcsCspDByMKzPPSJA8FAlem7KJYwksHUXWLsTuFC23ybBfgIhc4G7rb0MHCxXyZxYWIlxYEc42Ns9uRAW1sqn4WCvAxpMHqwK7B7gXDjgG6w9FtxnkbgEfBEOdl5VLUtY2JnWDpQNm0/pUAgHW8xZhoERy2MwT+sFDgF9wFHgpPXfADw2Mdo02H5gzLY/FZbpnvyMTbgD9omkTeshH7YuS1L8U2Wr15hgj2CprWJJdYag0/vtBAVfV08Wi/0I3FyaFfuAr4FvrB2O6TMfuB+4B1gCLAS2A/vt+Vqgw38hk2Vfy27FXwWtKRZEsDnm3YuC+fa8STAU7XMgl8FMQ9ktes528X4augp401tyAZ6KeXczcNzkd2whoWTLdpXmo98LXhFsM2sV/9/qWXYk8s4PggZ79kSS7r4sPlvinqyzeIASKS2efBqYYfLfwGpgFJgLbEnMaXPhYZNKQwS2WF4FDpvcXdzBxJW6LLC5MLBXe/Kf1u4GNpm8HnhgMgWZYPNhYKd58gnLEVabG3cAb6QaLQvs4jCwY578M/AocMpWto8ibhJv2SzRINB+bJ8XDeo9eWtWHQO5lGPHq4D2MJYd9eR/vHi7JquCVJ9tt+OeAOV05PetwHulKEiFXRIuRdzkyc22a2osRYFLg70rDOgOoGdinlyZUK2lKjk/2cSanfFEPKVeFtziTawPy9W1f7IYujYSHMsspyxUtQLbgDvKVXQ2nxAFHPBcGBe43jL+ed4+LCCsZcSLwk2uthBKziRNsPU1eEZ7NhfjAq3Aw7UIG+cG75aYvIxYGpm3uJSnOvcSg/mIVVcBKyfzG2CvbfR7gd64m0fnmGOpVLHeZktWJYPo9+NqM2hoktvFLtD0Ci7jWkzHLtClEmPsOKjRV9Yd02kv6EGQC3zd2QRaBypkhB30bxiXRx5eAD1dzftZD3wZ6OOUG85ddlEjFzl1KYAWTwVoBHoBaCNoOAb2Ld+yj1se8DZo2lSDRqAbQc+CjniwXdG727n/J2QC+Aq79VwuiX8BYST1cckoyOwAAAAASUVORK5CYII=-6.25 +
+ + -6.25 + + + -6.25 + + + 33.3333333333 + + + aucune de ces réponses n'est correcte-6.25 + + 1.0 +
+ + + $course$/amc/english + + + + true + + prez + + + + + + 100.0 + + + -50.0 + + + -50.0 + + +

]]>
iVBORw0KGgoAAAANSUhEUgAAACsAAAAzCAYAAAAO2PE2AAAAh3pUWHRSYXcgcHJvZmlsZSB0eXBlIGV4aWYAAHjaVY7bDYVACET/qcISeC0s5XiNJnZg+UJWs97zAZMJDMB+nQcsBSGDNu8WZphoaPCaouNAEImRqmcdPF0oFU8bhIew6I46B/XxX5pYt8PV3ZpttnGm8y4knDUPQaVivREzhH/vR/9+LXyBG0fHLEd7vP7vAAAJ6WlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNC40LjAtRXhpdjIiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iCiAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjQzIgogICBleGlmOlBpeGVsWURpbWVuc2lvbj0iNTEiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iMSIKICAgdGlmZjpJbWFnZUhlaWdodD0iNTEiLz4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/PuJV59YAAAAEc0JJVAgICAh8CGSIAAAEZ0lEQVRo3s2ZXYhVVRTHf/vOnZxGy3GUkjG0ESEbmokQHKLAtC/pk6AChRDJPpyXgoiglx5FiLSi7GVCMIke+rCHBFPpayQFx7laMQYxjqUx2ag4mpON8+/BdafN4Zw5596773Q3bPa69+yzzm8v1l577b2dJGq5OEcj0CRxMuccTzrHfc7R5hzX1hhoM7Ab6ATIA0uBl7wO54HfgBPAEeBb4DuJP6YYtAX4EmgDZtnfmgsaBSmlHgV1g9aAWiRRrQpaBBrwvv2yrogCtCUDbLQeBr0OuhfUEBC0A/R75FsbfdiFoLEygIv1L9BO0IugtjIhZ4KeB52J0d89AWudt1cAG63HQe+DXgCtBN0IysUA1oFWgD6wASfp+0wSrhi6nKMdKACuSnPmInAMqAeusdqY8d0eiTujI/08oHVD1n5J5CIj2FCja8Ns4D838OLbV8CyGoMdB+pzMQ+qYN1fgHVAf7kKcsCspDByMKzPPSJA8FAlem7KJYwksHUXWLsTuFC23ybBfgIhc4G7rb0MHCxXyZxYWIlxYEc42Ns9uRAW1sqn4WCvAxpMHqwK7B7gXDjgG6w9FtxnkbgEfBEOdl5VLUtY2JnWDpQNm0/pUAgHW8xZhoERy2MwT+sFDgF9wFHgpPXfADw2Mdo02H5gzLY/FZbpnvyMTbgD9omkTeshH7YuS1L8U2Wr15hgj2CprWJJdYag0/vtBAVfV08Wi/0I3FyaFfuAr4FvrB2O6TMfuB+4B1gCLAS2A/vt+Vqgw38hk2Vfy27FXwWtKRZEsDnm3YuC+fa8STAU7XMgl8FMQ9ktes528X4augp401tyAZ6KeXczcNzkd2whoWTLdpXmo98LXhFsM2sV/9/qWXYk8s4PggZ79kSS7r4sPlvinqyzeIASKS2efBqYYfLfwGpgFJgLbEnMaXPhYZNKQwS2WF4FDpvcXdzBxJW6LLC5MLBXe/Kf1u4GNpm8HnhgMgWZYPNhYKd58gnLEVabG3cAb6QaLQvs4jCwY578M/AocMpWto8ibhJv2SzRINB+bJ8XDeo9eWtWHQO5lGPHq4D2MJYd9eR/vHi7JquCVJ9tt+OeAOV05PetwHulKEiFXRIuRdzkyc22a2osRYFLg70rDOgOoGdinlyZUK2lKjk/2cSanfFEPKVeFtziTawPy9W1f7IYujYSHMsspyxUtQLbgDvKVXQ2nxAFHPBcGBe43jL+ed4+LCCsZcSLwk2uthBKziRNsPU1eEZ7NhfjAq3Aw7UIG+cG75aYvIxYGpm3uJSnOvcSg/mIVVcBKyfzG2CvbfR7gd64m0fnmGOpVLHeZktWJYPo9+NqM2hoktvFLtD0Ci7jWkzHLtClEmPsOKjRV9Yd02kv6EGQC3zd2QRaBypkhB30bxiXRx5eAD1dzftZD3wZ6OOUG85ddlEjFzl1KYAWTwVoBHoBaCNoOAb2Ld+yj1se8DZo2lSDRqAbQc+CjniwXdG727n/J2QC+Aq79VwuiX8BYST1cckoyOwAAAAASUVORK5CYII=-50.0 +
+ 1.0 +
+ + + $course$/amc/english + + + + false + + pref + + + + + + 50.0 + + + -12.5 + + + 50.0 + + + aucune de ces réponses n'est correcte-12.5 + + 1.0 + +