Compare commits

..

No commits in common. "9e0ea14d05fd1e20c73cc5a7826c3ad2882348a1" and "a50901556e243bca6098de19980a5a4a96329f65" have entirely different histories.

4 changed files with 102 additions and 178 deletions

View File

@ -15,11 +15,10 @@ layout = html.Div(
], ],
), ),
html.Main( html.Main(
children=[
html.Section( html.Section(
children=[ [
html.Div( html.Div(
children=[ [
"Classe: ", "Classe: ",
dcc.Dropdown( dcc.Dropdown(
id="tribe", id="tribe",
@ -32,36 +31,45 @@ layout = html.Div(
], ],
), ),
html.Div( html.Div(
children=[ [
"Evaluation: ", "Evaluation: ",
dcc.Dropdown(id="exam_select"), dcc.Dropdown(id="exam_select"),
], ],
), html.P(id="test"),
], ],
id="selects", id="select",
), ),
html.Section( html.Section(
children=[ [
html.Div( html.Div(
children=[], 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="final_score_table_container",
), ),
], ],
id="analysis", id="analysis",
), ),
html.Section( html.Section(
children=[
dash_table.DataTable(
id="scores_table", id="scores_table",
columns=[],
style_data_conditional=[],
fixed_columns={},
editable=True,
)
],
id="edit",
), ),
],
), ),
dcc.Store(id="scores"), dcc.Store(id="scores"),
], ],

View File

@ -1,15 +1,11 @@
#!/usr/bin/env python #!/usr/bin/env python
# encoding: utf-8 # encoding: utf-8
from dash.dependencies import Input, Output, State from dash.dependencies import Input, Output
import dash
from dash.exceptions import PreventUpdate from dash.exceptions import PreventUpdate
import dash_table
import json
import pandas as pd
from ...app import app from ...app import app
from .models import get_tribes, get_exams, get_unstack_scores, get_students_from_exam from .models import get_tribes, get_exams
@app.callback( @app.callback(
@ -19,11 +15,12 @@ from .models import get_tribes, get_exams, get_unstack_scores, get_students_from
], ],
[Input("tribe", "value")], [Input("tribe", "value")],
) )
def update_exams_choices(tribe): def update_csvs(value):
if not tribe: if not value:
raise PreventUpdate raise PreventUpdate
exams = get_exams(tribe) exams = get_exams(value)
exams.reset_index(inplace=True) exams.reset_index(inplace=True)
print(exams.loc[0, "name"])
if not exams.empty: if not exams.empty:
return [ return [
{"label": e["name"], "value": e.to_json()} for i, e in exams.iterrows() {"label": e["name"], "value": e.to_json()} for i, e in exams.iterrows()
@ -33,35 +30,24 @@ def update_exams_choices(tribe):
@app.callback( @app.callback(
[ [
Output("scores_table", "columns"), dash.dependencies.Output("final_score", "data"),
Output("scores_table", "data"),
Output("scores_table", "style_data_conditional"),
Output("scores_table", "fixed_columns"),
],
[
Input("exam_select", "value"),
], ],
[dash.dependencies.Input("scores_table", "data")],
) )
def update_scores_store(exam): def update_final_scores(data):
ctx = dash.callback_context if not data:
if not exam: raise PreventUpdate
return [[], [], [], {}]
exam = pd.DataFrame.from_dict([json.loads(exam)])
scores = get_unstack_scores(exam)
fixed_columns = [
"exercise",
"question",
"competence",
"theme",
"comment",
"score_rate",
"is_leveled",
]
columns = fixed_columns + list(get_students_from_exam(exam))
return [ scores = pd.DataFrame.from_records(data)
[{"id": c, "name": c} for c in columns], try:
scores.to_dict("records"), if scores.iloc[0]["Commentaire"] == "commentaire":
[], scores.drop([0], inplace=True)
{"headers": True, "data": len(fixed_columns)}, 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")]

View File

@ -1,8 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
# encoding: utf-8 # encoding: utf-8
from recopytex.database.filesystem.loader import CSVLoader from ....database.filesystem.loader import CSVLoader
from recopytex.lib.dataframe import column_values_to_column
LOADER = CSVLoader("./test_config.yml") LOADER = CSVLoader("./test_config.yml")
@ -14,17 +13,3 @@ def get_tribes():
def get_exams(tribe): def get_exams(tribe):
return LOADER.get_exams([tribe]) return LOADER.get_exams([tribe])
def get_record_scores(exam):
return LOADER.get_exam_scores(exam)
def get_unstack_scores(exam):
flat_scores = LOADER.get_exam_scores(exam)
kept_columns = [col for col in LOADER.score_columns if col != "score"]
return column_values_to_column(flat_scores, "student_name", "score", kept_columns)
def get_students_from_exam(exam):
flat_scores = LOADER.get_exam_scores(exam)
return flat_scores["student_name"].unique()

View File

@ -43,49 +43,6 @@ class CSVLoader(Loader):
""" Get config """ """ Get config """
return self._config return self._config
@property
def exam_columns(self):
return pd.Index(["name", "date", "term", "origin", "tribe", "id"])
@property
def question_columns(self):
return pd.Index(
[
"exercise",
"question",
"competence",
"theme",
"comment",
"score_rate",
"is_leveled",
"origin",
"exam_id",
"id",
]
)
@property
def score_columns(self):
return pd.Index(
[
"term",
"exam",
"date",
"exercise",
"question",
"competence",
"theme",
"comment",
"score_rate",
"is_leveled",
"origin",
"exam_id",
"question_id",
"student_name",
"score",
]
)
def rename_columns(self, dataframe): def rename_columns(self, dataframe):
"""Rename dataframe column to match with `csv_fields` """Rename dataframe column to match with `csv_fields`
@ -127,8 +84,8 @@ class CSVLoader(Loader):
:example: :example:
>>> loader = CSVLoader("./test_config.yml") >>> loader = CSVLoader("./test_config.yml")
>>> exams = loader.get_exams(["Tribe1"]) >>> exams = loader.get_exams(["Tribe1"])
>>> all(exams.columns == loader.exam_columns) >>> exams.columns
True Index(['name', 'date', 'term', 'origin', 'tribe', 'id'], dtype='object')
>>> exams >>> exams
name date term origin tribe id name date term origin tribe id
0 DS 12/01/2021 1 example/Tribe1/210112_DS.csv Tribe1 DS_Tribe1 0 DS 12/01/2021 1 example/Tribe1/210112_DS.csv Tribe1 DS_Tribe1
@ -161,7 +118,10 @@ class CSVLoader(Loader):
:example: :example:
>>> loader = CSVLoader("./test_config.yml") >>> loader = CSVLoader("./test_config.yml")
>>> exams = loader.get_exams(["Tribe1"]) >>> exams = loader.get_exams(["Tribe1"])
>>> all(loader.get_exam_questions([exams.iloc[0]]).columns == loader.score_columns) >>> loader.get_exam_questions([exams.iloc[0]]).columns
Index(['exercise', 'question', 'competence', 'theme', 'comment', 'score_rate',
'is_leveled', 'origin', 'exam_id', 'id'],
dtype='object')
>>> questions = loader.get_exam_questions(exams) >>> questions = loader.get_exam_questions(exams)
>>> questions.iloc[0] >>> questions.iloc[0]
exercise Exercice 1 exercise Exercice 1
@ -212,8 +172,11 @@ class CSVLoader(Loader):
>>> exams = loader.get_exams(["Tribe1"]) >>> exams = loader.get_exams(["Tribe1"])
>>> questions = loader.get_exam_questions(exams) >>> questions = loader.get_exam_questions(exams)
>>> scores = loader.get_questions_scores(questions) >>> scores = loader.get_questions_scores(questions)
>>> all(scores.columns == loader.score_columns) >>> scores.columns
True Index(['term', 'exam', 'date', 'exercise', 'question', 'competence', 'theme',
'comment', 'score_rate', 'is_leveled', 'origin', 'exam_id',
'question_id', 'student_name', 'score'],
dtype='object')
>>> scores["student_name"].unique() >>> scores["student_name"].unique()
array(['Star Tice', 'Umberto Dingate', 'Starlin Crangle', array(['Star Tice', 'Umberto Dingate', 'Starlin Crangle',
'Humbert Bourcq', 'Gabriella Handyside', 'Stewart Eaves', 'Humbert Bourcq', 'Gabriella Handyside', 'Stewart Eaves',
@ -251,24 +214,6 @@ class CSVLoader(Loader):
return pd.concat(scores) return pd.concat(scores)
def get_exam_scores(self, exams=[]):
"""Get scores for all question of the exam
:param exams: list or dataframe of exams metadatas (need origin field to find the csv)
:example:
>>> loader = CSVLoader("./test_config.yml")
>>> exams = loader.get_exams(["Tribe1"])
>>> scores = loader.get_exam_scores(exams)
>>> scores.columns
Index(['term', 'exam', 'date', 'exercise', 'question', 'competence', 'theme',
'comment', 'score_rate', 'is_leveled', 'origin', 'exam_id',
'question_id', 'student_name', 'score'],
dtype='object')
"""
questions = self.get_exam_questions(exams)
return self.get_questions_scores(questions)
def get_students(self, tribes=[]): def get_students(self, tribes=[]):
"""Get student list """Get student list