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 utilisateurs 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 : 267
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é 114 fois
ECM_ok.pdf
Le fichier pdf en sortie.
(39.48 Kio) Téléchargé 130 fois
ECM_ok.tex
Le fichier fonctionne.
(4.71 Kio) Téléchargé 118 fois
projetmbc
Utilisateur chevronné
Utilisateur chevronné
Messages : 2238
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 : 267
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 : 8058
Inscription : samedi 28 mai 2005, 14:23
Statut actuel : Enseignant
Contact :

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 : 267
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 : 8058
Inscription : samedi 28 mai 2005, 14:23
Statut actuel : Enseignant
Contact :

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é 109 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 : 267
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 : 8058
Inscription : samedi 28 mai 2005, 14:23
Statut actuel : Enseignant
Contact :

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 : 267
Inscription : lundi 07 juillet 2008, 08:15

Re: Formulaires

Message non lu par SB »

Effectivement, cela fonctionne. Merci MB.
cpierquet
Utilisateur confirmé
Utilisateur confirmé
Messages : 31
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 : 267
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 confirmé
Utilisateur confirmé
Messages : 31
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 : 267
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.
marco56
Utilisateur chevronné
Utilisateur chevronné
Messages : 1136
Inscription : jeudi 25 novembre 2010, 22:10

Re: Formulaires

Message non lu par marco56 »

Bojour,
Pour fusionner mes pdf sous linux (ubuntu), je fais :

Code : Tout sélectionner

        from PyPDF2 import PdfFileReader, PdfFileMerger
        date = time.strftime("%x")
        date = date[0:2]+"-"+date[3:5]+"_"+heure[0:2]
        fichier10_pdf = str(fichier0 + "-" + date + ".pdf")
        liste_pdf=[fichier_bareme,fichier2, fichier1, fichier3, fichier8]
        merger = PdfFileMerger()
        for fich_pdf in liste_pdf:
            merger.append(PdfFileReader(open(fich_pdf+".pdf",'rb')))
        merger.write(fichier10_pdf)
SB
Utilisateur éprouvé
Utilisateur éprouvé
Messages : 267
Inscription : lundi 07 juillet 2008, 08:15

Re: Formulaires

Message non lu par SB »

Merci marco56,

ce n'est pas la fusion de pdf qui me posait problème.

Je suis arrivé à ce que je voulais faire.
Pièces jointes
doc-pdf_tests.zip
fichiers PDF à l'issue des tests
(258.55 Kio) Téléchargé 98 fois
marco56
Utilisateur chevronné
Utilisateur chevronné
Messages : 1136
Inscription : jeudi 25 novembre 2010, 22:10

Re: Formulaires

Message non lu par marco56 »

Du coup, je n'ai pas compris. Si tu souhaites partager ton travail, ce sera avec plaisir, je suis toujours curieux, notamment sur les formulaires.
Une petite remarque en passant : tu devrais éviter les accents, les espaces et caractères dans les noms de fichiers ou répertoires, cela va te jouer des tours un jour ou l'autre.
SB
Utilisateur éprouvé
Utilisateur éprouvé
Messages : 267
Inscription : lundi 07 juillet 2008, 08:15

Re: Formulaires

Message non lu par SB »

marco56,

les histoires d'accent et d'espace a été une des péripéties de mon périple.
En l'état que puis-je partager à part mon contentement ? Sinon ce serait un répertoire avec tout plein de fichiers de différentes sortes.
Il est en pièce jointe. [ah ben non l'archive ne passe pas] :(

Les inputs des sudomaths sont dans 0_CREATION-EC/doc-source/_data_builder : data.csv et data.txt
Souvent quand j'en fais moi même je passe par des fichiers intermédiaires nommés data_builder.[...], ceux-ci ne servent à rien ici.
Il y a aussi le fichier _ input.xls du dossier _ input, qui me permet la sélection des élèves d'une classe (voire groupe).

-> exécution de data_builder.py

On récupère plein de choses dans 0_CREATION-EC/
doc-pdf
output-bin
output-tex

Dans 1_DIFFUSION-E :
-> exécution de data_diffuseur.py
pour récupérer ce qui a été fait dans 0_CREATION-EC, en particulier les documents pour les élèves (2elv)
J'y ai aussi récupéré les inputs (4prf) pour sauvegarde de ce qui a été fait dans 0_CREATION-EC, et, qui sera nécessaire pour les phases prochaines ... non encore stabilisées : collecte+correction le plus automatique possible.

voili voilou
marco56
Utilisateur chevronné
Utilisateur chevronné
Messages : 1136
Inscription : jeudi 25 novembre 2010, 22:10

Re: Formulaires

Message non lu par marco56 »

Ok, merci.
Répondre