master
Pascal LAFOURCADE 4 years ago
parent 346b8b25f0
commit 49964ce786

@ -0,0 +1,135 @@
% -*- coding: utf-8; -*-
\documentclass[a4paper,12pt]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[french,british]{babel}
%%%%%%%%% Gestion de la correction
\usepackage{ifthen}
\usepackage{framed}
\usepackage{environ}
\usepackage{xcolor}
\colorlet{shadecolor}{gray!10!red!5}
\ifdefined\iscorrec % Définition depuis le script d'appel
\else
\def\iscorrec{1} % 0=> sujet, 1=>corrigé
\fi
%%% \begin{correction}....\end{correction}
% le contenu ne s'affiche que si \iscorrec=1
\NewEnviron{correction}{\ifthenelse{\iscorrec=1}{%
\medskip\medskip\par\begin{shaded}\noindent{\bf Solution:} \BODY \end{shaded}
}{}}
%%%%%%%%% Paramètres individuels du sujet
%%% Valeurs par défaut (pour une compilation isolée)
\ifdefined\assignedparameters\else
\def\assignedparameters{1,1,1,1} % dans cet exemple, 4 paramètres requis
\fi
%%% Liste permettant d'accéder aux assignedparameters: \ListAP[1], \ListAP[2], etc.
\usepackage{listofitems}
\ifx\assignedparameters\empty % (erreur de \readlist dans ce cas)
\else
\readlist*\ListAP{\assignedparameters}
\fi
%%% Switch de versions, définie ici "à vide" pour mettre du renewcommand plus tard
\newcommand{\switch}{}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\noindent BUT, 1ère année \hfill 2021-22
\begin{center} \Large Examen de math \end{center}
%%%%%%%%%%%%%%
\subsection*{Exercice 1}
\def\versionExo{\ListAP[1]}
\ifnum\versionExo=1
MF1
\fi
\ifnum\versionExo=2
PB1
\fi
\ifnum\versionExo=3
FG1
\fi
\ifnum\versionExo=4
PL1
\fi
\subsection*{Exercice 2}
\def\versionExo{\ListAP[2]}
\ifnum\versionExo=1
MF2
\fi
\ifnum\versionExo=2
PB2
\fi
\ifnum\versionExo=3
FG2
\fi
\ifnum\versionExo=4
PL2
\fi
\subsection*{Exercice 3}
\def\versionExo{\ListAP[3]}
\ifnum\versionExo=1
MF3
\fi
\ifnum\versionExo=2
PB3
\fi
\ifnum\versionExo=3
FG3
\fi
\ifnum\versionExo=4
PL3
\fi
\subsection*{Exercice 4}
\def\versionExo{\ListAP[4]}
\ifnum\versionExo=1
MF4
\fi
\ifnum\versionExo=2
PB4
\fi
\ifnum\versionExo=3
FG4
\fi
\ifnum\versionExo=4
PL4
\fi
\end{document}

@ -0,0 +1,49 @@
=======================================================================================
Exemple 2 : idem + génération de sujets individualisés avec latex
=======================================================================================
assignation.ods : coordonnées et assignation des sujets pour chaque étudiant
Examen.tex : sources du sujet d'examen (incluant différentes versions possibles + corrections)
GÉNÉRATION DES SUJETS
======================
- Ouvrir un terminal dans ce répertoire, taper 'ruby genere_sujets.rb'
- Lit "assignation.ods", récupère les paramètres de chaque étudiant, et génère son sujet individuel en conséquence, avec pdflatex.
- Les emplacements des sujets, nom de fichier d'assignation, etc, se configurent : ouvrir le fichier genere_sujets.rb avec un éditeur de texte
- Lire les sources dans 'Examen.tex' afin de comprendre le lien entre "assignation.ods" et les variables latex correspondantes
ENVOI DES SUJETS
================
- Ouvrir un terminal dans ce répertoire, taper 'ruby envoie_sujets.rb'
- Fonctionne exactement comme dans l'exemple 1
AIDE À LA CORRECTION
====================
- Fonctionne exactement comme dans l'exemple 1 (les RENDUS ne sont pas remis ici, voir l'exemple 1)
Exécutables requis:
==================
Pour tous les scripts:
- ruby (avec les quelques "gem" requis installés -- a priori ils sont plutôt standard)
- unoconv (version ligne de commande de libreoffice)
Pour la génération basique de sujets:
- pdflatex
Pour l'aide à la correction:
- un navigateur de fichier, lecteur de photos, lecteur de pdf, etc.
- wmctrl (manipulation des fenêtres x11 en ligne de commande) -- optionnel

