A cause des réformes des retraites et des grèves qui ont suivi les examens sur table ont été annulés et ont été reprogrammé sous la forme d’un devoir à la maison.
Je devais donc envoyer mon QCM, élaboré avec auto-multiple-choice, à un grand nombre de candidats. Je ne rentrerai pas ici dans l’intérêt de faire un examen QCM à domicile …
Avant de commencer noter que je suis sous Mac Os X Catalina.
Je fournis ici les scripts Python nécessaires pour :
- Séparer le fichier PDF avec tous les sujets en autant de sujets qu’il y a de candidats
- Envoyer les mails avec mutt (installer avec brew) à tous les candidats avec leurs fichiers en attachés
Mon sujet comporte 4 pages. Les N pdf individuels produits sont redirigés vers un dossier PDFSplitted. Je me suis basé sur cette page pour mon script.
Les noms de mes fichier se nomment : DOC-sujet1.pdf et DOC-sujet2.pdf.
Changer la variable « DOC-« +sujet+ ».pdf » en fonction du nom de votre sujet.
#!/usr/bin/env python
from PyPDF2 import PdfFileWriter, PdfFileReader
from multiprocessing import Pool
import glob, sys
sujet="sujet2"
pdfs = glob.glob("DOC-"+sujet+".pdf")
def process_pdfs(pdf):
inputFile = PdfFileReader(open(pdf, "rb"))
print("Processing %s"% pdf)
for i in range(inputFile.numPages // 4):
output = PdfFileWriter()
output.addPage(inputFile.getPage(i * 4))
output.addPage(inputFile.getPage(i * 4 + 1))
output.addPage(inputFile.getPage(i * 4 + 2))
output.addPage(inputFile.getPage(i * 4 + 3))
newname = sujet + "-" + str(i+1) + ".pdf"
outputStream = open("PDFSplitted/"+newname, "wb")
output.write(outputStream)
outputStream.close()
p = Pool(processes=4)
p.map(process_pdfs, pdfs)
Une fois les sujets produits je vais boucler sur l’ensemble des étudiants pour leur envoyer un mail (avec mutt) avec leur sujets individuels en attaché (il y a 2 sujets au choix).
La liste des étudiants avec leurs mails se trouve dans le fichier Emails-L2-1920.xlsx.
Je parse celui-ci avec xlrd.
import xlrd
import subprocess
import os
def body(*arg):
mail_named="BodyMailStudents/"+str(arg[0]).replace(" ","-")+"-"+str(arg[1]).replace(" ","-")+"-N-"+str(arg[2])+".txt"
fichier = open(mail_named, "w")
temp=("Bonjour "+ str(arg[0])+ " " +str(arg[1]) + ",\n\n"\
+"\t veuillez trouver en attaché de ce mail le sujet d'examen: MÉTHODES STATISTIQUES - PY03E300.\n"+\
"Votre sujet n° " + str(arg[2]) +" est associé à votre numéro d'étudiant " + str(int(arg[3])) +".\n"\
"Imprimez dans la mesure du possible votre copie en recto verso. Ne remplissez QUE L'UN DE CES DEUX SUJETS ET PAS UN AUTRE.\n"
"Les copies doivent être rendues en mains propres à la scolarité entre le lundi 27 janvier\n"+\
"et le jeudi 30 janvier en vous munissant de votre carte d’étudiant pour signer la feuille d’émargement.\n"\
"Bon courage.\n\n"\
"\n\t\t\t\t Cordialement,\n"\
"\t\t\t\t\t Olivier Dadoun\n\n ")
fichier.write(temp)
fichier.close()
print(temp)
return mail_named
if __name__ == '__main__':
list_students="Emails-L2-1920.xlsx"
wb = xlrd.open_workbook(list_students,encoding_override="utf_16_le")
print(wb.sheet_names())
sh = wb.sheet_by_name('Feuil3')
num_etu = sh.col_values(0)
nom_pat_etu = sh.col_values(1)
prenom_etu = sh.col_values(2)
mail_etu = sh.col_values(3)
#list_pas_envoye=[18,30,40,41,44,45,51,56,57,100,101,102,103,109,115,119,128,158]
for i in range(1,len(num_etu)):
#for i in list_pas_envoye:
file_body=body(nom_pat_etu[i],prenom_etu[i],i,num_etu[i])
files_attached1="\"PDFSplitted/sujet1-"+str(i)+".pdf\""
files_attached2=files_attached1+" \"PDFSplitted/sujet2-"+str(i)+".pdf\""
#mail="vous-aurez-pas-mon-mail@gmail.com"
mail=mail_etu[i]
mailcc="ni-celui-ci@gmail.com"
bash_command="mutt -s \"Sujets d'examen MÉTHODES STATISTIQUES - PY03E300 \" " + mail + " -c " + mailcc + " -a " + str(files_attached2) + " -- < " + str(file_body)
os.system(bash_command)
print(bash_command)
os.system("sleep 2")
wb.release_resources()
Si pour une raison inconnue l’étudiant n'a pas reçu son sujet on peut lui renvoyer car le corps du mail a été sauvé dans un fichier qui se trouve dans le dossier BodyMailStudents/.
Si cette erreur apparait avec votre pdf
PyPDF2.utils.PdfReadError: Multiple definitions in dictionary at byte 0x9af9 for key /AcroForm
Remplacer
inputFile= PdfFileReader(open(pdf, "rb"))
par
inputFile= PdfFileReader(open(pdf, "rb"),strict=False)
4 réponses à Envoie de sujets par mail avec AMC ?