diff --git a/docs/source/examples/RWTH Evaluation.ipynb b/docs/source/examples/RWTH Evaluation.ipynb index 8a75c848ae0fb48311bf791ff1a963942432692f..2fcf5d0263159ce2628e14fc076ad2bbb0a7ec5d 100644 --- a/docs/source/examples/RWTH Evaluation.ipynb +++ b/docs/source/examples/RWTH Evaluation.ipynb @@ -13,25 +13,15 @@ "metadata": {}, "outputs": [], "source": [ - "from rwth_nb.misc.feedback import RWTHCollector\n", + "from rwth_nb.misc.feedback import RWTHFeedbackCollector\n", "\n", "path_to_folder = './Feedbacks' # path to folder with feedback json files\n", "\n", - "collector = RWTHCollector(path_to_folder)\n", + "collector = RWTHFeedbackCollector(path_to_folder)\n", "data = collector.get_all() # get feedback for all notebooks\n", "data" ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# feedback for only one notebook\n", - "data['GDET3_Discrete_Fourier-Transformation']" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -40,10 +30,17 @@ ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": null, "metadata": {}, + "outputs": [], "source": [ - "TBD" + "%matplotlib widget\n", + "\n", + "from rwth_nb.misc.feedback import RWTHFeedbackEvaluator\n", + "\n", + "eva = RWTHFeedbackEvaluator(data) # collect feedback data using rwth_nb.misc.feedback.RWTHFeedbackCollector first\n", + "eva.evaluate(lang='de')" ] } ], diff --git a/rwth_nb/misc/feedback.py b/rwth_nb/misc/feedback.py index 0abbd7a942efaa5e84e599fd558a74f57e7a3989..5eb4605aaf33b517cc162c5adb937f2e5e1a6c93 100644 --- a/rwth_nb/misc/feedback.py +++ b/rwth_nb/misc/feedback.py @@ -462,3 +462,91 @@ class RWTHCollector: logging.info('Done collecting!') return pd.DataFrame(self.feedbacks) + + +class RWTHFeedbackEvaluator: + """ RWTH Feedback Evaluator Class + + Processes pandas dataframes created with the collector class above into an evaluation interface. + Likert scale like answers are plotted in different styles (box only for now) + Free text answers are collected and displayed into a list for readability + + Parameters + ---------- + data: pandas.Dataframe + dataframe created by collector class using json files + + + Examples + -------- + >>> from rwth_nb.misc.feedback import RWTHFeedbackEvaluator + >>> eva = RWTHFeedbackEvaluator(data) # data: see rwth_nb.misc.feedback.RWTHFeedbackCollector + >>> eva.evaluate(lang='de') + """ + + def __init__(self, data): + self.data = data + + def evaluate(self, lang='en', scale_options=['learning', 'supervision', 'script'], + free_text_options=['likes', 'dislikes', 'misc']): + """ Actual evaluation + + Parameters + ---------- + lang: str, optional + language to be used; the likert scale is chosen accordingly from RWTHFeedback class + + scale_options: list(str), optional + list of ids of the scale option answers in the dataframe + counts of answers identified by those ids are plotted using the likert scale + (e.g. 'Strongly disagree' is incremented when detected, total counts are plotted) + + free_text_options: list(str), optional + list of ids of the free text option answers in the dataframe + answers identified by those ids are inserted into a list + """ + likert_scale = getattr(RWTHFeedback, f'feedback_scale_options_{lang}') + + scale_options = scale_options + free_text_options = free_text_options + + out = [widgets.Output() for _ in self.data] + + accordion = widgets.Accordion(children=out) + for ind, d in enumerate(self.data): + accordion.set_title(ind, d) + display(accordion) + + for ind, d in enumerate(self.data): + with out[ind]: + # likert scale plots + fig, axs = plt.subplots(1, len(scale_options), figsize=(13, 3)) + for i, l in enumerate(scale_options): + # list with counts + counts = [int(self.data[d][l].count(a)) for a in likert_scale] + + # create dataframe x: likert-scale, y: counts + df = pd.Series(counts, index=likert_scale) + + # plot for each option in scale_options + y_label = 'Anzahl' if lang == 'de' else 'Count' + axs[i].set_title(l) + axs[i].set_yticks(range(0, max(counts) + 2)) + df.plot(kind='bar', ax=axs[i], ylabel=y_label, rot=15, fontsize=8, position=0.5, + color=rwth_colors['rwth:blue']) + + plt.tight_layout() + + # free text lists + tab = widgets.Tab() + tab_children = [] + for i, f in enumerate(free_text_options): + tab.set_title(i, f) + + v_box = [widgets.HTML(f'<li>{label}</li>', description_width='initial') if label.strip() else widgets.Label('-') for label in + self.data[d][f]] + + tab_children.append(widgets.VBox(v_box)) + + tab.children = tab_children + display(tab)