395abb15037bcb371c6ad9c1bf19fa503e71b607
[pygrader.git] / pygrader / tabulate.py
1 # Copyright (C) 2012 W. Trevor King <wking@drexel.edu>
2 #
3 # This file is part of pygrader.
4 #
5 # pygrader is free software: you can redistribute it and/or modify it under the
6 # terms of the GNU General Public License as published by the Free Software
7 # Foundation, either version 3 of the License, or (at your option) any later
8 # version.
9 #
10 # pygrader is distributed in the hope that it will be useful, but WITHOUT ANY
11 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License along with
15 # pygrader.  If not, see <http://www.gnu.org/licenses/>.
16
17 import sys as _sys
18
19 try:
20     import numpy as _numpy
21 except ImportError:
22     raise  # TODO work around
23
24 from .color import standard_colors as _standard_colors
25 from .color import write_color as _write_color
26
27
28 def tabulate(course, statistics=False, stream=None, use_color=False, **kwargs):
29     """Return a table of student's grades to date
30     """
31     if stream is None:
32         stream = _sys.stdout
33     highlight,lowlight,good,bad = _standard_colors(use_color=use_color)
34     colors = [highlight, lowlight]
35     assignments = sorted(set(
36             grade.assignment for grade in course.grades))
37     students = sorted(set(grade.student for grade in course.grades))
38     _write_color(string='Student', color=colors[0], stream=stream)
39     for i,assignment in enumerate(assignments):
40         string = '\t{}'.format(assignment.name)
41         color = colors[(i+1)%len(colors)]
42         _write_color(string=string, color=color, stream=stream)
43     if len(assignments) == len(course.assignments):
44         string = '\t{}'.format('Total')
45         color = colors[(i+2)%len(colors)]
46         _write_color(string=string, color=color, stream=stream)
47     _write_color(string='\n', stream=stream)
48     for student in students:
49         _write_color(string=student.name, color=colors[0], stream=stream)
50         for i,assignment in enumerate(assignments):
51             try:
52                 grade = course.grade(student=student, assignment=assignment)
53                 gs = str(grade.points)
54             except ValueError:
55                 gs = '-'
56             string = '\t{}'.format(gs)
57             color = colors[(i+1)%len(colors)]
58             _write_color(string=string, color=color, stream=stream)
59         if len(assignments) == len(course.assignments):
60             string = '\t{}'.format(course.total(student))
61             color = colors[(i+2)%len(colors)]
62             _write_color(string=string, color=color, stream=stream)
63         _write_color(string='\n', stream=stream)
64     if statistics:
65         _write_color(string='--\n', stream=stream)
66         for stat in ['Mean', 'Std. Dev.']:
67             _write_color(string=stat, color=colors[0], stream=stream)
68             for i,assignment in enumerate(assignments):
69                 color = colors[(i+1)%len(colors)]
70                 grades = [g for g in course.grades
71                           if g.assignment == assignment]
72                 gs = _numpy.array([g.points for g in grades])
73                 if stat == 'Mean':
74                     sval = gs.mean()
75                 elif stat == 'Std. Dev.':
76                     sval = gs.std()
77                 else:
78                     raise NotImplementedError(stat)
79                 string = '\t{:.2f}'.format(sval)
80                 _write_color(string=string, color=color, stream=stream)
81             if len(assignments) == len(course.assignments):
82                 gs = _numpy.array([course.total(s) for s in students])
83                 if stat == 'Mean':
84                     sval = gs.mean()
85                 elif stat == 'Std. Dev.':
86                     sval = gs.std()
87                 else:
88                     raise NotImplementedError(stat)
89                 string = '\t{}'.format(sval)
90                 color = colors[(i+2)%len(colors)]
91                 _write_color(string=string, color=color, stream=stream)
92             _write_color(string='\n', stream=stream)