1
|
|
|
"""Various small utilities that might be useful everywhere""" |
2
|
|
|
|
3
|
|
|
from functools import wraps |
4
|
|
|
from itertools import chain |
5
|
|
|
import numpy as np |
|
|
|
|
6
|
|
|
import logging |
7
|
|
|
|
8
|
|
|
|
9
|
|
|
log = logging.getLogger() |
10
|
|
|
|
11
|
|
|
|
12
|
|
|
def deprecated(obj): |
13
|
|
|
"""Mark called object deprecated.""" |
14
|
|
|
@wraps(obj) |
15
|
|
|
def wrapper(*args, **kwargs): |
16
|
|
|
name = '{}.{}'.format(obj.__self__.__class__, obj.__name__) if hasattr(obj, '__self__') else obj |
17
|
|
|
log.warning('Call to deprecated {}'.format(name)) |
18
|
|
|
return obj(*args, **kwargs) |
19
|
|
|
return wrapper |
20
|
|
|
|
21
|
|
|
|
22
|
|
|
def flatten(lst): |
23
|
|
|
"""Flatten iterable a single level.""" |
24
|
|
|
return chain.from_iterable(lst) |
25
|
|
|
|
26
|
|
|
|
27
|
|
|
def scale(values, min=0, max=1): |
|
|
|
|
28
|
|
|
"""Return values scaled to [min, max]""" |
29
|
|
|
ptp = np.nanmax(values) - np.nanmin(values) |
30
|
|
|
if ptp == 0: |
31
|
|
|
return np.clip(values, min, max) |
32
|
|
|
return (-np.nanmin(values) + values) / ptp * (max - min) + min |
33
|
|
|
|
34
|
|
|
|
35
|
|
|
def abstract(obj): |
36
|
|
|
"""Designate decorated class or method abstract.""" |
37
|
|
|
if isinstance(obj, type): |
38
|
|
|
old__new__ = obj.__new__ |
39
|
|
|
|
40
|
|
|
def _refuse__new__(cls, *args, **kwargs): |
41
|
|
|
if cls == obj: |
42
|
|
|
raise NotImplementedError("Can't instantiate abstract class " + obj.__name__) |
43
|
|
|
return old__new__(cls, *args, **kwargs) |
44
|
|
|
|
45
|
|
|
obj.__new__ = _refuse__new__ |
46
|
|
|
return obj |
47
|
|
|
else: |
48
|
|
|
if not hasattr(obj, '__qualname__'): |
49
|
|
|
raise TypeError('Put @abstract decorator below (evaluated before) ' |
50
|
|
|
'any of @staticmethod, @classmethod, or @property.') |
51
|
|
|
cls_name = obj.__qualname__.rsplit('.', 1)[0] |
52
|
|
|
def _refuse__call__(*args, **kwargs): |
|
|
|
|
53
|
|
|
raise NotImplementedError("Can't call abstract method {} of class {}" |
54
|
|
|
.format(obj.__name__, cls_name)) |
55
|
|
|
return _refuse__call__ |
56
|
|
|
|
57
|
|
|
|
58
|
|
|
def export_globals(globals, module_name): |
|
|
|
|
59
|
|
|
""" |
60
|
|
|
Return list of important for export globals (callables, constants) from |
61
|
|
|
`globals` dict, defined in module `module_name`. |
62
|
|
|
|
63
|
|
|
Usage |
64
|
|
|
----- |
65
|
|
|
In some module, on the second-to-last line: |
66
|
|
|
|
67
|
|
|
__all__ = export_globals(globals(), __name__) |
68
|
|
|
|
69
|
|
|
""" |
70
|
|
|
return [getattr(v, '__name__', k) |
71
|
|
|
for k, v in globals.items() # export |
72
|
|
|
if ((callable(v) and v.__module__ == module_name # callables from this module |
73
|
|
|
or k.isupper()) and # or CONSTANTS |
74
|
|
|
not getattr(v, '__name__', k).startswith('_'))] # neither marked internal |
75
|
|
|
|
76
|
|
|
|
77
|
|
|
# For best result, keep this at the bottom |
78
|
|
|
__all__ = export_globals(globals(), __name__) |
79
|
|
|
|
80
|
|
|
# ONLY NON-EXPORTED VALUES BELOW HERE |
81
|
|
|
|
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.
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.