Update opolka/ScoDoc from ScoDoc/ScoDoc #2

Merged
opolka merged 1272 commits from ScoDoc/ScoDoc:master into master 2024-05-27 09:11:04 +02:00
4 changed files with 44 additions and 30 deletions
Showing only changes of commit 88d3ef020d - Show all commits

View File

@ -349,7 +349,7 @@ def do_formsemestre_archive(
if data: if data:
PVArchive.store(archive_id, "Tableau_moyennes" + scu.XLSX_SUFFIX, data) PVArchive.store(archive_id, "Tableau_moyennes" + scu.XLSX_SUFFIX, data)
# Tableau recap notes en HTML (pour tous les etudiants, n'utilise pas les groupes) # Tableau recap notes en HTML (pour tous les etudiants, n'utilise pas les groupes)
table_html, _ = gen_formsemestre_recapcomplet_html_table( table_html, _, _ = gen_formsemestre_recapcomplet_html_table(
formsemestre, res, include_evaluations=True formsemestre, res, include_evaluations=True
) )
if table_html: if table_html:

View File

@ -27,6 +27,7 @@
"""Tableau récapitulatif des notes d'un semestre """Tableau récapitulatif des notes d'un semestre
""" """
import collections
import datetime import datetime
import time import time
from xml.etree import ElementTree from xml.etree import ElementTree
@ -109,7 +110,7 @@ def formsemestre_recapcomplet(
force_publishing=force_publishing, force_publishing=force_publishing,
) )
table_html, table = _formsemestre_recapcomplet_to_html( table_html, table, freq_codes_annuels = _formsemestre_recapcomplet_to_html(
formsemestre, formsemestre,
filename=filename, filename=filename,
mode_jury=mode_jury, mode_jury=mode_jury,
@ -215,33 +216,37 @@ def formsemestre_recapcomplet(
""" """
) )
if mode_jury and table and sum(table.freq_codes_annuels.values()) > 0: if mode_jury and freq_codes_annuels and sum(freq_codes_annuels.values()) > 0:
nb_etud_avec_decision_annuelle = (
sum(freq_codes_annuels.values()) - freq_codes_annuels["total"]
)
H.append( H.append(
f""" f"""
<div class="jury_stats"> <div class="jury_stats">
<div>Nb d'étudiants avec décision annuelle: <div><b>Nb d'étudiants avec décision annuelle:</b>
{sum(table.freq_codes_annuels.values())} / {len(table)} {nb_etud_avec_decision_annuelle} / {freq_codes_annuels["total"]}
</div> </div>
<div><b>Codes annuels octroyés:</b></div> """
)
if nb_etud_avec_decision_annuelle > 0:
H.append(
"""<div><b>Codes annuels octroyés:</b></div>
<table class="jury_stats_codes"> <table class="jury_stats_codes">
""" """
) )
for code in sorted(table.freq_codes_annuels.keys()): for code in sorted(freq_codes_annuels.keys()):
if code != "total":
H.append( H.append(
f"""<tr> f"""<tr>
<td>{code}</td> <td>{code}</td>
<td style="text-align:right">{table.freq_codes_annuels[code]}</td> <td style="text-align:right">{freq_codes_annuels[code]}</td>
<td style="text-align:right">{ <td style="text-align:right">{
(100*table.freq_codes_annuels[code] / len(table)):2.1f}% (100*freq_codes_annuels[code] / freq_codes_annuels["total"]):2.1f}%
</td> </td>
</tr>""" </tr>"""
) )
H.append( H.append("""</table>""")
""" H.append("""</div>""")
</table>
</div>
"""
)
# Légende # Légende
H.append( H.append(
""" """
@ -272,12 +277,12 @@ def _formsemestre_recapcomplet_to_html(
filename: str = "", filename: str = "",
mode_jury=False, # saisie décisions jury mode_jury=False, # saisie décisions jury
selected_etudid=None, selected_etudid=None,
) -> tuple[str, TableRecap]: ) -> tuple[str, TableRecap, collections.Counter]:
"""Le tableau recap en html""" """Le tableau recap en html"""
if tabformat not in ("html", "evals"): if tabformat not in ("html", "evals"):
raise ScoValueError("invalid table format") raise ScoValueError("invalid table format")
res: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) res: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
table_html, table = gen_formsemestre_recapcomplet_html_table( table_html, table, freq_codes_annuels = gen_formsemestre_recapcomplet_html_table(
formsemestre, formsemestre,
res, res,
include_evaluations=(tabformat == "evals"), include_evaluations=(tabformat == "evals"),
@ -285,7 +290,7 @@ def _formsemestre_recapcomplet_to_html(
filename=filename, filename=filename,
selected_etudid=selected_etudid, selected_etudid=selected_etudid,
) )
return table_html, table return table_html, table, freq_codes_annuels
def _formsemestre_recapcomplet_to_file( def _formsemestre_recapcomplet_to_file(
@ -447,9 +452,9 @@ def gen_formsemestre_recapcomplet_html_table(
mode_jury=False, mode_jury=False,
filename="", filename="",
selected_etudid=None, selected_etudid=None,
) -> tuple[str, TableRecap]: ) -> tuple[str, TableRecap, collections.Counter]:
"""Construit table recap pour le BUT """Construit table recap pour le BUT
Cache le résultat pour le semestre (sauf en mode jury). Cache le résultat pour le semestre.
Note: on cache le HTML et non l'objet Table. Note: on cache le HTML et non l'objet Table.
Si mode_jury, occultera colonnes modules (en js) Si mode_jury, occultera colonnes modules (en js)
@ -461,6 +466,7 @@ def gen_formsemestre_recapcomplet_html_table(
""" """
table = None table = None
table_html = None table_html = None
table_html_cached = None
cache_class = { cache_class = {
(True, True): sco_cache.TableJuryWithEvalsCache, (True, True): sco_cache.TableJuryWithEvalsCache,
(True, False): sco_cache.TableJuryCache, (True, False): sco_cache.TableJuryCache,
@ -468,8 +474,8 @@ def gen_formsemestre_recapcomplet_html_table(
(False, False): sco_cache.TableRecapCache, (False, False): sco_cache.TableRecapCache,
}[(bool(mode_jury), bool(include_evaluations))] }[(bool(mode_jury), bool(include_evaluations))]
if not selected_etudid: if not selected_etudid:
table_html = cache_class.get(formsemestre.id) table_html_cached = cache_class.get(formsemestre.id)
if table_html is None: if table_html_cached is None:
table = _gen_formsemestre_recapcomplet_table( table = _gen_formsemestre_recapcomplet_table(
res, res,
include_evaluations, include_evaluations,
@ -478,9 +484,14 @@ def gen_formsemestre_recapcomplet_html_table(
selected_etudid=selected_etudid, selected_etudid=selected_etudid,
) )
table_html = table.html() table_html = table.html()
cache_class.set(formsemestre.id, table_html) freq_codes_annuels = (
table.freq_codes_annuels if hasattr(table, "freq_codes_annuels") else None
)
cache_class.set(formsemestre.id, (table_html, freq_codes_annuels))
else:
table_html, freq_codes_annuels = table_html_cached
return table_html, table return table_html, table, freq_codes_annuels
def _gen_formsemestre_recapcomplet_table( def _gen_formsemestre_recapcomplet_table(

View File

@ -2773,6 +2773,8 @@ table.notes_recapcomplet a:hover {
div.table_recap_caption { div.table_recap_caption {
width: fit-content; width: fit-content;
margin-top: 8px;
margin-bottom: 8px;
padding: 8px; padding: 8px;
border-radius: 8px; border-radius: 8px;
background-color: rgb(202, 255, 180); background-color: rgb(202, 255, 180);

View File

@ -78,6 +78,7 @@ class TableJury(TableRecap):
dec_rcue = deca.dec_rcue_by_ue.get(rcue.ue_1.id) dec_rcue = deca.dec_rcue_by_ue.get(rcue.ue_1.id)
if dec_rcue is not None: # None si l'UE n'est pas associée à un niveau if dec_rcue is not None: # None si l'UE n'est pas associée à un niveau
row.add_rcue_cols(dec_rcue) row.add_rcue_cols(dec_rcue)
self.freq_codes_annuels["total"] = len(self.rows)
def add_jury(self): def add_jury(self):
"""Ajoute la colonne code jury et le lien. """Ajoute la colonne code jury et le lien.