Skip to content

Commit

Permalink
Merge pull request #407 from sdv-dev/add_ruff
Browse files Browse the repository at this point in the history
Add ruff for linting, remove flake8, remove isort, remove pylint
  • Loading branch information
gsheni authored May 2, 2024
2 parents d6a3bdc + f19e087 commit 2f3a2be
Show file tree
Hide file tree
Showing 58 changed files with 631 additions and 778 deletions.
16 changes: 4 additions & 12 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ clean-test: ## remove test artifacts
.PHONY: clean
clean: clean-build clean-pyc clean-test clean-coverage clean-docs ## remove all build, test, coverage, docs and Python artifacts


# INSTALL TARGETS

.PHONY: install
Expand All @@ -82,23 +81,16 @@ install-test: clean-build clean-pyc ## install the package and test dependencies
install-develop: clean-build clean-pyc ## install the package in editable mode and dependencies for development
pip install -e .[dev]


# LINT TARGETS

.PHONY: lint
lint: ## check style with flake8 and isort
lint:
invoke lint

lint-docs: ## check docs formatting with doc8 and pydocstyle
doc8 . docs/
pydocstyle copulas/

.PHONY: fix-lint
fix-lint: ## fix lint issues using autoflake, autopep8, and isort
find copulas tests -name '*.py' | xargs autoflake --in-place --remove-all-unused-imports --remove-unused-variables
autopep8 --in-place --recursive --aggressive copulas tests
isort --apply --atomic copulas tests

fix-lint:
ruff check --fix .
ruff format .

# TEST TARGETS

Expand Down
7 changes: 3 additions & 4 deletions copulas/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ def validate_random_state(random_state):
else:
raise TypeError(
f'`random_state` {random_state} expected to be an int '
'or `np.random.RandomState` object.')
'or `np.random.RandomState` object.'
)


def get_instance(obj, **kwargs):
Expand Down Expand Up @@ -192,8 +193,7 @@ def decorated(self, X, *args, **kwargs):

if len(X.shape) == 2:
return np.fromiter(
(function(self, *x, *args, **kwargs) for x in X),
np.dtype('float64')
(function(self, *x, *args, **kwargs) for x in X), np.dtype('float64')
)

else:
Expand Down Expand Up @@ -243,7 +243,6 @@ def check_valid_values(function):
"""

def decorated(self, X, *args, **kwargs):

if isinstance(X, pd.DataFrame):
W = X.to_numpy()

Expand Down
4 changes: 2 additions & 2 deletions copulas/bivariate/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ def _compute_empirical(X):
right = sum(np.logical_and(U >= base[k], V >= base[k])) / N

if left > 0:

z_left.append(base[k])
L.append(left / base[k] ** 2)

Expand Down Expand Up @@ -151,7 +150,8 @@ def select_copula(X):

left_tail, empirical_left_aut, right_tail, empirical_right_aut = _compute_empirical(X)
candidate_left_auts, candidate_right_auts = _compute_candidates(
copula_candidates, left_tail, right_tail)
copula_candidates, left_tail, right_tail
)

empirical_aut = np.concatenate((empirical_left_aut, empirical_right_aut))
candidate_auts = [
Expand Down
14 changes: 6 additions & 8 deletions copulas/bivariate/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def __new__(cls, *args, **kwargs):
return super(Bivariate, cls).__new__(cls)

if not isinstance(copula_type, CopulaTypes):
if (isinstance(copula_type, str) and copula_type.upper() in CopulaTypes.__members__):
if isinstance(copula_type, str) and copula_type.upper() in CopulaTypes.__members__:
copula_type = CopulaTypes[copula_type.upper()]
else:
raise ValueError(f'Invalid copula type {copula_type}')
Expand Down Expand Up @@ -192,11 +192,7 @@ def to_dict(self):
dict: Parameters of the copula.
"""
return {
'copula_type': self.copula_type.name,
'theta': self.theta,
'tau': self.tau
}
return {'copula_type': self.copula_type.name, 'theta': self.theta, 'tau': self.tau}

@classmethod
def from_dict(cls, copula_dict):
Expand Down Expand Up @@ -297,6 +293,7 @@ def percent_point(self, y, V):
self.check_fit()
result = []
for _y, _v in zip(y, V):

def f(u):
return self.partial_derivative_scalar(u, _v) - _y

Expand Down Expand Up @@ -330,7 +327,7 @@ def partial_derivative(self, X):
np.ndarray
"""
delta = (-2 * (X[:, 1] > 0.5) + 1)
delta = -2 * (X[:, 1] > 0.5) + 1
delta = 0.0001 * delta
X_prime = X.copy()
X_prime[:, 1] += delta
Expand Down Expand Up @@ -411,10 +408,11 @@ def select_copula(cls, X):
"""
from copulas.bivariate import select_copula # noqa

warnings.warn(
'`Bivariate.select_copula` has been deprecated and will be removed in a later '
'release. Please use `copulas.bivariate.select_copula` instead',
DeprecationWarning
DeprecationWarning,
)
return select_copula(X)

