Completed
Push — master ( 97f98d...9ca1ad )
by Rich
01:51
created

Filter.neg()   A

Complexity

Conditions 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 3
rs 10
cc 1
1
#! /usr/bin/env python
2
#
3
# Copyright (C) 2015-2016 Rich Lewis <[email protected]>
4
# License: 3-clause BSD
5
6
"""
7
# skchem.filters
8
9
Chemical filters are defined.
10
11
"""
12
13
import pandas as pd
0 ignored issues
show
Configuration introduced by
The import pandas could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
14
15
from ..utils import method_takes_mol_series, method_takes_pandas
16
17
def _identity(x):
0 ignored issues
show
Coding Style Naming introduced by
The name x does not conform to the argument naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
18
    return x
19
20
def _identity_meth(_, x):
0 ignored issues
show
Coding Style Naming introduced by
The name x does not conform to the argument naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
21
    return x
22
23
class Filter(object):
24
25
    """ Filter base class
26
27
    Args:
28
        func (function: Mol => bool):
29
            The function to use to filter the arguments.
30
        agg (function: iterable<bool> => bool):
31
            The aggregation to use in the filter, for example `any` or `all`.
32
33
    Examples:
34
35
        >>> import skchem
36
37
        Initialize the filter with a function:
38
        >>> is_named = skchem.filters.Filter(lambda m: m.name is not None)
39
40
        Filter results can be found with `transform`:
41
        >>> ethane = skchem.Mol.from_smiles('CC', name='ethane')
42
        >>> is_named.transform(ethane)
43
        True
44
45
        >>> anonymous = skchem.Mol.from_smiles('c1ccccc1')
46
        >>> is_named.transform(anonymous)
47
        False
48
49
        The filter can also be used as a function:
50
        >>> ethane = skchem.Mol.from_smiles('CC', name='ethane')
51
        >>> is_named.transform(ethane)
52
        True
53
54
        Apply can take a series or dataframe:
55
        >>> mols = pd.Series({'anonymous': anonymous, 'ethane': ethane})
56
        >>> is_named.transform(mols)
57
        anonymous    False
58
        ethane        True
59
        dtype: bool
60
61
        Using `filter` will drop out molecules that fail the test:
62
        >>> is_named.filter(mols)
63
        ethane    <Mol: CC>
64
        dtype: object
65
66
        Only failed are retained with the `neg` keyword argument:
67
        >>> is_named.filter(mols, neg=True)
68
        anonymous    <Mol: c1ccccc1>
69
        dtype: object
70
    """
71
72
    _DEFAULT_AGG = _identity_meth
73
    _DEFAULT_IS_NEG = False
74
75
    def __init__(self, func,  agg=None, neg=False, **kwargs):
0 ignored issues
show
Coding Style introduced by
Exactly one space required after comma
def __init__(self, func, agg=None, neg=False, **kwargs):
^
Loading history...
76
77
        self.func = func
78
        self.agg = self._get_agg(agg) if agg is not None else self._DEFAULT_AGG
79
        self.neg = neg
80
        self.kwargs = kwargs
81
82
    @property
83
    def agg(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
84
        return self._agg
85
86
    @agg.setter
87
    def agg(self, val):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
88
        self._agg = self._get_agg(val)
0 ignored issues
show
Coding Style introduced by
The attribute _agg was defined outside __init__.

It is generally a good practice to initialize all attributes to default values in the __init__ method:

class Foo:
    def __init__(self, x=None):
        self.x = x
Loading history...
89
90
    def _get_agg(self, val):
91
        if val is True:
92
            return self._DEFAULT_AGG
93
        elif val is False:
94
            return _identity
95
        elif val is None:
96
            return self.agg
97
        else:
98
            return val
99
100
    @property
101
    def neg(self):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
102
        return self._get_neg(self._neg)
103
104
    @neg.setter
105
    def neg(self, val):
0 ignored issues
show
Coding Style introduced by
This method should have a docstring.

The coding style of this project requires that you add a docstring to this code element. Below, you find an example for methods:

class SomeClass:
    def some_method(self):
        """Do x and return foo."""

If you would like to know more about docstrings, we recommend to read PEP-257: Docstring Conventions.

Loading history...
106
107
        # xor
108
        self._neg = self._get_neg(val)
0 ignored issues
show
Coding Style introduced by
The attribute _neg was defined outside __init__.

It is generally a good practice to initialize all attributes to default values in the __init__ method:

class Foo:
    def __init__(self, x=None):
        self.x = x
Loading history...
109
110
111
    def _get_neg(self, val):
112
        if self._DEFAULT_IS_NEG:
113
            return not val
114
        else:
115
            return val
116
117
    @method_takes_mol_series
118
    def transform(self, mols, agg=None, neg=None):
119
120
        """ Apply the function and return the boolean values. """
121
122
        agg = self._get_agg(agg)
123
124
        if neg is None:
125
            neg = self._neg
126
        else:
127
            neg = self._get_neg(neg)
128
129
        res = self._transform(mols)
130
131
        if isinstance(res, pd.DataFrame):
132
            res = res.apply(agg, axis=1)
133
134
        if neg:
135
            res = ~res
136
137
        return res
138
139
    def _transform(self, ser):
140
        return ser.apply(self.func, **self.kwargs)
141
142
    @method_takes_pandas
143
    def filter(self, X, y=None, agg=None, neg=None):
0 ignored issues
show
Coding Style Naming introduced by
The name X does not conform to the argument naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style Naming introduced by
The name y does not conform to the argument naming conventions ([a-z_][a-z0-9_]{2,30}$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
144
145
        """ Apply the function and return filtered values.
146
147
        Args:
148
            X (pd.Series or pd.DataFrame):
149
                The compound dataframe. """
150
151
        if neg is None:
152
            neg = self.neg
153
154
        agg = self._get_agg(agg)
155
156
        res = self.transform(X, neg=neg, agg=agg)
157
158
        if y is None:
159
            return X[res]
160
        else:
161
            return X[res], y[res]
162
163
    def __call__(self, *args, **kwargs):
164
165
        return self.transform(*args, **kwargs)
166