2026-08-08 14:38:26 +02:00
2026-05-01 22:37:32 +02:00
2026-08-08 14:38:26 +02:00
2026-08-08 14:38:26 +02:00
2026-07-09 15:54:36 +02:00
2026-08-08 14:38:26 +02:00
2026-05-14 09:02:09 +02:00
2026-08-08 14:38:26 +02:00
2026-06-06 09:27:48 +02:00
2026-08-08 14:38:26 +02:00
2026-08-08 14:38:26 +02:00
2026-06-06 22:09:00 +02:00
2026-06-06 22:09:00 +02:00
2026-06-06 09:27:48 +02:00
2026-05-14 09:02:09 +02:00
2026-05-14 09:02:09 +02:00
2026-08-08 14:38:26 +02:00

Script

Méta

Quézaco

Ce dépôt contient un certain nombre de script Python que j'utilise pour faire corriger des copies par Gemini.

  1. Les copies sont découpées suivant les labels des questions.
  2. Des requêtes de correction sont faites à Gemini, qui met une note entre 0 et 4 à la question, ajoute des commentaires, et encadre certaines parties de la réponse.
  3. Une version pdf annotée de la copie est générée, faite pour être éditée sur tablette tactile. Le correcteur humain peut modifier la note, supprimer des commentaires de l'IA, ou ajouter des remarques manuscrites.
  4. Ces annotations manuscrites sont lues et recompilées en une version de la copie pour l'élève.

Disclaimer

J'utilise régulièrement cet outil et j'en suis satisfait, mais j'ai fait peu d'efforts pour le rendre universel et simple à l'emploi. Plusieurs parties de mon workflow sont spécifiques à mes représentations internes des sujets d'examens et/ou à mon environment.

L'utilisation de ce système nécessite une familiarité avec python et la ligne de commande unix ; cette familiarité n'est probablement pas suffisante en l'état, mais en théorie il devrait être possible de le faire tourner sur le dossier Example qui contient une copie initiale, les fichiers correspondant au sujet de l'interro, et des examples du rendu final (dans le sous dossier BGnot).

Cette situation s'améliorera peut-être, mais faciliter l'utilisation de ce système n'est pas une priorité.

Requirements

Python

Libraries :

pip install numpy pandas matplotlib pillow pydantic pypdf pdf2image reportlab img2pdf pymupdf ftfy ezodf google

Poppler (for pdf2image)

Accès à Gemini

Il faut créer une clef API pour Gemini (pas facile).

NB : Lors de la création, google offre (offrait ?) 300€ d'utilisation, mais seulement pendant les trois mois à venir.

Puis ajouter GEMINI_API_KEY à l'environnement avec :

export GEMINI_API_KEY=

ou éventuellement, la renseigner directement dans le fichier `config.py`.

Configuration

Copier `default_config.py` en `config.py`. Éventuellement le modifier.

Correction d'un paquet de copies

  1. Créer un fichier names dans le dossier courant, avec les noms/prénoms des élèves, un par ligne
  2. Créer un dossier correspondant à l'évaluation (Interro dans la suite)
  3. Suivre les instructions suivantes

Étapes et Script

Prétraitement de l'énoncé

Dans le dossier de l'évaluation, mettre les fichiers suivants de l'évaluation :

`enonce.pdf`, `enonce.tex`, `correction.tex`.

  • `python gemini_for_enonce.py Interro` or `python gemini_for_enonce.py Interro restart`

    À partir des trois fichiers précédents, se charge de détecter les labels des questions et leur contenu.

    Les questions vont également être regroupées. Par la suite, quand des requêtes de corrections seront effectuées sur une question, seulement les énoncés des questions du groupe seront envoyés (et le corrigé de la question). Il faut donc que chaque groupe contienne si possible le contexte nécessaire pour comprendre la question.

    Une fenêtre s'ouvre pour permettre d'éditer le résultat. Ne pas hésiter à faire des groupes plus gros que les groupes par défaut.

    Après relecture le script génère :

    • un fichier `labels` avec les labels des questions
    • Un dossier `Text` avec le contenu textuel des questions, regroupées.
    • Un dossier `Sol` avec le contenu textuel du corrigé, question par question.
    • Un dossier `Text2`, qui compile un fichier `.tex` pour chaque question (utilisé pour compiler un rendu pdf du corrigé pour chaque question)
    • Un dossier `Sol2`, qui compile un fichier `.tex` pour chaque correction de chaque question.
    • Un dossier `Persp` avec des instruction de barème pour chaque question.

    Éventuellement : vérifier et modifier les barèmes dans `Persp`.

  • Alternative personnelle : `python enonce_info.py Interro`

