Compare commits
4 Commits
3250a600c9
...
ff94470fb4
Author | SHA1 | Date | |
---|---|---|---|
ff94470fb4 | |||
d322452a6e | |||
e1d3940e9d | |||
7dba11996a |
@ -19,6 +19,12 @@ main {
|
|||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
section {
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Exam analysis */
|
/* Exam analysis */
|
||||||
|
|
||||||
#select {
|
#select {
|
||||||
|
@ -5,6 +5,7 @@ import dash
|
|||||||
import dash_html_components as html
|
import dash_html_components as html
|
||||||
import dash_core_components as dcc
|
import dash_core_components as dcc
|
||||||
import dash_table
|
import dash_table
|
||||||
|
import plotly.graph_objects as go
|
||||||
from datetime import date, datetime
|
from datetime import date, datetime
|
||||||
import uuid
|
import uuid
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
@ -56,68 +57,95 @@ layout = html.Div(
|
|||||||
),
|
),
|
||||||
html.Main(
|
html.Main(
|
||||||
children=[
|
children=[
|
||||||
html.Form(
|
html.Section(
|
||||||
id="new-exam",
|
|
||||||
children=[
|
children=[
|
||||||
html.Label(
|
html.Form(
|
||||||
|
id="new-exam",
|
||||||
children=[
|
children=[
|
||||||
"Classe",
|
html.Label(
|
||||||
dcc.Dropdown(
|
children=[
|
||||||
id="tribe",
|
"Classe",
|
||||||
options=[
|
dcc.Dropdown(
|
||||||
{"label": t["name"], "value": t["name"]}
|
id="tribe",
|
||||||
for t in config["tribes"]
|
options=[
|
||||||
],
|
{"label": t["name"], "value": t["name"]}
|
||||||
value=config["tribes"][0]["name"],
|
for t in config["tribes"]
|
||||||
|
],
|
||||||
|
value=config["tribes"][0]["name"],
|
||||||
|
),
|
||||||
|
]
|
||||||
),
|
),
|
||||||
]
|
html.Label(
|
||||||
),
|
children=[
|
||||||
html.Label(
|
"Nom de l'évaluation",
|
||||||
children=[
|
dcc.Input(
|
||||||
"Nom de l'évaluation",
|
id="exam_name",
|
||||||
dcc.Input(
|
type="text",
|
||||||
id="exam_name",
|
placeholder="Nom de l'évaluation",
|
||||||
type="text",
|
),
|
||||||
placeholder="Nom de l'évaluation",
|
]
|
||||||
),
|
),
|
||||||
]
|
html.Label(
|
||||||
),
|
children=[
|
||||||
html.Label(
|
"Date",
|
||||||
children=[
|
dcc.DatePickerSingle(
|
||||||
"Date",
|
id="date",
|
||||||
dcc.DatePickerSingle(
|
date=date.today(),
|
||||||
id="date",
|
**get_current_year_limit(),
|
||||||
date=date.today(),
|
),
|
||||||
**get_current_year_limit(),
|
]
|
||||||
),
|
),
|
||||||
]
|
html.Label(
|
||||||
),
|
children=[
|
||||||
html.Label(
|
"Trimestre",
|
||||||
children=[
|
dcc.Dropdown(
|
||||||
"Trimestre",
|
id="term",
|
||||||
dcc.Dropdown(
|
options=[
|
||||||
id="term",
|
{"label": i + 1, "value": i + 1}
|
||||||
options=[
|
for i in range(3)
|
||||||
{"label": i + 1, "value": i + 1}
|
],
|
||||||
for i in range(3)
|
value=1,
|
||||||
],
|
),
|
||||||
value=1,
|
]
|
||||||
),
|
),
|
||||||
]
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
id="form",
|
||||||
),
|
),
|
||||||
html.Div(
|
html.Section(
|
||||||
|
children=[
|
||||||
|
html.Div(
|
||||||
|
id="exercises",
|
||||||
|
children=[],
|
||||||
|
),
|
||||||
|
html.Button(
|
||||||
|
"Ajouter un exercice",
|
||||||
|
id="add-exercise",
|
||||||
|
className="add-exercise",
|
||||||
|
),
|
||||||
|
html.Div(
|
||||||
|
id="summary",
|
||||||
|
),
|
||||||
|
],
|
||||||
id="exercises",
|
id="exercises",
|
||||||
children=[],
|
|
||||||
),
|
),
|
||||||
html.Button(
|
html.Section(
|
||||||
"Ajouter un exercice",
|
children=[
|
||||||
id="add-exercise",
|
html.Div(
|
||||||
className="add-exercise",
|
id="score_rate",
|
||||||
),
|
),
|
||||||
html.Div(
|
html.Div(
|
||||||
id="summary",
|
id="exercises-viz",
|
||||||
|
),
|
||||||
|
html.Div(
|
||||||
|
id="competences-viz",
|
||||||
|
),
|
||||||
|
html.Div(
|
||||||
|
id="themes-viz",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
id="visualisation",
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
@ -279,6 +307,41 @@ def store_exam(tribe, exam_name, date, term, exercices, elements, elements_id):
|
|||||||
return exam.to_dict()
|
return exam.to_dict()
|
||||||
|
|
||||||
|
|
||||||
|
@app.callback(
|
||||||
|
dash.dependencies.Output("score_rate", "children"),
|
||||||
|
dash.dependencies.Input("exam_store", "data"),
|
||||||
|
prevent_initial_call=True,
|
||||||
|
)
|
||||||
|
def score_rate(data):
|
||||||
|
exam = Exam(**data)
|
||||||
|
return [html.P(f"Barème /{exam.score_rate}")]
|
||||||
|
|
||||||
|
|
||||||
|
@app.callback(
|
||||||
|
dash.dependencies.Output("competences-viz", "figure"),
|
||||||
|
dash.dependencies.Input("exam_store", "data"),
|
||||||
|
prevent_initial_call=True,
|
||||||
|
)
|
||||||
|
def competences_viz(data):
|
||||||
|
exam = Exam(**data)
|
||||||
|
return [html.P(str(exam.competences_rate))]
|
||||||
|
|
||||||
|
|
||||||
|
@app.callback(
|
||||||
|
dash.dependencies.Output("themes-viz", "children"),
|
||||||
|
dash.dependencies.Input("exam_store", "data"),
|
||||||
|
prevent_initial_call=True,
|
||||||
|
)
|
||||||
|
def themes_viz(data):
|
||||||
|
exam = Exam(**data)
|
||||||
|
themes_rate = exam.themes_rate
|
||||||
|
fig = go.Figure()
|
||||||
|
if themes_rate:
|
||||||
|
fig.add_trace(go.Pie(labels=list(themes_rate.keys()), values=list(themes_rate.values())))
|
||||||
|
return [dcc.Graph(figure=fig)]
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
@app.callback(
|
@app.callback(
|
||||||
dash.dependencies.Output("is-saved", "children"),
|
dash.dependencies.Output("is-saved", "children"),
|
||||||
dash.dependencies.Input("save-csv", "n_clicks"),
|
dash.dependencies.Input("save-csv", "n_clicks"),
|
||||||
|
@ -157,3 +157,46 @@ class Exam:
|
|||||||
|
|
||||||
self.tribe_path.mkdir(exist_ok=True)
|
self.tribe_path.mkdir(exist_ok=True)
|
||||||
base_df.to_csv(self.path(".csv"), index=False)
|
base_df.to_csv(self.path(".csv"), index=False)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def score_rate(self):
|
||||||
|
total = 0
|
||||||
|
for ex, questions in self._exercises.items():
|
||||||
|
total += sum([q["score_rate"] for q in questions])
|
||||||
|
|
||||||
|
return total
|
||||||
|
|
||||||
|
@property
|
||||||
|
def competences_rate(self):
|
||||||
|
""" Dictionnary with competences as key and total rate as value"""
|
||||||
|
rates = {}
|
||||||
|
for ex, questions in self._exercises.items():
|
||||||
|
for q in questions:
|
||||||
|
try:
|
||||||
|
q["competence"]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
rates[q["competence"]] += q["score_rate"]
|
||||||
|
except KeyError:
|
||||||
|
rates[q["competence"]] = q["score_rate"]
|
||||||
|
return rates
|
||||||
|
|
||||||
|
@property
|
||||||
|
def themes_rate(self):
|
||||||
|
""" Dictionnary with themes as key and total rate as value"""
|
||||||
|
rates = {}
|
||||||
|
for ex, questions in self._exercises.items():
|
||||||
|
for q in questions:
|
||||||
|
try:
|
||||||
|
q["theme"]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
if q["theme"]:
|
||||||
|
try:
|
||||||
|
rates[q["theme"]] += q["score_rate"]
|
||||||
|
except KeyError:
|
||||||
|
rates[q["theme"]] = q["score_rate"]
|
||||||
|
return rates
|
||||||
|
@ -88,7 +88,7 @@ def new_exam():
|
|||||||
|
|
||||||
@cli.command()
|
@cli.command()
|
||||||
@click.option("--debug", default=0, help="Debug mode for dash")
|
@click.option("--debug", default=0, help="Debug mode for dash")
|
||||||
def exam_analysis(debug):
|
def dashboard(debug):
|
||||||
dash.run_server(debug=bool(debug))
|
dash.run_server(debug=bool(debug))
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user