Completed
Push — master ( 1b49d8...c3d981 )
by Rich
17:58
created

ChemObjectIterator   A

Complexity

Total Complexity 3

Size/Duplication

Total Lines 18
Duplicated Lines 0 %

Test Coverage

Coverage 50%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 3
c 1
b 0
f 0
dl 0
loc 18
ccs 4
cts 8
cp 0.5
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __init__() 0 4 1
A __next__() 0 6 2
1
#! /usr/bin/env python
2
#
3
# Copyright (C) 2015-2016 Rich Lewis <[email protected]>
4
# License: 3-clause BSD
5
6 1
"""
7
## skchem.core.base
8
9
Define base classes for scikit chem objects
10
"""
11
12 1
from abc import ABCMeta, abstractmethod
13 1
import warnings
14 1
import numpy as np
0 ignored issues
show
Configuration introduced by
The import numpy 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...
15 1
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...
16
17
18 1
class ChemicalObject(object):
19
20
    """ A mixin for each chemical object in scikit-chem """
21
22 1
    @classmethod
23
    def from_super(cls, obj):
24
25
        """A method that converts the class of an object of parent class to that of the child. """
26
27 1
        obj.__class__ = cls
28 1
        return obj
29
30
31 1
class ChemicalObjectView(object):
32
33
    """ Atom interface wrapper """
34
35 1
    def __init__(self, owner):
36 1
        self.owner = owner
37 1
38
    def __iter__(self):
39 1
        return ChemObjectIterator(self)
40 1
41 1
    def __str__(self):
42
        return str(list(str(obj) for obj in self))
43 1
44 1
    @property
