PrintResults._print_results()   B
last analyzed

Complexity

Conditions 6

Size

Total Lines 55
Code Lines 44

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 44
nop 7
dl 0
loc 55
rs 7.8906
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
"""Results printing utilities for hyperparameter optimization.
2
3
Author: Simon Blanke
4
Email: [email protected]
5
License: MIT License
6
"""
7
8
import logging
9
10
import numpy as np
11
12
indent = "  "
13
14
15
class PrintResults:
16
    """PrintResults class."""
17
18
    def __init__(self, opt_pros, verbosity):
19
        self.opt_pros = opt_pros
20
        self.verbosity = verbosity
21
22
    def _print_times(self, eval_time, iter_time, n_iter):
23
        opt_time = iter_time - eval_time
24
        iterPerSec = n_iter / iter_time
25
26
        print(
27
            indent,
28
            "Evaluation time   :",
29
            eval_time,
30
            "sec",
31
            indent,
32
            f"[{round(eval_time / iter_time * 100, 2)} %]",
33
        )
34
        print(
35
            indent,
36
            "Optimization time :",
37
            opt_time,
38
            "sec",
39
            indent,
40
            f"[{round(opt_time / iter_time * 100, 2)} %]",
41
        )
42
        if iterPerSec >= 1:
43
            print(
44
                indent,
45
                "Iteration time    :",
46
                iter_time,
47
                "sec",
48
                indent,
49
                f"[{round(iterPerSec, 2)} iter/sec]",
50
            )
51
        else:
52
            secPerIter = iter_time / n_iter
53
            print(
54
                indent,
55
                "Iteration time    :",
56
                iter_time,
57
                "sec",
58
                indent,
59
                f"[{round(secPerIter, 2)} sec/iter]",
60
            )
61
        print(" ")
62
63
    def align_para_names(self, para_names):
64
        """Align Para Names function."""
65
        str_lengths = [len(str_) for str_ in para_names]
66
        max_length = max(str_lengths)
67
68
        para_names_align = {}
69
        for para_name, str_length in zip(para_names, str_lengths):
70
            added_spaces = max_length - str_length
71
            para_names_align[para_name] = " " * added_spaces
72
73
        return para_names_align
74
75
    def _print_results(
76
        self,
77
        objective_function,
78
        best_score,
79
        best_para,
80
        best_iter,
81
        best_additional_results,
82
        random_seed,
83
    ):
84
        print(f"\nResults: '{objective_function.__name__}'", " ")
85
        if best_para is None:
86
            print(indent, "Best score:", best_score, " ")
87
            print(indent, "Best parameter set:", best_para, " ")
88
            print(indent, "Best iteration:", best_iter, " ")
89
90
        else:
91
            print(indent, "Best score:", best_score, " ")
92
93
            if best_additional_results:
94
                print(indent, "Best additional results:")
95
                add_results_names = list(best_additional_results.keys())
96
                add_results_names_align = self.align_para_names(add_results_names)
97
98
                for best_additional_result in best_additional_results.keys():
99
                    added_spaces = add_results_names_align[best_additional_result]
100
                    print(
101
                        indent,
102
                        indent,
103
                        f"'{best_additional_result}'",
104
                        f"{added_spaces}:",
105
                        best_additional_results[best_additional_result],
106
                        " ",
107
                    )
108
109
            if best_para:
110
                print(indent, "Best parameter set:")
111
                para_names = list(best_para.keys())
112
                para_names_align = self.align_para_names(para_names)
113
114
                for para_key in best_para.keys():
115
                    added_spaces = para_names_align[para_key]
116
                    print(
117
                        indent,
118
                        indent,
119
                        f"'{para_key}'",
120
                        f"{added_spaces}:",
121
                        best_para[para_key],
122
                        " ",
123
                    )
124
125
            print(indent, "Best iteration:", best_iter, " ")
126
127
        print(" ")
128
        print(indent, "Random seed:", random_seed, " ")
129
        print(" ")
130
131
    def print_process(self, results, nth_process):
132
        """Print Process function."""
133
        verbosity = self.verbosity
134
        objective_function = self.opt_pros[nth_process].objective_function
135
        search_space = self.opt_pros[nth_process].s_space.search_space
136
137
        search_data = results["search_data"]
138
139
        try:
140
            best_sample = search_data.iloc[search_data["score"].idxmax()]
141
142
        except TypeError:
143
            logging.warning(
144
                "Warning: Cannot index by location index with a non-integer key"
145
            )
146
147
        else:
148
            best_score = best_sample["score"]
149
            best_values = best_sample[list(search_space.keys())]
150
            best_para = dict(zip(list(search_space.keys()), best_values))
151
            best_additional_results_df = best_sample.drop(
152
                ["score"] + list(search_space.keys())
153
            )
154
            best_additional_results = best_additional_results_df.to_dict()
155
156
            best_iter = results["best_iter"]
157
            eval_times = results["eval_times"]
158
            iter_times = results["iter_times"]
159
            random_seed = results["random_seed"]
160
161
            n_iter = self.opt_pros[nth_process].n_iter
162
163
            eval_time = np.array(eval_times).sum()
164
            iter_time = np.array(iter_times).sum()
165
166
            if "print_results" in verbosity:
167
                self._print_results(
168
                    objective_function,
169
                    best_score,
170
                    best_para,
171
                    best_iter,
172
                    best_additional_results,
173
                    random_seed,
174
                )
175
176
            if "print_times" in verbosity:
177
                self._print_times(eval_time, iter_time, n_iter)
178