Skip to content

Commit

Permalink
Fix code quality issues (#59)
Browse files Browse the repository at this point in the history
* test first corrected file

* update tests to include/exclude

* fixes for remaining docstrings

* fix import orders
  • Loading branch information
trevorstephens committed Nov 11, 2017
1 parent 68c50b4 commit 6ab0bbc
Show file tree
Hide file tree
Showing 13 changed files with 83 additions and 44 deletions.
12 changes: 11 additions & 1 deletion .landscape.yaml
Original file line number Diff line number Diff line change
@@ -1 +1,11 @@
doc-warnings: yes
strictness: medium
test-warnings: false
doc-warnings: true

pep257:
disable:
- D211 # No blank lines allowed before class docstring
- D213 # Multi-line docstring summary should start at the second line
enable:
- D203 # 1 blank line required before class docstring
- D212 # Multi-line docstring summary should start at the first line
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ env:
- PYTHON_VERSION="2.7" SKLEARN_VERSION="0.18.1"
- PYTHON_VERSION="3.4" LATEST="true"
- PYTHON_VERSION="3.5" LATEST="true"
- PYTHON_VERSION="3.6" QUALITY="true" LATEST="true"
- PYTHON_VERSION="3.6" LATEST="true"
install: source continuous_integration/install.sh
script: bash continuous_integration/test_script.sh
after_success:
Expand Down
8 changes: 4 additions & 4 deletions continuous_integration/test_script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ python -c "import numpy; print('numpy %s' % numpy.__version__)"
python -c "import scipy; print('scipy %s' % scipy.__version__)"
python -c "import sklearn; print('sklearn %s' % sklearn.__version__)"

if [[ "$QUALITY" == "true" ]]; then
prospector --profile $TRAVIS_BUILD_DIR/.landscape gplearn || true;
fi

if [[ "$COVERAGE" == "true" ]]; then
nosetests -s -v --with-coverage --cover-package=gplearn
else
nosetests -s -v gplearn
fi

if [[ "$QUALITY" == "true" ]]; then
prospector --doc-warnings gplearn || true;
fi

#make test-doc test-sphinxext
1 change: 1 addition & 0 deletions gplearn/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Genetic Programming in Python, with a scikit-learn inspired API
``gplearn`` is a set of algorithms for learning genetic programming models.
"""
__version__ = '0.3.dev0'

Expand Down
23 changes: 17 additions & 6 deletions gplearn/_program.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@
#
# License: BSD 3 clause

import numpy as np

from copy import deepcopy

import numpy as np
from sklearn.utils.random import sample_without_replacement

from .functions import _Function
Expand Down Expand Up @@ -104,6 +103,7 @@ class _Program(object):
length_ : int
The number of functions and terminals in the program.
"""

def __init__(self,
Expand Down Expand Up @@ -156,9 +156,10 @@ def build_program(self, random_state):
-------
program : list
The flattened tree representation of the program.
"""
if self.init_method == 'half and half':
method = ['grow', 'full'][random_state.randint(2)]
method = ('full' if random_state.randint(2) else 'grow')
else:
method = self.init_method
max_depth = random_state.randint(*self.init_depth)
Expand All @@ -169,7 +170,7 @@ def build_program(self, random_state):
program = [function]
terminal_stack = [function.arity]

while len(terminal_stack) != 0:
while terminal_stack:
depth = len(terminal_stack)
choice = self.n_features + len(self.function_set)
choice = random_state.randint(choice)
Expand All @@ -189,7 +190,7 @@ def build_program(self, random_state):
terminal_stack[-1] -= 1
while terminal_stack[-1] == 0:
terminal_stack.pop()
if len(terminal_stack) == 0:
if not terminal_stack:
return program
terminal_stack[-1] -= 1

Expand Down Expand Up @@ -244,6 +245,7 @@ def export_graphviz(self, fade_nodes=None):
-------
output : string
The Graphviz script to plot the tree representation of the program.
"""
terminals = []
if fade_nodes is None:
Expand Down Expand Up @@ -278,7 +280,7 @@ def export_graphviz(self, fade_nodes=None):
if len(terminals[-1]) == 2:
parent = terminals[-1][-1]
terminals.pop()
if len(terminals) == 0:
if not terminals:
return output + "}"
terminals[-1].append(parent)
terminals[-1][0] -= 1
Expand Down Expand Up @@ -318,6 +320,7 @@ def execute(self, X):
-------
y_hats : array-like, shape = [n_samples]
The result of executing the program on X.
"""
# Check for single-node programs
node = self.program[0]
Expand Down Expand Up @@ -374,6 +377,7 @@ def get_all_indices(self, n_samples=None, max_samples=None,
not_indices : array-like, shape = [n_samples]
The out-of-sample indices.
"""
if self._indices_state is None and random_state is None:
raise ValueError('The program has not been evaluated for fitness '
Expand Down Expand Up @@ -421,6 +425,7 @@ def raw_fitness(self, X, y, sample_weight):
-------
raw_fitness : float
The raw fitness of the program.
"""
y_pred = self.execute(X)
raw_fitness = self.metric(y, y_pred, sample_weight)
Expand All @@ -440,6 +445,7 @@ def fitness(self, parsimony_coefficient=None):
-------
fitness : float
The penalized fitness of the program.
"""
if parsimony_coefficient is None:
parsimony_coefficient = self.parsimony_coefficient
Expand All @@ -462,6 +468,7 @@ def get_subtree(self, random_state, program=None):
-------
start, end : tuple of two ints
The indices of the start and end of the random subtree.
"""
if program is None:
program = self.program
Expand Down Expand Up @@ -503,6 +510,7 @@ def crossover(self, donor, random_state):
-------
program : list
The flattened tree representation of the program.
"""
# Get a subtree to replace
start, end = self.get_subtree(random_state)
Expand Down Expand Up @@ -535,6 +543,7 @@ def subtree_mutation(self, random_state):
-------
program : list
The flattened tree representation of the program.
"""
# Build a new naive program
chicken = self.build_program(random_state)
Expand All @@ -558,6 +567,7 @@ def hoist_mutation(self, random_state):
-------
program : list
The flattened tree representation of the program.
"""
# Get a subtree to replace
start, end = self.get_subtree(random_state)
Expand Down Expand Up @@ -587,6 +597,7 @@ def point_mutation(self, random_state):
-------
program : list
The flattened tree representation of the program.
"""
program = deepcopy(self.program)

Expand Down
6 changes: 4 additions & 2 deletions gplearn/fitness.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
#
# License: BSD 3 clause

import numpy as np
import numbers

import numpy as np
from scipy.stats import rankdata
from sklearn.externals import six
import numbers

__all__ = ['make_fitness']

Expand All @@ -37,6 +37,7 @@ class _Fitness(object):
Whether a higher value from `function` indicates a better fit. In
general this would be False for metrics indicating the magnitude of
the error, and True for metrics indicating the quality of fit.
"""

def __init__(self, function, greater_is_better):
Expand Down Expand Up @@ -70,6 +71,7 @@ def make_fitness(function, greater_is_better):
Whether a higher value from `function` indicates a better fit. In
general this would be False for metrics indicating the magnitude of
the error, and True for metrics indicating the quality of fit.
"""
if not isinstance(greater_is_better, bool):
raise ValueError('greater_is_better must be bool, got %s'
Expand Down
3 changes: 2 additions & 1 deletion gplearn/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
# License: BSD 3 clause

import numpy as np

from sklearn.externals import six

__all__ = ['make_function']
Expand All @@ -35,6 +34,7 @@ class _Function(object):
arity : int
The number of arguments that the ``function`` takes.
"""

def __init__(self, function, name, arity):
Expand Down Expand Up @@ -66,6 +66,7 @@ def make_function(function, name, arity):
arity : int
The number of arguments that the `function` takes.
"""
if not isinstance(arity, int):
raise ValueError('arity must be an int, got %s' % type(arity))
Expand Down
26 changes: 15 additions & 11 deletions gplearn/genetic.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,23 @@
#
# License: BSD 3 clause

import numpy as np
import itertools

from abc import ABCMeta, abstractmethod
from time import time
from warnings import warn

import numpy as np
from scipy.stats import rankdata

from sklearn.base import BaseEstimator, RegressorMixin, TransformerMixin
from sklearn.externals import six
from sklearn.externals.joblib import Parallel, delayed
from sklearn.utils.validation import check_X_y, check_array

from .utils import _partition_estimators
from .utils import check_random_state, NotFittedError

from ._program import _Program
from .fitness import _fitness_map, _Fitness
from .functions import _function_map, _Function

from ._program import _Program
from .utils import _partition_estimators
from .utils import check_random_state, NotFittedError

__all__ = ['SymbolicRegressor', 'SymbolicTransformer']

Expand Down Expand Up @@ -157,6 +153,7 @@ class BaseSymbolic(six.with_metaclass(ABCMeta, BaseEstimator)):
Warning: This class should not be used directly.
Use derived classes instead.
"""

@abstractmethod
Expand Down Expand Up @@ -231,6 +228,7 @@ def _verbose_reporter(self,
length : list
The current population's lengths.
"""
if start_time is None:
print('%4s|%-25s|%-42s|' % (' ', 'Population Average'.center(25),
Expand Down Expand Up @@ -287,6 +285,7 @@ def fit(self, X, y, sample_weight=None):
-------
self : object
Returns self.
"""
random_state = check_random_state(self.random_state)

Expand Down Expand Up @@ -323,7 +322,7 @@ def fit(self, X, y, sample_weight=None):
else:
raise ValueError('invalid type %s found in `function_set`.'
% type(function))
if len(self._function_set) == 0:
if not self._function_set:
raise ValueError('No valid functions found in `function_set`.')

# For point-mutation to find a compatible replacement node
Expand Down Expand Up @@ -660,7 +659,7 @@ class SymbolicRegressor(BaseSymbolic, RegressorMixin):
If None, the random number generator is the RandomState instance used
by `np.random`.
See also
See Also
--------
SymbolicTransformer
Expand All @@ -669,6 +668,7 @@ class SymbolicRegressor(BaseSymbolic, RegressorMixin):
.. [1] J. Koza, "Genetic Programming", 1992.
.. [2] R. Poli, et al. "A Field Guide to Genetic Programming", 2008.
"""

def __init__(self,
Expand Down Expand Up @@ -733,6 +733,7 @@ def predict(self, X):
-------
y : array, shape = [n_samples]
Predicted values for X.
"""
if not hasattr(self, "_program"):
raise NotFittedError("SymbolicRegressor not fitted.")
Expand Down Expand Up @@ -913,7 +914,7 @@ class SymbolicTransformer(BaseSymbolic, TransformerMixin):
If None, the random number generator is the RandomState instance used
by `np.random`.
See also
See Also
--------
SymbolicRegressor
Expand All @@ -922,6 +923,7 @@ class SymbolicTransformer(BaseSymbolic, TransformerMixin):
.. [1] J. Koza, "Genetic Programming", 1992.
.. [2] R. Poli, et al. "A Field Guide to Genetic Programming", 2008.
"""

def __init__(self,
Expand Down Expand Up @@ -1003,6 +1005,7 @@ def transform(self, X):
-------
X_new : array-like, shape = [n_samples, n_components]
Transformed array.
"""
if not hasattr(self, "_best_programs"):
raise NotFittedError("SymbolicTransformer not fitted.")
Expand Down Expand Up @@ -1038,5 +1041,6 @@ def fit_transform(self, X, y, sample_weight=None):
-------
X_new : array-like, shape = [n_samples, n_components]
Transformed array.
"""
return self.fit(X, y, sample_weight).transform(X)
2 changes: 1 addition & 1 deletion gplearn/tests/test_fitness.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
#
# License: BSD 3 clause

from gplearn.fitness import make_fitness, _mean_square_error
from sklearn.utils.testing import assert_raises

from gplearn.fitness import make_fitness, _mean_square_error

def test_validate_fitness():
"""Check that valid fitness measures are accepted & invalid raise error"""
Expand Down
4 changes: 1 addition & 3 deletions gplearn/tests/test_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@
# License: BSD 3 clause

import numpy as np

from numpy import maximum
from sklearn.utils.testing import assert_raises

from gplearn.functions import _protected_sqrt, make_function

from sklearn.utils.testing import assert_raises


def test_validate_function():
"""Check that valid functions are accepted & invalid ones raise error"""
Expand Down
Loading

0 comments on commit 6ab0bbc

Please sign in to comment.