45
    def props(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...
46 1
        return MolPropertyView(self)
47 1
48
    def __repr__(self):
49 1
        return '<{class_} values="{values}" at {address}>'.format(
50
            class_=self.__class__.__name__,
51
            values=str(self),
52 1
            address=hex(id(self)))
53
54
55
class ChemObjectIterator(object):
56 1
57
    """ Atom iterator """
58
59
    def __init__(self, view):
60 1
        self.view = view
61
        self._current = 0
62
        self._high = len(self.view)
63
64 1
    def __next__(self):
65
        if self._current >= self._high:
66
            raise StopIteration
67
        else:
68 1
            self._current += 1
69
            return self.view[self._current - 1]
70
71
    # py2 compat
72
    next = __next__
73
74
75 1
class View(object):
76
77
    """ View wrapper interface """
78
    __metaclass__ = ABCMeta
79 1
80 1
    @abstractmethod
81 1
    def keys(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...
82 1
        return []
83
84 1
    def get(self, index, default=None):
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...
85 1
        if index in self.keys():
86 1
            return self[index]
87
        else:
88 1
            return default
89 1
90
    def pop(self, index, default=None):
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...
91
        if default:
92 1
            val = self.get(index, default)
93
        else:
94
            val = self[index]
95 1
        self.remove(index)
96
        return val
97
98 1
    def clear(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...
99
        for idx in self.keys():
100 1
            self.remove(idx)
101
102
    def items(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...
103
        return list((k, self[k]) for k in self.keys())
104 1
105 1
    def remove(self, key):
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 1
        self.__delitem__(key)
107
108 1
    def __getitem__(self, key):
109
        raise NotImplemented
0 ignored issues
show
Best Practice introduced by
NotImplemented raised - should raise NotImplementedError
Loading history...
110 1
111 1
    def __setitem__(self, key, value):
112
        raise NotImplemented
0 ignored issues
show
Best Practice introduced by
NotImplemented raised - should raise NotImplementedError
Loading history...
113
114 1
    def __delitem__(self, key):
115 1
        raise NotImplemented
0 ignored issues
show
Best Practice introduced by
NotImplemented raised - should raise NotImplementedError
Loading history...
116 1
117
    def __iter__(self):
118 1
        return iter(self.keys())
119 1
120 1
    def __str__(self):
121
        return str(self.to_dict())
122 1
123 1
    def __len__(self):
124
        return len(self.keys())
125 1
126 1
    def __repr__(self):
127
        return '<{klass} values="{values}" at {address}>'.format(
128 1
            klass=self.__class__.__name__,
129
            values=str(self),
130
            address=hex(id(self)))
131 1
132
    def to_dict(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...
133
        return dict(self)
134 1
135
    def to_series(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...
136
        return pd.Series(self.to_dict())
137 1
138
139
class PropertyView(View):
140 1
141
    """ Property object wrapper """
142
143 1
    def __init__(self, owner):
144 1
        self._owner = owner
145
146 1
    def keys(self):
147
        return list(k for k in self._owner.GetPropNames() if k[:1] != '_')
148
149
    def __getitem__(self, key):
150
151
        # we manually work out if it was a float that was stored, as GetProp
152
        # returns floats and ints set by SetDoubleProp and SetIntProp as strings
153 1
        value = self._owner.GetProp(str(key))
154
        try:
155
            return int(value)
156
        except ValueError:
157 1
            try:
158 1
                return float(value)
159
            except ValueError:
160 1
                return value
161 1
162
    def __setitem__(self, key, value):
163 1
164
        if not isinstance(key, str):
165
            warnings.warn("RDKit property keys can only be of type `str`.  Using `{key}` as a `str`.".format(key=key))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (118/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
166
            key = str(key)
167 1
168 1
        if key[0] == '_':
169 1
            warnings.warn("`{value}` is a private RDKit property key. "
170 1
                          "Using this may have unintended consequences.".format(value=value))
171 1
172 1
        if isinstance(value, str):
173 1
            self._owner.SetProp(key, value)
174 1
        elif isinstance(value, (int, np.int64, np.int32)):
175
            self._owner.SetIntProp(key, value)
176 1
        elif isinstance(value, (float, np.float64, np.float32)):
177
            self._owner.SetDoubleProp(key, value)
178 1
        else:
179 1
            warnings.warn("RDKit property keys can only be `str`, `int` or `float`."
180 1
                          "Using `{value}` as a `str`.".format(value=value))
181
            self._owner.SetProp(key, str(value))
182 1
183
    def __delitem__(self, index):
184
        self._owner.ClearProp(index)
185
186 1
187 1
188 1
class MolPropertyView(View):
189 1
190 1
    """ Mol property wrapper """
191 1
192
    def __init__(self, obj_view):
193
        self._obj_view = obj_view
194
195
    def keys(self):
196
        res = set()
197 1
        for atom in self._obj_view:
198 1
            res = res.union(set(atom.props.keys()))
199
        return list(res)
200
201 1
    def get(self, key, default=None):
202
        return pd.Series((a.props.get(key, default) for a in self._obj_view), index=self._obj_view.index)
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (105/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
203
204
    def __getitem__(self, key):
205 1
        if key not in self.keys():
206 1
            raise KeyError('No atoms have the property set.')
207
        return self.get(key, None)
208 1
209 1
    def __setitem__(self, key, value):
210 1
        if isinstance(value, (pd.Series, dict)):
211 1
            for idx, val in pd.compat.iteritems(value):
212 1
                self._obj_view[int(idx)].props[key] = val
213
        else:
214 1
            assert len(self._obj_view) == len(value), "Must pass same number of values as atoms."
215 1
            for atom, val in zip(self._obj_view, value):
216
                atom.props[key] = val
217 1
218 1
    def __delitem__(self, key):
219 1
        for atom in self._obj_view:
220 1
            atom.props.remove(key)
221
222 1
    def to_frame(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...
223 1
        return pd.DataFrame(dict(self), index=self._obj_view.index)
224 1
225 1
    def to_dict(self):
226
        return {k: v.tolist() for k, v in pd.compat.iteritems(self)}
227 1
228 1
    def __str__(self):
229 1
        return str(self.to_dict())
230
231