Feat: add row to scores_table!!
This commit is contained in:
parent
21397272c9
commit
0a5a931d01
@ -11,6 +11,7 @@ from pathlib import Path
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
import dash_bootstrap_components as dbc
|
||||||
|
|
||||||
|
|
||||||
from .. import flat_df_students, pp_q_scores
|
from .. import flat_df_students, pp_q_scores
|
||||||
@ -25,66 +26,87 @@ COLORS = {
|
|||||||
3: "#68D42F",
|
3: "#68D42F",
|
||||||
}
|
}
|
||||||
|
|
||||||
external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]
|
app = dash.Dash(external_stylesheets=[dbc.themes.SIMPLEX])
|
||||||
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
|
# external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]
|
||||||
|
# app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
|
||||||
# app = dash.Dash(__name__)
|
# app = dash.Dash(__name__)
|
||||||
|
|
||||||
app.layout = html.Div(
|
app.layout = html.Div(
|
||||||
children=[
|
children=[
|
||||||
html.H1("Analyse des notes"),
|
dbc.NavbarSimple(
|
||||||
html.Div(
|
children=[
|
||||||
[
|
dbc.Alert("Dernière sauvegarde", id="lastsave", color="success"),
|
||||||
"Classe: ",
|
|
||||||
dcc.Dropdown(
|
|
||||||
id="tribe",
|
|
||||||
options=[
|
|
||||||
{"label": t["name"], "value": t["name"]}
|
|
||||||
for t in config["tribes"]
|
|
||||||
],
|
|
||||||
value=config["tribes"][0]["name"],
|
|
||||||
),
|
|
||||||
"Evaluation: ",
|
|
||||||
dcc.Dropdown(id="csv"),
|
|
||||||
],
|
],
|
||||||
style={"columnCount": 2},
|
brand="Analyse des notes",
|
||||||
|
brand_href="#",
|
||||||
|
color="success",
|
||||||
|
dark=True,
|
||||||
),
|
),
|
||||||
html.Div(
|
html.Br(),
|
||||||
|
dbc.Row(
|
||||||
[
|
[
|
||||||
dash_table.DataTable(
|
dbc.Col(
|
||||||
id="final_score_table",
|
[
|
||||||
columns=[
|
"Classe: ",
|
||||||
{"id": "Élève", "name": "Élève"},
|
dbc.Select(
|
||||||
{"id": "Note", "name": "Note"},
|
id="tribe",
|
||||||
{"id": "Barème", "name": "Bareme"},
|
options=[
|
||||||
],
|
{"label": t["name"], "value": t["name"]}
|
||||||
data=[],
|
for t in config["tribes"]
|
||||||
style_data_conditional=[
|
],
|
||||||
{
|
value=config["tribes"][0]["name"],
|
||||||
"if": {"row_index": "odd"},
|
),
|
||||||
"backgroundColor": "rgb(248, 248, 248)",
|
]
|
||||||
}
|
|
||||||
],
|
|
||||||
style_header={
|
|
||||||
"backgroundColor": "rgb(230, 230, 230)",
|
|
||||||
"fontWeight": "bold",
|
|
||||||
},
|
|
||||||
style_data={
|
|
||||||
"width": "100px",
|
|
||||||
"maxWidth": "100px",
|
|
||||||
"minWidth": "100px",
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
html.Div(
|
dbc.Col(
|
||||||
|
[
|
||||||
|
"Evaluation: ",
|
||||||
|
dbc.Select(id="csv"),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
html.Br(),
|
||||||
|
dbc.Row(
|
||||||
|
[
|
||||||
|
dbc.Col(
|
||||||
|
dash_table.DataTable(
|
||||||
|
id="final_score_table",
|
||||||
|
columns=[
|
||||||
|
{"id": "Élève", "name": "Élève"},
|
||||||
|
{"id": "Note", "name": "Note"},
|
||||||
|
{"id": "Barème", "name": "Bareme"},
|
||||||
|
],
|
||||||
|
data=[],
|
||||||
|
style_data_conditional=[
|
||||||
|
{
|
||||||
|
"if": {"row_index": "odd"},
|
||||||
|
"backgroundColor": "rgb(248, 248, 248)",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
style_header={
|
||||||
|
"backgroundColor": "rgb(230, 230, 230)",
|
||||||
|
"fontWeight": "bold",
|
||||||
|
},
|
||||||
|
style_data={
|
||||||
|
"width": "100px",
|
||||||
|
"maxWidth": "100px",
|
||||||
|
"minWidth": "100px",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
),
|
||||||
|
dbc.Col(
|
||||||
[
|
[
|
||||||
dash_table.DataTable(
|
dash_table.DataTable(
|
||||||
id="final_score_describe",
|
id="final_score_describe",
|
||||||
),
|
),
|
||||||
dcc.Graph(id="fig_assessment_hist"),
|
dcc.Graph(
|
||||||
dcc.Graph(id="fig_competences"),
|
id="fig_assessment_hist",
|
||||||
|
),
|
||||||
|
# dcc.Graph(id="fig_competences"),
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
style={"columnCount": 2},
|
|
||||||
),
|
),
|
||||||
html.Br(),
|
html.Br(),
|
||||||
html.Div(
|
html.Div(
|
||||||
@ -98,10 +120,10 @@ app.layout = html.Div(
|
|||||||
},
|
},
|
||||||
style_data_conditional=[],
|
style_data_conditional=[],
|
||||||
editable=True,
|
editable=True,
|
||||||
)
|
),
|
||||||
|
dbc.Button("Ajouter un élément", id="btn_add_element"),
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
html.P(id="lastsave"),
|
|
||||||
dcc.Store(id="final_score"),
|
dcc.Store(id="final_score"),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@ -201,74 +223,78 @@ def update_final_scores_hist(data):
|
|||||||
hovertemplate="",
|
hovertemplate="",
|
||||||
marker_color="#4E89DE",
|
marker_color="#4E89DE",
|
||||||
)
|
)
|
||||||
# fig = go.Figure(
|
fig.update_layout(
|
||||||
# data=go.Histogram(
|
height=300,
|
||||||
# x=assessment_scores["Note"],
|
margin=dict(l=5, r=5, b=5, t=5),
|
||||||
# xbins={"start": 0, "end": assessment_scores["Bareme"].max(), "size": 0.25},
|
)
|
||||||
# ),
|
|
||||||
# )
|
|
||||||
return [fig]
|
return [fig]
|
||||||
|
|
||||||
|
|
||||||
|
# @app.callback(
|
||||||
|
# [
|
||||||
|
# dash.dependencies.Output("fig_competences", "figure"),
|
||||||
|
# ],
|
||||||
|
# [dash.dependencies.Input("scores_table", "data")],
|
||||||
|
# )
|
||||||
|
# def update_competence_fig(data):
|
||||||
|
# scores = pd.DataFrame.from_records(data)
|
||||||
|
# scores = flat_df_students(scores).dropna(subset=["Score"])
|
||||||
|
# scores = pp_q_scores(scores)
|
||||||
|
# pt = pd.pivot_table(
|
||||||
|
# scores,
|
||||||
|
# index=["Exercice", "Question", "Commentaire"],
|
||||||
|
# columns="Score",
|
||||||
|
# aggfunc="size",
|
||||||
|
# fill_value=0,
|
||||||
|
# )
|
||||||
|
# for i in {i for i in pt.index.get_level_values(0)}:
|
||||||
|
# pt.loc[(str(i), "", ""), :] = ""
|
||||||
|
# pt.sort_index(inplace=True)
|
||||||
|
# index = (
|
||||||
|
# pt.index.get_level_values(0)
|
||||||
|
# + ":"
|
||||||
|
# + pt.index.get_level_values(1)
|
||||||
|
# + " "
|
||||||
|
# + pt.index.get_level_values(2)
|
||||||
|
# )
|
||||||
|
#
|
||||||
|
# fig = go.Figure()
|
||||||
|
# bars = [
|
||||||
|
# {"score": -1, "name": "Pas de réponse", "color": COLORS["."]},
|
||||||
|
# {"score": 0, "name": "Faut", "color": COLORS[0]},
|
||||||
|
# {"score": 1, "name": "Peu juste", "color": COLORS[1]},
|
||||||
|
# {"score": 2, "name": "Presque juste", "color": COLORS[2]},
|
||||||
|
# {"score": 3, "name": "Juste", "color": COLORS[3]},
|
||||||
|
# ]
|
||||||
|
# for b in bars:
|
||||||
|
# try:
|
||||||
|
# fig.add_bar(
|
||||||
|
# x=index, y=pt[b["score"]], name=b["name"], marker_color=b["color"]
|
||||||
|
# )
|
||||||
|
# except KeyError:
|
||||||
|
# pass
|
||||||
|
# fig.update_layout(barmode="relative")
|
||||||
|
# return [fig]
|
||||||
|
|
||||||
|
|
||||||
@app.callback(
|
@app.callback(
|
||||||
[
|
[
|
||||||
dash.dependencies.Output("fig_competences", "figure"),
|
dash.dependencies.Output("lastsave", "children"),
|
||||||
|
dash.dependencies.Output("lastsave", "color"),
|
||||||
],
|
],
|
||||||
[dash.dependencies.Input("scores_table", "data")],
|
|
||||||
)
|
|
||||||
def update_competence_fig(data):
|
|
||||||
scores = pd.DataFrame.from_records(data)
|
|
||||||
scores = flat_df_students(scores).dropna(subset=["Score"])
|
|
||||||
scores = pp_q_scores(scores)
|
|
||||||
pt = pd.pivot_table(
|
|
||||||
scores,
|
|
||||||
index=["Exercice", "Question", "Commentaire"],
|
|
||||||
columns="Score",
|
|
||||||
aggfunc="size",
|
|
||||||
fill_value=0,
|
|
||||||
)
|
|
||||||
for i in {i for i in pt.index.get_level_values(0)}:
|
|
||||||
pt.loc[(str(i), "", ""), :] = ""
|
|
||||||
pt.sort_index(inplace=True)
|
|
||||||
index = (
|
|
||||||
pt.index.get_level_values(0)
|
|
||||||
+ ":"
|
|
||||||
+ pt.index.get_level_values(1)
|
|
||||||
+ " "
|
|
||||||
+ pt.index.get_level_values(2)
|
|
||||||
)
|
|
||||||
|
|
||||||
fig = go.Figure()
|
|
||||||
bars = [
|
|
||||||
{"score": -1, "name": "Pas de réponse", "color": COLORS["."]},
|
|
||||||
{"score": 0, "name": "Faut", "color": COLORS[0]},
|
|
||||||
{"score": 1, "name": "Peu juste", "color": COLORS[1]},
|
|
||||||
{"score": 2, "name": "Presque juste", "color": COLORS[2]},
|
|
||||||
{"score": 3, "name": "Juste", "color": COLORS[3]},
|
|
||||||
]
|
|
||||||
for b in bars:
|
|
||||||
try:
|
|
||||||
fig.add_bar(
|
|
||||||
x=index, y=pt[b["score"]], name=b["name"], marker_color=b["color"]
|
|
||||||
)
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
fig.update_layout(barmode="relative")
|
|
||||||
return [fig]
|
|
||||||
|
|
||||||
|
|
||||||
@app.callback(
|
|
||||||
[dash.dependencies.Output("lastsave", "children")],
|
|
||||||
[
|
[
|
||||||
dash.dependencies.Input("scores_table", "data"),
|
dash.dependencies.Input("scores_table", "data"),
|
||||||
dash.dependencies.State("csv", "value"),
|
dash.dependencies.State("csv", "value"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
def save_scores(data, csv):
|
def save_scores(data, csv):
|
||||||
scores = pd.DataFrame.from_records(data)
|
try:
|
||||||
print(f"save at {csv} ({datetime.today()})")
|
scores = pd.DataFrame.from_records(data)
|
||||||
scores.to_csv(csv, index=False)
|
scores.to_csv(csv, index=False)
|
||||||
return [datetime.today()]
|
except:
|
||||||
|
return [f"Soucis pour sauvegarder à {datetime.today()} dans {csv}"], "warning"
|
||||||
|
else:
|
||||||
|
return [f"Dernière sauvegarde {datetime.today()} dans {csv}"], "success"
|
||||||
|
|
||||||
|
|
||||||
def highlight_value(df):
|
def highlight_value(df):
|
||||||
@ -293,18 +319,23 @@ def highlight_value(df):
|
|||||||
dash.dependencies.Output("scores_table", "data"),
|
dash.dependencies.Output("scores_table", "data"),
|
||||||
dash.dependencies.Output("scores_table", "style_data_conditional"),
|
dash.dependencies.Output("scores_table", "style_data_conditional"),
|
||||||
],
|
],
|
||||||
[dash.dependencies.Input("csv", "value")],
|
[
|
||||||
|
dash.dependencies.Input("csv", "value"),
|
||||||
|
dash.dependencies.Input("btn_add_element", "n_clicks"),
|
||||||
|
dash.dependencies.State("scores_table", "data"),
|
||||||
|
],
|
||||||
)
|
)
|
||||||
def update_scores_table(value):
|
def update_scores_table(csv, add_element, data):
|
||||||
if not value:
|
ctx = dash.callback_context
|
||||||
raise PreventUpdate
|
if ctx.triggered[0]['prop_id'] == "csv.value":
|
||||||
stack = pd.read_csv(value, encoding="UTF8")
|
stack = pd.read_csv(csv, encoding="UTF8")
|
||||||
# try:
|
elif ctx.triggered[0]['prop_id'] == "btn_add_element.n_clicks":
|
||||||
# stack = stack.drop(columns=["Nom", "Trimestre", "Date", "Competence", "Domaine", "Est_nivele", "Bareme"])
|
stack = pd.DataFrame.from_records(data)
|
||||||
# except KeyError:
|
infos = pd.DataFrame.from_records([{k: stack.iloc[-1][k] for k in NO_ST_COLUMNS.values()}])
|
||||||
# stack = stack
|
stack = stack.append(infos)
|
||||||
return (
|
return (
|
||||||
[{"id": c, "name": c} for c in stack.columns],
|
[{"id": c, "name": c} for c in stack.columns],
|
||||||
stack.to_dict("records"),
|
stack.to_dict("records"),
|
||||||
highlight_value(stack),
|
highlight_value(stack),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user