Prétraitement des copies

Mettre les copies scannées au format pdf dans Interro.

  1. ./rotate_all.sh Interro (facultatif) Retourne tous les pdf de 180°, si la photocopie a été faite à l'envers.
  2. ./rename_to_copie.sh Interro change le nom des copies en Copie{id}.pdf
  3. python page_splitter.py Interro

    Découpe des copies A3 en pages A4, en retirant les pages vides.

    Pour chaque page double il est possible

    • de garder les deux pages
    • de ne garder qu'une des deux pages.
    • de jeter les deux pages
    • de déplacer la délimitation à droite/gauche

    Fix issues with python page_splitter.py Interro14/Copies/Copie01.pdf

  4. python cutleft.py Interro Découpe la partie gauche des copies, là où il devrait y avoir les labels des exercices/questions. Rerun on a single file with python cutleft.py Interro/Copies/Copie01.pdf

Labelisation et regroupement

Set proxy with export HTTPS_PROXY="http://10.0.0.1:3128"

  1. python gemini_for_labels.py Interro, avec éventuellement --overwrite Fait des requêtes à Gemini pour identifier les labels des questions dans images générées à partir des parties gauches des copies.
  2. python plotting.py Interro

    Permet de vérifier visuellement les labels trouvés.

    • Sous linux, on peut faire e pour ouvrir le fichier .json et l'éditer a la main.
    • Quand un label est manquant, il est possible de cliquer sur l'image, ce qui copie les coordonnées dans le presse papier (sous linux…), puis on peut l'ajouter à la main.
    • Utilisation de `_`, `|…` et `…|` :

      • `|…` n'est pas arrêté verticalement par son type opposé.
      • `…|` est stoppé horizontalement par le `|…` le plus proche.

    Pour modifier une seule copie : python plotting.py Interro/Copies/Copie01.pdf

    It also generates les Copie01.json, à partir des Copie01_01.json

    1. En cas de soucis, (par exemple les pages ne sont pas dans le bon ordre)

      • Réordonner les pages du fichier pdf
      • Rerun python cutleft.py Interro/Copie{id}
      • Rerun python gemini_dir_batching.py Interro/Copie{id} ?? À vérifier, pas sûr que ça marche.
  3. python splitting_int.py Interro Découpe les copies suivant les exercices Peut-être appelé avec une seule copie.
  4. python grouping.py Interro Regroupe les mêmes questions de différentes copies en groupes de tailles raisonnables.

Correction et annotation

Set proxy with export HTTPS_PROXY="http://10.0.0.1:3128"

  1. Il faut créer des persp, pour indication de comment corriger, et relancer enonce_info.py
  2. python correction.py Interro --limit 240 OU python correction.py Interro/Par\ label/Ex\ 2/Group_1.jpg OU python correction.py Interro --overwrite python correction.py Interro --pro-by-label (needs `labels_for_pro`)

    Fais les requêtes de correction à Gemini.

    L'argument limit limite le nombre de requêtes à Gemini Pro (chères), pour une version low cost, passer --limit 0, toutes les requêtes seront sur Gemini Flash.

    Will it resume ? It seems so. Best to wait a bit.

    Pour diminuer le coût, il est possible de batch les requêtes, qui seront alors traitées sous au plus 24h.

    • python correction.py Interro --batch
    • OU python correction.py Interro --batch-from 'Ex 4'
    • python submit_batches.py Interro
    • python batch_status.py
    • python fetch_batched_results.py Interro
    • python correction.py Interro --deal-with-batched
  3. python post-correction.py Interro

    • Essaye de corriger des erreurs d'encodage/d'accents dans correction.json.
    • aussi échappe les `_` en dehors du mode math, pour LaTeX.
  4. Résolution manuel de conflits

    Edit `manual_resolutions.txt`. Use :

    • `->` or `x>` : Here set a pipe `|` before or after the new_label name
    • `-x` : replace the goal
    • `ss` : do nothing
    • `sx` : stay, and remove goal.
    • `xx` : move to goal.
    • `xs` : remove old, keep goal.

    Then call `python resolve_manual.py Interro`

  5. Call `python correction.py Interro refaire`.

