# Génération des bulletins en Python Informations internes à destination des développeurs. ## Types de bulletins - Formations classiques - HTML, court, intermédiaire, long - XML (deprecated) - JSON - PDF - Formations BUT - JSON (utilisé par la version HTML) - XML (partiel, deprecated) - PDF - "but court" HTML - "but court" PDF ## Balises décisions de jury pour chaque type ## Organisation A minima, il vous faut créer un module python (fichier .py) qui se définira une classe chargée de générer vos bulletins. Ce fichier doit être placé dans le répertoire `/opt/scodoc/instance/Products/ScoDoc` Il faut aussi l'importer dans `sco_bulletins_generator.py` (voir tout à la fin de ce fichier). Voici un module minimal commenté (le fichier `sco_bulletins_example.py` est fournit avec ScoDoc): ```py """Génération d'un bulletin de note style "Exemple" (commentaire libre ici) """ # Quelques modules [ScoDoc](ScoDoc.md) utiles: from sco_pdf import * import sco_preferences from notes_log import log import sco_bulletins_generator import sco_bulletins_standard class [BulletinGeneratorExample](BulletinGeneratorExample.md)(sco_bulletins_standard.BulletinGeneratorStandard): """Un exemple simple de bulletin de notes en version PDF seulement. Part du bulletin standard et redéfini la partie centrale. """ description = 'exemple (ne pas utiliser)' # la description doit être courte: elle apparait dans le menu de paramétrage supported_formats = [ 'pdf' ] # indique que ce générateur ne peut produire que du PDF (la version web sera donc celle standard de [ScoDoc](ScoDoc.md)) # En général, on veut définir un format de table spécial, sans changer le reste (titre, pied de page). # Si on veut changer le reste, surcharger les méthodes: # .bul_title_pdf(self) : partie haute du bulletin # .bul_part_below(self, format=*) : infos sous la table # .bul_signatures_pdf(self) : signatures def bul_table(self, fmt=*): """Défini la partie centrale de notre bulletin PDF. Doit renvoyer une liste d'objets PLATYPUS """ assert format == 'pdf' # garde fou return [ Paragraph( SU("L'étudiant %(nomprenom)s a une moyenne générale de %(moy_gen)s" % self.infos), self.CellStyle # un style pdf standard ) ] # Déclarer votre classe à ScoDoc sco_bulletins_generator.register_bulletin_class(BulletinGeneratorExample) ``` Si l'on voulait générer aussi du HTML (pour la version web), il suffirait de le déclarer dans la liste `supported_formats` et que la méthode `bul_table()` renvoie une chaîne HTML si le paramètre `fmt` vaut `'html'`. Pour modifier l'en-tête du bulletin PDF (partie au dessus de la table), il faut surcharger la méthode `bul_title_pdf` qui elle aussi renvoie une liste d'objets PLATYPUS: ```py def bul_title_pdf(self): ... ``` De même, les informations placées sous la table principale sont renvoyées par la méthode `gen_part_below`: ```py def gen_part_below(self, format=*): """Génère les informations placées sous la table de notes (absences, appréciations, décisions de jury...) Renvoie: - en HTML: une chaine - en PDF: une liste d'objets platypus """ ... ``` et les signatures (seulement sur le PDF) par `bul_signatures_pdf`. Toutes ces méthodes renvoient des listes d'objets PLATYPUS quelconques. Vous pouvez partir d'un format de bulletin existant et proche de ce que voulez obtenir et définir une sous-classe modifiant (surchargeant) seulement les méthodes qui génèrent les éléments que vous voulez modifier. /!\ Attention: ne pas modifier après coup le nom des classes de générateurs (ici `BulletinGeneratorExample`), car il va être stocké en base de données par ScoDoc. ## Accès aux informations La plupart des informations nécessaires sont accessibles via des attributs de votre instance de générateur que ScoDoc aura positionné avant d'appeler vos méthodes. Notamment: * `self.formsemestre`: l'objet `FormSemestre` * `self.infos`: un (grand) dictionnaire python avec la plupart des informations préparée pour le bulletin à générer (voir plus loin); * `self.version`: indique la version de bulletin demandée par l'utilisateur ("long" ou "short", vous pouvez en faire ce que bon vous semble); ## Le dictionnaire d'informations L'attribut `infos` est un dictionnaire qui contient de très nombreuses informations. il doit être utilisé en **lecture seule** (il est possible que des informations soient partagées entre threads différents, aussi les modifier peut avoir des effets indésirables). . ### Paramètres (préférences) Tous les paramètres du semestre sont accessibles via leur nom. Voir la liste sur la page [NomsPreferences](NomsPreferences.md). Exemple: `infos['SCOLAR_FONT_SIZE']` est un entier, `infos['UnivName']` est le nom de l'université. ### Informations sur l'étudiant #### Identité Type | Nom | Description | Exemple de valeur ----| --- | ---- | --- | string * | etudid | id ScoDoc de l'étudiant | 'EID15219' | string | code_ine | | * string | code_nip | | * string | codepostaldomicile | | '75018' | date_naissance | | * | annee_naissance | | '1947' | domicile | | * | email | | * | lieu_naissance | | * | nationalite | | * | ne | "e" si étudiante, vide sinon | * | nom | | 'FOURIER' | prenom | | 'JOSEPH' | sexe | | 'M.' | nomprenom | | 'M. Joseph Fourier' | paysdomicile | | * | telephone | | * | telephonemobile | | * | telephonemobilestr | | * | telephonestr | | * | typeadresse | | 'domicile' | villedomicile | | * | villelycee | | #### Admission Informations importées dans ScoDoc lors de la création de l'étudiant (import des données d'admission): établissement d'origine, notes de lycée, etc.) Type | Nom | Description | Exemple de valeur ----| --- | ---- | --- | bac | Série de bac | 'S' | specialite | Spécialité de bac | 'SVT' | math | note math antérieure (en terminale ou au bac ou ...) | * | physique | note physique antérieure | * | francais | note francais (au bac en général) | * | anglais | note anglais antérieure | * | annee_bac | année d'obtention du bac | '2010' | nomlycee | | * | codelycee | | * | codepostallycee | | * | qualite | note de qualité du dossier attribuée par le jury d'admission | * | rang | rang de cet établissement dans les voeux du candidat (si applicable) | * | rap | | "Pas d'informations sur les conditions d'admission." | rapporteur | pseudo du collègue chargé de l'examen de ce dossier | * | score | Score calculé pour ce dossier à l'admission | * | commentaire | Commentaire du jury d'admission| * | decision | Décision du jury d'admission | 'ADMIS' | description | Comment l'étudiant a été inscrit | '(creation individuelle)' #### Inscription Type | Nom | Description | Exemple de valeur ----| --- | ---- | --- int | annee | | 2011 string | etatincursem | état (I=inscrit, D=démissionnaire) | 'I' string | inscription | | 'DUT GEII, semestre 1 FI (Mars 2011 - Jul 2011)' string | situation | | 'inscrit en DUT GEII, semestre 1 FI (Mars 2011 - Jul 2011) le 11/09/2011' string | statut | ? | * | descr_inscription | | 'Inscrit le 27/06/2011.' En outre, les attributs `sems`, `cursem` et `ins` apportent des informations sur les semestres auxquels l'étudiant est ou a été inscrit. `etud['sems']`est une liste de dictionnaire représentants les semestres auxquels est ou a été inscrit l'étudiant. #### Parcours et référentiel BUT Type | Nom | Description | Exemple de valeur --------| ---------------------- | ---- | --- string | parcours_titre | titre du parcours | "Cybersécurité" string | parcours_code | code du parcours | "Cyber" string | refcomp_specialite | code spécialité | "RT" string | refcomp_specialite_long| spécialité | "Réseaux et Télécommunications" ### Résultats (notes) de l'étudiant dans le semestre Quelques infos sur les résultats. Le détail des notes est dans la liste `infos['ues']` et ses sous-listes imbriquées (modules, evaluation). Type | Nom | Description | Exemple de valeur ----| --- | ---- | --- string | moy_gen | moyenne générale de l'étudiant dans le semestre | '12.00' string | bonus_sport_culture | bonus appliqué | 0 string | moy_max | moyenne max promo | '12.00' string | moy_min | moyenne min promo | '10.00' string | moy_moy | moyenne des moyennes promo | '11.00' int | nb_inscrits | nombre étudiants du semestre (incluant démissionnaires et défaillants) | 78 int | nb_demissions | nombre de démissions dans le semestre | 3 int | nb_defaillants | nombre de défaillants dans le semestre | 2 int | nbabs | nombre de 1/2 journées d'absences | 0L int | nbabsjust | idem, justifiées | 0L string | rang | classement | '(attente)' string | rang_txt | classement (avec titre) | 'Rang (attente) / 2' list | ues | résultats dans les UE, voir ci-dessous | [ liste de dict ] Chaque élément de la liste `ues` représente les résultats de l'étudiant dans une UE. Type | Nom | Description | Exemple de valeur ----| --- | ---- | --- string | acronyme | | 'UE 1' string | coef_ue_txt | Coefficient (chaîne) | '2' string| cur_moy_ue_txt | Moyenne prise en compte pour cette UE | '12.00' float | max | moyenne max promo | 12.0 float | min | moyenne min promo | 10.0 list | modules | détails notes dans les modules de l'UE | [ liste de dict] list | modules_capitalized | | [] float | moy | | 11.0 string | moy_ue_txt | moyenne étudiant dans UE | '12.00' int | nb_moy | nombre de moyenens calculées dans cette UE (inscrits, sans démissionnaires ni défaillants) | 76 int | numero | rang tri UE | 1 string | titre | | 'Formation Générale' int | type | code type UE | 0 string | ue_code | code dans programme formation | 'UCOD5' string | ue_descr_html | rang ou autre info à afficher | '(attente)/2' string | ue_descr_txt | rang ou autre info à afficher | '(attente)/2' string | ue_id | id interne ScoDoc | 'UE14572' dict | ue_status | statut de l'UE (voir ci-dessous)| { dict } **Statut d'une UE (champ `ue_status`):** Type | Nom | Description | Exemple de valeur ----| --- | ---- | --- float | coef_ue | | 2.0 | coefs_bonus_gen | | [] | cur_coef_ue | | 2.0 | cur_moy_ue | | 12.0 string | expr_diag | infos erreur calcul formule utilisateur | {} bool | is_capitalized | est-elle capitalisée? | False | moy | | 12.0 | nb_missing | | 1 | nb_notes | | 1 | notes_bonus_gen | | [] | sum_coefs | | 2.0 | was_capitalized | | False **Résultats dans un module:** Type | Nom | Description | Exemple de valeur ----| --- | ---- | --- | code | | * | code_html | | * | code_txt | | * | computation_expr | | * | ens | | [] | evaluations | | [] | formsemestre_id | | 'SEM15176' | mat | | {'titre': 'Mathématiques' } | mod_coef_txt | | '2' | mod_descr_txt | | "Module Fondamentaux d'algèbre et de trigonométrie, coef. 2 (Béatrice DUPONT)" | mod_eff | | 2 | mod_moy_txt | | '12.00' | mod_rang | | '(attente)' | mod_rang_txt | | '(attente)/2' | module | | {voir plus loin} | module_id | | 'MOD14576' | moduleimpl_id | | 'MIP15178' | name | | 'Algèbre' | responsable_id | id du responsable | 'dupont' | stats | statistiques sur les notes du module | `{'moy': 9.576, 'nb_missing': 2, 'max': 16.5, 'min': 0.0, 'nb_notes': 39, 'nb_valid_evals': 1}` Le module (tel que décrit dans le programme de la formation) est représenté par: Type | Nom | Description | Exemple de valeur ----| --- | ---- | --- string | titre | | "Fondamentaux d'algèbre et de trigonométrie" string | abbrev | | 'Algèbre' string | code | | 'M1' float | coefficient | | 2.0 | ects | | None | formation_id | | 'FORM14570' | heures_cours | | 0.0 | heures_td | | 30.0 | heures_tp | | 0.0 | matiere_id | | 'MAT14574' | module_id | | 'MOD14576' | numero | | 10 | semestre_id | | 1 | ue_id | | 'UE14572' **Résultat dans une évaluation:** Type | Nom | Description | Exemple de valeur ----| --- | ---- | --- | coef_txt | | '1' | coefficient | | 1.0 | descrheure | | ' ? 08h00' | description | | * | duree | | '2h' | etat | | { voir plus loin } | evaluation_id | | 'EVAL15226' | evaluation_type | | 0 | heure_debut | | '08h00' | heure_fin | | '08h00' | jour | | '01/07/2011' | moduleimpl_id | | 'MIP15178' | name | | 'le 01/07/2011' | nb_abs | | 0 | nb_att | | 0 | nb_inscrits | | 2 | nb_neutre | | 0 | nb_notes | | 2 | note_html | | '12.00' | note_max | | 20.0 | note_txt | | '12.00' | notes | | { voir plus loin } | publish_incomplete | | '0' | visibulletin | | '1' **Etat d'une évaluation:** Le champ `etat` d'une évaluation est un dict donnant des informations sur les résultats de la promo (et des groupes) dans cette évaluation: Type | Nom | Description | Exemple de valeur ----| --- | ---- | --- bool | evalattente | | False bool | evalcomplete | | True | evaluation_id | id interne | 15226 list | gr_incomplets | | [] list | gr_moyennes | | [] list | groups | liste des groupes | {} datetime | last_modif | | datetime string | median | note médianne promo | '11.00' string | moy | note moyenne promo | '11.00' | nb_abs | nb étudiants absents | 0 | nb_att | nb notes en attente | 0 | nb_inscrits | nb inscrits à ce module | 2 | nb_neutre | nb notes neutralisées | 0 | nb_notes | nb notes saisies | 2 `gr_moyennes` est un dict: Type | Nom | Description | Exemple de valeur ----| --- | ---- | --- | gr_median | | '11.00' | gr_moy | | '11.00' | gr_nb_att | | 0 | gr_nb_notes | | 2 | group_id | | 'G24919' | group_name | | None **Notes dans une évaluation:** Le champ `notes` dans une évaluation est un dictionnaire dont les clés sont les `etudids`, et les valeurs des dictionnaires donnant les informations sur la note de l'étudiant dans cette évaluation: Type | Nom | Description | Exemple de valeur ----| --- | ---- | --- string | comment | commentaire saisie note | * datetime | date | date de saisie | string | etudid | | 'EID15214' string | evaluation_id | | 'EVAL15226' string | uid | utilisateur ayant saisi la note | 'admin' float | value | valeur de la note (sur 20) | 10.0 ### Décisions de jury et autres informations Type | Nom | Description | Exemple de valeur ----| --- | ---- | --- | decision_sem | | None ou dict string | decision_jury | décision du jury en clair (présent seulement si décision saisie) | 'Validé' list | appreciations | | [] list | appreciations_list | | [] list | appreciations_txt | | [] string | mention | texte de la mention calculée | 'Très bien' | filigranne | texte en surimpression | 'Provisoire' ## Note: la fonction log Pour la mise au point, il peut être utile de recourir à la bonne vieille fonction log, qui envoie du texte dans le fichier de log courant, normalement `/opt/scodoc-data/log/scodoc.log`. La date et le saut de ligne final sont automatiquement ajoutés. ``` log("toto") ```