Begin versioning! (better late than never)
[pygrader.git] / pygrader / tabulate.py
1 # Copyright
2
3 import sys as _sys
4
5 try:
6     import numpy as _numpy
7 except ImportError:
8     raise  # TODO work around
9
10 from .color import standard_colors as _standard_colors
11 from .color import write_color as _write_color
12
13
14 def tabulate(course, statistics=False, stream=None, use_color=False, **kwargs):
15     """Return a table of student's grades to date
16     """
17     if stream is None:
18         stream = _sys.stdout
19     highlight,lowlight,good,bad = _standard_colors(use_color=use_color)
20     colors = [highlight, lowlight]
21     assignments = sorted(set(
22             grade.assignment for grade in course.grades))
23     students = sorted(set(grade.student for grade in course.grades))
24     _write_color(string='Student', color=colors[0], stream=stream)
25     for i,assignment in enumerate(assignments):
26         string = '\t{}'.format(assignment.name)
27         color = colors[(i+1)%len(colors)]
28         _write_color(string=string, color=color, stream=stream)
29     if len(assignments) == len(course.assignments):
30         string = '\t{}'.format('Total')
31         color = colors[(i+2)%len(colors)]
32         _write_color(string=string, color=color, stream=stream)
33     _write_color(string='\n', stream=stream)
34     for student in students:
35         _write_color(string=student.name, color=colors[0], stream=stream)
36         for i,assignment in enumerate(assignments):
37             try:
38                 grade = course.grade(student=student, assignment=assignment)
39                 gs = str(grade.points)
40             except ValueError:
41                 gs = '-'
42             string = '\t{}'.format(gs)
43             color = colors[(i+1)%len(colors)]
44             _write_color(string=string, color=color, stream=stream)
45         if len(assignments) == len(course.assignments):
46             string = '\t{}'.format(course.total(student))
47             color = colors[(i+2)%len(colors)]
48             _write_color(string=string, color=color, stream=stream)
49         _write_color(string='\n', stream=stream)
50     if statistics:
51         _write_color(string='--\n', stream=stream)
52         for stat in ['Mean', 'Std. Dev.']:
53             _write_color(string=stat, color=colors[0], stream=stream)
54             for i,assignment in enumerate(assignments):
55                 color = colors[(i+1)%len(colors)]
56                 grades = [g for g in course.grades
57                           if g.assignment == assignment]
58                 gs = _numpy.array([g.points for g in grades])
59                 if stat == 'Mean':
60                     sval = gs.mean()
61                 elif stat == 'Std. Dev.':
62                     sval = gs.std()
63                 else:
64                     raise NotImplementedError(stat)
65                 string = '\t{:.2f}'.format(sval)
66                 _write_color(string=string, color=color, stream=stream)
67             if len(assignments) == len(course.assignments):
68                 gs = _numpy.array([course.total(s) for s in students])
69                 if stat == 'Mean':
70                     sval = gs.mean()
71                 elif stat == 'Std. Dev.':
72                     sval = gs.std()
73                 else:
74                     raise NotImplementedError(stat)
75                 string = '\t{}'.format(sval)
76                 color = colors[(i+2)%len(colors)]
77                 _write_color(string=string, color=color, stream=stream)
78             _write_color(string='\n', stream=stream)