#!/usr/bin/env python3 """Evaluate grades from a moodle activity grades csv export""" import argparse import csv import locale # Example: Donnerstag, 16. Oktober 2025 MOODLE_DATE_FORMAT = '%A, %d. %B %Y, %H:%M' def print_group_means(grades: dict[str, list[str]], groups_csv_path: str): """Print the means of groups""" with open(groups_csv_path, 'r', encoding='utf-8') as groups_csv_file: # groups_reader = csv.reader(groups_csv_file) # groups_data = list(groups_reader) # groups_data = list(groups_reader) lines = groups_csv_file.readlines() groups_data = [l.strip().split(',') for l in lines] groups = {} for student, group in groups_data: groups[student] = group results = {} for student, grade in grades.items(): group = groups[student] results[group] = [float(grade[6].replace(',', '.'))] + results.get( group, []) for group, results in results.items(): mean = sum(results) / len(results) print(f'{group}: {mean}') def main(): """Entry point loading grades and evaluating them""" parser = argparse.ArgumentParser() parser.add_argument("--points", help="The maximum amount of points for the grades", type=int, default=3) parser.add_argument("--scale", help="The scale of the grades", default="0-10") parser.add_argument("--locale", help="The locale to use", default="de_DE.utf8") parser.add_argument("--teacher", help="Name of the teacher to exclude their grades.", default="Florian Fischer") parser.add_argument( "--groups-csv", help="CSV file containing student names and their groups") parser.add_argument("grades", help="The csv file containing the grades") args = parser.parse_args() locale.setlocale(locale.LC_ALL, args.locale) scale = args.scale.split('-') scale = (int(scale[0]), int(scale[1])) with open(args.grades, 'r', encoding='utf-8') as grades_file: grades_reader = csv.reader(grades_file) next(grades_reader) # skip headers grades_data = list(grades_reader) grades = {} # Collect all first attempts for grade in grades_data: student = grade[1] # Original grade if not grade[5] and grade[6] and student != args.teacher: assert student not in grades grades[student] = grade if args.groups_csv: print_group_means(grades, args.groups_csv) else: results = [ float(grade[6].replace(',', '.')) for grade in grades.values() ] mean = sum(results) / len(results) print(f'mean: {mean} -> {args.points*(mean-scale[0])/scale[1]}') if __name__ == '__main__': main()