Skip to content

Commit 0f56599

Browse files
committed
Move loggers to loggers.py file
This move allows us to stop tracking tests for these two objects and have the package's coverage report more closely representing what it should.
1 parent d34f890 commit 0f56599

File tree

9 files changed

+146
-142
lines changed

9 files changed

+146
-142
lines changed

.coveragerc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ omit =
2121
*/setup.py
2222
examples/*
2323
tests/*
24+
bayes_opt/logger.py

bayes_opt/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from .bayesian_optimization import BayesianOptimization, Events
22
from .util import UtilityFunction
3-
from .observer import ScreenLogger, JSONLogger
3+
from .logger import ScreenLogger, JSONLogger
44

55
__all__ = [
66
"BayesianOptimization",

bayes_opt/bayesian_optimization.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from .target_space import TargetSpace
55
from .event import Events, DEFAULT_EVENTS
6-
from .observer import _get_default_logger
6+
from .logger import _get_default_logger
77
from .util import UtilityFunction, acq_max, ensure_rng
88

99
from sklearn.gaussian_process.kernels import Matern

bayes_opt/logger.py

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
from __future__ import print_function
2+
import os
3+
import json
4+
5+
from .observer import _Tracker
6+
from .event import Events
7+
from .util import Colours
8+
9+
10+
def _get_default_logger(verbose):
11+
return ScreenLogger(verbose=verbose)
12+
13+
14+
class ScreenLogger(_Tracker):
15+
_default_cell_size = 9
16+
_default_precision = 4
17+
18+
def __init__(self, verbose=2):
19+
self._verbose = verbose
20+
self._header_length = None
21+
super(ScreenLogger, self).__init__()
22+
23+
@property
24+
def verbose(self):
25+
return self._verbose
26+
27+
@verbose.setter
28+
def verbose(self, v):
29+
self._verbose = v
30+
31+
def _format_number(self, x):
32+
if isinstance(x, int):
33+
s = "{x:< {s}}".format(
34+
x=x,
35+
s=self._default_cell_size,
36+
)
37+
else:
38+
s = "{x:< {s}.{p}}".format(
39+
x=x,
40+
s=self._default_cell_size,
41+
p=self._default_precision,
42+
)
43+
44+
if len(s) > self._default_cell_size:
45+
if "." in s:
46+
return s[:self._default_cell_size]
47+
else:
48+
return s[:self._default_cell_size - 3] + "..."
49+
return s
50+
51+
def _format_key(self, key):
52+
s = "{key:^{s}}".format(
53+
key=key,
54+
s=self._default_cell_size
55+
)
56+
if len(s) > self._default_cell_size:
57+
return s[:self._default_cell_size - 3] + "..."
58+
return s
59+
60+
def _step(self, instance, colour=Colours.black):
61+
res = instance.res[-1]
62+
cells = []
63+
64+
cells.append(self._format_number(self._iterations + 1))
65+
cells.append(self._format_number(res["target"]))
66+
67+
for key in instance.space.keys:
68+
cells.append(self._format_number(res["params"][key]))
69+
70+
return "| " + " | ".join(map(colour, cells)) + " |"
71+
72+
def _header(self, instance):
73+
cells = []
74+
cells.append(self._format_key("iter"))
75+
cells.append(self._format_key("target"))
76+
for key in instance.space.keys:
77+
cells.append(self._format_key(key))
78+
79+
line = "| " + " | ".join(cells) + " |"
80+
self._header_length = len(line)
81+
return line + "\n" + ("-" * self._header_length)
82+
83+
def _is_new_max(self, instance):
84+
if self._previous_max is None:
85+
self._previous_max = instance.max["target"]
86+
return instance.max["target"] > self._previous_max
87+
88+
def update(self, event, instance):
89+
if event == Events.OPTMIZATION_START:
90+
line = self._header(instance) + "\n"
91+
elif event == Events.OPTMIZATION_STEP:
92+
is_new_max = self._is_new_max(instance)
93+
if self._verbose == 1 and not is_new_max:
94+
line = ""
95+
else:
96+
colour = Colours.purple if is_new_max else Colours.black
97+
line = self._step(instance, colour=colour) + "\n"
98+
elif event == Events.OPTMIZATION_END:
99+
line = "=" * self._header_length + "\n"
100+
101+
if self._verbose:
102+
print(line, end="")
103+
self._update_tracker(event, instance)
104+
105+
106+
class JSONLogger(_Tracker):
107+
def __init__(self, path):
108+
self._path = path if path[-5:] == ".json" else path + ".json"
109+
try:
110+
os.remove(self._path)
111+
except OSError:
112+
pass
113+
super(JSONLogger, self).__init__()
114+
115+
def update(self, event, instance):
116+
if event == Events.OPTMIZATION_STEP:
117+
data = dict(instance.res[-1])
118+
119+
now, time_elapsed, time_delta = self._time_metrics()
120+
data["datetime"] = {
121+
"datetime": now,
122+
"elapsed": time_elapsed,
123+
"delta": time_delta,
124+
}
125+
126+
with open(self._path, "a") as f:
127+
f.write(json.dumps(data) + "\n")
128+
129+
self._update_tracker(event, instance)

bayes_opt/observer.py

Lines changed: 0 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
11
"""
22
observers...
33
"""
4-
from __future__ import print_function
5-
import os
6-
import json
74
from datetime import datetime
8-
95
from .event import Events
10-
from .util import Colours
116

127

138
class Observer:
@@ -51,124 +46,3 @@ def _time_metrics(self):
5146
time_elapsed.total_seconds(),
5247
time_delta.total_seconds()
5348
)
54-
55-
56-
def _get_default_logger(verbose):
57-
return ScreenLogger(verbose=verbose)
58-
59-
60-
class ScreenLogger(_Tracker):
61-
_default_cell_size = 9
62-
_default_precision = 4
63-
64-
def __init__(self, verbose=2):
65-
self._verbose = verbose
66-
self._header_length = None
67-
super(ScreenLogger, self).__init__()
68-
69-
@property
70-
def verbose(self):
71-
return self._verbose
72-
73-
@verbose.setter
74-
def verbose(self, v):
75-
self._verbose = v
76-
77-
def _format_number(self, x):
78-
if isinstance(x, int):
79-
s = "{x:< {s}}".format(
80-
x=x,
81-
s=self._default_cell_size,
82-
)
83-
else:
84-
s = "{x:< {s}.{p}}".format(
85-
x=x,
86-
s=self._default_cell_size,
87-
p=self._default_precision,
88-
)
89-
90-
if len(s) > self._default_cell_size:
91-
if "." in s:
92-
return s[:self._default_cell_size]
93-
else:
94-
return s[:self._default_cell_size - 3] + "..."
95-
return s
96-
97-
def _format_key(self, key):
98-
s = "{key:^{s}}".format(
99-
key=key,
100-
s=self._default_cell_size
101-
)
102-
if len(s) > self._default_cell_size:
103-
return s[:self._default_cell_size - 3] + "..."
104-
return s
105-
106-
def _step(self, instance, colour=Colours.black):
107-
res = instance.res[-1]
108-
cells = []
109-
110-
cells.append(self._format_number(self._iterations + 1))
111-
cells.append(self._format_number(res["target"]))
112-
113-
for key in instance.space.keys:
114-
cells.append(self._format_number(res["params"][key]))
115-
116-
return "| " + " | ".join(map(colour, cells)) + " |"
117-
118-
def _header(self, instance):
119-
cells = []
120-
cells.append(self._format_key("iter"))
121-
cells.append(self._format_key("target"))
122-
for key in instance.space.keys:
123-
cells.append(self._format_key(key))
124-
125-
line = "| " + " | ".join(cells) + " |"
126-
self._header_length = len(line)
127-
return line + "\n" + ("-" * self._header_length)
128-
129-
def _is_new_max(self, instance):
130-
if self._previous_max is None:
131-
self._previous_max = instance.max["target"]
132-
return instance.max["target"] > self._previous_max
133-
134-
def update(self, event, instance):
135-
if event == Events.OPTMIZATION_START:
136-
line = self._header(instance) + "\n"
137-
elif event == Events.OPTMIZATION_STEP:
138-
is_new_max = self._is_new_max(instance)
139-
if self._verbose == 1 and not is_new_max:
140-
line = ""
141-
else:
142-
colour = Colours.purple if is_new_max else Colours.black
143-
line = self._step(instance, colour=colour) + "\n"
144-
elif event == Events.OPTMIZATION_END:
145-
line = "=" * self._header_length + "\n"
146-
147-
if self._verbose:
148-
print(line, end="")
149-
self._update_tracker(event, instance)
150-
151-
class JSONLogger(_Tracker):
152-
def __init__(self, path):
153-
self._path = path if path[-5:] == ".json" else path + ".json"
154-
try:
155-
os.remove(self._path)
156-
except OSError:
157-
pass
158-
super(JSONLogger, self).__init__()
159-
160-
def update(self, event, instance):
161-
if event == Events.OPTMIZATION_STEP:
162-
data = dict(instance.res[-1])
163-
164-
now, time_elapsed, time_delta = self._time_metrics()
165-
data["datetime"] = {
166-
"datetime": now,
167-
"elapsed": time_elapsed,
168-
"delta": time_delta,
169-
}
170-
171-
with open(self._path, "a") as f:
172-
f.write(json.dumps(data) + "\n")
173-
174-
self._update_tracker(event, instance)

bayes_opt/util.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ def _wrap_colour(cls, s, colour):
191191

192192
@classmethod
193193
def black(cls, s):
194-
"""Wrap text in blue."""
194+
"""Wrap text in black."""
195195
return cls._wrap_colour(s, cls.END)
196196

197197
@classmethod

tests/test_bayesian_optimization.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import numpy as np
33
from bayes_opt import UtilityFunction
44
from bayes_opt import BayesianOptimization
5-
from bayes_opt.observer import ScreenLogger
5+
from bayes_opt.logger import ScreenLogger
66
from bayes_opt.event import Events, DEFAULT_EVENTS
77

88

@@ -71,7 +71,7 @@ def test_probe_eager():
7171

7272

7373
def test_suggest_at_random():
74-
util = UtilityFunction(kind="ucb", kappa=5, xi=0)
74+
util = UtilityFunction(kind="poi", kappa=5, xi=0)
7575
optimizer = BayesianOptimization(target_func, PBOUNDS, random_state=1)
7676

7777
for _ in range(50):
@@ -248,7 +248,8 @@ def update_end(self, event, instance):
248248
def reset(self):
249249
self.__init__()
250250

251-
optimizer = BayesianOptimization(target_func, PBOUNDS, random_state=1)
251+
optimizer = BayesianOptimization(target_func, PBOUNDS,
252+
random_state=np.random.RandomState(1))
252253

253254
tracker = Tracker()
254255
optimizer.subscribe(
@@ -282,6 +283,13 @@ def reset(self):
282283
assert tracker.step_count == 3
283284
assert tracker.end_count == 2
284285

286+
optimizer.maximize(init_points=0, n_iter=2)
287+
assert optimizer._queue.empty
288+
assert len(optimizer.space) == 5
289+
assert tracker.start_count == 3
290+
assert tracker.step_count == 5
291+
assert tracker.end_count == 3
292+
285293

286294
if __name__ == '__main__':
287295
r"""

tests/test_observer.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from bayes_opt.bayesian_optimization import Observable
2-
from bayes_opt.observer import ScreenLogger, _Tracker, _get_default_logger
2+
from bayes_opt.observer import _Tracker
33
from bayes_opt.event import Events
44

55

@@ -112,15 +112,6 @@ def max(self):
112112
assert previous_time < tracker._previous_time
113113

114114

115-
def test_get_default_logger():
116-
logger = _get_default_logger(verbose=1)
117-
assert isinstance(logger, ScreenLogger)
118-
assert logger._verbose == 1
119-
120-
logger = _get_default_logger(verbose=2)
121-
assert logger._verbose == 2
122-
123-
124115
if __name__ == '__main__':
125116
r"""
126117
CommandLine:

tests/test_util.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ def f(x, y):
148148

149149
def test_colours():
150150
colour_wrappers = [
151+
(Colours.END, Colours.black),
151152
(Colours.BLUE, Colours.blue),
152153
(Colours.BOLD, Colours.bold),
153154
(Colours.CYAN, Colours.cyan),

0 commit comments

Comments
 (0)