@ -0,0 +1,197 @@
#!/usr/bin/ruby
# -*- coding: utf-8 -*-
# encoding: utf-8
# Envoi individuel des sujets d'interro + consignes
# Lancement :
# ruby envoie_sujets.rb
# Exécutables nécessaires à installer :
# * unoconv : version 'ligne de commande' de libreoffice.
# Problèmes connus :
# * Classe ou gem ruby manquant : installer le gem correspondant
# --> exemple pour installer le gem 'highline' : sudo gem install highline
# * Erreur de unoconv : "Error: Unable to connect or start own listener. Aborting."
# --> Survient parfois si un fichier .ods est déjà ouvert. Simplement relancer le script.
# Classes et gems ruby nécessaires
#####################################
# pour installer un gem manquant, par exemple le gem 'highline' :
# sudo gem install highline
require 'net/smtp'
require 'mail' # gère tous types de serveurs d'envoi et permet de joindre facilement des fichiers (contrairement à net/smtp où j'ai eu des problèmes).
# https://www.rubydoc.info/github/mikel/mail
# Configuration
#####################################
FileEtud = "assignation.ods"
SujetDir = "Sujets" # emplacement des sujets
NomEnvoi = "Examen.pdf" # nom générique de la pièce jointe à envoyer
ReallySend = true # passer à true pour vraiment procéder à l'envoi
### Paramètres du mail
Who='Pascal Lafourcade'
From='pascal.lafourcade@uca.fr'
MTA='smtp.uca.fr'
Subject="BD P3 -- Sujet Partiel"
InteractivePwd = true
# true -> demande le MDP de la boîte mail lors l'exécution. Plus sécure. Nécessite le gem highline.
# false -> entrer le MDP de la boîte mail en dur, en argument de l'appel. Moins sécure. Ne nécessite pas le gem highline.
# - usage basique dans ce cas : ruby envoie_sujets.rb monmotdepasse
# - permet aussi le scheduling : echo "ruby envoie_sujets.rb monmotdepasse" | at 13h25
require 'highline/import' if InteractivePwd
# Demande de mot de passe pour le serveur mail (fonction)
#####################################
$mail_initialized = false
def initMail
if not $mail_initialized
# récupération du mot de passe
pwd = InteractivePwd ?
ask("Enter your password for connection to the smtp server: ") { |q| q.echo = "*" } :
ARGV[0]
# https://medium.com/derek-gc/sending-emails-in-ruby-with-smtp-3d40bed6c437
Mail.defaults do
delivery_method :smtp, address: MTA, port: 587, password: pwd, authentication: :login, user_name: From
end
$mail_initialized = true
end
end
# Contenu du mail (fonction)
#####################################
def sendMail(adresse,nom,prenom,sujet_pdf)
corps = <<EOF
Bonjour #{prenom} #{nom},
Voici votre sujet individualisé pour le partiel de BD P3. Le sujet est construit à partir d'exercices choisis aléatoirement dont les thématiques contrôlées sont les mêmes pour tous et la difficulté équivalente. En résumé, vous n'aurez pas les mêmes sujets (dommage pour ceux qui pensaient pouvoir échanger, ça ne serait que du temps perdu!)
- La durée du contrôle est de 1h30
- la durée inclut le temps de réflexion, rédaction et dépôt de l'examen.
- Dans le sujet vous allez donc avoir plusieurs exercices. Les solutions seront rédigées à l'aide d'un éditeur de texte.
- La solution de chaque exercice doit être un fichier indépendant nommé EXOn°exo-votreNOM-votrePRENOM-Gn°groupe (exemple EXO1-DUPONT-Pierre-G5).
- Les solutions seront regroupées dans une archive qui sera déposée sur la plateforme Moodle,
Cours: BDD Semestre 2 P3
Section: Dépôt Examen PL/SQL
puis au choix:
Dépôt Exam PL/SQL Groupe 1-2
ou Dépôt Exam PL/SQL Groupe 3-4
ou Dépôt Exam PL/SQL Groupe 5-6
ou Dépôt Exam PL/SQL Groupe 7-8
Vous devez gérer votre temps.
N'hésitez pas à discuter sous TEAMS avec MF. Servajean et F. Glaziou si des questions restent en suspend pendant le partiel.
Bonne journée,
Vos enseignants,
Mmes P. Brigoulet et MF. Servajean,
MM R. Delage, P. Lafourcade et F. Glaziou
Cordialement,
L'équipe enseignante de BD P3
EOF
# Commande d'envoi simplifiée avec le gem Mail
if ReallySend
initMail
Mail.deliver do
#charset='UTF-8' # marche pas ? bref... :(
from From
to adresse
subject Subject
text_part do
content_type "text/plain; charset=utf-8"
body corps
end
add_file :filename => NomEnvoi, :content => File.read(sujet_pdf)
end
else
# simple affichage
puts From
puts adresse
puts Subject
puts corps
end
end
# Lecture du fichier étudiant et envoi des mails
#####################################
### Conversion automatique du fichier ODS (ou XLS) en un fichier CSV
# Options du filtre: voir
# https://wiki.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Filter_Options
ods2csv_command = "unoconv -f csv -e FilterOptions=58,34,76,3,,2060,true,true"
ext = File.extname(FileEtud)
if ext != ".ods" and ext != ".xls"
puts "ERROR. Wrong file format. Only .ods or .xls accepted"
exit(1)
end
csvfile = ".#{File.basename(FileEtud, ext)}.csv"
if not system(ods2csv_command+" -o #{csvfile} #{FileEtud}")
warn "Unoconv conversion error (arrive souvent, relancer simplement le script)"
exit(1)
end
### Lecture des lignes du CSV et envoi
IO.readlines(csvfile).each_with_index { |l, id|
begin # (permet de récupérer la ligne d'un éventuel problème)
data = l.chomp.split(":"); # chomp vire le \n final
# 5 premières colonnes (toujours les mêmes)
grnum = Integer(data.shift()) rescue nil
next unless grnum && grnum >= 0 # Continue uniquement pour les "vraies" lignes, caractérisées par un "vrai" numéro de groupe en 1ère colonne (entir poitif).
nom = data.shift().tr('"', '')
prenom = data.shift().tr('"', '')
adresse = data.shift().tr('"', '')
pdfname = data.shift().tr('"', '')
sujet_pdf = "#{SujetDir}/#{pdfname}.pdf"
puts "Envoi à #{nom} #{prenom}"
sendMail(adresse, nom, prenom, sujet_pdf)
rescue Exception => e
puts "ERREUR, pendant le traitement de la ligne #{id+1}, du fichier de notes #{csvfile} :"
puts e.message
print "\n"+e.backtrace.join("\n")+"\n"
exit(1)
end
}
puts "Passer ReallySend à true pour vraiment procéder à l'envoi" unless ReallySend

