J'avais raconté l'an dernier comment je corrige des copies, et ce n'est pas un hasard si je reviens sur un sujet proche à peu près un an plus tard.
En gros, ma méthode est la suivante : ouvrir un tableur avec une ligne par copie (= par élève, λ), une colonne par question du contrôle (i) ; et remplir chaque case avec un nombre réel xλ,i entre 0 (question complètement fausse ou non traitée) et 1 (question traitée de façon parfaitement satisfaisante). Puis décider d'un barème, c'est-à-dire un poids pi pour chaque question : a priori la note (Nλ de la copie λ) est la somme des xλ,j pondérée par les pj, c'est-à-dire Nλ := ∑j(pj·xλ,j) ; sauf qu'en fait, j'ai envie de pouvoir ajuster plus commodément le coefficient multiplicatif : donc au lieu que pi soit directement le nombre de points sur lequel est notée la question i, ça va être un poids relatif, je choisis un total Nmax sur lequel est noté le contrôle, et j'applique la formule Nλ := Nmax·∑j(pj·xλ,j)/∑j(pj). Traditionnellement, en France, les notes sont exprimées sur 20, mais Nmax peut prendre une autre valeur, par exemple quand le sujet était trop long et qu'on n'exige pas de tout traiter pour obtenir la note maximale, je mettrai Nmax à 21, 22 ou plus. Le fait de choisir indépendamment Nmax et les pj signifie que je peux ajuster librement le poids relatif des questions (typiquement pj vaudra 1 pour une question « normale », 0.5 pour une question simple et facile, 1.5 pour une question plus complexe, 2 pour une question particulièrement longue et discriminante… si le poids devient plus grand que ça, je vais généralement subdiviser la question en plusieurs sous-questions) sans avoir à me préoccuper d'arriver au bon total : la question i sera notée, au final, sur Nmax·pi/∑j(pj), et tant pis si je me retrouve avec un exercice noté sur, disons, 7.737 et deux sur 6.632.
L'avantage de ce système est que je n'ai pas le carcan d'une granularité du point, demi-point ou quart de point. Pour chaque question je me fais un sous-barème mental (du genre : ici, une réponse correcte mais non justifiée vaudra 0.6, c'est-à-dire 60% de la valeur de la question ; dans tel ou tel raisonnement, une bonne idée qui n'aboutit pas peut valoir 0.2, ou 0.4, ou selon ce que j'estime qu'il vaut). Au final, mes notes sont des rationnels essentiellement arbitraires que j'arrondis à 0.1 point par excès avant de les envoyer à l'administration.
Tout cela est assez facile à faire avec LibreOffice : disons que
j'inscris les notes xλ,i
entre 0 et 1 dans les lignes 2
à 32
,
colonnes D
à R
d'un tableur (la
ligne 1
contient les intitulés des colonnes, les
colonnes A
à C
me servant typiquement à
entrer le nom et prénom, et un 1 si l'élève était effectivement
présent) ; je mets le barème pj dans
la ligne 34
(cellules D34
à R34
), la note maximal
théorique Nmax dans la case S33
, et
la note dans la ligne λ de la colonne S
sera
calculée par la
formule =SUMPRODUCT($Dλ:$Rλ,$D$34:$R$34)/SUM($D$34:$R$34)*$S$33
(copiée-collée dans toutes cellules S2
à S32
).
Je n'aime pas la manière dont les tableurs incitent à faire
travailler avec des numéros de ligne et des lettres de colonne
explicites, et obligent à tout stocker dans des cellules d'une
structure 2d, on se croirait à l'époque du BASIC où
il fallait numéroter les lignes de programme. Il est vrai qu'il y a
des moyens d'éviter ça au moins partiellement (on peut donner des noms
symboliques à des cellules ou groupes de cellules) et j'avoue que je
n'ai pas fait l'effort d'apprendre à m'en servir. Mais ce que je
déteste particulièrement avec les tableurs, en fait, c'est surtout la
manière dont on se retrouve à reproduire les formules à coup de
copier-coller, parfois on cible mal le copier-coller (on sélectionne
une ligne de moins en haut ou en bas, ou pas le bon ensemble de
feuilles) et du coup la formule d'une cellule n'est pas changée avec
toutes les autres et il y a un risque important de ne pas s'en
apercevoir parce que toute la colonne est censée être uniforme. Et je
déteste aussi le fait qu'on doive marquer tout ce qui est « absolu »
par un $
alors que, dans ce que je manipule, il y a
typiquement beaucoup plus de références lignes et colonnes absolues
que relatives.
Ce que j'ai décrit, là, c'est la manière dont j'utilise un tableur quand je suis tout seul (je pourrais tout aussi bien utiliser un format de données personnel, mais ça n'aurait pas grand intérêt puisque, justement, dans ce cadre-là, les tableurs ne sont pas encore trop pénibles). Là où les choses deviennent plus lourdingues, c'est quand je dois coordonner plusieurs correcteurs, ce qui est cas pour un cours dont j'avais signalé le poly ici. Je crée un tableau avec une feuille par correcteur selon le modèle décrit ci-dessus, et chacun remplit les xλ,i (entre 0 et 1) pour ses copies. Déjà c'est plus pénible, parce que la gestion des feuilles, elle n'est pas aussi commode que celle des lignes et des colonnes (qui est déjà perfectible) : plus d'une fois je me suis retrouvé à faire accidentellement des modifications sur toutes les feuilles à la fois alors que je voulais les faire sur une seule, ou le contraire.
Certains de mes collègues utilisent un tableur Microsoft (je suppose que c'est Excel), donc je dois prier pour que l'import sous LibreOffice fonctionne correctement : pour juste des nombres, ça marche, mais pour les formules, je suis déjà plus méfiant. Par ailleurs, les cases d'un tableur viennent aussi avec des réglages de polices, tailles, couleurs et autres bizarreries que je ne comprends pas bien, qu'il me faut ensuite expurger (ou penser à demander de ne pas recopier). Voilà autre chose que je déteste : le mélange complètement bizarre entre le fond (les quantités dans le tableau) et la forme (la manière dont elles peuvent être formatées : dans certains cas, ça peut avoir un sens de considérer que ça fait partie du fond, mais, justement, le tableur ne semble pas permettre de distinguer ça proprement).
Un cas montrant à quel point tout ça est dangereux. Un de mes
collègues m'a rendu un tableau dont les moyennes étaient
particulièrement basses, et j'ai remarqué que les nombres étaient
alignés bizarrement. En regardant de plus près, j'ai compris que les
nombres comme 0.7
étaient considérés comme
du texte (comme la chaîne de
caractère
) et pas comme des nombres (le
réel 7/10), et comptaient comme zéro dans toutes les formules ; et
ceci s'appliquait à tout nombre non-entier : autrement dit, le tableur
avait effectivement transformé en zéro toutes les notes strictement
comprises entre 0 et 1 mises par mon collègue à une question ! Des
élèves auraient pu être lourdement pénalisés par une misfeature
logicielle stupide.0.7
Je suppose que la raison est qu'à un moment ou un autre, LibreOffice a décidé qu'il était en français et que le séparateur décimal en français est la virgule et pas le point.
Je digresse pour ranter à ce sujet. La seule convention
qui fait sens est de considérer que la virgule ET le point sont
tous les deux des séparateurs décimaux valables, quelle que soit la
langue : c'est la position normalisée par la 22e Convention
Générale des Poids et Mesures
(résolution 10)
et par le standard ISO 31-0 (après amendement 2) ;
et c'est surtout la seule position conforme
au principe
de Postel. (Pour des raisons analogues, le séparateur de milliers
doit être soit absent soit une espace insécable fine, mais en aucun
cas une virgule ni autre chose.) Personnellement, j'ai pris
l'habitude de systématiquement utiliser le point dans un contexte
informatique (parce que la plupart des langages informatiques
l'exigent et que ça simplifie le copier-coller), et la virgule quand
j'écris à la main (parce qu'elle est plus visible que le point), et
ce, que j'écrive en anglais ou en français. (De toute façon, je suis,
par principe, favorable à adopter des conventions d'écriture et de
typographie orthogonales aux langues dans lesquelles on écrit,
mais j'ai déjà dit tout ça. Je ne
sais pas pourquoi les gens ont tellement de mal à concevoir que « les
deux sont permis » est la meilleure réponse possible à un grand nombre
de choix de ce genre.) Toujours est-il que le programmeur qui a fait
en sorte qu'un 0.7
tapé dans un tableau, fût-il en français,
soit interprété comme une chaîne de caractères et pas comme le nombre
réel 7/10, mérite une énorme paire de baffes. (Et méritent aussi une
énorme paire de baffes ceux qui ont pondu le système de locales et qui
n'ont prévu qu'un séparateur décimal et pas de mécanisme pour
dire l'affichage utilisera tel séparateur, mais, en lecture, tel
autre séparateur sera également accepté
alors que c'est justement
ce qu'imposent les standards !)
De toute façon, la gestion des nombres par LibreOffice a l'air
tellement cassée et incohérente que je renonce à y comprendre quoi que
ce soit. On m'a fait remarquer, par exemple, que suite à une
opération de recherche-remplacement, LibreOffice réinterprète les
chaînes comme des nombres si ce sont des nombres valables et que la
case a effectivement été remplacée. Par exemple, si je
rentre
comme chaîne de caractères
(cela se fait en tapant 0.7
) et que je fais une
opération de recherche-remplacement globale de la
chaîne '0.7
en 0.7
, alors la
case se transforme en nombre 0.5
0.5
, bien que j'aie
fait un remplacement sur des chaînes. (C'est complètement
incohérent vu que, si je fais une opération de recherche-remplacement
globale de la chaîne
en 0.7
, évidemment, rien ne change.) C'est
vraiment abominable, ça veut dire qu'il y a parfois du typage, mais
parfois pas, et ce, de façon juste incohérente. Je n'ai pas cherché à
comprendre plus loin.0.7
Mais revenons à la notation de copies. Mes collègues se sont
plaints, par le passé, que noter chaque question sur 1 (c'est-à-dire
utiliser des réels entre 0 et 1) n'est pas très commode, parce que
taper 0.25 en notant sur 1 est moins pratique que taper 1 en notant
sur 4. J'ai donc ajouté une ligne à mes tableaux, disons la
ligne 33
, qui permet de spécifier sur combien on a noté
la colonne (de façon complètement indépendante de son poids), et les
nombres dans le tableau sont divisés par la ligne en question avant
toute autre opération. La formule calculant la note devient alors un
chouïa plus
compliquée : =SUMPRODUCT(($Dλ:$Rλ)/($D$33:$R$33),$D$34:$R$34)/SUM($D$34:$R$34)*$S$33
c'est-à-dire Nλ
:= Nmax·∑j(pj·(xλ,j/xmax,j))/∑j(pj)
en écrivant xmax,j pour le nombre sur
lequel la question j a été notée. J'avoue au passage que
je ne comprends pas bien les subtilités des fonctions de tableau de
LibreOffice : par exemple, =SUM(Z1:Z42)
somme les
cellules Z1
à Z42
(disons que celles-ci
contiennent des nombres), ce qui fait exactement
comme =SUMPRODUCT(Z1:Z42)
; mais si on veut calculer,
disons, la somme des sinus des valeurs en question,
alors =SUM(SIN(Z1:Z42))
ne fonctionne pas (il
renvoie #VALUE!
) tandis
que =SUMPRODUCT(SIN(Z1:Z42))
fonctionne : c'est
probablement lié au fait que SUMPRODUCT
est une fonction
de tableu alors que SUM
est… euh, je ne sais pas, autre
chose. C'est probablement expliqué quelque part, mais en tout cas,
c'est excessivement byzantin.
Bon, et quand on a plusieurs correcteurs, on peut avoir envie d'harmoniser les notes selon le principe que les correcteurs ne notent pas toujours aussi généreusement. La fonction d'harmonisation que j'ai envie de prendre est la fonction x ↦ xγ, appliquée à la note de chaque question (entre 0 et 1, donc), avec γ un réel strictement positif (et plutôt proche de 1) choisi d'autant plus grand que le correcteur est généreux, ou d'autant plus petit qu'il est sévère : l'idée est que tout le monde sera d'accord pour dire qu'une question totalement fausse vaut 0 et qu'une question parfaite vaut 1, les divergences viennent surtout des cas où on décide de mettre une partie des points. Donc l'idée serait d'appliquer cette fonction, qui fixe 0 et 1, aux notes de toutes les questions mises par un correcteur. (D'autres fonctions seraient possibles, mais celle-ci a le mérite d'être simple et standard.) Idéalement, ce qu'il faudrait faire, c'est répartir les copies aléatoirement entre les correcteurs, pour pouvoir faire l'hypothèse que chaque tas est de même niveau, puis appliquer la fonction à la note de chaque question avec un γ choisi, correcteur par correcteur, pour que les notes soient de niveaux égaux (niveau mesuré par la moyenne, ou la médiane, ou quelque chose comme ça — peut-être la moyenne des n/2 notes médianes, histoire de faire un compromis entre les deux et écarter les queues de distribution sans trop faire d'hypothèse sur le centre). Mais sans aller jusqu'à un tel niveau de précision, appliquer un γ un peu au-dessus de 1 pour un correcteur qui a tendance à être trop généreux avec les points partiels, et un peu en-dessous de 1 pour un correcteur qui a tendance à être trop sévère avec eux, permet d'harmoniser un peu. (D'où l'intérêt, aussi, d'insister pour que les correcteurs mettent effectivement des fractions de points quand il y a quelques idées de juste : ce sera toujours ajustable derrière, tandis que des 0 et des 1 ne le sont pas trop.) À ce stade-là, les notes ne sont même plus des rationnels (ce sont des algébriques parce que je prends des γ rationnels, mais bon, on s'en fout, on ne va pas faire des calculs exacts dessus).
Ma formule de calcul de note devient encore un peu plus compliquée : mathématiquement, c'est Nλ := Nmax·∑j(pj·(xλ,j/xmax,j)γ)/∑j(pj), je vous la refais en MathML juste pour le plaisir d'écrire du MathML et de rappeler que Firefox est meilleur que Chrome,
et dans LibreOffice, cela
devient =SUMPRODUCT(POWER(($Dλ:$Rλ)/($D$33:$R$33),$A$36),$D$34:$R$34)/SUM($D$34:$R$34)*$S$33
si j'ai mis le γ affecté au correcteur dans la
cellule A36
de sa feuille à lui. Ah oui, et il faut sans
doute mettre un CEILING(…,0.1)
si on veut arrondir
tout ça. Voire ajouter des tests pour certaines notes particulières
provoquant des effets de seuil (par exemple, en première année à
Télécom, il y a un seuil à 6/20, donc il vaut mieux éviter une note
comme 5.9). Ça commence à devenir vraiment fastidieux !
Difficulté suivante : communiquer les notes aux élèves. Bien sûr, mon école a une infrastructure prévue pour saisir les notes — mais il s'agit uniquement de la note finale du module. Si je veux communiquer aux élèves des notes intermédiaires, ou un décompte exercice par exercice, c'est à moi de me démerder. Et l'école ne veut pas non plus (ce qui est raisonnable) qu'on envoie à tout le monde un grand tableau avec les notes de tout le monde. La solution semble donc d'envoyer 150 mails individuels, et pour ça il est évident que je vais automatiser le processus. (Bien sûr, une meilleure solution aurait été que l'école s'arrange d'emblée pour que chaque élève se génère une paire publique/privée de clés cryptographiques et publie les clés publiques de tous les élèves : comme ça, j'aurais pu publier en une seule fois les informations pour chaque élève chiffrées de manière à ce qu'il soit le seul à pouvoir les déchiffrer. Mais ce n'est pas le cas, et par ailleurs je n'assure plus de cours de crypto, donc oublions.)
Or scripter l'envoi de mails est étonnamment difficile. Sous Unix,
on peut bien invoquer /usr/lib/sendmail
directement, mais
encore faut-il que l'agent mail de la machine en question soit
correctement configuré pour faire ce qu'il faut, ce qui est loin
d'être évident ; et même si ça marche, il ne va pas s'occuper des
choses pénibles adjacentes à l'envoi, comme
l'encodage MIME et autres petites merdes de ce
genre. Il y a toutes sortes de programmes comme mail
et mailx
qui sont censés être scriptables
(même mutt
, qui est mon agent utilisateur normal pour
tout mon mail non-professionnel), mais, bien sûr, il n'y en a pas deux
qui se comportent de la même manière (et plein de programmes
différents peuvent se cacher sous le nom de mail
, c'est
une horreur). Le mieux que j'aie trouvé était, finalement, le
programme s-nail
.
J'ai quand même passé beaucoup de temps à trouver quelles options lui
donner pour qu'il arrive à parler au serveur de mon école (du
genre : set smtp-use-starttls
, set
ssl-verify=ignore
, set smtp-auth=login
, set
smtp-auth-user=mylogin@telecom-paristech.fr
, set
smtp-auth-password=mypassword
et set
smtp=smtp://z.mines-telecom.fr
) et qu'il ne commette pas de
crime de lèse-Unicode (set encoding=8bit
et set
sendcharsets=utf-8
). Ensuite, il n'y a « plus qu'à » exporter
le fichier des notes en CSV, et écrire un script Perl qui
envoie les mails (je suppose, bien sûr, que j'aurais aussi pu trouver
un module Perl qui fait le boulot d'envoyer les mails ; sauf qu'en
fait j'aurais certainement trouvé douze modules différents, certains
obsolètes, le rapport entre lesquels n'est pas clair, et dont les noms
n'indiquent pas clairement ce qu'ils font). Et puis, bien sûr,
personne n'a l'air de bien savoir combien de mails j'ai le droit
d'envoyer par unité de temps.
Je ne peux que méditer les mots immortels
du grand David
M.*
x : le chemin de l'enfer est pavé de petites
crottes de ragondin
.