From a50901556e243bca6098de19980a5a4a96329f65 Mon Sep 17 00:00:00 2001 From: Bertrand Benjamin Date: Sun, 18 Apr 2021 10:02:10 +0200 Subject: [PATCH] Feat: start exams scores pages --- recopytex/dashboard/pages/exam_scores/app.py | 0 .../dashboard/pages/exam_scores/callbacks.py | 0 .../dashboard/pages/exam_scores/models.py | 0 .../{exam_scores => exams_scores}/__init__.py | 0 recopytex/dashboard/pages/exams_scores/app.py | 76 +++++++++++++++++++ .../dashboard/pages/exams_scores/callbacks.py | 53 +++++++++++++ .../dashboard/pages/exams_scores/models.py | 15 ++++ recopytex/dashboard/routes.py | 19 ++--- 8 files changed, 154 insertions(+), 9 deletions(-) delete mode 100644 recopytex/dashboard/pages/exam_scores/app.py delete mode 100644 recopytex/dashboard/pages/exam_scores/callbacks.py delete mode 100644 recopytex/dashboard/pages/exam_scores/models.py rename recopytex/dashboard/pages/{exam_scores => exams_scores}/__init__.py (100%) create mode 100644 recopytex/dashboard/pages/exams_scores/app.py create mode 100644 recopytex/dashboard/pages/exams_scores/callbacks.py create mode 100644 recopytex/dashboard/pages/exams_scores/models.py diff --git a/recopytex/dashboard/pages/exam_scores/app.py b/recopytex/dashboard/pages/exam_scores/app.py deleted file mode 100644 index e69de29..0000000 diff --git a/recopytex/dashboard/pages/exam_scores/callbacks.py b/recopytex/dashboard/pages/exam_scores/callbacks.py deleted file mode 100644 index e69de29..0000000 diff --git a/recopytex/dashboard/pages/exam_scores/models.py b/recopytex/dashboard/pages/exam_scores/models.py deleted file mode 100644 index e69de29..0000000 diff --git a/recopytex/dashboard/pages/exam_scores/__init__.py b/recopytex/dashboard/pages/exams_scores/__init__.py similarity index 100% rename from recopytex/dashboard/pages/exam_scores/__init__.py rename to recopytex/dashboard/pages/exams_scores/__init__.py diff --git a/recopytex/dashboard/pages/exams_scores/app.py b/recopytex/dashboard/pages/exams_scores/app.py new file mode 100644 index 0000000..3072a8b --- /dev/null +++ b/recopytex/dashboard/pages/exams_scores/app.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python +# encoding: utf-8 + +import dash_html_components as html +import dash_core_components as dcc +from .models import get_tribes, get_exams +from .callbacks import * + +layout = html.Div( + children=[ + html.Header( + children=[ + html.H1("Analyse des notes"), + html.P("Dernière sauvegarde", id="lastsave"), + ], + ), + html.Main( + html.Section( + [ + html.Div( + [ + "Classe: ", + dcc.Dropdown( + id="tribe", + options=[ + {"label": t["name"], "value": t["name"]} + for t in get_tribes().values() + ], + value=next(iter(get_tribes().values()))["name"], + ), + ], + ), + html.Div( + [ + "Evaluation: ", + dcc.Dropdown(id="exam_select"), + ], + html.P(id="test"), + ], + id="select", + ), + html.Section( + [ + html.Div( + dash_table.DataTable( + id="final_score_table", + columns=[ + {"id": "Eleve", "name": "Élève"}, + {"id": "Note", "name": "Note"}, + {"id": "Bareme", "name": "Barème"}, + ], + data=[], + style_data_conditional=[ + { + "if": {"row_index": "odd"}, + "backgroundColor": "rgb(248, 248, 248)", + } + ], + style_data={ + "width": "100px", + "maxWidth": "100px", + "minWidth": "100px", + }, + ), + id="final_score_table_container", + ), + ], + id="analysis", + ), + html.Section( + id="scores_table", + ), + ), + dcc.Store(id="scores"), + ], +) diff --git a/recopytex/dashboard/pages/exams_scores/callbacks.py b/recopytex/dashboard/pages/exams_scores/callbacks.py new file mode 100644 index 0000000..b5b6198 --- /dev/null +++ b/recopytex/dashboard/pages/exams_scores/callbacks.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python +# encoding: utf-8 + +from dash.dependencies import Input, Output +from dash.exceptions import PreventUpdate + +from ...app import app +from .models import get_tribes, get_exams + + +@app.callback( + [ + Output("exam_select", "options"), + Output("exam_select", "value"), + ], + [Input("tribe", "value")], +) +def update_csvs(value): + if not value: + raise PreventUpdate + exams = get_exams(value) + exams.reset_index(inplace=True) + print(exams.loc[0, "name"]) + if not exams.empty: + return [ + {"label": e["name"], "value": e.to_json()} for i, e in exams.iterrows() + ], exams.loc[0].to_json() + return [], None + + +@app.callback( + [ + dash.dependencies.Output("final_score", "data"), + ], + [dash.dependencies.Input("scores_table", "data")], +) +def update_final_scores(data): + if not data: + raise PreventUpdate + + scores = pd.DataFrame.from_records(data) + try: + if scores.iloc[0]["Commentaire"] == "commentaire": + scores.drop([0], inplace=True) + except KeyError: + pass + scores = flat_df_students(scores).dropna(subset=["Score"]) + if scores.empty: + return [{}] + + scores = pp_q_scores(scores) + assessment_scores = scores.groupby(["Eleve"]).agg({"Note": "sum", "Bareme": "sum"}) + return [assessment_scores.reset_index().to_dict("records")] diff --git a/recopytex/dashboard/pages/exams_scores/models.py b/recopytex/dashboard/pages/exams_scores/models.py new file mode 100644 index 0000000..9d38e7e --- /dev/null +++ b/recopytex/dashboard/pages/exams_scores/models.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python +# encoding: utf-8 + +from ....database.filesystem.loader import CSVLoader + +LOADER = CSVLoader("./test_config.yml") + + +def get_tribes(): + return LOADER.get_tribes() + + +def get_exams(tribe): + return LOADER.get_exams([tribe]) + diff --git a/recopytex/dashboard/routes.py b/recopytex/dashboard/routes.py index 4d081a0..77e1642 100644 --- a/recopytex/dashboard/routes.py +++ b/recopytex/dashboard/routes.py @@ -5,21 +5,22 @@ from dash.dependencies import Input, Output from .app import app from .pages.home import app as home +from .pages.exams_scores import app as exams_scores @app.callback(Output("page-content", "children"), [Input("url", "pathname")]) def render_page_content(pathname): if pathname == "/": return home.layout - # elif pathname == gdp_page_location: - # return gdp.layout + elif pathname == "/exams/scores/": + return exams_scores.layout # elif pathname == iris_page_location: # return iris.layout # # If the user tries to reach a different page, return a 404 message - # return dbc.Jumbotron( - # [ - # html.H1("404: Not found", className="text-danger"), - # html.Hr(), - # html.P(f"The pathname {pathname} was not recognised..."), - # ] - # ) + return html.Div( + [ + html.H1("404: Not found", className="text-danger"), + html.Hr(), + html.P(f"The pathname {pathname} was not recognised..."), + ] + )