Génération des copies annotées

  1. python annotating.py Interro (facultatif) Ajoute les annotations Gemini aux copies, enregistrées dans le dossier Anot. On peut passer l'argument --overwrite.
  2. python annotating_with_checks.py Interro Ajoute les annotations Gemini, et des checkboxes à cocher. Enregistrées dans le dossier Bnot, --overwrite

OU

  1. python annotating_by_label.py Interro dans BGnot Ajoute les annotations Gemini, et des checkboxes, et regroupe les réponses par question. Enregistrées dans BGnot Needs : label_groups file (made automatically by this function), qui dit quelles questions regrouper.
  1. python to_tablette.py Interro (gestion perso) Cela déplace les groupes dans SyncCopies/À Annoter.

    • Les mettre dans le dossier racine de la tablette, et renommer en aaa.
    • Vider Syncthing/Annotées sur la tablette et localement. À automatiser, aussi c'est lent…

Lecture de la correction manuscrite

  1. python from_tablette.py Interro (gestion perso) Before : delete ~/SyncCopies/Annotées, copy or sync from the tablette to here.

Une fois les corrections manuelles appliquées aux fichiers Concat.pdf, il faut enregistrer le fichier annoté au même endroit, sous le nom Concat_annotated.pdf.

(À faire : universaliser to_tablette.py et from_tablette.py)

  1. python reading_annotations.py Interro Lit les Concat_annotated dans Bnot, regénère les copies avec les modifications.

OU

  1. python reading_grouped_annotations.py Interro Idem, mais pour BGnot.
  2. python giving_names.py Interro BGnot

    Crée un dossier A Rendre avec des liens symboliques vers

    • La copie à rendre
    • un fichier score.json qui contient les notes par question

    Si un nom est Unknown : renommer à la main le dossier et le fichier dedans.

  3. On peut faire des changements manuels aux score.json ici, puis

    • `python reading_annotations.py update-score Interro`
    • `python reading_grouped_annotations.py update-score Interro`

    pour mettre à jour les scores dans les images.

  4. (gestion perso)

    • gestion_classe ne pour créer l'interro puis
    • gestion_classe we (set barème here)
    • python update_ods.py Interro ou python update_ods.py Interro --sum (en l'absence de barème)
    • gestion_classe re
    • gestion_classe wsent
    • python add_final_score.py Interro21 (this makes files in Server/copies)
  5. (gestion perso)

    • Deploy miqmacs-copies-assets, and
    • update the copies from miqmacs.fr/admin.
  6. (gestion perso) Impression d'une copie. Via Evince » print to pdf.

Recorrection d'une seule copie (peu testé)

!! Attention, refaire ne marchera pas si tu fais une annotation non groupée into refaire !!

  1. Redécoupage

    • python plotting.py InterroTest/Copie01.pdf
    • python splitting_int.py InterroTest/Copie20.pdf
  2. Créer refaire.json, avec un contenu comme

    [["Copie02", []],
     ["Copie01", ["Ex 1 : 1)"]]]
    
  3. Appeler correction avec refaire. Il doit créer des groupes individuels, faire des requêtes, et remplacer les corrections précédentes (à sauver ailleurs). Ou non, si tu veux le faire à la main.
  4. ?? Si je fais refaire, avant d'avoir créer les annotating with checks, que se passe-t-il ???
  5. Appeler annotating_with_checks.py --refaire --overwrite
  6. python to_tablette.py --refaire Interro24
  7. python from_tablette.py --refaire Interro24
  8. python reading_grouped_annotations.py --refaire Interro24

Exemple de replotting, refaire d'une copie

  1. replot it.
  2. `python splitting_int.py DS09VA/Copies/Copie25.pdf` this will get rid of old/new. !! Attention, et si ça dégage un new : bad bad bad.
  3. Make `refaire.json`, avec la copie, et les labels à refaire.
  4. `python correction.py DS09VA refaire`
  5. `python annotating_with_checks.py DS09VA refaire`
  6. `python from_tablette.py Interro24 refaire`
S
Description
No description provided
Readme
33 MiB
Languages
Python 99.7%
Shell 0.3%