Passed
Pull Request — master (#101)
by Simon
01:37
created

search_space   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 135
Duplicated Lines 92.59 %

Importance

Changes 0
Metric Value
eloc 98
dl 125
loc 135
rs 9.6
c 0
b 0
f 0
wmc 35

13 Methods

Rating   Name   Duplication   Size   Complexity  
A SearchSpace.__init__() 17 17 2
A SearchSpace.__call__() 2 2 1
A SearchSpace._string_or_object() 11 11 5
A SearchSpace.check_list() 9 9 3
A DictClass.keys() 2 2 1
A DictClass.__getitem__() 2 2 1
A DictClass.values() 2 2 1
A SearchSpace.dim_types() 14 14 4
A SearchSpace._create_num_str_ss() 17 17 5
A SearchSpace.is_number() 11 11 3
A SearchSpace.is_function() 8 8 3
A DictClass.__init__() 2 2 1
A SearchSpace.check_non_num_values() 15 15 5

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
# Author: Simon Blanke
2
# Email: [email protected]
3
# License: MIT License
4
5
import numpy as np
6
7
8 View Code Duplication
class DictClass:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
9
    def __init__(self, search_space):
10
        self.search_space = search_space
11
12
    def __getitem__(self, key):
13
        return self.search_space[key]
14
15
    def keys(self):
16
        return self.search_space.keys()
17
18
    def values(self):
19
        return self.search_space.values()
20
21
22 View Code Duplication
class SearchSpace(DictClass):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
23
    def __init__(self, search_space):
24
        super().__init__(search_space)
25
        self.search_space = search_space
26
27
        self.dim_keys = list(search_space.keys())
28
        self.values_l = list(self.search_space.values())
29
30
        positions = {}
31
        for key in search_space.keys():
32
            positions[key] = np.array(range(len(search_space[key])))
33
        self.positions = positions
34
35
        self.check_list()
36
        self.check_non_num_values()
37
38
        self.data_types = self.dim_types()
39
        self.func2str = self._create_num_str_ss()
40
41
    def __call__(self):
42
        return self.search_space
43
44
    def dim_types(self):
45
        data_types = {}
46
        for dim_key in self.dim_keys:
47
            dim_values = np.array(list(self.search_space[dim_key]))
48
            try:
49
                np.subtract(dim_values, dim_values)
50
                np.array(dim_values).searchsorted(dim_values)
51
            except:
52
                _type_ = "object"
53
            else:
54
                _type_ = "number"
55
56
            data_types[dim_key] = _type_
57
        return data_types
58
59
    def _create_num_str_ss(self):
60
        func2str = {}
61
        for dim_key in self.dim_keys:
62
            if self.data_types[dim_key] == "number":
63
                func2str[dim_key] = self.search_space[dim_key]
64
            else:
65
                func2str[dim_key] = []
66
67
                dim_values = self.search_space[dim_key]
68
                for value in dim_values:
69
                    try:
70
                        func_name = value.__name__
71
                    except:
72
                        func_name = value
73
74
                    func2str[dim_key].append(func_name)
75
        return func2str
76
77
    def check_list(self):
78
        for dim_key in self.dim_keys:
79
            search_dim = self.search_space[dim_key]
80
81
            err_msg = "\n Value in '{}' of search space dictionary must be of type list \n".format(
82
                dim_key
83
            )
84
            if not isinstance(search_dim, list):
85
                raise ValueError(err_msg)
86
87
    @staticmethod
88
    def is_function(value):
89
        try:
90
            value.__name__
91
        except:
92
            return False
93
        else:
94
            return True
95
96
    @staticmethod
97
    def is_number(value):
98
        try:
99
            float(value)
100
            value * 0.1
101
            value - 0.1
102
            value / 0.1
103
        except:
104
            return False
105
        else:
106
            return True
107
108
    def _string_or_object(self, dim_key, dim_values):
109
        for dim_value in dim_values:
110
            is_str = isinstance(dim_value, str)
111
            is_func = self.is_function(dim_value)
112
            is_number = self.is_number(dim_value)
113
114
            if not is_str and not is_func and not is_number:
115
                msg = "\n The value '{}' of type '{}' in the search space dimension '{}' must be number, string or function \n".format(
116
                    dim_value, type(dim_value), dim_key
117
                )
118
                raise ValueError(msg)
119
120
    def check_non_num_values(self):
121
        for dim_key in self.dim_keys:
122
            dim_values = np.array(list(self.search_space[dim_key]))
123
124
            try:
125
                np.subtract(dim_values, dim_values)
126
                np.array(dim_values).searchsorted(dim_values)
127
            except:
128
                self._string_or_object(dim_key, dim_values)
129
            else:
130
                if dim_values.ndim != 1:
131
                    msg = "Array-like object in '{}' must be one dimensional".format(
132
                        dim_key
133
                    )
134
                    raise ValueError(msg)
135