From: W. Trevor King Date: Sat, 20 Oct 2012 18:24:11 +0000 (-0400) Subject: tabulate: work around missing NumPy. X-Git-Url: http://git.tremily.us/?p=pygrader.git;a=commitdiff_plain;h=c38f1735aaa115192ae1c13d422e16bbe807abbc tabulate: work around missing NumPy. --- diff --git a/pygrader/tabulate.py b/pygrader/tabulate.py index 4e21279..d8a962d 100644 --- a/pygrader/tabulate.py +++ b/pygrader/tabulate.py @@ -14,17 +14,67 @@ # You should have received a copy of the GNU General Public License along with # pygrader. If not, see . +import math as _math # for numpy workarounds and testing import sys as _sys +_numpy_import_error = None try: import numpy as _numpy -except ImportError: - raise # TODO work around +except ImportError as e: + _numpy = None + _numpy_import_error = e +from . import LOG as _LOG from .color import standard_colors as _standard_colors from .color import write_color as _write_color +def _mean(iterable): # missing-numpy workaround + """Return the mean of a list of items. + + >>> print(_mean([0,1,2,3,4,5,6])) + 3.0 + """ + length = len(iterable) + return sum(iterable) / float(length) + +def _std(iterable): # missing-numpy workaround + """Return the standard deviation of a list of items. + + >>> print(_std([0,1,2,3,4,5,6])) + 2.0 + """ + length = len(iterable) + m = _mean(iterable) + return _math.sqrt(sum((x-m)**2 for x in iterable) / length) + +if _numpy is None: + _statistics_container = list +else: + _statistics_container = _numpy.array + +def _statistic(iterabale, statistic): + """Calculate statistics on an list of numbers + """ + global _numpy_import_error + if _numpy_import_error: + assert _numpy_import_error is not None + _LOG.warning('error importing numpy, falling back to workarounds') + _LOG.warning(str(_numpy_import_error)) + _numpy_import_error = None + if stat == 'Mean': + if _numpy is None: # work around missing numpy + return _mean(iterable) + else: + return gs.mean() + elif stat == 'Std. Dev.': + if _numpy is None: # work around missing numpy + sval = _std(iterable) + else: + return gs.std() + else: + raise NotImplementedError(stat) + def tabulate(course, statistics=False, stream=None, use_color=None, **kwargs): """Return a table of student's grades to date """ @@ -69,23 +119,13 @@ def tabulate(course, statistics=False, stream=None, use_color=None, **kwargs): color = colors[(i+1)%len(colors)] grades = [g for g in course.grades if g.assignment == assignment] - gs = _numpy.array([g.points for g in grades]) - if stat == 'Mean': - sval = gs.mean() - elif stat == 'Std. Dev.': - sval = gs.std() - else: - raise NotImplementedError(stat) + gs = _statistics_container([g.points for g in grades]) + sval = _statistic(gs, statistic=stat) string = '\t{:.2f}'.format(sval) _write_color(string=string, color=color, stream=stream) if len(assignments) == len(course.assignments): - gs = _numpy.array([course.total(s) for s in students]) - if stat == 'Mean': - sval = gs.mean() - elif stat == 'Std. Dev.': - sval = gs.std() - else: - raise NotImplementedError(stat) + gs = _statistics_container([course.total(s) for s in students]) + sval = _statistic(gs, statistic=stat) string = '\t{}'.format(sval) color = colors[(i+2)%len(colors)] _write_color(string=string, color=color, stream=stream)