Expand Down
5 changes: 3 additions & 2 deletions copulas/bivariate/clayton.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,10 @@ def cumulative_distribution(self, X):
cdfs = [
np.power(
np.power(U[i], -self.theta) + np.power(V[i], -self.theta) - 1,
-1.0 / self.theta
-1.0 / self.theta,
)
if (U[i] > 0 and V[i] > 0) else 0
if (U[i] > 0 and V[i] > 0)
else 0
for i in range(len(U))
]

Expand Down
1 change: 1 addition & 0 deletions copulas/bivariate/frank.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ def compute_theta(self):

def _tau_to_theta(self, alpha):
"""Relationship between tau and theta as a solvable equation."""

def debye(t):
return t / (np.exp(t) - 1)

Expand Down
11 changes: 2 additions & 9 deletions copulas/datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,7 @@ def sample_bivariate_age_income(size=1000, seed=42):
income += np.random.normal(loc=np.log(age) / 100, scale=10, size=size)
income[np.random.randint(0, 10, size=size) == 0] /= 1000

return pd.DataFrame({
'age': age,
'income': income
})
return pd.DataFrame({'age': age, 'income': income})


def sample_trivariate_xyz(size=1000, seed=42):
Expand All @@ -61,11 +58,7 @@ def sample_trivariate_xyz(size=1000, seed=42):
with set_random_state(validate_random_state(seed), _dummy_fn):
x = stats.beta.rvs(a=0.1, b=0.1, size=size)
y = stats.beta.rvs(a=0.1, b=0.5, size=size)
return pd.DataFrame({
'x': x,
'y': y,
'z': np.random.normal(size=size) + y * 10
})
return pd.DataFrame({'x': x, 'y': y, 'z': np.random.normal(size=size) + y * 10})


def sample_univariate_bernoulli(size=1000, seed=42):
Expand Down
8 changes: 1 addition & 7 deletions copulas/multivariate/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,4 @@
from copulas.multivariate.tree import Tree, TreeTypes
from copulas.multivariate.vine import VineCopula

__all__ = (
'Multivariate',
'GaussianMultivariate',
'VineCopula',
'Tree',
'TreeTypes'
)
__all__ = ('Multivariate', 'GaussianMultivariate', 'VineCopula', 'Tree', 'TreeTypes')
13 changes: 9 additions & 4 deletions copulas/multivariate/gaussian.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,14 @@
from scipy import stats

from copulas import (
EPSILON, check_valid_values, get_instance, get_qualified_name, random_state, store_args,
validate_random_state)
EPSILON,
check_valid_values,
get_instance,
get_qualified_name,
random_state,
store_args,
validate_random_state,
)
from copulas.multivariate.base import Multivariate
from copulas.univariate import GaussianUnivariate, Univariate

Expand Down Expand Up @@ -149,8 +155,7 @@ def probability_density(self, X):
self.check_fit()
transformed = self._transform_to_normal(X)

return stats.multivariate_normal.pdf(
transformed, cov=self.correlation, allow_singular=True)
return stats.multivariate_normal.pdf(transformed, cov=self.correlation, allow_singular=True)

def cumulative_distribution(self, X):
"""Compute the cumulative distribution value for each point in X.
Expand Down
22 changes: 10 additions & 12 deletions copulas/multivariate/tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def get_tau_matrix(self):
left_parent, right_parent = edge.parents
left_u, right_u = Edge.get_conditional_uni(left_parent, right_parent)

tau[i, j], pvalue = scipy.stats.kendalltau(left_u, right_u)
tau[i, j], _pvalue = scipy.stats.kendalltau(left_u, right_u)

return tau

Expand Down Expand Up @@ -212,8 +212,7 @@ def __str__(self):
"""Produce printable representation of the class."""
template = 'L:{} R:{} D:{} Copula:{} Theta:{}'
return '\n'.join([
template.format(edge.L, edge.R, edge.D, edge.name, edge.theta)
for edge in self.edges
template.format(edge.L, edge.R, edge.D, edge.name, edge.theta) for edge in self.edges
])

def _serialize_previous_tree(self):
Expand All @@ -237,11 +236,7 @@ def to_dict(self):
Parameters of this Tree.
"""
fitted = self.fitted
result = {
'tree_type': self.tree_type,
'type': get_qualified_name(self),
'fitted': fitted
}
result = {'tree_type': self.tree_type, 'type': get_qualified_name(self), 'fitted': fitted}

