From 65683154ff1a20d76259606f691f02c3719c7b42 Mon Sep 17 00:00:00 2001 From: Camil Staps Date: Fri, 22 Jul 2016 16:02:06 +0200 Subject: --where-has added --- plotgrades.py | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) (limited to 'plotgrades.py') diff --git a/plotgrades.py b/plotgrades.py index 9973627..165d0bc 100755 --- a/plotgrades.py +++ b/plotgrades.py @@ -64,14 +64,23 @@ def remove_empty_lists(headers, data): new_data.append(d) return new_headers, new_data -def regex_callback(header, regex='', invert=False): +def header_regex_callback(header, regex='', invert=False): """Check whether a regex occurs in a header This is an example of a possible callback function.""" match = re.compile(regex).search(header) != None return match != invert -def check_callback(headers, data, header_callback): +def participant_wherehas_callback(headers, participant, regex='', invert=False): + """Check whether a participant has a grade for some assignment""" + regex = re.compile(regex) + mh = [regex.search(h) != None for h in headers[6:]] + for h, d in zip(mh, participant[6:]): + if h and d != '': + return (not invert) + return invert + +def check_header_callback(headers, data, header_callback): """For each header, check that we want to show it, and remove data if not""" new_headers, new_data = [], [] for h, d in zip(headers, data): @@ -80,12 +89,23 @@ def check_callback(headers, data, header_callback): new_data.append(d) return new_headers, new_data -def plotgrades(headers, data, header_callback=lambda x:True): +def check_participant_callback(headers, data, participant_callback): + """For each participant, check that we want to show it, and remove if not""" + new_data = [] + for d in data: + if participant_callback(headers, d): + new_data.append(d) + return new_data + +def plotgrades(headers, data, skip=0, + participant_callback=lambda x:True, header_callback=lambda x:True): """Plot grades corresponding to headers in a boxplot""" + data = check_participant_callback(headers, data, participant_callback) + headers, data = headers[skip:], data[skip:] data = parse_floats(data) data = remove_zeros(data) headers, data = remove_empty_lists(headers, data) - headers, data = check_callback(headers, data, header_callback) + headers, data = check_header_callback(headers, data, header_callback) data = normalise(data) headers = [strip_header(h) for h in headers] @@ -106,8 +126,12 @@ def parse_args(): help='Skip the first n columns') pars.add_argument('-w', '--where', metavar='regex', default='', help='Restrict what grades are shown with a regex') - pars.add_argument('-i', '--invert', action='store_true', + pars.add_argument('-wh', '--where-has', metavar='regex', default='', + help='Only count participants with a grade for a matching item') + pars.add_argument('-iw', '--invert-where', action='store_true', help='Invert --where regex') + pars.add_argument('-iwh', '--invert-where-has', action='store_true', + help='Invert --where-has regex') pars.add_argument('filename', metavar='file', help='The CSV file as exported by BlackBoard') @@ -117,8 +141,12 @@ def main(): """Plot BlackBoard grades from a CSV file in boxplots""" args = parse_args() headers, data = readcsv(args.filename) - plotgrades(headers[args.skip:], data[:,args.skip:], - partial(regex_callback, regex=args.where, invert=args.invert)) + + plotgrades(headers, data, skip=args.skip, + header_callback=partial(header_regex_callback, + regex=args.where, invert=args.invert_where), + participant_callback=partial(participant_wherehas_callback, + regex=args.where_has, invert=args.invert_where_has)) if __name__ == '__main__': main() -- cgit v1.2.3