Gradescope-Util/process-gradescope-grades.py

89 lines
3.0 KiB
Python
Executable File

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Script to ...
#
# Minimally tested. Seems to work. Use at your own risk.
#
# By James Eagan <james.eagan@telecom-paris.fr>
# https://james.eagan.fr
import pandas as pd
import re
skipCols = ['SID', 'Email', 'Submission ID', 'Submission Time',
'Lateness (H:M:S)', 'View Count', 'Submission Count',
]
def readCSV(fileName):
cols = list(pd.read_csv(fileName, nrows=1))
keepCols = [col for col in cols if col not in skipCols]
df = pd.read_csv(fileName, usecols=keepCols)
df = df.sort_values(by='Nom')
return df
pattern = re.compile(r'(\d+\.?\d*): (.+) \((\d+\.\d*) pts\)')
def massageHeaders(df, args):
multiHeaders = [[], [], []]
for header in df.columns:
match = pattern.match(header)
if match:
# Question in the form: '11.4: types d'attributs (variables) (1.0 pts)'
multiHeaders[0].append('Q' + match.group(1)) # Q1, Q2, Q3.1, Q3.2, etc
multiHeaders[1].append(match.group(2)) # Question label
multiHeaders[2].append(float(match.group(3))) # Question points (e.g. 1, 2, 1.5)
else:
multiHeaders[0].append('')
multiHeaders[1].append('')
multiHeaders[2].append(header)
df.columns = pd.MultiIndex.from_arrays(multiHeaders)
return df
def writeExcel(df, fileName):
with pd.ExcelWriter(fileName) as writer:
df.to_excel(writer)
# with open(basename + "-out.csv", 'w') as writer:
# writer.write(df.to_csv())
if __name__ == '__main__':
import argparse
import sys
def parse_args():
parser = argparse.ArgumentParser(description="Massage Gradescope data")
parser.add_argument("csv", help="csv file as exported from Gradescope")
parser.add_argument("-o", "--out", help="file to write output")
group = parser.add_mutually_exclusive_group()
group.add_argument("-,", "--commas", help="use commas for decimal separator", action="store_true")
group.add_argument("-.", "--dots", help="use dots for decimal separator", action="store_true")
group.add_argument("-d", "--decimal-separator", help="decimal separator for real numbers", default=",")
parser.add_argument("-s", "--sep", help="csv column separator (default: ',' when decimal separator is '.' and ';' for ',')")
args = parser.parse_args()
if args.commas:
args.decimal_separator = ","
elif args.dots:
args.decimal_separator = "."
if not args.sep:
args.sep = ';' if args.decimal_separator == ',' else ','
return args
def writeOutput(df, args):
if args.out:
writeExcel(df, args.out)
else :
df.to_csv(sys.stdout, sep=args.sep, decimal=args.decimal_separator)
def nowDoIt():
args = parse_args()
df = readCSV(args.csv)
massageHeaders(df, args)
writeOutput(df, args)
nowDoIt()