@ -0,0 +1,104 @@
#!/usr/bin/ruby
# -*- coding: utf-8 -*-
# Génération individuelle des sujets avec pdflatex
# Lancement :
# ruby genere_sujets.rb
# Exécutables nécessaires à installer :
# * unoconv : version 'ligne de commande' de libreoffice.
# Problèmes connus :
# * Classe ou gem ruby manquant : installer le gem correspondant
# --> exemple pour installer le gem 'highline' : sudo gem install highline
# * Erreur de unoconv : "Error: Unable to connect or start own listener. Aborting."
# --> Survient parfois si un fichier .ods est déjà ouvert. Simplement relancer le script.
# Classes et gems ruby nécessaires
#####################################
# pour installer un gem manquant, par exemple le gem 'machin' :
# sudo gem install machin
require 'fileutils'
# Configuration
#####################################
$file = "assignation.ods" # format ods (ou xls)
$source = "Examen.tex"
$sujetdir = "Sujets" # destination des sujets
$correcdir = "Corrigés" # destination des corrigés
$builddir = "build" # destination des fichiers auxiliaires
#$a_generer = [:sujet]
#$a_generer = [:corrige]
$a_generer = [:sujet, :corrige]
# Conversion automatique du fichier ODS (ou XLS) en un fichier (caché) CSV
######################################
# nécesite d'avoir installé unoconv
# Options du filtre: voir
# https://wiki.openoffice.org/wiki/Documentation/DevGuide/Spreadsheets/Filter_Options
ods2csv_command = "unoconv -f csv -e FilterOptions=58,34,76,3,,2060,true,true"
ext = File.extname($file)
if ext != ".ods" and ext != ".xls"
puts "ERROR. Wrong file format. Only .ods or .xls accepted"
exit(1)
end
csvfile = ".#{File.basename($file, ext)}.csv"
if not system(ods2csv_command+" -o #{csvfile} #{$file}")
warn "Unoconv conversion error (arrive souvent, relancer simplement le script)"
exit(1)
end
# Génération des sujets
######################################
puts "Génération des sujets avec PDFLATEX"
IO.readlines(csvfile).each do |l|
data = l.chomp.split(":"); # chomp vire le \n final
# 5 premières colonnes (toujours les mêmes)
grnum = Integer(data.shift()) rescue nil
next unless grnum && grnum >= 0 # Continue uniquement pour les "vraies" lignes, caractérisées par un "vrai" numéro de groupe en 1ère colonne (entier poitif).
nom = data.shift().tr('"', '')
prenom = data.shift().tr('"', '')
adresse = data.shift().tr('"', '')
pdfname = data.shift().tr('"', '')
# Colonnes restantes -> assignedparameters
assignedparameters=data.map{|d| d.tr('"', '')}.join(",")
$a_generer.each do |sujcorr|
case sujcorr
when :sujet
pdfdir = $sujetdir
iscorrec = 0
when :corrige
pdfdir = $correcdir
iscorrec = 1
end
FileUtils.mkdir "#{pdfdir}" if not Dir.exists? "#{pdfdir}"
FileUtils.mkdir "#{$builddir}" if not Dir.exists? "#{$builddir}"
pdflatex_command = "pdflatex -jobname=\"#{pdfname}\" -output-directory #{$builddir} \"\\def\\iscorrec{#{iscorrec}} \\def\\assignedparameters{#{assignedparameters}} \\input{#{$source}}\""
if not system(pdflatex_command)
warn "pdflatex error"
exit(1)
end
FileUtils.mv("#{$builddir}/#{pdfname}.pdf",pdfdir)
FileUtils.rm_r Dir.glob("#{$builddir}/*")
end
end
Loading…
Cancel
Save