aboutsummaryrefslogtreecommitdiff
path: root/scripts/eval_moodle_grades.py
blob: 01a71eacb87f65bd61a65559a12ca43c57ea132e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!/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()