#!/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 = ; 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 = ; chomp($nom); print "Prénom\n"; my $prenom = ; 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 = ; 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 = ; 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 = ; 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 = ; 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 = ; 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 = ) { if($int eq "\n") { last }; chomp($int); push(@interros,$int); $int = ; chomp($int); push(@table, [ split(/ /, $int) ] ); $int = ; chomp($int); push(@tablequestion, [ split(/ /, $int) ] ); $int = ; chomp($int); push(@points, [ split(/ /, $int) ] ); } my $int = ; while(1) { if($int eq "\n") { last }; my $intn = ; chomp($intn); my $key = $int.$intn; $corr_nom{$key} = (); while($intn = ) { 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 = ; 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 = ; 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 = ; 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 = ; 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 = ; 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();