Skip to content

Commit

Permalink
Linter cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
rgerkin committed Aug 10, 2018
1 parent 218bccd commit 57118c1
Show file tree
Hide file tree
Showing 10 changed files with 255 additions and 228 deletions.
77 changes: 38 additions & 39 deletions sciunit/__main__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""
This module implements the SciUnit command line tools.
With SciUnit installed, a .sciunit configuration file can be created from
With SciUnit installed, a .sciunit configuration file can be created from
a *nix shell with:
`sciunit create`
and if models, tests, etc. are in locations specified by the configuration file
Expand All @@ -18,7 +18,7 @@
import re

import nbformat
from nbformat.v4.nbbase import new_notebook,new_markdown_cell
from nbformat.v4.nbbase import new_notebook, new_markdown_cell
from nbconvert.preprocessors import ExecutePreprocessor

import sciunit
Expand All @@ -30,27 +30,29 @@
import codecs
try:
import matplotlib
matplotlib.use('Agg') # Anticipate possible headless environments
matplotlib.use('Agg') # Anticipate possible headless environments
except ImportError:
pass

NB_VERSION = 4


def main(*args):
"""The main routine."""
parser = argparse.ArgumentParser()
parser.add_argument("action", help="create, check, run, make-nb, or run-nb")
parser.add_argument("--directory", "-dir", default=os.getcwd(),
help="path to directory with a .sciunit file")
parser.add_argument("--stop", "-s", default=True,
help="stop and raise errors, halting the program")
parser.add_argument("--tests", "-t", default=False,
help="runs tests instead of suites")
parser.add_argument("action",
help="create, check, run, make-nb, or run-nb")
parser.add_argument("--directory", "-dir", default=os.getcwd(),
help="path to directory with a .sciunit file")
parser.add_argument("--stop", "-s", default=True,
help="stop and raise errors, halting the program")
parser.add_argument("--tests", "-t", default=False,
help="runs tests instead of suites")
if args:
args = parser.parse_args(args)
else:
args = parser.parse_args()
file_path = os.path.join(args.directory,'.sciunit')
file_path = os.path.join(args.directory, '.sciunit')
config = None
if args.action == 'create':
create(file_path)
Expand All @@ -59,11 +61,11 @@ def main(*args):
print("\nNo configuration errors reported.")
elif args.action == 'run':
config = parse(file_path)
run(config, path=args.directory,
run(config, path=args.directory,
stop_on_error=args.stop, just_tests=args.tests)
elif args.action == 'make-nb':
config = parse(file_path)
make_nb(config, path=args.directory,
make_nb(config, path=args.directory,
stop_on_error=args.stop, just_tests=args.tests)
elif args.action == 'run-nb':
config = parse(file_path)
Expand All @@ -75,10 +77,11 @@ def main(*args):


def create(file_path):
"""Create a default .sciunit config file if one does not already exist"""
"""Create a default .sciunit config file if one does not already exist."""
if os.path.exists(file_path):
raise IOError("There is already a configuration file at %s" % file_path)
with open(file_path,'w') as f:
raise IOError("There is already a configuration file at %s" %
file_path)
with open(file_path, 'w') as f:
config = configparser.ConfigParser()
config.add_section('misc')
config.set('misc', 'config-version', '1.0')
Expand All @@ -96,9 +99,9 @@ def create(file_path):


def parse(file_path=None, show=False):
"""Parse a .sciunit config file"""
"""Parse a .sciunit config file."""
if file_path is None:
file_path = os.path.join(os.getcwd(),'.sciunit')
file_path = os.path.join(os.getcwd(), '.sciunit')
if not os.path.exists(file_path):
raise IOError('No .sciunit file was found at %s' % file_path)

Expand All @@ -112,7 +115,7 @@ def parse(file_path=None, show=False):
print(section)
for options in config.options(section):
if show:
print("\t%s: %s" % (options,config.get(section, options)))
print("\t%s: %s" % (options, config.get(section, options)))
return config


Expand All @@ -121,17 +124,17 @@ def prep(config=None, path=None):
config = parse()
if path is None:
path = os.getcwd()
root = config.get('root','path')
root = os.path.join(path,root)
root = config.get('root', 'path')
root = os.path.join(path, root)
root = os.path.realpath(root)
os.environ['SCIDASH_HOME'] = root
if sys.path[0] != root:
sys.path.insert(0,root)
sys.path.insert(0, root)


def run(config, path=None, stop_on_error=True, just_tests=False):
"""Run sciunit tests for the given configuration"""
"""Run sciunit tests for the given configuration."""

if path is None:
path = os.getcwd()
prep(config, path=path)
Expand All @@ -141,14 +144,15 @@ def run(config, path=None, stop_on_error=True, just_tests=False):
suites = __import__('suites')

print('\n')
for x in ['models','tests','suites']:
for x in ['models', 'tests', 'suites']:
module = __import__(x)
assert hasattr(module,x), "'%s' module requires attribute '%s'" % (x,x)
assert hasattr(module, x), "'%s' module requires attribute '%s'" %\
(x, x)

if just_tests:
for test in tests.tests:
_run(test, models, stop_on_error)

else:
for suite in suites.suites:
_run(suite, models, stop_on_error)
Expand All @@ -158,28 +162,23 @@ def _run(test_or_suite, models, stop_on_error):
kind = 'Test' if isinstance(test_or_suite,sciunit.Test) else 'Suite'
print('\n%s %s:\n%s\n' % (kind,test_or_suite,score_array_or_matrix))


def nb_name_from_path(config,path):
"""Get a notebook name from a path to a notebook"""
if path is None:
path = os.getcwd()
root = config.get('root','path')
root = config.get('root', 'path')
root = os.path.join(path,root)
root = os.path.realpath(root)
default_nb_name = os.path.split(os.path.realpath(root))[1]
nb_name = config.get('misc','nb-name',fallback=default_nb_name)
nb_name = config.get('misc', 'nb-name',fallback=default_nb_name)
return root,nb_name



def make_nb(config, path=None, stop_on_error=True, just_tests=False):
"""Create a Jupyter notebook sciunit tests for the given configuration"""



root,nb_name = nb_name_from_path(config,path)
clean = lambda varStr: re.sub('\W|^(?=\d)','_', varStr)
name = clean(nb_name)

mpl_style = config.get('misc','matplotlib',fallback='inline')
cells = [new_markdown_cell('## Sciunit Testing Notebook for %s' % nb_name)]
add_code_cell(cells, (
Expand All @@ -199,10 +198,10 @@ def make_nb(config, path=None, stop_on_error=True, just_tests=False):
" score_matrix = suite.judge(%s.models.models, stop_on_error=%r)\n"
" display(score_matrix)") % (name,name,stop_on_error))
write_nb(root,nb_name,cells)


def write_nb(root,nb_name,cells):
"""Writes a jupyter notebook to disk given a root directory, a notebook
"""Writes a jupyter notebook to disk given a root directory, a notebook
name, and a list of cells.
"""

Expand Down Expand Up @@ -231,7 +230,7 @@ def run_nb(config, path=None):
print(("No notebook found at %s. "
"Create the notebook first with make-nb?") % path)
sys.exit(0)

with codecs.open(nb_path, encoding='utf-8', mode='r') as nb_file:
nb = nbformat.read(nb_file, as_version=NB_VERSION)
ep = ExecutePreprocessor(timeout=600)#, kernel_name='python3')
Expand Down
2 changes: 1 addition & 1 deletion sciunit/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ class SciUnit(Versioned):
def __init__(self):
self.unpicklable = []

""" A list of attributes that cannot or should not be pickled."""
"""A list of attributes that cannot or should not be pickled."""
unpicklable = []

"""A URL where the code for this object can be found."""
Expand Down
8 changes: 4 additions & 4 deletions sciunit/scores/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"""
This module contains classes for different representations of test scores.
It also contains score collections such as arrays and matrices.
"""Contains classes for different representations of test scores.
It also contains score collections such as arrays and matrices.
"""

from .base import Score,ErrorScore
from .base import Score, ErrorScore
from .complete import *
from .incomplete import *
63 changes: 34 additions & 29 deletions sciunit/scores/base.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
"""
Base class for SciUnit scores.
"""
"""Base class for SciUnit scores."""

from copy import copy

import numpy as np

from sciunit.base import SciUnit
from sciunit.utils import log,config_get
from sciunit.utils import log, config_get
from sciunit.errors import InvalidScoreError

#
# Scores
#

class Score(SciUnit):
"""Abstract base class for scores."""

def __init__(self, score, related_data=None):
"""Abstract base class for scores.
Args:
score (int, float, bool): A raw value to wrap in a Score class.
related_data (dict, optional): Artifacts to store with the score.
"""
self.check_score(score)
if related_data is None:
related_data = {}
self.score, self.related_data = score, related_data
if isinstance(score,Exception):
self.__class__ = ErrorScore # Set to error score to use its summarize().
super(Score,self).__init__()
if isinstance(score, Exception):
# Set to error score to use its summarize().
self.__class__ = ErrorScore
super(Score, self).__init__()

score = None
"""The score itself."""
Expand Down Expand Up @@ -59,9 +63,9 @@ def __init__(self, score, related_data=None):

def check_score(self, score):
if self._allowed_types and \
not isinstance(score,self._allowed_types+(Exception,)):
raise InvalidScoreError(self._allowed_types_message % \
(type(score),self._allowed_types))
not isinstance(score, self._allowed_types+(Exception,)):
raise InvalidScoreError(self._allowed_types_message %
(type(score), self._allowed_types))
self._check_score(score)

def _check_score(self,score):
Expand All @@ -77,6 +81,7 @@ def norm_score(self):
return self.score

def color(self, value=None):
"""Turn the score intp an RGB color tuple of three 8-bit integers."""
if value is None:
value = self.norm_score
rgb = Score.value_color(value)
Expand All @@ -86,10 +91,10 @@ def color(self, value=None):
def value_color(cls, value):
import matplotlib.cm as cm
if value is None or np.isnan(value):
rgb = (128,128,128)
rgb = (128, 128, 128)
else:
cmap_low = config_get('cmap_low',38)
cmap_high = config_get('cmap_high',218)
cmap_low = config_get('cmap_low', 38)
cmap_high = config_get('cmap_high', 218)
cmap_range = cmap_high - cmap_low
cmap = cm.RdYlGn(int(cmap_range*value+cmap_low))[:3]
rgb = tuple([x*256 for x in cmap])
Expand All @@ -115,8 +120,8 @@ def _describe(self):
return result

def describe_from_docstring(self):
s = [self.test.score_type.__doc__.strip().\
replace('\n','').replace(' ','')]
s = [self.test.score_type.__doc__.strip().
replace('\n', '').replace(' ', '')]
if self.test.converter:
s += [self.test.converter.description]
s += [self._description]
Expand All @@ -133,9 +138,9 @@ def describe(self, quiet=False):
@property
def raw(self):
value = self._raw if self._raw else self.score
if isinstance(value,(float,np.ndarray)):
if isinstance(value, (float, np.ndarray)):
string = '%.4g' % value
if hasattr(value,'magnitude'):
if hasattr(value, 'magnitude'):
string += ' %s' % str(value.units)[4:]
else:
string = None
Expand All @@ -152,42 +157,42 @@ def __str__(self):
return '%s' % self.score

def __eq__(self, other):
if isinstance(other,Score):
if isinstance(other, Score):
result = self.norm_score == other.norm_score
else:
result = self.score == other
return result

def __ne__(self, other):
if isinstance(other,Score):
if isinstance(other, Score):
result = self.norm_score != other.norm_score
else:
result = self.score != other
return result

def __gt__(self, other):
if isinstance(other,Score):
if isinstance(other, Score):
result = self.norm_score > other.norm_score
else:
result = self.score > other
return result

def __ge__(self, other):
if isinstance(other,Score):
if isinstance(other, Score):
result = self.norm_score >= other.norm_score
else:
result = self.score >= other
return result

def __lt__(self, other):
if isinstance(other,Score):
if isinstance(other, Score):
result = self.norm_score < other.norm_score
else:
result = self.score < other
return result

def __le__(self, other):
if isinstance(other,Score):
if isinstance(other, Score):
result = self.norm_score <= other.norm_score
else:
result = self.score <= other
Expand All @@ -214,10 +219,10 @@ def extract_mean_or_value(cls, obs_or_pred, key=None):
"""

result = None
if not isinstance(obs_or_pred,dict):
if not isinstance(obs_or_pred, dict):
result = obs_or_pred
else:
keys = ([key] if key is not None else []) + ['mean','value']
keys = ([key] if key is not None else []) + ['mean', 'value']
for k in keys:
if k in obs_or_pred:
result = obs_or_pred[k]
Expand All @@ -238,7 +243,7 @@ def norm_score(self):
@property
def summary(self):
"""Summarize the performance of a model on a test."""
return "=== Model %s did not complete test %s due to error '%s'. ===" % \
return "== Model %s did not complete test %s due to error '%s'. ==" %\
(str(self.model), str(self.test), str(self.score))

def _describe(self):
Expand Down

0 comments on commit 57118c1

Please sign in to comment.