Formulaires

Tout ce qui concerne le langage TeX/LaTeX et ses variantes. Ce langage est utilisable sur le forum via les balises tex.
[participation réservée aux membres inscrits]
Règles du forum
Merci de soigner la rédaction de vos messages et de consulter ce sujet avant de poster. Pensez également à utiliser la fonction recherche du forum.
SB
Utilisateur éprouvé
Utilisateur éprouvé
Messages : 260
Inscription : lundi 07 juillet 2008, 08:15

Formulaires

Message non lu par SB »

Bonjour,

Je suis en mesure de transmettre des exercices à mes élèves sous forme de pdf avec formulaire intégré, le module hyperref fait ça très bien.
Je souhaite pouvoir automatiser énoncés+corrections et j'ai été ravi de voir qu'il existe un module python, PyPDF2 qui est capable de récupérer le formulaire dans le pdf et ses réponses, sous forme de dictionnaire.

En pièce jointe, deux ECM d'"énoncé", que je me suis efforcé de rendre le plus minimal : l'un ok l'autre ko, tous les deux en .tex et la version ok en pdf aussi.
(Pour ceux qui connaissent, ce sont des grilles de sudomaths, et j'ai besoin de pouvoir envoyer une trentaine de grilles)

Premier écueil l'utilisation répétée de macro pour intégrer des cases à remplir le fait saturer, du fait d'une compilation latex->ps->pdf.

Code : Tout sélectionner

! TeX capacity exceeded, sorry [main memory size=3000000].\g@addto@macro ...fter {#1#2}\xdef #1{\the \toks@}\endgroup \end{tabularx}
Cela compile avec pdfllatex ou lualatex, mais en bout de course je n'arrive pas à récupérer les formulaires avec PyPDF2.

J'ai alors fait en sorte, via un traitement en python, de pouvoir générer la trentaine de grilles avec la compilation latex->ps->pdf fichier par fichier, cela fonctionne, mais j'ai une trentaine de fichier que j'aimerais pouvoir fusionner.

Là, deuxième écueil : le module pdfpages fusionne mais je ne peux pas récupérer les formulaires avec PyPDF2.
Je précise que je suis un windowsien qui se soigne : l'outil PDFsam Basic fusionne tout bien comme il faut, mais j'aimerais me dispenser de cette étape manuelle et disposer d'une ligne de commande magique pour que ce soit automatisé du début à la fin.

Voilà, si vous êtes encore là à me lire après tout ça, un petit coup de pouce pour arriver à ce que je souhaite serait fort sympathique de votre part.

Pour résumer : comment fusionner mes trente pdf en préservant les formulaires pour pouvoir être récupérés via PyPDF2 (ou autre pourvu que ce soit du code).
Je suis bien sûr aussi preneur d'autres suggestions pour atteindre mon objectif annoncé au début.

Merci de votre attention.
Pièces jointes
ECM_ko.tex
Cela ne fonctionne plus, il y a un appel de plus à une macro par rapport à la version ok.
(4.73 Kio) Téléchargé 7 fois
ECM_ok.pdf
Le fichier pdf en sortie.
(39.48 Kio) Téléchargé 13 fois
ECM_ok.tex
Le fichier fonctionne.
(4.71 Kio) Téléchargé 9 fois
projetmbc
Utilisateur chevronné
Utilisateur chevronné
Messages : 2035
Inscription : samedi 29 décembre 2007, 00:58

Re: Formulaires

Message non lu par projetmbc »

Bonjour.

Connais-tu AMC ?
SB
Utilisateur éprouvé
Utilisateur éprouvé
Messages : 260
Inscription : lundi 07 juillet 2008, 08:15

Re: Formulaires

Message non lu par SB »

Bonjour projetmbc,

merci pour cette suggestion mais :
- le scan des copies, même automatique, c'est non. J'ai avancé dans la voie exposée avant pour ne plus avoir de papier, ou alors exceptionnellement. Dans le lycée où je suis des ordinateurs portables sont distribués aux élèves de seconde à la rentrée.
- je me souviens avoir galéré il y a une dizaine d'années parce qu'il fallait émuler un autre système d'exploitation.

Merci encore.
MB
Administrateur
Administrateur
Messages : 7768
Inscription : samedi 28 mai 2005, 14:23
Statut actuel : Enseignant

Re: Formulaires

Message non lu par MB »

SB a écrit : samedi 06 août 2022, 15:00 Cela compile avec pdfllatex ou lualatex, mais en bout de course je n'arrive pas à récupérer les formulaires avec PyPDF2.
Bonjour, serait-il possible d'indiquer le code python utilisé pour la récupération afin de pouvoir tester ?
MB. (rejoignez pCloud et bénéficiez de 10Go de stockage en ligne gratuits)
Pas d'aide en message privé. Merci de consulter ce sujet avant de poster votre premier message.
SB
Utilisateur éprouvé
Utilisateur éprouvé
Messages : 260
Inscription : lundi 07 juillet 2008, 08:15

Re: Formulaires

Message non lu par SB »

Bonjour MB,

le voici :

Code : Tout sélectionner

import PyPDF2
f = PyPDF2.PdfFileReader('nom_du_fichier.pdf')
ff = f.getFields()
print(ff)
MB
Administrateur
Administrateur
Messages : 7768
Inscription : samedi 28 mai 2005, 14:23
Statut actuel : Enseignant

Re: Formulaires

Message non lu par MB »

Merci, l'erreur obtenue après compilation lualatex est bien la suivante ?

Code : Tout sélectionner

PyPDF2.errors.PdfReadError: Multiple definitions in dictionary at byte 0x10760 for key /AcroForm
[Edit] En remplaçant PyPDF2.PdfFileReader('nom_du_fichier.pdf') par PyPDF2.PdfFileReader('nom_du_fichier.pdf',strict=False), j'arrive à obtenir un dictionnaire associé au pdf en pièce jointe.

Code : Tout sélectionner

{
'Aa1': {'/T': 'Aa1', '/FT': '/Tx', '/V': '1', '/DV': ''},
'Ab1': {'/T': 'Ab1', '/FT': '/Tx', '/V': '2', '/DV': ''},
'Ac1': {'/T': 'Ac1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ad1': {'/T': 'Ad1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ae1': {'/T': 'Ae1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Af1': {'/T': 'Af1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ag1': {'/T': 'Ag1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ah1': {'/T': 'Ah1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Bb1': {'/T': 'Bb1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Bc1': {'/T': 'Bc1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Be1': {'/T': 'Be1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Bh1': {'/T': 'Bh1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Bi1': {'/T': 'Bi1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ca1': {'/T': 'Ca1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Cb1': {'/T': 'Cb1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Cc1': {'/T': 'Cc1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ce1': {'/T': 'Ce1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ci1': {'/T': 'Ci1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Db1': {'/T': 'Db1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Dd1': {'/T': 'Dd1', '/FT': '/Tx', '/V': '', '/DV': ''},
'De1': {'/T': 'De1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Df1': {'/T': 'Df1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Dg1': {'/T': 'Dg1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Di1': {'/T': 'Di1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Eb1': {'/T': 'Eb1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ec1': {'/T': 'Ec1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ed1': {'/T': 'Ed1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ef1': {'/T': 'Ef1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Eh1': {'/T': 'Eh1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ei1': {'/T': 'Ei1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Fa1': {'/T': 'Fa1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Fb1': {'/T': 'Fb1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Fc1': {'/T': 'Fc1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Fe1': {'/T': 'Fe1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ff1': {'/T': 'Ff1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Fh1': {'/T': 'Fh1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Fi1': {'/T': 'Fi1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ga1': {'/T': 'Ga1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Gb1': {'/T': 'Gb1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Gc1': {'/T': 'Gc1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ge1': {'/T': 'Ge1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Gg1': {'/T': 'Gg1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Gh1': {'/T': 'Gh1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Hb1': {'/T': 'Hb1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Hf1': {'/T': 'Hf1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Hh1': {'/T': 'Hh1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ia1': {'/T': 'Ia1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ib1': {'/T': 'Ib1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ic1': {'/T': 'Ic1', '/FT': '/Tx', '/V': '', '/DV': ''},
'If1': {'/T': 'If1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ig1': {'/T': 'Ig1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ih1': {'/T': 'Ih1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ii1': {'/T': 'Ii1', '/FT': '/Tx', '/V': '', '/DV': ''},
'Aa2': {'/T': 'Aa2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ac2': {'/T': 'Ac2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ag2': {'/T': 'Ag2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ah2': {'/T': 'Ah2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ai2': {'/T': 'Ai2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ba2': {'/T': 'Ba2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Bb2': {'/T': 'Bb2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Bd2': {'/T': 'Bd2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Bf2': {'/T': 'Bf2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Bg2': {'/T': 'Bg2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Bh2': {'/T': 'Bh2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ca2': {'/T': 'Ca2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Cb2': {'/T': 'Cb2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Cc2': {'/T': 'Cc2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Cd2': {'/T': 'Cd2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ce2': {'/T': 'Ce2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Cf2': {'/T': 'Cf2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Cg2': {'/T': 'Cg2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ci2': {'/T': 'Ci2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Da2': {'/T': 'Da2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Db2': {'/T': 'Db2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Dd2': {'/T': 'Dd2', '/FT': '/Tx', '/V': '', '/DV': ''},
'De2': {'/T': 'De2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Df2': {'/T': 'Df2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Dg2': {'/T': 'Dg2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Dh2': {'/T': 'Dh2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Di2': {'/T': 'Di2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ee2': {'/T': 'Ee2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ef2': {'/T': 'Ef2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Eg2': {'/T': 'Eg2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Eh2': {'/T': 'Eh2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ei2': {'/T': 'Ei2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Fa2': {'/T': 'Fa2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Fb2': {'/T': 'Fb2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Fd2': {'/T': 'Fd2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ff2': {'/T': 'Ff2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Fi2': {'/T': 'Fi2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Gb2': {'/T': 'Gb2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Gc2': {'/T': 'Gc2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Gd2': {'/T': 'Gd2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ge2': {'/T': 'Ge2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Gf2': {'/T': 'Gf2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Gh2': {'/T': 'Gh2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ha2': {'/T': 'Ha2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Hc2': {'/T': 'Hc2', '/FT': '/Tx', '/V': '', '/DV': ''},
'He2': {'/T': 'He2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Hg2': {'/T': 'Hg2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ib2': {'/T': 'Ib2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Id2': {'/T': 'Id2', '/FT': '/Tx', '/V': '', '/DV': ''},
'If2': {'/T': 'If2', '/FT': '/Tx', '/V': '', '/DV': ''},
'Ig2': {'/T': 'Ig2', '/FT': '/Tx', '/V': '', '/DV': ''}}
Pièces jointes
ECM_ok_lualatex.pdf
(332.06 Kio) Téléchargé 7 fois
MB. (rejoignez pCloud et bénéficiez de 10Go de stockage en ligne gratuits)
Pas d'aide en message privé. Merci de consulter ce sujet avant de poster votre premier message.
SB
Utilisateur éprouvé
Utilisateur éprouvé
Messages : 260
Inscription : lundi 07 juillet 2008, 08:15

Re: Formulaires

Message non lu par SB »

MB,

J'ai plus de messages d'erreur que ce que vous me demandez de comparer.

J'ai mis en entrée pour python votre fichier pdf obtenu avec lualatex, j'ai essayé aussi avec le fichier que j'obtiens de mon côté.
J'obtiens dans les deux cas une série d'erreurs du type :

Code : Tout sélectionner

Multiple definitions in dictionary at byte 0x11c1e for key /AcroForm
Merci en tout cas.
MB
Administrateur
Administrateur
Messages : 7768
Inscription : samedi 28 mai 2005, 14:23
Statut actuel : Enseignant

Re: Formulaires

Message non lu par MB »

Oui, j'obtiens effectivement cette série de messages, mais avec l'argument strict=False le programme ne s'arrête pas et le dictionnaire est affiché.
MB. (rejoignez pCloud et bénéficiez de 10Go de stockage en ligne gratuits)
Pas d'aide en message privé. Merci de consulter ce sujet avant de poster votre premier message.
SB
Utilisateur éprouvé
Utilisateur éprouvé
Messages : 260
Inscription : lundi 07 juillet 2008, 08:15

Re: Formulaires

Message non lu par SB »

Effectivement, cela fonctionne. Merci MB.
cpierquet
Utilisateur débutant
Utilisateur débutant
Messages : 7
Inscription : dimanche 29 novembre 2020, 21:29
Statut actuel : Enseignant

Re: Formulaires

Message non lu par cpierquet »

J'avais essayé il y a quelques temps de faire des qcms "autocorrectifs' avec des champs pdf à compléter et puis un script python pour récupérer les valeurs des champs et pour compter...

Pour ce que tu veux faire, je pense que tu auras un problème au niveau de la fusion car les champs de ton fichier fusionné vont être redondants, et ce sera problématique pour les récupérer...

Ce que j'avais essayé de faire :
-> garder un pdf par élève (avec le nom stocké dans un champ pdf) ;
-> lancer un script python pour extraire les infos de chaque pdf ;
-> traiter chaque extraction pour corriger/noter.
SB
Utilisateur éprouvé
Utilisateur éprouvé
Messages : 260
Inscription : lundi 07 juillet 2008, 08:15

Re: Formulaires

Message non lu par SB »

Merci cpierquet,

je crois que je vais me diriger vers un fichier nominatif par élève, ainsi je garderai la compilation latex->ps->pdf que je fais depuis toujours et cela ne m'enchante pas d'ignorer des warnings que je ne comprends pas.
Puis je transmettrai une archive qui regroupe le tout : ils ne garderont que le leur et me le renverront complété.
cpierquet
Utilisateur débutant
Utilisateur débutant
Messages : 7
Inscription : dimanche 29 novembre 2020, 21:29
Statut actuel : Enseignant

Re: Formulaires

Message non lu par cpierquet »

Tu ne peux pas leur envoyer un seul fichier (vierge) qu'ils te renverront avec leur nom dans le champ prévu (ça éviterait d'envoyer un pack avec tous les fichiers...) ?
SB
Utilisateur éprouvé
Utilisateur éprouvé
Messages : 260
Inscription : lundi 07 juillet 2008, 08:15

Re: Formulaires

Message non lu par SB »

L'avantage de ces sudomaths (développé par py-maths ou mutuamaths je ne sais plus) c'est qu'on peut faire des énoncés différents pour chaque élève avec le même niveau de difficulté.

Cela ne solutionne pas le problème de la différenciation pédagogique, mais cela m'épargne l'amertume de corriger vingt fois le même Devoir Maison.
Il n'y a pas de rédaction du style "on sait que ..", mais là je voudrais juste pouvoir contrôler, rapidement et surement que mes élèves fournissent un travail le plus régulier possible.