Compare commits
4 Commits
a8b2ac455d
...
7553628306
Author | SHA1 | Date | |
---|---|---|---|
7553628306 | |||
effc049578 | |||
411f910ce6 | |||
00d81d694a |
23
recopytex/dashboard/common/formating.py
Normal file
23
recopytex/dashboard/common/formating.py
Normal file
@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
|
||||
def highlight_scores(highlight_columns, score_color):
|
||||
""" Cells style in a datatable for scores
|
||||
|
||||
:param highlight_columns: columns to highlight
|
||||
:param value_color: dictionnary {"score": "color"}
|
||||
|
||||
"""
|
||||
hight = []
|
||||
for v, color in score_color.items():
|
||||
if v:
|
||||
hight += [
|
||||
{
|
||||
"if": {"filter_query": "{{{}}} = {}".format(col, v), "column_id": col},
|
||||
"backgroundColor": color,
|
||||
"color": "white",
|
||||
}
|
||||
for col in highlight_columns
|
||||
]
|
||||
return hight
|
@ -8,8 +8,16 @@ import dash_table
|
||||
import json
|
||||
import pandas as pd
|
||||
|
||||
from ...app import app
|
||||
from .models import get_tribes, get_exams, get_unstack_scores, get_students_from_exam
|
||||
from recopytex.dashboard.app import app
|
||||
from recopytex.dashboard.common.formating import highlight_scores
|
||||
|
||||
from .models import (
|
||||
get_tribes,
|
||||
get_exams,
|
||||
get_unstack_scores,
|
||||
get_students_from_exam,
|
||||
get_score_colors,
|
||||
)
|
||||
|
||||
|
||||
@app.callback(
|
||||
@ -57,11 +65,15 @@ def update_scores_store(exam):
|
||||
"score_rate",
|
||||
"is_leveled",
|
||||
]
|
||||
columns = fixed_columns + list(get_students_from_exam(exam))
|
||||
|
||||
students = list(get_students_from_exam(exam))
|
||||
columns = fixed_columns + students
|
||||
|
||||
score_color = get_score_colors()
|
||||
|
||||
return [
|
||||
[{"id": c, "name": c} for c in columns],
|
||||
scores.to_dict("records"),
|
||||
[],
|
||||
highlight_scores(students, score_color),
|
||||
{"headers": True, "data": len(fixed_columns)},
|
||||
]
|
||||
|
@ -2,7 +2,7 @@
|
||||
# encoding: utf-8
|
||||
|
||||
from recopytex.database.filesystem.loader import CSVLoader
|
||||
from recopytex.lib.dataframe import column_values_to_column
|
||||
from recopytex.datalib.dataframe import column_values_to_column
|
||||
|
||||
LOADER = CSVLoader("./test_config.yml")
|
||||
|
||||
@ -22,9 +22,17 @@ def get_record_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)
|
||||
return column_values_to_column("student_name", "score", kept_columns, flat_scores)
|
||||
|
||||
|
||||
def get_students_from_exam(exam):
|
||||
flat_scores = LOADER.get_exam_scores(exam)
|
||||
return flat_scores["student_name"].unique()
|
||||
|
||||
|
||||
def get_score_colors():
|
||||
scores_config = LOADER.get_config()["valid_scores"]
|
||||
score_color = {}
|
||||
for key, score in scores_config.items():
|
||||
score_color[score["value"]] = score["color"]
|
||||
return score_color
|
||||
|
@ -22,13 +22,27 @@ competences: # Competences
|
||||
abrv: Com
|
||||
|
||||
valid_scores: #
|
||||
BAD: 0 # Everything is bad
|
||||
FEW: 1 # Few good things
|
||||
NEARLY: 2 # Nearly good but things are missing
|
||||
GOOD: 3 # Everything is good
|
||||
BAD: # Everything is bad
|
||||
value: 0
|
||||
color: "#E7472B"
|
||||
FEW: # Few good things
|
||||
value: 1
|
||||
color: "#FF712B"
|
||||
NEARLY: # Nearly good but things are missing
|
||||
value: 2
|
||||
color: "#F2EC4C"
|
||||
GOOD: # Everything is good
|
||||
value: 3
|
||||
color: "#68D42F"
|
||||
NOTFILLED: # The item is not scored yet
|
||||
NOANSWER: . # Student gives no answer (count as 0)
|
||||
ABS: "a" # Student has absent (this score won't be impact the final mark)
|
||||
value: ""
|
||||
color: white
|
||||
NOANSWER: # Student gives no answer (count as 0)
|
||||
value: "."
|
||||
color: black
|
||||
ABS: # Student has absent (this score won't be impact the final mark)
|
||||
value: a
|
||||
color: lightgray
|
||||
|
||||
csv_fields: # dataframe_field: csv_field
|
||||
term: Trimestre
|
||||
|
@ -31,10 +31,10 @@ class CSVLoader(Loader):
|
||||
:example:
|
||||
>>> loader = CSVLoader()
|
||||
>>> loader.get_config()
|
||||
{'source': './', 'competences': {'Chercher': {'name': 'Chercher', 'abrv': 'Cher'}, 'Représenter': {'name': 'Représenter', 'abrv': 'Rep'}, 'Modéliser': {'name': 'Modéliser', 'abrv': 'Mod'}, 'Raisonner': {'name': 'Raisonner', 'abrv': 'Rai'}, 'Calculer': {'name': 'Calculer', 'abrv': 'Cal'}, 'Communiquer': {'name': 'Communiquer', 'abrv': 'Com'}}, 'valid_scores': {'BAD': 0, 'FEW': 1, 'NEARLY': 2, 'GOOD': 3, 'NOTFILLED': None, 'NOANSWER': '.', 'ABS': 'a'}, 'csv_fields': {'term': 'Trimestre', 'exam': 'Nom', 'date': 'Date', 'exercise': 'Exercice', 'question': 'Question', 'competence': 'Competence', 'theme': 'Domaine', 'comment': 'Commentaire', 'score_rate': 'Bareme', 'is_leveled': 'Est_nivele'}, 'id_templates': {'exam': '{name}_{tribe}', 'question': '{exam_id}_{exercise}_{question}_{comment}'}}
|
||||
{'source': './', 'competences': {'Chercher': {'name': 'Chercher', 'abrv': 'Cher'}, 'Représenter': {'name': 'Représenter', 'abrv': 'Rep'}, 'Modéliser': {'name': 'Modéliser', 'abrv': 'Mod'}, 'Raisonner': {'name': 'Raisonner', 'abrv': 'Rai'}, 'Calculer': {'name': 'Calculer', 'abrv': 'Cal'}, 'Communiquer': {'name': 'Communiquer', 'abrv': 'Com'}}, 'valid_scores': {'BAD': {'value': 0, 'color': '#E7472B'}, 'FEW': {'value': 1, 'color': '#FF712B'}, 'NEARLY': {'value': 2, 'color': '#F2EC4C'}, 'GOOD': {'value': 3, 'color': '#68D42F'}, 'NOTFILLED': {'value': '', 'color': 'white'}, 'NOANSWER': {'value': '.', 'color': 'black'}, 'ABS': {'value': 'a', 'color': 'lightgray'}}, 'csv_fields': {'term': 'Trimestre', 'exam': 'Nom', 'date': 'Date', 'exercise': 'Exercice', 'question': 'Question', 'competence': 'Competence', 'theme': 'Domaine', 'comment': 'Commentaire', 'score_rate': 'Bareme', 'is_leveled': 'Est_nivele'}, 'id_templates': {'exam': '{name}_{tribe}', 'question': '{exam_id}_{exercise}_{question}_{comment}'}}
|
||||
>>> loader = CSVLoader("./test_config.yml")
|
||||
>>> loader.get_config()
|
||||
{'source': './example', 'competences': {'Chercher': {'name': 'Chercher', 'abrv': 'Cher'}, 'Représenter': {'name': 'Représenter', 'abrv': 'Rep'}, 'Modéliser': {'name': 'Modéliser', 'abrv': 'Mod'}, 'Raisonner': {'name': 'Raisonner', 'abrv': 'Rai'}, 'Calculer': {'name': 'Calculer', 'abrv': 'Cal'}, 'Communiquer': {'name': 'Communiquer', 'abrv': 'Com'}}, 'valid_scores': {'BAD': 0, 'FEW': 1, 'NEARLY': 2, 'GOOD': 3, 'NOTFILLED': None, 'NOANSWER': '.', 'ABS': 'a'}, 'csv_fields': {'term': 'Trimestre', 'exam': 'Nom', 'date': 'Date', 'exercise': 'Exercice', 'question': 'Question', 'competence': 'Competence', 'theme': 'Domaine', 'comment': 'Commentaire', 'score_rate': 'Bareme', 'is_leveled': 'Est_nivele'}, 'id_templates': {'exam': '{name}_{tribe}', 'question': '{exam_id}_{exercise}_{question}_{comment}'}, 'output': './output', 'templates': 'templates/', 'tribes': {'Tribe1': {'name': 'Tribe1', 'type': 'Type1', 'students': 'tribe1.csv'}, 'Tribe2': {'name': 'Tribe2', 'students': 'tribe2.csv'}}}
|
||||
{'source': './example', 'competences': {'Chercher': {'name': 'Chercher', 'abrv': 'Cher'}, 'Représenter': {'name': 'Représenter', 'abrv': 'Rep'}, 'Modéliser': {'name': 'Modéliser', 'abrv': 'Mod'}, 'Raisonner': {'name': 'Raisonner', 'abrv': 'Rai'}, 'Calculer': {'name': 'Calculer', 'abrv': 'Cal'}, 'Communiquer': {'name': 'Communiquer', 'abrv': 'Com'}}, 'valid_scores': {'BAD': {'value': 0, 'color': '#E7472B'}, 'FEW': {'value': 1, 'color': '#FF712B'}, 'NEARLY': {'value': 2, 'color': '#F2EC4C'}, 'GOOD': {'value': 3, 'color': '#68D42F'}, 'NOTFILLED': {'value': '', 'color': 'white'}, 'NOANSWER': {'value': '.', 'color': 'black'}, 'ABS': {'value': 'a', 'color': 'lightgray'}}, 'csv_fields': {'term': 'Trimestre', 'exam': 'Nom', 'date': 'Date', 'exercise': 'Exercice', 'question': 'Question', 'competence': 'Competence', 'theme': 'Domaine', 'comment': 'Commentaire', 'score_rate': 'Bareme', 'is_leveled': 'Est_nivele'}, 'id_templates': {'exam': '{name}_{tribe}', 'question': '{exam_id}_{exercise}_{question}_{comment}'}, 'output': './output', 'templates': 'templates/', 'tribes': {'Tribe1': {'name': 'Tribe1', 'type': 'Type1', 'students': 'tribe1.csv'}, 'Tribe2': {'name': 'Tribe2', 'students': 'tribe2.csv'}}}
|
||||
"""
|
||||
|
||||
CONFIG = DEFAULT_CONFIG
|
||||
|
21
recopytex/datalib/dataframe.py
Normal file
21
recopytex/datalib/dataframe.py
Normal file
@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
|
||||
|
||||
def column_values_to_column(pivot_column, value_column, kept_columns, df):
|
||||
"""Pivot_column's values go to column with value_column under it, keeping kept_columns
|
||||
|
||||
:param pivot_column: column name where value will become columns
|
||||
:param value_column: column name where value will be under pivot_column
|
||||
:param kept_columns: unchanged columns
|
||||
:param df: DataFrame to work with
|
||||
|
||||
:return: Stack dataframe
|
||||
|
||||
"""
|
||||
if pivot_column in kept_columns:
|
||||
pivot_columns = kept_columns
|
||||
else:
|
||||
pivot_columns = kept_columns + [pivot_column]
|
||||
|
||||
return df.set_index(pivot_columns).unstack(pivot_column)[value_column].reset_index()
|
Loading…
Reference in New Issue
Block a user