From 8d74f8feedfff41c5b1845ea8db0b85e3078aaf6 Mon Sep 17 00:00:00 2001 From: viennet Date: Fri, 1 Jan 2021 18:40:47 +0100 Subject: [PATCH] blackify and some minor fixes --- README.md | 2 +- ZScoUsers.py | 7 +-- csv2rules.py | 0 dutrules.py | 22 +++++++- gen_tables.py | 53 +++++++++-------- html_sco_header.py | 3 +- html_sidebar.py | 3 +- htmlutils.py | 2 +- intervals.py | 100 ++++++++++++++++----------------- notes_cache.py | 2 +- notes_log.py | 2 +- notes_table.py | 46 +++++++-------- pe_avislatex.py | 21 ++++--- pe_jurype.py | 34 +++++------ pe_settag.py | 7 +-- pe_tagtable.py | 4 +- pe_tools.py | 8 +-- pe_view.py | 2 +- sco_abs_notification.py | 15 ++--- sco_apogee_compare.py | 15 ++--- sco_apogee_csv.py | 37 +++++------- sco_archives_etud.py | 24 +++----- sco_bac.py | 2 +- sco_bulletins_legacy.py | 17 ++---- sco_bulletins_signature.py | 3 +- sco_bulletins_ucac.py | 3 +- sco_cache.py | 3 +- sco_dump_db.py | 9 +-- sco_edit_formation.py | 9 +-- sco_edit_matiere.py | 3 +- sco_edit_module.py | 9 +-- sco_edit_ue.py | 13 ++--- sco_edt_cal.py | 12 ++-- sco_etape_apogee.py | 19 ++++--- sco_etape_apogee_view.py | 31 +++++----- sco_excel.py | 3 +- sco_export_results.py | 5 +- sco_find_etud.py | 5 +- sco_formsemestre_validation.py | 15 ++--- sco_import_users.py | 5 +- sco_lycee.py | 6 +- sco_modalites.py | 6 +- sco_page_etud.py | 26 ++++----- sco_pdf.py | 2 +- sco_placement.py | 25 +++++---- sco_poursuite_dut.py | 6 +- sco_saisie_notes.py | 16 ++---- sco_semset.py | 25 ++++----- sco_tag_module.py | 19 +++---- sco_trombino_tours.py | 6 +- sco_ue_external.py | 10 ++-- sco_up_to_date.py | 3 +- scolog.py | 3 +- 53 files changed, 331 insertions(+), 397 deletions(-) mode change 100644 => 100755 csv2rules.py diff --git a/README.md b/README.md index 2d36e41c..b5a53fca 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # SCODOC - gestion de la scolarité -(c) Emmanuel Viennet 1999 - 2020 (voir LICENCE.txt) +(c) Emmanuel Viennet 1999 - 2021 (voir LICENCE.txt) Installation: voir instructions à jour sur diff --git a/ZScoUsers.py b/ZScoUsers.py index 241a769d..3d435335 100644 --- a/ZScoUsers.py +++ b/ZScoUsers.py @@ -277,7 +277,7 @@ class ZScoUsers( def user_info(self, user_name=None, user=None): """Donne infos sur l'utilisateur (qui peut ne pas etre dans notre base). - Si user_name est specifie, interroge la BD. Sinon, user doit etre un dict. + Si user_name est specifie, interroge la BD. Sinon, user doit etre un dict. """ if user_name: infos = self._user_list(args={"user_name": user_name}) @@ -919,7 +919,7 @@ class ZScoUsers( self, edit, user_name="", nom="", prenom="", email="", roles=[] ): """Vérifie que et utilisateur peut etre crée (edit=0) ou modifié (edit=1) - Cherche homonymes. + Cherche homonymes. returns (ok, msg) - ok : si vrai, peut continuer avec ces parametres (si ok est faux, l'utilisateur peut quand même forcer la creation) @@ -1252,8 +1252,7 @@ class ZScoUsers( security.declareProtected(ScoView, "get_user_name_from_nomplogin") def get_user_name_from_nomplogin(self, nomplogin): - """Returns user_name (login) from nomplogin - """ + """Returns user_name (login) from nomplogin""" m = re.match(r".*\((.*)\)", nomplogin.strip()) if m: return m.group(1) diff --git a/csv2rules.py b/csv2rules.py old mode 100644 new mode 100755 diff --git a/dutrules.py b/dutrules.py index e0c37115..9e524058 100644 --- a/dutrules.py +++ b/dutrules.py @@ -4,7 +4,27 @@ # # Command: ./csv2rules.py misc/parcoursDUT.csv # -from sco_codes_parcours import * +from sco_codes_parcours import ( + DUTRule, + ADC, + ADJ, + ADM, + AJ, + ALL, + ATB, + ATJ, + ATT, + CMP, + NAR, + NEXT, + RA_OR_NEXT, + RA_OR_RS, + RAT, + REO, + REDOANNEE, + REDOSEM, + RS_OR_NEXT, +) rules_source_file = "misc/parcoursDUT.csv" diff --git a/gen_tables.py b/gen_tables.py index 1ee16ebf..c1a84d18 100644 --- a/gen_tables.py +++ b/gen_tables.py @@ -45,9 +45,20 @@ from collections import OrderedDict # XML generation package (apt-get install jaxml) import jaxml +import json +from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Frame, PageBreak +from reportlab.platypus import Table, TableStyle, Image, KeepInFrame +from reportlab.lib.colors import Color +from reportlab.lib import styles +from reportlab.lib.units import inch, cm, mm +from reportlab.rl_config import defaultPageSize # pylint: disable=no-name-in-module + +import sco_utils as scu import sco_excel -from sco_pdf import * +import sco_pdf +from sco_pdf import SU +from notes_log import log def mark_paras(L, tags): @@ -280,7 +291,7 @@ class GenTable: if not row: return "" # empty row - if self.html_col_width: # XXXX Obsolete ? + if self.html_col_width: std = ' style="width:%s;"' % self.html_col_width else: std = "" @@ -382,10 +393,6 @@ class GenTable: else: cls = "" - if self.html_col_width: - std = ' style="width:%s;"' % self.html_col_width - else: - std = "" H = [self.html_before_table, "" % (hid, cls)] line_num = 0 @@ -438,14 +445,14 @@ class GenTable: if self.xls_link: H.append( ' %s' - % (self.base_url, ICON_XLS) + % (self.base_url, scu.ICON_XLS) ) if self.xls_link and self.pdf_link: H.append("  ") if self.pdf_link: H.append( ' %s' - % (self.base_url, ICON_PDF) + % (self.base_url, scu.ICON_PDF) ) H.append("

