/
grade_tally.py
executable file
·103 lines (86 loc) · 3.68 KB
/
grade_tally.py
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
91
92
93
94
95
96
97
98
99
100
101
102
103
#!/usr/bin/env python2
import fileinput
import re
import argparse
import sys
import ast
import os
import shlex
import scholar
import StringIO
from find_commented import find_commented
from maybe import maybe
paren_points = re.compile(r'\(([+-][\d]+)\)')
bracket_points = re.compile(r'\[([+-][\d]+)\]')
comments_match = re.compile(r'##.*$')
def collect_points(f):
tally = 0
comments = []
fname = os.path.basename(f.name)
for (lineno,line) in enumerate(f):
m = bracket_points.findall(line)
if m:
for number in m:
tally += float(number)
m = comments_match.search(line)
if m:
comments.append((fname, lineno, line))
return (tally,comments)
def collect_problem(path, problem, **kwargs):
verbose = False
if 'verbose' in kwargs:
verbose = kwargs['verbose']
points=0
comments = []
total_points = maybe(problem, 'points', int(0))
try:
with open(os.path.join(path,problem['src']), 'r') as f:
(points,comments) = collect_points(f)
except IOError as e:
points = -total_points
comments.append((problem['src'],0,'Could not find source file\n'))
subtotal = total_points+points
if verbose:
sys.stderr.write("\tpoints for {}: {}/{}\n".format(problem['src'],subtotal,total_points))
sys.stderr.writelines("\t{}:{} {}".format(fname,lineno,line) for (fname,lineno,line) in comments if not line.strip() == '###DKM')
return (subtotal, total_points, comments)
if __name__ == "__main__":
parser = argparse.ArgumentParser("Tally up grades for homework")
parser.add_argument("files", metavar='FILE', nargs="*", help="Path to program to test")
parser.add_argument("-v","--verbose", action='store_true', help="Be verbose")
parser.add_argument("-f", type=argparse.FileType('r'), help="Path to homework data file")
args = parser.parse_args()
(homework,scholar) = scholar.open_homework(args.f)
for (pid,path) in map(shlex.split, fileinput.input(args.files)):
if args.verbose:
sys.stderr.write("Student: %s\n" % pid)
#for problem in homework['problems']:
#path = scholar.feedback_attachments(pid)
commented_files = find_commented(path, '### *DKM')
if commented_files:
for commented_file in commented_files:
if not os.path.basename(commented_file) in [ problem['src'] for problem in homework['problems']]:
homework['problems'].append({'src': os.path.basename(commented_file)})
results = [ collect_problem(path,problem,verbose=args.verbose) for problem in homework['problems'] ]
comments_file = scholar.comments_file(pid)
if args.verbose:
sys.stderr.write("Writing comments to {}\n".format(comments_file))
student_total = 0
f = StringIO.StringIO()
for (problem, (subtotal, outof, comments)) in zip(homework['problems'], results):
if outof > 0:
point_report="{}/{}".format(subtotal,outof)
else:
point_report="{}".format(subtotal)
f.write("## {}: {}\n\n".format(problem['src'], point_report))
if args.verbose:
sys.stderr.write("{} comments: {}\n".format(problem['src'], comments))
f.writelines("\tline {}: {}\n".format(lineno, comment.strip()) for (fname,lineno,comment) in comments if not comment.strip() == '###DKM' )
f.write("\n")
student_total += subtotal
f.write("\n*subtotal:* {}/{}\n".format(student_total, sum(maybe(x, 'points', 0) for x in homework['problems'])))
if args.verbose:
sys.stderr.write("Markdown comments:\n{}".format(f.getvalue()))
scholar.write_comments(pid,f.getvalue())
f.close()
print "{} {}".format(pid,student_total)