if not fitted:
return result
Expand Down Expand Up @@ -451,7 +446,7 @@ def get_tree(tree_type):
Instance of a Tree of the specified type.
"""
if not isinstance(tree_type, TreeTypes):
if (isinstance(tree_type, str) and tree_type.upper() in TreeTypes.__members__):
if isinstance(tree_type, str) and tree_type.upper() in TreeTypes.__members__:
tree_type = TreeTypes[tree_type.upper()]
else:
raise ValueError(f'Invalid tree type {tree_type}')
Expand Down Expand Up @@ -657,7 +652,7 @@ def to_dict(self):
'theta': self.theta,
'tau': self.tau,
'U': U,
'likelihood': self.likelihood
'likelihood': self.likelihood,
}

@classmethod
Expand All @@ -674,8 +669,11 @@ def from_dict(cls, edge_dict):
Instance of the edge defined on the parameters.
"""
instance = cls(
edge_dict['index'], edge_dict['L'], edge_dict['R'],
edge_dict['name'], edge_dict['theta']
edge_dict['index'],
edge_dict['L'],
edge_dict['R'],
edge_dict['name'],
edge_dict['theta'],
)
instance.U = np.array(edge_dict['U'])
parents = edge_dict['parents']
Expand Down
18 changes: 12 additions & 6 deletions copulas/multivariate/vine.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@
import pandas as pd

from copulas import (
EPSILON, check_valid_values, get_qualified_name, random_state, store_args,
validate_random_state)
EPSILON,
check_valid_values,
get_qualified_name,
random_state,
store_args,
validate_random_state,
)
from copulas.bivariate.base import Bivariate, CopulaTypes
from copulas.multivariate.base import Multivariate
from copulas.multivariate.tree import Tree, get_tree
Expand Down Expand Up @@ -103,7 +108,7 @@ def to_dict(self):
result = {
'type': get_qualified_name(self),
'vine_type': self.vine_type,
'fitted': self.fitted
'fitted': self.fitted,
}

if not self.fitted:
Expand All @@ -118,7 +123,7 @@ def to_dict(self):
'tau_mat': self.tau_mat.tolist(),
'u_matrix': self.u_matrix.tolist(),
'unis': [distribution.to_dict() for distribution in self.unis],
'columns': self.columns
'columns': self.columns,
})
return result

Expand Down Expand Up @@ -293,8 +298,9 @@ def _sample_row(self):
# get index of edge to retrieve
for edge in current_tree:
if i == 0:
if (edge.L == current and edge.R == visited[0]) or\
(edge.R == current and edge.L == visited[0]):
if (edge.L == current and edge.R == visited[0]) or (
edge.R == current and edge.L == visited[0]
):
current_ind = edge.index
break
else:
Expand Down
7 changes: 4 additions & 3 deletions copulas/optimize/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ def chandrupatla(f, xmin, xmax, eps_m=None, eps_a=None, maxiter=50):
# to determine which method we should use next
xi = (a - b) / (c - b)
phi = (fa - fb) / (fc - fb)
iqi = np.logical_and(phi**2 < xi, (1 - phi)**2 < 1 - xi)
iqi = np.logical_and(phi**2 < xi, (1 - phi) ** 2 < 1 - xi)

if not shape:
# scalar case
Expand All @@ -143,8 +143,9 @@ def chandrupatla(f, xmin, xmax, eps_m=None, eps_a=None, maxiter=50):
# array case
t = np.full(shape, 0.5)
a2, b2, c2, fa2, fb2, fc2 = a[iqi], b[iqi], c[iqi], fa[iqi], fb[iqi], fc[iqi]
t[iqi] = fa2 / (fb2 - fa2) * fc2 / (fb2 - fc2) + (c2 - a2) / \
(b2 - a2) * fa2 / (fc2 - fa2) * fb2 / (fc2 - fb2)
t[iqi] = fa2 / (fb2 - fa2) * fc2 / (fb2 - fc2) + (c2 - a2) / (b2 - a2) * fa2 / (
fc2 - fa2
) * fb2 / (fc2 - fb2)

# limit to the range (tlim, 1-tlim)
t = np.minimum(1 - tlim, np.maximum(tlim, t))
Expand Down
2 changes: 1 addition & 1 deletion copulas/univariate/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@
'ParametricType',
'BoundedType',
'UniformUnivariate',
'LogLaplace'
'LogLaplace',
)
19 changes: 15 additions & 4 deletions copulas/univariate/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@
import numpy as np

from copulas import (
NotFittedError, get_instance, get_qualified_name, random_state, store_args,
validate_random_state)
NotFittedError,
get_instance,
get_qualified_name,
random_state,
store_args,
validate_random_state,
)
from copulas.univariate.selection import select_univariate


Expand Down Expand Up @@ -84,8 +89,14 @@ def _select_candidates(cls, parametric=None, bounded=None):
return candidates

@store_args
def __init__(self, candidates=None, parametric=None, bounded=None, random_state=None,
selection_sample_size=None):
def __init__(
self,
candidates=None,
parametric=None,
bounded=None,
random_state=None,
selection_sample_size=None,
):
self.candidates = candidates or self._select_candidates(parametric, bounded)
self.random_state = validate_random_state(random_state)
self.selection_sample_size = selection_sample_size
Expand Down
Loading

0 comments on commit 2f3a2be

Please sign in to comment.