|
1
|
|
|
""" |
|
2
|
|
|
Optional: |
|
3
|
|
|
|
|
4
|
|
|
It might make sense to use a class instead of a dictionary for the search-space. |
|
5
|
|
|
The search-space can have specifc properties, that can be computed from the params (previously called search-space-dictionary). |
|
6
|
|
|
The search-space can have a certain size, has n dimensions, some of which are numeric, some of which are categorical. |
|
7
|
|
|
""" |
|
8
|
|
|
|
|
9
|
|
|
from typing import Union, List, Dict, Type |
|
10
|
|
|
from collections.abc import MutableMapping |
|
11
|
|
|
|
|
12
|
|
|
from ._properties import calculate_properties |
|
13
|
|
|
|
|
14
|
|
|
|
|
15
|
|
View Code Duplication |
class SearchSpaceDictLike(MutableMapping): |
|
|
|
|
|
|
16
|
|
|
_search_space: dict = None |
|
17
|
|
|
|
|
18
|
|
|
def __init__(self, constraints: List[callable] = None, **param_space): |
|
19
|
|
|
self._search_space = dict(**param_space) |
|
20
|
|
|
self.constraints = constraints |
|
21
|
|
|
|
|
22
|
|
|
def __getitem__(self, key): |
|
23
|
|
|
return self._search_space[key] |
|
24
|
|
|
|
|
25
|
|
|
def __setitem__(self, key, value): |
|
26
|
|
|
self._search_space[key] = value |
|
27
|
|
|
|
|
28
|
|
|
def __delitem__(self, key): |
|
29
|
|
|
del self._search_space[key] |
|
30
|
|
|
|
|
31
|
|
|
def __iter__(self): |
|
32
|
|
|
return iter(self._search_space) |
|
33
|
|
|
|
|
34
|
|
|
def __len__(self): |
|
35
|
|
|
return len(self._search_space) |
|
36
|
|
|
|
|
37
|
|
|
def __repr__(self): |
|
38
|
|
|
return f"{self.__class__.__name__}({self._search_space})" |
|
39
|
|
|
|
|
40
|
|
|
def __call__(self): |
|
41
|
|
|
return self._search_space |
|
42
|
|
|
|
|
43
|
|
|
def keys(self): |
|
44
|
|
|
return self._search_space.keys() |
|
45
|
|
|
|
|
46
|
|
|
def values(self): |
|
47
|
|
|
return self._search_space.values() |
|
48
|
|
|
|
|
49
|
|
|
def items(self): |
|
50
|
|
|
return self._search_space.items() |
|
51
|
|
|
|
|
52
|
|
|
|
|
53
|
|
View Code Duplication |
class SearchConfig(SearchSpaceDictLike): |
|
|
|
|
|
|
54
|
|
|
|
|
55
|
|
|
@calculate_properties |
|
56
|
|
|
def __init__(self, **param_space): |
|
57
|
|
|
super().__init__(**param_space) |
|
58
|
|
|
|
|
59
|
|
|
for key, value in param_space.items(): |
|
60
|
|
|
setattr(self, key, value) |
|
61
|
|
|
|
|
62
|
|
|
@calculate_properties |
|
63
|
|
|
def __setitem__(self, key, value): |
|
64
|
|
|
SearchSpaceDictLike.__setitem__(self, key, value) |
|
65
|
|
|
|
|
66
|
|
|
@calculate_properties |
|
67
|
|
|
def __delitem__(self, key): |
|
68
|
|
|
SearchSpaceDictLike.__delitem__(self, key) |
|
69
|
|
|
|
|
70
|
|
|
def print(self, indent=2, max_list_length=5): |
|
71
|
|
|
""" |
|
72
|
|
|
Prints the dictionary in a readable format. |
|
73
|
|
|
|
|
74
|
|
|
Args: |
|
75
|
|
|
indent (int): The number of spaces to indent nested structures. |
|
76
|
|
|
max_list_length (int): The maximum number of items to display from long lists. |
|
77
|
|
|
""" |
|
78
|
|
|
|
|
79
|
|
|
def format_value(value, level=0): |
|
80
|
|
|
prefix = " " * (level * indent) |
|
81
|
|
|
if isinstance(value, list): |
|
82
|
|
|
if len(value) > max_list_length: |
|
83
|
|
|
# Truncate long lists for readability |
|
84
|
|
|
result = "[\n" |
|
85
|
|
|
result += "".join( |
|
86
|
|
|
f"{prefix}{' ' * indent}{repr(item)},\n" |
|
87
|
|
|
for item in value[:max_list_length] |
|
88
|
|
|
) |
|
89
|
|
|
result += f"{prefix}{' ' * indent}... ({len(value) - max_list_length} more items)\n" |
|
90
|
|
|
result += f"{prefix}]" |
|
91
|
|
|
else: |
|
92
|
|
|
result = "[\n" |
|
93
|
|
|
result += "".join( |
|
94
|
|
|
f"{prefix}{' ' * indent}{repr(item)},\n" |
|
95
|
|
|
for item in value |
|
96
|
|
|
) |
|
97
|
|
|
result += f"{prefix}]" |
|
98
|
|
|
elif isinstance(value, dict): |
|
99
|
|
|
# Format nested dictionaries |
|
100
|
|
|
result = "{\n" |
|
101
|
|
|
for k, v in value.items(): |
|
102
|
|
|
result += f"{prefix}{' ' * indent}{repr(k)}: {format_value(v, level + 1)},\n" |
|
103
|
|
|
result += f"{prefix}}}" |
|
104
|
|
|
else: |
|
105
|
|
|
result = repr(value) |
|
106
|
|
|
return result |
|
107
|
|
|
|
|
108
|
|
|
for key, value in self.items(): |
|
109
|
|
|
print(f"{key}: {format_value(value)}") |
|
110
|
|
|
|