#!/use/bin/env python # encoding: utf-8 from recopytex.database.filesystem.loader import CSVLoader from recopytex.datalib.dataframe import column_values_to_column import recopytex.datalib.on_score_column as on_column import pandas as pd LOADER = CSVLoader("./test_confia.ml") SCORES_CONFIG = LOADER.get_config()["scores"] def unstack_scores(scores): """Put student_name values to columns :param scores: Score dataframe with one line per score :returns: Scrore dataframe with student_name in columns """ kept_columns = [col for col in LOADER.score_columns if col != "score"] return column_values_to_column("student_name", "score", kept_columns, scores) def stack_scores(scores): """Student columns are melt to rows with student_name column :param scores: Score dataframe with student_name in columns :returns: Scrore dataframe with one line per score """ kept_columns = [ c for c in LOADER.score_columns if c not in ["score", "student_name"] ] student_names = [c for c in scores.columns if c not in kept_columns] return pd.melt( scores, id_vars=kept_columns, value_vars=student_names, var_name="student_name", value_name="score", ) def get_tribes(): return LOADER.get_tribes() def 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) return unstack_scores(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(): score_color = {} for key, score in SCORES_CONFIG.items(): score_color[score["value"]] = score["color"] return score_color def get_level_color_bar(): return [ {"score": s["value"], "name": s["comment"], "color": s["color"]} for s in SCORES_CONFIG.values() ] is_none_score = lambda x: on_column.is_none_score(x, SCORES_CONFIG) score_to_numeric_score = lambda x: on_column.score_to_numeric_score(x, SCORES_CONFIG) score_to_mark = lambda x: on_column.score_to_mark( x, max([v["value"] for v in SCORES_CONFIG.values() if isinstance(v["value"], int)]) ) def score_to_final_mark(scores): """ Compute marks then reduce to final mark per student """ filtered_scores = scores[~scores.apply(is_none_score, axis=1)] filtered_scores = filtered_scores.assign( score=filtered_scores.apply(score_to_numeric_score, axis=1) ) filtered_scores = filtered_scores.assign( mark=filtered_scores.apply(score_to_mark, axis=1) ) final_score = filtered_scores.groupby(["student_name"])[ ["mark", "score_rate"] ].sum() return [final_score.reset_index().to_dict("records")] def pivot_score_on(scores, index, columns, aggfunc="size"): """Pivot scores on index, columns with aggfunc It assumes thant scores are levels """ filtered_scores = scores[~scores.apply(is_none_score, axis=1)] pt = pd.pivot_table( scores, index=index, columns=columns, aggfunc=aggfunc, fill_value=0, ) return pt