#!/usr/local/bin/perl
# The MIT License (MIT)
#
# Copyright (c) 2011-2015 Ismaël Bouya http://www.normalesup.org/~bouya/
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
# Feel like tipping/donating? https://www.immae.eu/licenses_and_tipping
use Switch;
use strict;
my @table = ();
my @interros = ();
my @tablequestion = ();
my @points = ();
my %corr_nom ;
my $interro_courante = 0;
my $fichier = "notes.dat";
if($#ARGV == 0) {
$fichier = $ARGV[0];
}
sub ajout_interro {
print "Nom de l'interrogation\n";
my $interro = <STDIN>;
chomp($interro);
push(@interros,$interro);
push(@tablequestion,[]);
push(@table,[]);
push(@points,[]);
foreach my $key (keys %corr_nom) {
push(@{ $corr_nom{$key} }, "Absent" );
}
}
sub ajout_eleve {
print "Nom\n";
my $nom = <STDIN>;
chomp($nom);
print "Prénom\n";
my $prenom = <STDIN>;
chomp($prenom);
$corr_nom{$prenom."\n".$nom} = ();
for my $i (0..$#interros) {
push(@{ $corr_nom{$prenom."\n".$nom} }, "Absent" );
}
}
sub definir_exos {
my $interro = shift;
my $nbexos = "a";
while($nbexos =~ m/\D/) {
print "Nombre d'exercices\n";
$nbexos = <STDIN>;
chomp($nbexos);
if($nbexos =~ /\D/) {
print "Mauvaise entrée\n";
}
}
if($nbexos == "") {
$nbexos = 0;
}
push(@{ $table[$interro] }, $nbexos);
if($nbexos == 0) {
push(@{ $tablequestion[$interro] }, "");
}
for(my $i = 1; $i <= $nbexos; $i++) {
my $questions = "a";
while($questions =~ m/\D/) {
print "Nombre de questions dans l'exercice ",$i,"\n";
$questions = <STDIN>;
chomp($questions);
if($questions =~ /\D/) {
print "Mauvaise entrée\n";
}
}
if($questions eq "") {
$questions = 0;
}
if($questions > 1) {
push(@{ $table[$interro] }, $questions);
for(my $j = 1; $j <= $questions; $j++) {
my $ssquestions = "a";
while($ssquestions =~ m/\D/) {
print "Nombre de sous-questions dans la question ",$i,".",$j,"\n";
$ssquestions = <STDIN>;
chomp($ssquestions);
if($ssquestions =~ /\D/) {
print "Mauvaise entrée\n";
}
}
if($ssquestions eq "") {
$ssquestions = 0;
}
if($ssquestions > 1) {
push(@{ $table[$interro] }, $j.".".$ssquestions);
for(my $k = 1; $k<= $ssquestions; $k++) {
push(@{ $tablequestion[$interro] }, $i.".".$j.".".$k);
}
}
else {
push(@{ $tablequestion[$interro] }, $i.".".$j);
}
}
}
else {
push(@{ $tablequestion[$interro] }, $i);
}
}
}
sub entrer_notes {
my $interro = shift;
my $eleve = shift;
my @boucle;
if($eleve) {
@boucle = ($eleve);
}
else {
@boucle = sort sort_alpha keys %corr_nom;
}
foreach my $key (@boucle) {
my $keyt = $key;
$keyt =~ s/\n/ /;
print $keyt." (mettre A pour indiquer une absence)\n";
my @int;
if(ref($corr_nom{$key}[$interro]) eq 'ARRAY') {
@int = @{$corr_nom{$key}[$interro]};
}
$corr_nom{$key}[$interro] = ();
Interro: for my $i (0..$#{$tablequestion[$interro]}) {
my $pourcentage = "a";
my $def = 0;
if(!@int && $i == 0) {
$def = "A";
}
if(scalar(@int) > 0) {
$def = $int[$i];
}
while($pourcentage =~ m/\D/ || $pourcentage > 100) {
if($tablequestion[$interro][$i] =~ m/\D/ ) {
print "Pourcentage pour la question ".$tablequestion[$interro][$i]." [".$def."]\n";
}
else {
print "Pourcentage pour l'exercice ".$tablequestion[$interro][$i]." [".$def."]\n";
}
$pourcentage = <STDIN>;
chomp($pourcentage);
if($pourcentage eq "") {
$pourcentage = $def;
}
if($pourcentage =~ m/^a$/i) {
$corr_nom{$key}[$interro] = "Absent";
last Interro;
}
if($pourcentage =~ /\D/ || $pourcentage > 100) {
print "Il faut un pourcentage entre 0 et 100\n";
}
}
push(@{ $corr_nom{$key}[$interro] },$pourcentage);
}
}
}
sub entrer_bareme {
my $interro = shift;
foreach my $nomquestion ( @{ $tablequestion[$interro] } ) {
my $point = "a";
while($point =~ /[^\d\.]/) {
if($nomquestion =~ m/\D/ ) {
print "Points pour la question ".$nomquestion."\n";
}
else {
print "Points pour l'exercice ".$nomquestion."\n";
}
$point = <STDIN>;
chomp($point);
if($point =~ /[^\d\.]/) {
print "Il faut donner un nombre de points\n";
}
}
if($point eq "") {
$point = 0;
}
push(@{ $points[$interro] },$point);
}
}
sub sauver {
open FILE, ">".$fichier;
foreach my $i (0..$#table) {
print FILE $interros[$i]."\n";
print FILE "@{ $table[$i] }\n";
print FILE "@{ $tablequestion[$i] }\n";
print FILE "@{ $points[$i] }\n";
}
print FILE "\n";
foreach my $ligne (keys(%corr_nom)) {
print FILE $ligne."\n";
foreach my $lig (@{ $corr_nom{$ligne} }) {
if($lig eq "Absent") {
print FILE "! \n";
}
else {
print FILE "* @$lig\n";
}
}
}
print FILE "\n";
close FILE;
}
sub charger {
open FILE, $fichier;
while(my $int = <FILE>) {
if($int eq "\n") { last };
chomp($int);
push(@interros,$int);
$int = <FILE>;
chomp($int);
push(@table, [ split(/ /, $int) ] );
$int = <FILE>;
chomp($int);
push(@tablequestion, [ split(/ /, $int) ] );
$int = <FILE>;
chomp($int);
push(@points, [ split(/ /, $int) ] );
}
my $int = <FILE>;
while(1) {
if($int eq "\n") { last };
my $intn = <FILE>;
chomp($intn);
my $key = $int.$intn;
$corr_nom{$key} = ();
while($intn = <FILE>) {
if($intn =~ m/^\*/) {
chomp($intn);
push(@{ $corr_nom{$key} }, [ split(/ /, substr($intn,2)) ] );
}
elsif($intn =~ m/^!/) {
push(@{ $corr_nom{$key} }, "Absent" );
}
else {
$int = $intn;
last;
}
}
}
close FILE;
}
sub sort_alpha {
my @p_na = split(/\n/,$a);
my @p_nb = split(/\n/,$b);
return $p_na[1] cmp $p_nb[1] || $p_na[0] cmp $p_nb[0];
}
sub export_latex {
print "Fichier ?\n";
my $f_export = <STDIN>;
chomp($f_export);
if($f_export eq "") { return 0 };
open FILE, ">".$f_export;
print FILE "\\documentclass[landscape]{article}\n";
print FILE "\\usepackage[T1]{fontenc}\n";
print FILE "\\usepackage[utf8]{inputenc}\n";
print FILE "\\usepackage{geometry}\n";
print FILE "\\geometry{margin=1cm}\n";
print FILE "\\begin{document}\n";
for my $interro (0..$#table) {
print FILE "\\begin{tabular}{|l|";
my @exosansq = grep(/^[1-9]\d*$/,@{ $tablequestion[$interro] });
print FILE "c|"x (scalar(@{ $tablequestion[$interro] })+$table[$interro][0] - scalar(@exosansq));
print FILE "|c|}\n";
my @ign = ();
my @pts = ();
my @max = ();
my @min = ();
my @somme = ();
print FILE "\\multicolumn{",(scalar(@{ $tablequestion[$interro] })+$table[$interro][0] - scalar(@exosansq) + 2),"}{c}{\\Large ".$interros[$interro]."}\\\\\n";
if($table[$interro][0] > 0) {
print FILE "\\hline\n\t ";
for(my $i = 1; $i <= $table[$interro][0]; $i++) {
my @b = grep(/^$i/,@{ $tablequestion[$interro] });
if(scalar(@b) == 1) {
print FILE "& Exercice $i ";
}
else {
print FILE "& \\multicolumn{",scalar(@b)+1,"}{c|}{Exercice ",$i,"} ";
}
}
print FILE "& Total ";
print FILE "\\\\\n";
print FILE "\\hline\n\t";
my $rank = -1;
for(my $i = 1; $i <= $table[$interro][0]; $i++) {
my @b = grep(/^$i(\D|$)/,@{ $tablequestion[$interro] });
for(my $j = 1; $j <= scalar(@b); $j++) {
my @c = grep(/^$i\.$j(\D|$)/,@{ $tablequestion[$interro] });
$rank += scalar(@c);
if(scalar(@c) == 1) {
print FILE "& $j) ";
}
elsif(scalar(@c) > 0) {
print FILE "& \\multicolumn{",scalar(@c),"}{c|}{",$j,")} ";
}
elsif($j == 1) {
$rank +=1;
push(@ign,$rank+$i-1);
#print FILE "& ";
}
}
print FILE "& Total ";
push(@pts,$rank);
}
print FILE "& \\\\\n";
}
print FILE "\\hline\n\t";
print FILE "points ";
my $totalexo = 0;
my $total = 0;
my $nq = 0;
for my $i (0.. $#{ $points[$interro] }) {
print FILE "& $points[$interro][$i] ";
push(@min,$points[$interro][$i]);
push(@max,0);
push(@somme,0);
$totalexo += $points[$interro][$i];
$total += $points[$interro][$i];
$nq++;
if((grep {$_ == $i} @pts) > 0) {
if($nq > 1) {
print FILE "& $totalexo ";
}
push(@min,$totalexo);
push(@max,0);
push(@somme,0);
$totalexo = 0;
$nq = 0;
}
}
print FILE "& $total ";
push(@min,$total);
push(@max,0);
push(@somme,0);
print FILE "\\\\\n";
print FILE "\\hline\n\t";
print FILE "\\hline\n\t";
my @sortednotes = sort sort_alpha (keys %corr_nom);
#print "@sortednotes";
#my $somme = 0;
my $nombre_eleves = 0;
for my $i (0.. $#sortednotes) {
my $np = $sortednotes[$i];
$np =~ s/\n/ /;
print FILE $np;
my @ligne = @{ $corr_nom{$sortednotes[$i]} };
if($ligne[$interro] eq "Absent") {
print FILE "& \\multicolumn{",scalar(@{ $tablequestion[$interro] })+$table[$interro][0]+1,"}{c|}{Absent}";
}
else {
my @ligneo = @{ $ligne[$interro] };
my $totalexo = 0;
my $total = 0;
$nombre_eleves++;
my $k = 0;
my $nq = 0;
foreach my $l (0.. $#ligneo ) {
my $val = sprintf("%.0f",4.*$ligneo[$l]*$points[$interro][$l]/100)/4;
print FILE "& ",$val;
if($min[$k] > $val) {
$min[$k] = $val;
}
if($max[$k] < $val) {
$max[$k] = $val;
}
$somme[$k] += $val;
$k++;
$nq++;
$totalexo += $val;
$total += $val;
if((grep {$_ == $l} @pts) > 0) {
if($min[$k] > $totalexo) {
$min[$k] = $totalexo;
}
if($max[$k] < $totalexo) {
$max[$k] = $totalexo;
}
$somme[$k] += $totalexo;
if($nq > 1) {
print FILE "& $totalexo ";
}
$k++;
$totalexo = 0;
$nq = 0;
}
}
print FILE "& $total ";
if($min[$k] > $total) {
$min[$k] = $total;
}
if($max[$k] < $total) {
$max[$k] = $total;
}
$somme[$k] += $total;
$k++;
}
print FILE "\\\\\n";
print FILE "\\hline\n\t";
}
print FILE "\\hline\n\t";
print FILE "Moyenne";
for my $l (0.. $#somme) {
next if((grep {$_ == $l} @ign) > 0);
print FILE "& ".sprintf("%.0f",4.*$somme[$l]/$nombre_eleves)/4;
}
print FILE "\\\\\n";
print FILE "\\hline\n\t";
print FILE "Min";
for my $l (0.. $#min) {
next if((grep {$_ == $l} @ign) > 0);
print FILE "& $min[$l]";
}
print FILE "\\\\\n";
print FILE "\\hline\n\t";
print FILE "Max";
for my $l (0.. $#max) {
next if((grep {$_ == $l} @ign) > 0);
print FILE "& $max[$l]";
}
#print FILE "Moyenne & \\multicolumn{",scalar(@{ $tablequestion[$interro] })+$table[$interro][0],"}{c||}{ }";
#my $moyenne = sprintf("%.0f",4.*$somme/$nombre_eleves)/4;
#print FILE " & $moyenne\\\\\n";
print FILE "\\\\\n";
print FILE "\\hline\n\t";
print FILE "\\end{tabular}\n";
print FILE "\\vfill\n";
print FILE "\\newpage\n";
}
print FILE "\\end{document}\n";
close FILE;
}
sub export_csv {
my $interro = shift;
print "Fichier ?\n";
my $f_export = <STDIN>;
chomp($f_export);
if($f_export eq "") { return 0 };
open FILE, ">".$f_export;
for my $interro (0..$#table) {
print FILE "; ".$interros[$interro]."\n";
my @pts = ();
my @ign = ();
my @max = ();
my @min = ();
my @somme = ();
if($table[$interro][0] > 0) {
for(my $i = 1; $i <= $table[$interro][0]; $i++) {
my @b = grep(/^$i/,@{ $tablequestion[$interro] });
if(scalar(@b) == 1) {
print FILE "; Exercice $i ";
}
else {
print FILE "; Exercice $i","; "x scalar(@b);
}
}
print FILE "; Total \n";
my $rank = -1;
for(my $i = 1; $i <= $table[$interro][0]; $i++) {
my @b = grep(/^$i(\D|$)/,@{ $tablequestion[$interro] });
for(my $j = 1; $j <= scalar(@b); $j++) {
my @c = grep(/^$i\.$j(\D|$)/,@{ $tablequestion[$interro] });
$rank += scalar(@c);
if(scalar(@c) == 1) {
print FILE "; $j) ";
}
elsif(scalar(@c) > 0) {
my $char = "a";
for my $num (0..$#c) {
print FILE "; $j) ".$char.") ";
$char++;
}
#print FILE "; $j) ","; "x (scalar(@c)-1);
}
elsif($j == 1) {
$rank += 1;
push(@ign,$rank+$i-1);
#print FILE "; ";
}
}
print FILE "; Total ";
push(@pts,$rank);
}
print FILE "; \n";
}
print FILE "points ";
my $totalexo = 0;
my $total = 0;
my $nq = 0;
for my $i (0.. $#{ $points[$interro] }) {
print FILE "; $points[$interro][$i] ";
push(@min,$points[$interro][$i]);
push(@max,0);
push(@somme,0);
$totalexo += $points[$interro][$i];
$total += $points[$interro][$i];
$nq++;
if((grep {$_ == $i} @pts) > 0) {
if($nq > 1) {
print FILE "; $totalexo ";
}
push(@min,$totalexo);
push(@max,0);
push(@somme,0);
$totalexo = 0;
$nq = 0;
}
}
print FILE "; $total ";
push(@min,$total);
push(@max,0);
push(@somme,0);
print FILE "\n";
my @sortednotes = sort sort_alpha (keys %corr_nom);
#print "@sortednotes";
#my $somme = 0;
my $nombre_eleves = 0;
for my $i (0.. $#sortednotes) {
my $np = $sortednotes[$i];
$np =~ s/\n/ /;
print FILE $np;
my @ligne = @{ $corr_nom{$sortednotes[$i]} };
if($ligne[$interro] eq "Absent") {
print FILE "; Absent","; "x (scalar(@{ $tablequestion[$interro] })+$table[$interro][0]);
}
else {
my @ligneo = @{ $ligne[$interro] };
my $totalexo = 0;
my $total = 0;
$nombre_eleves++;
my $k = 0;
my $nq = 0;
foreach my $l (0.. $#ligneo ) {
my $val = sprintf("%.0f",4.*$ligneo[$l]*$points[$interro][$l]/100)/4;
print FILE "; ",$val;
if($min[$k] > $val) {
$min[$k] = $val;
}
if($max[$k] < $val) {
$max[$k] = $val;
}
$somme[$k] += $val;
$k++;
$totalexo += $val;
$total += $val;
$nq++;
if((grep {$_ == $l} @pts) > 0) {
if($nq > 1) {
print FILE "; $totalexo ";
}
if($min[$k] > $totalexo) {
$min[$k] = $totalexo;
}
if($max[$k] < $totalexo) {
$max[$k] = $totalexo;
}
$somme[$k] += $totalexo;
$k++;
$totalexo = 0;
$nq = 0;
}
}
print FILE "; $total ";
if($min[$k] > $total) {
$min[$k] = $total;
}
if($max[$k] < $total) {
$max[$k] = $total;
}
$somme[$k] += $total;
$k++;
}
print FILE "\n";
}
print FILE "Moyenne";
for my $l (0.. $#somme) {
next if((grep {$_ == $l} @ign) > 0);
print FILE "; ".sprintf("%.0f",4.*$somme[$l]/$nombre_eleves)/4;
}
print FILE "\n";
print FILE "Min";
for my $l (0.. $#min) {
next if((grep {$_ == $l} @ign) > 0);
print FILE "; $min[$l]";
}
print FILE "\n";
print FILE "Max";
for my $l (0.. $#max) {
next if((grep {$_ == $l} @ign) > 0);
print FILE "; $max[$l]";
}
#print FILE "Moyenne & \\multicolumn{",scalar(@{ $tablequestion[$interro] })+$table[$interro][0],"}{c||}{ }";
#my $moyenne = sprintf("%.0f",4.*$somme/$nombre_eleves)/4;
#print FILE " & $moyenne\\\\\n";
print FILE "\n";
print FILE "\n\n\n";
}
close FILE;
}
if(-e $fichier) {
&charger();
}
sub choisir_interro() {
while(1) {
my $i = 1;
my $var;
my $message = '';
foreach $var ( @interros ) {
$message .= $i++.') '.$var."\n";
}
print $message;
$var = <STDIN>;
chop($var);
if(/\D/ || $var < 1 || $var > $i) {
print "Mauvaise entrée\n";
next;
}
$interro_courante = $var-1;
last;
}
}
sub editer_eleve() {
my $eleve;
while(1) {
open COL, "| column";
my $i = 1;
my @eleves = sort sort_alpha keys(%corr_nom);
foreach my $eleve_l (@eleves) {
my $eleve_lm = $eleve_l;
$eleve_lm =~ s/\n/ /;
print COL $i++.") ".$eleve_lm."\n";
}
print COL $i.") Annuler\n";
close COL;
my $var = <STDIN>;
chop($var);
if(/\D/ || $var < 1 || $var > $i) {
print "Mauvaise entrée\n";
next;
}
elsif( $var == $i ) {
return;
}
$eleve = $eleves[$var-1];
last;
}
my $notes_c = ${$corr_nom{$eleve}}[$interro_courante];
if($notes_c == "Absent") {
print "Absent à ".$interros[$interro_courante]."\n";
}
&entrer_notes($interro_courante,$eleve);
}
sub quitter() {
exit 0;
}
my @actions = ("Ajouter une interro", "Ajouter un élève");
my @actions_f = (\&ajout_interro,
\&ajout_eleve,
\&choisir_interro,
\&editer_eleve,
\&definir_exos,
\&entrer_bareme,
\&entrer_notes,
\&sauver,
\&export_latex,
\&export_csv,
\&quitter,
);
while(1) {
if(scalar(@interros)>0) {
$actions[2] = "Choisir une interro";
$actions[3] = "Éditer les notes d'un élève";
$actions[4] = "Définir les exercices de l'interro";
$actions[5] = "Définir le barême de l'interro";
$actions[6] = "Entrer les notes de l'interro";
$actions[7] = "Sauvegarder";
$actions[8] = "Exporter en LaTeX";
$actions[9] = "Exporter en CSV";
}
my $action;
while(1) {
my $i = 1;
my $var;
my @vart = ( @actions, 'Quitter' );
my $message = 'Interro sélectionnée : '.$interros[$interro_courante]."\n";
foreach $var ( @vart ) {
$message .= $i++.') '.$var."\n";
}
print $message;
$var = <STDIN>;
chop($var);
if(/\D/ || $var < 1 || $var > $i) {
print "Mauvaise entrée\n";
next;
}
$action = $actions_f[$var-1];
last;
}
&{$action}($interro_courante);
}
#&export_latex();