") @@ -483,10 +490,10 @@ class GenTable: "PDF representation: returns a ReportLab's platypus Table instance" r = [] try: - PDFLOCK.acquire() + sco_pdf.PDFLOCK.acquire() r = self._pdf() finally: - PDFLOCK.release() + sco_pdf.PDFLOCK.release() return r def _pdf(self): @@ -513,7 +520,7 @@ class GenTable: CellStyle.leading = 1.0 * self.preferences["SCOLAR_FONT_SIZE"] # vertical space LINEWIDTH = 0.5 # - titles = ["%s" % x for x in self.get_titles_list()] + # titles = ["%s" % x for x in self.get_titles_list()] pdf_style_list = [] Pt = [ [Paragraph(SU(str(x)), CellStyle) for x in line] @@ -530,10 +537,10 @@ class GenTable: # log('len(Pt)=%s' % len(Pt)) # log( 'line lens=%s' % [ len(x) for x in Pt ] ) # log( 'style=\n%s' % pdf_style_list) - col_min = min([x[1][0] for x in pdf_style_list]) - col_max = max([x[2][0] for x in pdf_style_list]) - lin_min = min([x[1][1] for x in pdf_style_list]) - lin_max = max([x[2][1] for x in pdf_style_list]) + # col_min = min([x[1][0] for x in pdf_style_list]) + # col_max = max([x[2][0] for x in pdf_style_list]) + # lin_min = min([x[1][1] for x in pdf_style_list]) + # lin_max = max([x[2][1] for x in pdf_style_list]) # log('col_min=%s col_max=%s lin_min=%s lin_max=%s' % (col_min, col_max, lin_min, lin_max)) T = Table(Pt, repeatRows=1, colWidths=self.pdf_col_widths, style=pdf_style_list) @@ -559,7 +566,7 @@ class GenTable: The tag names and can be changed using xml_outer_tag and xml_row_tag """ - doc = jaxml.XML_document(encoding=SCO_ENCODING) + doc = jaxml.XML_document(encoding=scu.SCO_ENCODING) getattr(doc, self.xml_outer_tag)( id=self.table_id, origin=self.origin or "", caption=self.caption or "" ) @@ -593,7 +600,7 @@ class GenTable: v = str(v) r[cid] = v d.append(r) - return json.dumps(d, encoding=SCO_ENCODING) + return json.dumps(d, encoding=scu.SCO_ENCODING) def make_page( self, @@ -637,11 +644,11 @@ class GenTable: return "\n".join(H) elif format == "pdf": objects = self.pdf() - doc = pdf_basic_page( + doc = sco_pdf.pdf_basic_page( objects, title=title, preferences=self.preferences, context=context ) if publish: - return sendPDFFile(REQUEST, doc, filename + ".pdf") + return scu.sendPDFFile(REQUEST, doc, filename + ".pdf") else: return doc elif format == "xls": @@ -653,16 +660,16 @@ class GenTable: elif format == "text": return self.text() elif format == "csv": - return sendCSVFile(REQUEST, self.text(), filename + ".csv") + return scu.sendCSVFile(REQUEST, self.text(), filename + ".csv") elif format == "xml": xml = self.xml() if REQUEST and publish: - REQUEST.RESPONSE.setHeader("content-type", XML_MIMETYPE) + REQUEST.RESPONSE.setHeader("content-type", scu.XML_MIMETYPE) return xml elif format == "json": js = self.json() if REQUEST and publish: - REQUEST.RESPONSE.setHeader("content-type", JSON_MIMETYPE) + REQUEST.RESPONSE.setHeader("content-type", scu.JSON_MIMETYPE) return js else: log("make_page: format=%s" % format) @@ -687,7 +694,7 @@ class SeqGenTable: def excel(self): """Export des genTables dans un unique fichier excel avec plusieurs feuilles tagguées""" book = sco_excel.Workbook() # Le fichier xls en devenir - for (name, gt) in self.genTables.items(): + for (_, gt) in self.genTables.items(): gt.excel(wb=book) # Ecrit dans un fichier excel return book.savetostr() diff --git a/html_sco_header.py b/html_sco_header.py index 2a51e3ea..05ef45f2 100644 --- a/html_sco_header.py +++ b/html_sco_header.py @@ -257,6 +257,5 @@ def sco_header( def sco_footer(context, REQUEST=None): - """Main HTMl pages footer - """ + """Main HTMl pages footer""" return """""" + CUSTOM_HTML_FOOTER + """""" diff --git a/html_sidebar.py b/html_sidebar.py index 797aca41..ea05e71c 100644 --- a/html_sidebar.py +++ b/html_sidebar.py @@ -158,8 +158,7 @@ def sidebar(context, REQUEST=None): def sidebar_dept(context, REQUEST=None): - """Partie supérieure de la marge de gauche - """ + """Partie supérieure de la marge de gauche""" infos = { "BASE0": REQUEST.BASE0, "DeptIntranetTitle": context.get_preference("DeptIntranetTitle"), diff --git a/htmlutils.py b/htmlutils.py index 61fe9eaa..70ff837c 100644 --- a/htmlutils.py +++ b/htmlutils.py @@ -49,7 +49,7 @@ def histogram_notes(notes): "HTML code drawing histogram" if not notes: return "" - bins, H = listhistogram.ListHistogram(notes, 21, minmax=(0, 20)) + _, H = listhistogram.ListHistogram(notes, 21, minmax=(0, 20)) D = ['
    • '] left = 5 colwidth = 16 # must match #q-graph li.bar width in stylesheet diff --git a/intervals.py b/intervals.py index f7ac47d0..74140c0a 100644 --- a/intervals.py +++ b/intervals.py @@ -10,53 +10,53 @@ from itertools import izip class intervalmap(object): """ - This class maps a set of intervals to a set of values. - - >>> i = intervalmap() - >>> i[0:5] = '0-5' - >>> i[8:12] = '8-12' - >>> print i[2] - 0-5 - >>> print i[10] - 8-12 - >>> print repr(i[-1]) - None - >>> print repr(i[17]) - None - >>> i[4:9] = '4-9' - >>> print [(j,i[j]) for j in range(6)] - [(0, '0-5'), (1, '0-5'), (2, '0-5'), (3, '0-5'), (4, '4-9'), (5, '4-9')] - >>> print list(i.items()) - [((0, 4), '0-5'), ((4, 9), '4-9'), ((9, 12), '8-12')] - >>> i[:0] = 'less than 0' - >>> i[-5] - 'less than 0' - >>> i[0] - '0-5' - >>> print list(i.items()) - [((None, 0), 'less than 0'), ((0, 4), '0-5'), ((4, 9), '4-9'), ((9, 12), '8-12')] - >>> i[21:] = 'more than twenty' - >>> i[42] - 'more than twenty' - >>> i[10.5:15.5] = '10.5-15.5' - >>> i[11.5] - '10.5-15.5' - >>> i[0.5] - '0-5' - >>> print list(i.items()) - [((None, 0),... ((9, 10.5), '8-12'), ((10.5, 15.5), '10.5-15.5'), ((21, None),... - >>> i = intervalmap() - >>> i[0:2] = 1 - >>> i[2:8] = 2 - >>> i[4:] = 3 - >>> i[5:6] = 4 - >>> i - {[0, 2] => 1, [2, 4] => 2, [4, 5] => 3, [5, 6] => 4, [6, None] => 3} + This class maps a set of intervals to a set of values. + + >>> i = intervalmap() + >>> i[0:5] = '0-5' + >>> i[8:12] = '8-12' + >>> print i[2] + 0-5 + >>> print i[10] + 8-12 + >>> print repr(i[-1]) + None + >>> print repr(i[17]) + None + >>> i[4:9] = '4-9' + >>> print [(j,i[j]) for j in range(6)] + [(0, '0-5'), (1, '0-5'), (2, '0-5'), (3, '0-5'), (4, '4-9'), (5, '4-9')] + >>> print list(i.items()) + [((0, 4), '0-5'), ((4, 9), '4-9'), ((9, 12), '8-12')] + >>> i[:0] = 'less than 0' + >>> i[-5] + 'less than 0' + >>> i[0] + '0-5' + >>> print list(i.items()) + [((None, 0), 'less than 0'), ((0, 4), '0-5'), ((4, 9), '4-9'), ((9, 12), '8-12')] + >>> i[21:] = 'more than twenty' + >>> i[42] + 'more than twenty' + >>> i[10.5:15.5] = '10.5-15.5' + >>> i[11.5] + '10.5-15.5' + >>> i[0.5] + '0-5' + >>> print list(i.items()) + [((None, 0),... ((9, 10.5), '8-12'), ((10.5, 15.5), '10.5-15.5'), ((21, None),... + >>> i = intervalmap() + >>> i[0:2] = 1 + >>> i[2:8] = 2 + >>> i[4:] = 3 + >>> i[5:6] = 4 + >>> i + {[0, 2] => 1, [2, 4] => 2, [4, 5] => 3, [5, 6] => 4, [6, None] => 3} """ def __init__(self): """ - Initializes an empty intervalmap. + Initializes an empty intervalmap. """ self._bounds = [] self._items = [] @@ -64,7 +64,7 @@ class intervalmap(object): def __setitem__(self, _slice, _value): """ - Sets an interval mapping. + Sets an interval mapping. """ assert isinstance(_slice, slice), "The key must be a slice object" @@ -112,7 +112,7 @@ class intervalmap(object): def __getitem__(self, _point): """ - Gets a value from the mapping. + Gets a value from the mapping. """ assert not isinstance(_point, slice), "The key cannot be a slice object" @@ -124,9 +124,9 @@ class intervalmap(object): def items(self): """ - Returns an iterator with each item being - ((low_bound,high_bound), value). The items are returned - in order. + Returns an iterator with each item being + ((low_bound,high_bound), value). The items are returned + in order. """ previous_bound = None for b, v in izip(self._bounds, self._items): @@ -138,8 +138,8 @@ class intervalmap(object): def values(self): """ - Returns an iterator with each item being a stored value. The items - are returned in order. + Returns an iterator with each item being a stored value. The items + are returned in order. """ for v in self._items: if v is not None: diff --git a/notes_cache.py b/notes_cache.py index b53a7873..ef4c8b30 100644 --- a/notes_cache.py +++ b/notes_cache.py @@ -61,5 +61,5 @@ class CacheFunc: def inval_cache(self): # > "clear whole cache" - log("inval_cache %s(%s)" % (str(self.func), str(args))) # > + log("inval_cache %s" % (str(self.func))) # > self.cache = {} diff --git a/notes_log.py b/notes_log.py index 03583375..de2d4619 100644 --- a/notes_log.py +++ b/notes_log.py @@ -88,7 +88,7 @@ def retreive_dept(): return "" try: url = REQUEST.URL - m = re.match("^.*ScoDoc/(\w+).*$", url) + m = re.match(r"^.*ScoDoc/(\w+).*$", url) return m.group(1) except: return "" diff --git a/notes_table.py b/notes_table.py index 9c2c1b3e..82613e8a 100644 --- a/notes_table.py +++ b/notes_table.py @@ -51,7 +51,7 @@ BONUS_TWO_ARGS = len(inspect.getargspec(CONFIG.compute_bonus)[0]) == 2 def comp_ranks(T): - """Calcul rangs à partir d'une liste ordonnée de tuples [ (valeur, ..., etudid) ] + """Calcul rangs à partir d'une liste ordonnée de tuples [ (valeur, ..., etudid) ] (valeur est une note numérique), en tenant compte des ex-aequos Le resultat est: { etudid : rang } où rang est une chaine decrivant le rang """ @@ -135,8 +135,8 @@ class NotesTable: - inscrlist: étudiants inscrits à ce semestre, par ordre alphabétique (avec demissions) - identdict: { etudid : ident } - sem : le formsemestre - get_table_moyennes_triees: [ (moy_gen, moy_ue1, moy_ue2, ... moy_ues, moy_mod1, ..., moy_modn, etudid) ] - (où toutes les valeurs sont soit des nombrs soit des chaines spéciales comme 'NA', 'NI'), + get_table_moyennes_triees: [ (moy_gen, moy_ue1, moy_ue2, ... moy_ues, moy_mod1, ..., moy_modn, etudid) ] + (où toutes les valeurs sont soit des nombrs soit des chaines spéciales comme 'NA', 'NI'), incluant les UE de sport - bonus[etudid] : valeur du bonus "sport". @@ -145,7 +145,7 @@ class NotesTable: - _modmoys : { moduleimpl_id : { etudid: note_moyenne_dans_ce_module } } - _ues : liste des UE de ce semestre (hors capitalisees) - _matmoys : { matiere_id : { etudid: note moyenne dans cette matiere } } - + """ def __init__(self, context, formsemestre_id): @@ -408,7 +408,7 @@ class NotesTable: def get_ues(self, filter_sport=False, filter_non_inscrit=False, etudid=None): """liste des ue, ordonnée par numero. - Si filter_non_inscrit, retire les UE dans lesquelles l'etudiant n'est + Si filter_non_inscrit, retire les UE dans lesquelles l'etudiant n'est inscrit à aucun module. Si filter_sport, retire les UE de type SPORT """ @@ -580,11 +580,11 @@ class NotesTable: return matmoy.get(etudid, "NA") def comp_etud_moy_ue(self, etudid, ue_id=None, cnx=None): - """Calcule moyenne gen. pour un etudiant dans une UE + """Calcule moyenne gen. pour un etudiant dans une UE Ne prend en compte que les evaluations où toutes les notes sont entrées Return a dict(moy, nb_notes, nb_missing, sum_coefs) Si pas de notes, moy == 'NA' et sum_coefs==0 - Si non inscrit, moy == 'NI' et sum_coefs==0 + Si non inscrit, moy == 'NI' et sum_coefs==0 """ assert ue_id modimpls = self.get_modimpls(ue_id) @@ -608,7 +608,6 @@ class NotesTable: est_inscrit = False # inscrit à l'un des modules de cette UE ? for modimpl in modimpls: - mod_ue_id = modimpl["ue"]["ue_id"] # module ne faisant pas partie d'une UE capitalisee val = self._modmoys[modimpl["moduleimpl_id"]].get(etudid, "NI") # si 'NI', etudiant non inscrit a ce module @@ -711,7 +710,7 @@ class NotesTable: def comp_etud_moy_gen(self, etudid, cnx): """Calcule moyenne gen. pour un etudiant Return a dict: - moy : moyenne générale + moy : moyenne générale nb_notes, nb_missing, sum_coefs ects_pot : (float) nb de crédits ECTS qui seraient validés (sous réserve de validation par le jury), ects_pot_fond: (float) nb d'ECTS issus d'UE fondamentales (non électives) @@ -721,14 +720,14 @@ class NotesTable: 'est_inscrit' : True si étudiant inscrit à au moins un module de cette UE 'moy' : moyenne, avec capitalisation eventuelle 'coef_ue' : coef de l'UE utilisé pour le calcul de la moyenne générale - (la somme des coefs des modules, ou le coef d'UE capitalisée, + (la somme des coefs des modules, ou le coef d'UE capitalisée, ou encore le coef d'UE si l'option use_ue_coefs est active) 'cur_moy_ue' : moyenne de l'UE en cours (sans considérer de capitalisation) 'cur_coef_ue': coefficient de l'UE courante 'is_capitalized' : True|False, 'ects_pot' : (float) nb de crédits ECTS qui seraient validés (sous réserve de validation par le jury), - 'ects_pot_fond': 0. si UE non fondamentale, = ects_pot sinon, - 'ects_pot_pro' : 0 si UE non pro, = ects_pot sinon, + 'ects_pot_fond': 0. si UE non fondamentale, = ects_pot sinon, + 'ects_pot_pro' : 0 si UE non pro, = ects_pot sinon, 'formsemestre_id' : (si capitalisee), 'event_date' : (si capitalisee) } @@ -760,7 +759,6 @@ class NotesTable: sem_ects_pot_pro = 0.0 for ue in self.get_ues(): - ue_id = ue["ue_id"] # - On calcule la moyenne d'UE courante: if not block_computation: mu = self.comp_etud_moy_ue(etudid, ue_id=ue["ue_id"], cnx=cnx) @@ -956,10 +954,10 @@ class NotesTable: Ne considère que les UE ayant des notes (moyenne calculée). (les UE sans notes ne sont pas comptées comme sous la barre) Prend en compte les éventuelles UE capitalisées. - + Pour les parcours habituels, cela revient à vérifier que les moyennes d'UE sont toutes > à leur barre (sauf celles sans notes) - + Pour les parcours non standards (LP2014), cela peut être plus compliqué. Return: True|False, message explicatif @@ -1000,8 +998,7 @@ class NotesTable: ) def get_table_moyennes_dict(self): - """{ etudid : (liste des moyennes) } comme get_table_moyennes_triees - """ + """{ etudid : (liste des moyennes) } comme get_table_moyennes_triees""" D = {} for t in self.T: D[t[-1]] = t @@ -1209,13 +1206,13 @@ class NotesTable: # return sum(c_list) def get_etud_ue_cap_coef(self, etudid, ue, ue_cap, cnx=None): - """Calcule le coefficient d'une UE capitalisée, pour cet étudiant, + """Calcule le coefficient d'une UE capitalisée, pour cet étudiant, injectée dans le semestre courant. ue : ue du semestre courant - + ue_cap = resultat de formsemestre_get_etud_capitalisation - { 'ue_id' (dans le semestre source), + { 'ue_id' (dans le semestre source), 'ue_code', 'moy', 'event_date','formsemestre_id' } """ # log("get_etud_ue_cap_coef\nformsemestre_id='%s'\netudid='%s'\nue=%s\nue_cap=%s\n" % (self.formsemestre_id, etudid, ue, ue_cap)) @@ -1291,8 +1288,7 @@ class NotesTable: return len(cursor.fetchall()) > 0 def get_evaluations_etats(self): # evaluation_list_in_sem - """[ {...evaluation et son etat...} ] - """ + """[ {...evaluation et son etat...} ]""" if self._evaluations_etats is None: self._evaluations_etats = sco_evaluations.do_evaluation_list_in_sem( self.context, self.formsemestre_id @@ -1301,13 +1297,11 @@ class NotesTable: return self._evaluations_etats def get_sem_evaluation_etat_list(self): - """Liste des evaluations de ce semestre, avec leur etat - """ + """Liste des evaluations de ce semestre, avec leur etat""" return self.get_evaluations_etats() def get_mod_evaluation_etat_list(self, moduleimpl_id): - """Liste des évaluations de ce module - """ + """Liste des évaluations de ce module""" return [ e for e in self.get_evaluations_etats() diff --git a/pe_avislatex.py b/pe_avislatex.py index 76d2c76b..d0dce49f 100644 --- a/pe_avislatex.py +++ b/pe_avislatex.py @@ -50,7 +50,7 @@ DONNEE_MANQUANTE = ( # ---------------------------------------------------------------------------------------- def get_code_latex_from_modele(fichier): """Lit le code latex à partir d'un modèle. Renvoie une chaine unicode. - + Le fichier doit contenir le chemin relatif vers le modele : attention pas de vérification du format d'encodage Le fichier doit donc etre enregistré avec le même codage que ScoDoc (utf-8) @@ -85,7 +85,7 @@ def get_tags_latex(code_latex): à la lecture d'un modèle d'avis pe). Ces tags sont répérés par les balises **, débutant et finissant le tag et sont renvoyés sous la forme d'une liste. - + result: liste de chaines unicode """ if code_latex: @@ -144,7 +144,7 @@ def comp_latex_parcourstimeline(etudiant, promo, taille=17): # ---------------------------------------------------------------------------------------- def interprete_tag_latex(tag): - """Découpe les tags latex de la forme S1:groupe:dut:min et renvoie si possible + """Découpe les tags latex de la forme S1:groupe:dut:min et renvoie si possible le résultat sous la forme d'un quadruplet. """ infotag = tag.split(":") @@ -164,7 +164,7 @@ def get_code_latex_avis_etudiant( donnees_etudiant, un_avis_latex, annotationPE, footer_latex, prefs ): """ - Renvoie le code latex permettant de générer l'avis d'un étudiant en utilisant ses + Renvoie le code latex permettant de générer l'avis d'un étudiant en utilisant ses donnees_etudiant contenu dans le dictionnaire de synthèse du jury PE et en suivant un fichier modele donné @@ -228,8 +228,8 @@ def get_code_latex_avis_etudiant( # ---------------------------------------------------------------------------------------- def get_annotation_PE(context, etudid, tag_annotation_pe): - """Renvoie l'annotation PE dans la liste de ces annotations ; - Cette annotation est reconnue par la présence d'un tag **PE** + """Renvoie l'annotation PE dans la liste de ces annotations ; + Cette annotation est reconnue par la présence d'un tag **PE** (cf. context.get_preferences -> pe_tag_annotation_avis_latex). Result: chaine unicode @@ -269,8 +269,8 @@ def get_annotation_PE(context, etudid, tag_annotation_pe): # ---------------------------------------------------------------------------------------- def str_from_syntheseJury(donnees_etudiant, aggregat, groupe, tag_scodoc, champ): - """Extrait du dictionnaire de synthèse du juryPE pour un étudiant donnée, - une valeur indiquée par un champ ; + """Extrait du dictionnaire de synthèse du juryPE pour un étudiant donnée, + une valeur indiquée par un champ ; si champ est une liste, renvoie la liste des valeurs extraites. Result: chaine unicode ou liste de chaines unicode @@ -322,7 +322,7 @@ def str_from_syntheseJury(donnees_etudiant, aggregat, groupe, tag_scodoc, champ) # ---------------------------------------------------------------------------------------- def get_bilanParTag(donnees_etudiant, groupe="groupe"): - """Renvoie le code latex d'un tableau récapitulant, pour tous les tags trouvés dans + """Renvoie le code latex d'un tableau récapitulant, pour tous les tags trouvés dans les données étudiants, ses résultats. result: chaine unicode """ @@ -474,8 +474,7 @@ def get_templates_from_distrib(template="avis"): # ---------------------------------------------------------------------------------------- def table_syntheseAnnotationPE(context, syntheseJury, tag_annotation_pe): - """Génère un fichier excel synthétisant les annotations PE telles qu'inscrites dans les fiches de chaque étudiant - """ + """Génère un fichier excel synthétisant les annotations PE telles qu'inscrites dans les fiches de chaque étudiant""" sT = SeqGenTable() # le fichier excel à générer # Les etudids des étudiants à afficher, triés par ordre alphabétiques de nom+prénom diff --git a/pe_jurype.py b/pe_jurype.py index b0aee940..cc000237 100644 --- a/pe_jurype.py +++ b/pe_jurype.py @@ -88,7 +88,7 @@ class JuryPE: {'etudid : { 'nom', 'prenom', 'sexe', 'diplome', '', }} Rq: il contient à la fois les étudiants qui vont être diplomés à la date prévue et ceux qui sont éliminés (abandon, redoublement, ...) pour affichage alternatif - + Note (EV:): les attributs sont des chaines encodées (utf8), comme dans ScoDoc (pas des unicodes) """ @@ -210,8 +210,7 @@ class JuryPE: # ------------------------------------------------------------------------------------------------------------------ def get_zipped_data(self): - """returns zipped data with all generated (CSV) files - """ + """returns zipped data with all generated (CSV) files""" if self.zipfile: self.zipfile.close() self.zipfile = None @@ -366,7 +365,7 @@ class JuryPE: # ------------------------------------------------------------------------------------------------------------------ def add_etudiants(self, etudid): - """ Ajoute un étudiant (via son etudid) au dictionnaire de synthèse jurydict. + """Ajoute un étudiant (via son etudid) au dictionnaire de synthèse jurydict. L'ajout consiste à : > insérer une entrée pour l'étudiant en mémorisant ses infos (get_etudInfo), avec son nom, prénom, etc... @@ -479,7 +478,7 @@ class JuryPE: pour autant avoir été indiqué NAR ou DEM ; recherche son dernier semestre validé et regarde s'il n'existe pas parmi les semestres existants dans scodoc un semestre postérieur (en terme de date de début) de n° au moins égal à celui de son dernier semestre valide dans lequel il aurait pu - s'inscrire mais ne l'a pas fait. """ + s'inscrire mais ne l'a pas fait.""" sessems = self.get_semestresDUT_d_un_etudiant( etudid ) # les semestres de l'étudiant @@ -868,9 +867,7 @@ class JuryPE: return semDeb["annee_debut"] def get_parcoursIUT(self, etudid): - """Renvoie une liste d'infos sur les semestres du parcours d'un étudiant - - """ + """Renvoie une liste d'infos sur les semestres du parcours d'un étudiant""" etudinfo = self.ETUDINFO_DICT[etudid] sems = self.get_semestresDUT_d_un_etudiant(etudid) @@ -934,7 +931,7 @@ class JuryPE: def get_allTagForAggregat(self, nom_aggregat): """Extrait du dictionnaire syntheseJury la liste des tags d'un semestre ou - d'un aggrégat donné par son nom (S1, S2, S3 ou S4, 1A, ...). Renvoie [] si aucun tag.""" + d'un aggrégat donné par son nom (S1, S2, S3 ou S4, 1A, ...). Renvoie [] si aucun tag.""" taglist = set() for etudid in self.get_etudids_du_jury(): taglist = taglist.union( @@ -1127,10 +1124,9 @@ class JuryPE: # ------------------------------------------------------------------------------------------------------------------ def get_cache_notes_d_un_semestre( - cls, context, formsemestre_id + self, context, formsemestre_id ): # inutile en realité ! - """Charge la table des notes d'un formsemestre - """ + """Charge la table des notes d'un formsemestre""" return context.Notes._getNotesCache().get_NotesTable( context.Notes, formsemestre_id ) @@ -1196,7 +1192,7 @@ class JuryPE: # ---------------------------------------------------------------------------------------- def get_annee_diplome_semestre(sem): - """ Pour un semestre donne, décrit par le biais du dictionnaire sem usuel : + """Pour un semestre donne, décrit par le biais du dictionnaire sem usuel : sem = {'formestre_id': ..., 'semestre_id': ..., 'annee_debut': ...}, à condition qu'il soit un semestre de formation DUT, predit l'annee à laquelle sera remis le diplome DUT des etudiants scolarisés dans le semestre @@ -1230,12 +1226,12 @@ def get_annee_diplome_semestre(sem): # ---------------------------------------------------------------------------------- def get_cosemestres_diplomants(context, semBase, avec_meme_formation=False): - """ Partant d'un semestre de Base = {'formsemestre_id': ..., 'semestre_id': ..., 'annee_debut': ...}, - renvoie la liste de tous ses co-semestres (lui-meme inclus) - Par co-semestre, s'entend les semestres : - > dont l'annee predite pour la remise du diplome DUT est la meme - > dont la formation est la même (optionnel) - > ne prenant en compte que les etudiants sans redoublement + """Partant d'un semestre de Base = {'formsemestre_id': ..., 'semestre_id': ..., 'annee_debut': ...}, + renvoie la liste de tous ses co-semestres (lui-meme inclus) + Par co-semestre, s'entend les semestres : + > dont l'annee predite pour la remise du diplome DUT est la meme + > dont la formation est la même (optionnel) + > ne prenant en compte que les etudiants sans redoublement """ tousLesSems = ( context.Notes.formsemestre_list() diff --git a/pe_settag.py b/pe_settag.py index 841e6f04..38bfc566 100644 --- a/pe_settag.py +++ b/pe_settag.py @@ -144,8 +144,7 @@ class SetTag(pe_tagtable.TableTag): # ------------------------------------------------------------------------------------------------------------------- def do_tagdict(self): - """Synthétise la liste des modules pris en compte dans le calcul d'un tag (pour analyse des résultats) - """ + """Synthétise la liste des modules pris en compte dans le calcul d'un tag (pour analyse des résultats)""" self.tagdict = {} for semtag in self.SemTagDict.values(): for tag in semtag.get_all_tags(): @@ -208,8 +207,8 @@ class SetTag(pe_tagtable.TableTag): class SetTagInterClasse(pe_tagtable.TableTag): """Récupère les moyennes de SetTag aggrégant un même parcours (par ex un ['S1', 'S2'] n'ayant pas fini au même S2 - pour fournir un interclassement sur un groupe d'étudiant => seul compte alors la promo - nom_combinaison = 'S1' ou '1A' + pour fournir un interclassement sur un groupe d'étudiant => seul compte alors la promo + nom_combinaison = 'S1' ou '1A' """ # ------------------------------------------------------------------------------------------------------------------- diff --git a/pe_tagtable.py b/pe_tagtable.py index 3cd9cefa..fcdcd178 100644 --- a/pe_tagtable.py +++ b/pe_tagtable.py @@ -95,7 +95,7 @@ class TableTag: # ----------------------------------------------------------------------------------------------------------- def get_coeff_from_resultats(self, tag, etudid): - """Renvoie la somme des coeffs de pondération normalisée utilisés dans le calcul de la moyenne à un tag d'un étudiant + """Renvoie la somme des coeffs de pondération normalisée utilisés dans le calcul de la moyenne à un tag d'un étudiant au regard du format de self.resultats. """ return ( @@ -329,7 +329,7 @@ def moyenne_ponderee_terme_a_terme(notes, coeffs=None, force=False): # ------------------------------------------------------------------------------------------- def conversionDate_StrToDate(date_fin): - """ Conversion d'une date fournie sous la forme d'une chaine de caractère de + """Conversion d'une date fournie sous la forme d'une chaine de caractère de type 'jj/mm/aaaa' en un objet date du package datetime. Fonction servant au tri des semestres par date """ diff --git a/pe_tools.py b/pe_tools.py index 3826a3ef..7340d49f 100644 --- a/pe_tools.py +++ b/pe_tools.py @@ -97,7 +97,7 @@ def print_semestres_description(sems, avec_affichage_debug=False): # ---------------------------------------------------------------------------------------- def calcul_age(born): - """Calcule l'age à partir de la date de naissance sous forme d'une chaine de caractère 'jj/mm/aaaa'. + """Calcule l'age à partir de la date de naissance sous forme d'une chaine de caractère 'jj/mm/aaaa'. Aucun test de validité sur le format de la date n'est fait. """ if not isinstance(born, str) or born == "": @@ -122,8 +122,7 @@ def remove_accents(input_unicode_str): def escape_for_latex(s): - """Protège les caractères pour inclusion dans du source LaTeX - """ + """Protège les caractères pour inclusion dans du source LaTeX""" if not s: return "" conv = { @@ -162,8 +161,7 @@ def list_directory_filenames(path): def add_local_file_to_zip(zipfile, ziproot, pathname, path_in_zip): - """Read pathname server file and add content to zip under path_in_zip - """ + """Read pathname server file and add content to zip under path_in_zip""" rooted_path_in_zip = os.path.join(ziproot, path_in_zip) data = open(pathname).read() zipfile.writestr(rooted_path_in_zip, data) diff --git a/pe_view.py b/pe_view.py index 21bab713..09837713 100644 --- a/pe_view.py +++ b/pe_view.py @@ -89,7 +89,7 @@ def pe_view_sem_recap( REQUEST=None, ): """Génération des avis de poursuite d'étude - + mode_debug = Pour "squeezer" le calcul du jury pe (long) et debugger uniquement la partie avis latex """ diff --git a/sco_abs_notification.py b/sco_abs_notification.py index 13e4f41b..7dfa682e 100644 --- a/sco_abs_notification.py +++ b/sco_abs_notification.py @@ -47,7 +47,7 @@ import sco_formsemestre def abs_notify(context, etudid, date): """Check if notifications are requested and send them - Considère le nombre d'absence dans le semestre courant + Considère le nombre d'absence dans le semestre courant (s'il n'y a pas de semestre courant, ne fait rien, car l'etudiant n'est pas inscrit au moment de l'absence!). """ @@ -64,8 +64,7 @@ def abs_notify(context, etudid, date): def do_abs_notify(context, sem, etudid, date, nbabs, nbabsjust): - """Given new counts of absences, check if notifications are requested and send them. - """ + """Given new counts of absences, check if notifications are requested and send them.""" # prefs fallback to global pref if sem is None: if sem: formsemestre_id = sem["formsemestre_id"] @@ -131,8 +130,7 @@ def abs_notify_send( def abs_notify_get_destinations(context, sem, prefs, etudid, date, nbabs, nbabsjust): - """Returns set of destination emails to be notified - """ + """Returns set of destination emails to be notified""" formsemestre_id = sem["formsemestre_id"] destinations = [] # list of email address to notify @@ -176,8 +174,8 @@ def abs_notify_is_above_threshold(context, etudid, nbabs, nbabsjust, formsemestr nbabs: nombre d'absence (de tous types, unité de compte = demi-journée) nbabsjust: nombre d'absences justifiées - - (nbabs > abs_notify_abs_threshold) + + (nbabs > abs_notify_abs_threshold) (nbabs - nbabs_last_notified) > abs_notify_abs_increment """ abs_notify_abs_threshold = context.get_preference( @@ -282,8 +280,7 @@ def retreive_current_formsemestre(context, etudid, cur_date): def mod_with_evals_at_date(context, date_abs, etudid): - """Liste des moduleimpls avec des evaluations a la date indiquée - """ + """Liste des moduleimpls avec des evaluations a la date indiquée""" req = """SELECT m.* FROM notes_moduleimpl m, notes_evaluation e, notes_moduleimpl_inscription i WHERE m.moduleimpl_id = e.moduleimpl_id AND e.moduleimpl_id = i.moduleimpl_id AND i.etudid = %(etudid)s AND e.jour = %(date_abs)s""" diff --git a/sco_apogee_compare.py b/sco_apogee_compare.py index b5232478..221e707a 100644 --- a/sco_apogee_compare.py +++ b/sco_apogee_compare.py @@ -62,8 +62,7 @@ _help_txt = """ def apo_compare_csv_form(context, REQUEST=None): - """Form: submit 2 CSV files to compare them. - """ + """Form: submit 2 CSV files to compare them.""" H = [ context.sco_header(REQUEST, page_title="Comparaison de fichiers Apogée"), """

      Comparaison de fichiers Apogée

      @@ -90,8 +89,7 @@ def apo_compare_csv_form(context, REQUEST=None): def apo_compare_csv(context, A_file, B_file, autodetect=True, REQUEST=None): - """Page comparing 2 Apogee CSV files - """ + """Page comparing 2 Apogee CSV files""" A = _load_apo_data(A_file, autodetect=autodetect) B = _load_apo_data(B_file, autodetect=autodetect) @@ -182,7 +180,11 @@ def _apo_compare_csv(context, A, B, REQUEST=None): elts_only_B = B_elts - A_elts.intersection(B_elts) L.append( 'différents (%d en commun, %d seulement dans A, %d seulement dans B)' - % (len(elts_communs), len(elts_only_A), len(elts_only_B),) + % ( + len(elts_communs), + len(elts_only_A), + len(elts_only_B), + ) ) if elts_only_A: L.append( @@ -244,8 +246,7 @@ def _apo_compare_csv(context, A, B, REQUEST=None): def apo_table_compare_etud_results(context, A, B, REQUEST=None): - """ - """ + """""" D = compare_etuds_res(A, B) T = GenTable( rows=D, diff --git a/sco_apogee_csv.py b/sco_apogee_csv.py index f097f4de..45b71e92 100644 --- a/sco_apogee_csv.py +++ b/sco_apogee_csv.py @@ -112,8 +112,7 @@ APO_NEWLINE = "\r\n" def code_scodoc_to_apo(code): - """Conversion code jury ScoDoc en code Apogée - """ + """Conversion code jury ScoDoc en code Apogée""" return { ATT: "AJAC", ATB: "AJAC", @@ -159,7 +158,7 @@ def fix_data_encoding( text, default_source_encoding=APO_INPUT_ENCODING, dest_encoding=APO_INPUT_ENCODING ): """Try to ensure that text is using dest_encoding - returns converted text, and a message describing the conversion. + returns converted text, and a message describing the conversion. """ message = "" detected_encoding = guess_data_encoding(text) @@ -241,8 +240,7 @@ VOID_APO_RES = dict(N="", B="", J="", R="", M="") class ApoEtud(dict): - """Etudiant Apogee: - """ + """Etudiant Apogee:""" def __init__( self, @@ -361,7 +359,7 @@ class ApoEtud(dict): Autres éléments: résultats du semestre ou de l'année scolaire: => VRTW1: code additionnel au semestre ("code élement semestre", elt_sem_apo) => VRT1A: le même que le VET: ("code élement annuel", elt_annee_apo) - Attention, si le semestre couvre plusieurs étapes, indiquer les codes des éléments, + Attention, si le semestre couvre plusieurs étapes, indiquer les codes des éléments, séparés par des virgules. Args: @@ -369,7 +367,7 @@ class ApoEtud(dict): sem (dict): semestre dans lequel on cherche l'élément cur_sem (dict): semestre "courant" pour résultats annuels (VET) autre_sem (dict): autre semestre utilisé pour calculé les résultats annuels (VET) - + Returns: dict: with N, B, J, R keys, ou None si elt non trouvé """ @@ -701,8 +699,7 @@ class ApoData: self.periode = periode def setup(self, context): - """Recherche semestres ScoDoc concernés - """ + """Recherche semestres ScoDoc concernés""" self.context = context self.sems_etape = comp_apo_sems(context, self.etape_apogee, self.annee_scolaire) self.etape_formsemestre_ids = {s["formsemestre_id"] for s in self.sems_etape} @@ -803,7 +800,7 @@ class ApoData: Clé: id apogée, eg 'V1RT', 'V1GE2201', ... Valeur: ApoElt, avec les attributs code, type_objet - Si les id Apogée ne sont pas uniques (ce n'est pas garanti), garde le premier + Si les id Apogée ne sont pas uniques (ce n'est pas garanti), garde le premier """ elts = collections.OrderedDict() for col_id in sorted(cols.keys(), reverse=True): @@ -849,8 +846,7 @@ class ApoData: return L def get_etape_apogee(self): - """Le code etape: 'V1RT', donné par le code de l'élément VET - """ + """Le code etape: 'V1RT', donné par le code de l'élément VET""" for elt in self.apo_elts.values(): if elt.type_objet == "VET": return elt.code @@ -893,8 +889,7 @@ class ApoData: f.write(self.column_titles) def write_etuds(self, f): - """write apo CSV etuds on f - """ + """write apo CSV etuds on f""" for e in self.etuds: fs = [] # e['nip'], e['nom'], e['prenom'], e['naissance'] ] for col_id in self.col_ids: @@ -983,8 +978,7 @@ class ApoData: return codes_by_sem def build_cr_table(self): - """Table compte rendu des décisions - """ + """Table compte rendu des décisions""" CR = [] # tableau compte rendu des decisions for e in self.etuds: cr = { @@ -1015,14 +1009,14 @@ class ApoData: def _apo_read_cols(f): - """Lecture colonnes apo : + """Lecture colonnes apo : Démarre après la balise XX-APO_COLONNES-XX et s'arrête après la balise APO_COL_VAL_FIN Colonne Apogee: les champs sont données par la ligne - apoL_a01_code de la section XX-APO_COLONNES-XX + apoL_a01_code de la section XX-APO_COLONNES-XX col_id est apoL_c0001, apoL_c0002, ... - + :return: { col_id : { title : value } } Example: { 'apoL_c0001' : { 'Type Objet' : 'VET', 'Code' : 'V1IN', ... }, ... } """ @@ -1116,8 +1110,7 @@ def comp_apo_sems(context, etape_apogee, annee_scolaire): def nar_etuds_table(context, apo_data, NAR_Etuds): - """Liste les NAR -> excel table - """ + """Liste les NAR -> excel table""" code_etape = apo_data.etape_apogee today = datetime.datetime.today().strftime("%d/%m/%y") L = [] @@ -1186,7 +1179,7 @@ def export_csv_to_apogee( export_res_rat=True, REQUEST=None, ): - """Genere un fichier CSV Apogée + """Genere un fichier CSV Apogée à partir d'un fichier CSV Apogée vide (ou partiellement rempli) et des résultats ScoDoc. Si dest_zip, ajoute les fichiers générés à ce zip diff --git a/sco_archives_etud.py b/sco_archives_etud.py index cfbf3923..01e2db6a 100644 --- a/sco_archives_etud.py +++ b/sco_archives_etud.py @@ -49,14 +49,12 @@ EtudsArchive = EtudsArchiver() def can_edit_etud_archive(context, authuser): - """True si l'utilisateur peut modifier les archives etudiantes - """ + """True si l'utilisateur peut modifier les archives etudiantes""" return authuser.has_permission(ScoEtudAddAnnotations, context) def etud_list_archives_html(context, REQUEST, etudid): - """HTML snippet listing archives - """ + """HTML snippet listing archives""" can_edit = can_edit_etud_archive(context, REQUEST.AUTHENTICATED_USER) L = [] for archive_id in EtudsArchive.list_obj_archives(context, etudid): @@ -122,8 +120,7 @@ def add_archives_info_to_etud_list(context, etuds): def etud_upload_file_form(context, REQUEST, etudid): - """Page with a form to choose and upload a file, with a description. - """ + """Page with a form to choose and upload a file, with a description.""" # check permission if not can_edit_etud_archive(context, REQUEST.AUTHENTICATED_USER): raise AccessDenied( @@ -178,8 +175,7 @@ def etud_upload_file_form(context, REQUEST, etudid): def _store_etud_file_to_new_archive( context, REQUEST, etudid, data, filename, description="" ): - """Store data to new archive. - """ + """Store data to new archive.""" filesize = len(data) if filesize < 10 or filesize > CONFIG.ETUD_MAX_FILE_SIZE: return 0, "Fichier image de taille invalide ! (%d)" % filesize @@ -188,8 +184,7 @@ def _store_etud_file_to_new_archive( def etud_delete_archive(context, REQUEST, etudid, archive_name, dialog_confirmed=False): - """Delete an archive - """ + """Delete an archive""" # check permission if not can_edit_etud_archive(context, REQUEST.AUTHENTICATED_USER): raise AccessDenied( @@ -218,8 +213,7 @@ def etud_delete_archive(context, REQUEST, etudid, archive_name, dialog_confirmed def etud_get_archived_file(context, REQUEST, etudid, archive_name, filename): - """Send file to client. - """ + """Send file to client.""" return EtudsArchive.get_archived_file( context, REQUEST, etudid, archive_name, filename ) @@ -227,8 +221,7 @@ def etud_get_archived_file(context, REQUEST, etudid, archive_name, filename): # --- Upload d'un ensemble de fichiers (pour un groupe d'étudiants) def etudarchive_generate_excel_sample(context, group_id=None, REQUEST=None): - """Feuille excel pour import fichiers etudiants (utilisé pour admissions) - """ + """Feuille excel pour import fichiers etudiants (utilisé pour admissions)""" fmt = ImportScolars.sco_import_format() data = ImportScolars.sco_import_generate_excel_sample( fmt, @@ -249,8 +242,7 @@ def etudarchive_generate_excel_sample(context, group_id=None, REQUEST=None): def etudarchive_import_files_form(context, group_id, REQUEST=None): - """Formualaire pour importation fichiers d'un groupe - """ + """Formualaire pour importation fichiers d'un groupe""" H = [ context.sco_header( REQUEST, page_title="Import de fichiers associés aux étudiants" diff --git a/sco_bac.py b/sco_bac.py index b7902ac2..64eb96e6 100644 --- a/sco_bac.py +++ b/sco_bac.py @@ -162,4 +162,4 @@ class Baccalaureat: return self.type() == "G" def is_techno(self): - return selt.type() == "T" + return self.type() == "T" diff --git a/sco_bulletins_legacy.py b/sco_bulletins_legacy.py index 75bda0bb..84dc40cb 100644 --- a/sco_bulletins_legacy.py +++ b/sco_bulletins_legacy.py @@ -80,8 +80,7 @@ class BulletinGeneratorLegacy(sco_bulletins_generator.BulletinGenerator): return [self.buildTableObject(P, pdfTableStyle, colWidths)] def bul_table_html(self): - """Génère la table centrale du bulletin de notes: chaine HTML - """ + """Génère la table centrale du bulletin de notes: chaine HTML""" format = "html" I = self.infos authuser = self.authuser @@ -130,13 +129,10 @@ class BulletinGeneratorLegacy(sco_bulletins_generator.BulletinGenerator): continue # saute les modules où on n'est pas inscrit H.append('
' % rowstyle) if context.get_preference("bul_show_minmax_mod", formsemestre_id): - rang_minmax = ( - '%s [%s, %s]' - % ( - mod["mod_rang_txt"], - fmt_note(mod["stats"]["min"]), - fmt_note(mod["stats"]["max"]), - ) + rang_minmax = '%s [%s, %s]' % ( + mod["mod_rang_txt"], + fmt_note(mod["stats"]["min"]), + fmt_note(mod["stats"]["max"]), ) else: rang_minmax = mod["mod_rang_txt"] # vide si pas option rang @@ -386,8 +382,7 @@ sco_bulletins_generator.register_bulletin_class(BulletinGeneratorLegacy) class BulTableStyle: - """Construction du style de tables reportlab platypus pour les bulletins "classiques" - """ + """Construction du style de tables reportlab platypus pour les bulletins "classiques" """ LINEWIDTH = 0.5 LINECOLOR = Color(0, 0, 0) diff --git a/sco_bulletins_signature.py b/sco_bulletins_signature.py index 45f0399c..403526f3 100644 --- a/sco_bulletins_signature.py +++ b/sco_bulletins_signature.py @@ -57,8 +57,7 @@ import os def form_change_bul_sig(context, side, formsemestre_id=None, REQUEST=None): - """Change pdf signature - """ + """Change pdf signature""" filename = _get_sig_existing_filename( context, side, formsemestre_id=formsemestre_id ) diff --git a/sco_bulletins_ucac.py b/sco_bulletins_ucac.py index b27dc067..381486ad 100644 --- a/sco_bulletins_ucac.py +++ b/sco_bulletins_ucac.py @@ -305,5 +305,4 @@ sco_bulletins_generator.register_bulletin_class(BulletinGeneratorUCAC) def bulletin_table_ucac(context, I, version=None): - """ - """ + """""" diff --git a/sco_cache.py b/sco_cache.py index 33e44a79..b6425c5d 100644 --- a/sco_cache.py +++ b/sco_cache.py @@ -35,6 +35,7 @@ import thread, time # Cache data class simpleCache: def __init__(self): + self.cache = {} self.inval_cache() # > def inval_cache(self, key=None): # > @@ -56,7 +57,7 @@ class simpleCache: class expiringCache(simpleCache): """A simple cache wich cache data for a most "duration" seconds. - This is used for users (which may be updated from external + This is used for users (which may be updated from external information systems) """ diff --git a/sco_dump_db.py b/sco_dump_db.py index 10ffa9d8..621fd96b 100644 --- a/sco_dump_db.py +++ b/sco_dump_db.py @@ -64,8 +64,7 @@ SCO_DUMP_LOCK = "/tmp/scodump.lock" def sco_dump_and_send_db(context, REQUEST=None): - """Dump base de données du département courant et l'envoie anonymisée pour debug - """ + """Dump base de données du département courant et l'envoie anonymisée pour debug""" H = [context.sco_header(REQUEST, page_title="Assistance technique")] # get currect (dept) DB name: cursor = SimpleQuery(context, "SELECT current_database()", {}) @@ -150,8 +149,7 @@ def _duplicate_db(db_name, ano_db_name): def _anonymize_db(ano_db_name): - """Anonymize a departement database - """ + """Anonymize a departement database""" cmd = os.path.join(SCO_CONFIG_DIR, "anonymize_db.py") log("_anonymize_db: {}".format(cmd)) try: @@ -171,8 +169,7 @@ def _get_scodoc_serial(context): def _send_db(context, REQUEST, ano_db_name): - """Dump this (anonymized) database and send it to tech support - """ + """Dump this (anonymized) database and send it to tech support""" log("dumping anonymized database {}".format(ano_db_name)) try: data = subprocess.check_output("pg_dump {} | gzip".format(ano_db_name), shell=1) diff --git a/sco_edit_formation.py b/sco_edit_formation.py index 8b206e4d..96c318e3 100644 --- a/sco_edit_formation.py +++ b/sco_edit_formation.py @@ -37,8 +37,7 @@ import sco_formsemestre def formation_delete(context, formation_id=None, dialog_confirmed=False, REQUEST=None): - """Delete a formation - """ + """Delete a formation""" F = context.formation_list(args={"formation_id": formation_id}) if not F: raise ScoValueError("formation inexistante !") @@ -89,14 +88,12 @@ def formation_delete(context, formation_id=None, dialog_confirmed=False, REQUEST def formation_create(context, REQUEST=None): - """Creation d'une formation - """ + """Creation d'une formation""" return formation_edit(context, create=True, REQUEST=REQUEST) def formation_edit(context, formation_id=None, create=False, REQUEST=None): - """Edit or create a formation - """ + """Edit or create a formation""" if create: H = [ context.sco_header(REQUEST, page_title="Création d'une formation"), diff --git a/sco_edit_matiere.py b/sco_edit_matiere.py index 83f4a4d6..2cdda893 100644 --- a/sco_edit_matiere.py +++ b/sco_edit_matiere.py @@ -36,8 +36,7 @@ import sco_formsemestre def matiere_create(context, ue_id=None, REQUEST=None): - """Creation d'une matiere - """ + """Creation d'une matiere""" UE = context.do_ue_list(args={"ue_id": ue_id})[0] H = [ context.sco_header(REQUEST, page_title="Création d'une matière"), diff --git a/sco_edit_module.py b/sco_edit_module.py index 270304b4..64b51b6b 100644 --- a/sco_edit_module.py +++ b/sco_edit_module.py @@ -55,8 +55,7 @@ saisir et modifier les notes de ce module. def module_create(context, matiere_id=None, REQUEST=None): - """Creation d'un module - """ + """Creation d'un module""" if not matiere_id: raise ScoValueError("invalid matiere !") M = context.do_matiere_list(args={"matiere_id": matiere_id})[0] @@ -436,8 +435,7 @@ def module_list(context, formation_id, REQUEST=None): def formation_add_malus_modules(context, formation_id, titre=None, REQUEST=None): - """Création d'un module de "malus" dans chaque UE d'une formation - """ + """Création d'un module de "malus" dans chaque UE d'une formation""" ue_list = context.do_ue_list(args={"formation_id": formation_id}) for ue in ue_list: @@ -457,8 +455,7 @@ def formation_add_malus_modules(context, formation_id, titre=None, REQUEST=None) def ue_add_malus_module(context, ue_id, titre=None, code=None, REQUEST=None): - """Add a malus module in this ue - """ + """Add a malus module in this ue""" ue = context.do_ue_list(args={"ue_id": ue_id})[0] if titre is None: diff --git a/sco_edit_ue.py b/sco_edit_ue.py index e37daf8e..5e9f16b1 100644 --- a/sco_edit_ue.py +++ b/sco_edit_ue.py @@ -41,14 +41,12 @@ import sco_tag_module def ue_create(context, formation_id=None, REQUEST=None): - """Creation d'une UE - """ + """Creation d'une UE""" return ue_edit(context, create=True, formation_id=formation_id, REQUEST=REQUEST) def ue_edit(context, ue_id=None, create=False, formation_id=None, REQUEST=None): - """Modification ou creation d'une UE - """ + """Modification ou creation d'une UE""" create = int(create) if not create: U = context.do_ue_list(args={"ue_id": ue_id}) @@ -227,7 +225,7 @@ def ue_edit(context, ue_id=None, create=False, formation_id=None, REQUEST=None): def _add_ue_semestre_id(context, ue_list): """ajoute semestre_id dans les ue, en regardant le premier module de chacune. - Les UE sans modules se voient attribuer le numero UE_SEM_DEFAULT (1000000), + Les UE sans modules se voient attribuer le numero UE_SEM_DEFAULT (1000000), qui les place à la fin de la liste. """ for ue in ue_list: @@ -281,7 +279,7 @@ def ue_delete( def ue_list(context, formation_id=None, msg="", REQUEST=None): - """Liste des matières et modules d'une formation, avec liens pour + """Liste des matières et modules d'une formation, avec liens pour editer (si non verrouillée). """ authuser = REQUEST.AUTHENTICATED_USER @@ -781,8 +779,7 @@ def edit_ue_set_code_apogee(context, id=None, value=None, REQUEST=None): # ---- Table recap formation def formation_table_recap(context, formation_id, format="html", REQUEST=None): - """ - """ + """""" F = context.formation_list(args={"formation_id": formation_id}) if not F: raise ScoValueError("invalid formation_id") diff --git a/sco_edt_cal.py b/sco_edt_cal.py index 3462532f..33a70de9 100644 --- a/sco_edt_cal.py +++ b/sco_edt_cal.py @@ -67,8 +67,7 @@ def formsemestre_get_ics_url(context, sem): def formsemestre_load_ics(context, sem): - """Load ics data, from our cache or, when necessary, from external provider - """ + """Load ics data, from our cache or, when necessary, from external provider""" # TODO: cacher le résultat ics_url = formsemestre_get_ics_url(context, sem) if not ics_url: @@ -86,15 +85,13 @@ def formsemestre_load_ics(context, sem): def formsemestre_edt_groups_used(context, sem): - """L'ensemble des groupes EDT utilisés dans l'emplois du temps publié - """ + """L'ensemble des groupes EDT utilisés dans l'emplois du temps publié""" cal = formsemestre_load_ics(context, sem) return {e["X-GROUP-ID"].decode("utf8") for e in events} def get_edt_transcodage_groups(context, formsemestre_id): - """ -> { nom_groupe_edt : nom_groupe_scodoc } - """ + """-> { nom_groupe_edt : nom_groupe_scodoc }""" # TODO: valider ces données au moment où on enregistre les préférences edt2sco = {} sco2edt = {} @@ -161,8 +158,7 @@ for e in events: def experimental_calendar(context, group_id=None, formsemestre_id=None, REQUEST=None): - """experimental page - """ + """experimental page""" return "\n".join( [ context.sco_header( diff --git a/sco_etape_apogee.py b/sco_etape_apogee.py index f07376cb..1a60edca 100644 --- a/sco_etape_apogee.py +++ b/sco_etape_apogee.py @@ -190,8 +190,7 @@ def apo_csv_list_stored_etapes(context, annee_scolaire, sem_id=None, etapes=None def apo_csv_delete(context, archive_id): - """Delete archived CSV - """ + """Delete archived CSV""" ApoCSVArchive.delete_archive(archive_id) @@ -224,19 +223,18 @@ def apo_csv_get(context, etape_apo="", annee_scolaire="", sem_id=""): def apo_get_sem_etapes(context, sem): - """Etapes de ce semestre: pour l'instant, celles déclarées - Dans une future version, on pourrait aussi utiliser les étapes - d'inscription des étudiants, recupérées via le portail, + """Etapes de ce semestre: pour l'instant, celles déclarées + Dans une future version, on pourrait aussi utiliser les étapes + d'inscription des étudiants, recupérées via le portail, voir check_paiement_etuds(). - + :return: list of etape_apo (ApoEtapeVDI instances) """ return sem["etapes"] def apo_csv_check_etape(context, semset, set_nips, etape_apo): - """Check etape vs set of sems - """ + """Check etape vs set of sems""" # Etudiants dans la maquette CSV: csv_data = apo_csv_get( context, etape_apo, semset["annee_scolaire"], semset["sem_id"] @@ -254,7 +252,10 @@ def apo_csv_check_etape(context, semset, set_nips, etape_apo): return nips_ok, apo_nips, nips_no_apo, nips_no_sco, maq_elems, sem_elems -def apo_csv_semset_check(context, semset, allow_missing_apo=False, allow_missing_csv=False): # was apo_csv_check + +def apo_csv_semset_check( + context, semset, allow_missing_apo=False, allow_missing_csv=False +): # was apo_csv_check """ check students in stored maqs vs students in semset Cas à détecter: diff --git a/sco_etape_apogee_view.py b/sco_etape_apogee_view.py index f0fdb01c..d03b5107 100644 --- a/sco_etape_apogee_view.py +++ b/sco_etape_apogee_view.py @@ -58,9 +58,7 @@ def apo_semset_maq_status( block_export_res_sdj=True, REQUEST=None, ): - """Page statut / tableau de bord - - """ + """Page statut / tableau de bord""" if not semset_id: raise ValueError("invalid null semset_id") semset = sco_semset.SemSet(context, semset_id=semset_id) @@ -91,7 +89,9 @@ def apo_semset_maq_status( apo_dups, maq_elems, sem_elems, - ) = sco_etape_apogee.apo_csv_semset_check(context, semset, allow_missing_apo, allow_missing_csv) + ) = sco_etape_apogee.apo_csv_semset_check( + context, semset, allow_missing_apo, allow_missing_csv + ) if not allow_missing_decisions: ok_for_export &= semset["jury_ok"] @@ -265,9 +265,7 @@ def apo_semset_maq_status( ) if allow_missing_csv: H.append("checked") - H.append( - """ >autoriser export même si étapes sans maquettes""" - ) + H.append(""" >autoriser export même si étapes sans maquettes""") H.append("""""") if semset and ok_for_export: @@ -295,7 +293,9 @@ def apo_semset_maq_status( H.append( """
""" % checked( - block_export_res_etape, "export_res_etape", "résultat de l'étape (VET), sauf si diplôme" + block_export_res_etape, + "export_res_etape", + "résultat de l'étape (VET), sauf si diplôme", ) ) H.append( @@ -424,8 +424,7 @@ def apo_semset_maq_status( def table_apo_csv_list(context, semset, REQUEST=None): - """Table des archives (triée par date d'archivage) - """ + """Table des archives (triée par date d'archivage)""" annee_scolaire = semset["annee_scolaire"] sem_id = semset["sem_id"] @@ -481,8 +480,7 @@ def table_apo_csv_list(context, semset, REQUEST=None): def view_apo_etuds(context, semset_id, title="", nips=[], format="html", REQUEST=None): - """Table des étudiants Apogée par nips - """ + """Table des étudiants Apogée par nips""" if not semset_id: raise ValueError("invalid null semset_id") semset = sco_semset.SemSet(context, semset_id=semset_id) @@ -520,8 +518,7 @@ def view_apo_etuds(context, semset_id, title="", nips=[], format="html", REQUEST def view_scodoc_etuds( context, semset_id, title="", etudids=None, nips=None, format="html", REQUEST=None ): - """Table des étudiants ScoDoc par nips ou etudids - """ + """Table des étudiants ScoDoc par nips ou etudids""" if etudids is not None: if type(etudids) != type([]): etudids = [etudids] @@ -636,8 +633,7 @@ def view_apo_csv_store( def view_apo_csv_download_and_store(context, etape_apo="", semset_id="", REQUEST=None): - """Download maquette and store it - """ + """Download maquette and store it""" if not semset_id: raise ValueError("invalid null semset_id") semset = sco_semset.SemSet(context, semset_id=semset_id) @@ -656,8 +652,7 @@ def view_apo_csv_download_and_store(context, etape_apo="", semset_id="", REQUEST def view_apo_csv_delete( context, etape_apo="", semset_id="", dialog_confirmed=False, REQUEST=None ): - """Delete CSV file - """ + """Delete CSV file""" if not semset_id: raise ValueError("invalid null semset_id") semset = sco_semset.SemSet(context, semset_id=semset_id) diff --git a/sco_excel.py b/sco_excel.py index 5b00a7be..dc8777ff 100644 --- a/sco_excel.py +++ b/sco_excel.py @@ -237,8 +237,7 @@ class ScoExcelSheet: def Excel_SimpleTable(titles=[], lines=[[]], SheetName="feuille", titlesStyles=[]): - """Export simple type 'CSV': 1ere ligne en gras, le reste tel quel - """ + """Export simple type 'CSV': 1ere ligne en gras, le reste tel quel""" # XXX devrait maintenant utiliser ScoExcelSheet wb = Workbook() ws0 = wb.add_sheet(SheetName.decode(SCO_ENCODING)) diff --git a/sco_export_results.py b/sco_export_results.py index 55ac49db..d330a9a8 100644 --- a/sco_export_results.py +++ b/sco_export_results.py @@ -201,8 +201,7 @@ def _build_results_list(context, dpv_by_sem, etuds_infos): def get_set_formsemestre_id_dates(context, start_date, end_date): - """Ensemble des formsemestre_id entre ces dates - """ + """Ensemble des formsemestre_id entre ces dates""" s = SimpleDictFetch( context, "SELECT formsemestre_id FROM notes_formsemestre WHERE date_debut >= %(start_date)s AND date_fin <= %(end_date)s", @@ -216,7 +215,7 @@ def scodoc_table_results( ): """Page affichant la table des résultats Les dates sont en dd/mm/yyyy (datepicker javascript) - types_parcours est la liste des types de parcours à afficher + types_parcours est la liste des types de parcours à afficher (liste de chaines, eg ['100', '210'] ) """ log("scodoc_table_results: start_date=%s" % (start_date,)) # XXX diff --git a/sco_find_etud.py b/sco_find_etud.py index 73be7040..d8137c4c 100644 --- a/sco_find_etud.py +++ b/sco_find_etud.py @@ -216,7 +216,7 @@ def search_etud_in_dept( # Was chercheEtudsInfo() def search_etuds_infos(context, expnom=None, code_nip=None, REQUEST=None): """recherche les étudiants correspondants à expnom ou au code_nip - et ramene liste de mappings utilisables en DTML. + et ramene liste de mappings utilisables en DTML. """ may_be_nip = is_valid_code_nip(expnom) cnx = context.GetDBConnexion() @@ -286,8 +286,7 @@ def search_etud_by_name(context, term, REQUEST=None): def form_search_etud_in_accessible_depts(context, REQUEST): - """Form recherche etudiants pour page accueil ScoDoc - """ + """Form recherche etudiants pour page accueil ScoDoc""" authuser = REQUEST.AUTHENTICATED_USER # present form only to authenticated users if not authuser.has_role("Authenticated"): diff --git a/sco_formsemestre_validation.py b/sco_formsemestre_validation.py index 53fa0c67..afee3e8c 100644 --- a/sco_formsemestre_validation.py +++ b/sco_formsemestre_validation.py @@ -480,7 +480,7 @@ def formsemestre_recap_parcours_table( show_details=False, ): """Tableau HTML recap parcours - Si with_links, ajoute liens pour modifier decisions (colonne de droite) + Si with_links, ajoute liens pour modifier decisions (colonne de droite) sem_info = { formsemestre_id : txt } permet d'ajouter des informations associées à chaque semestre with_all_columns: si faux, pas de colonne "assiduité". """ @@ -690,8 +690,7 @@ def formsemestre_recap_parcours_table( def form_decision_manuelle( context, Se, formsemestre_id, etudid, desturl="", sortcol=None ): - """Formulaire pour saisie décision manuelle - """ + """Formulaire pour saisie décision manuelle""" H = [ """