Skip to content

Commit 0780fdf

Browse files
committed
Add ability to force candidates to be evaluated first
If the control has side effects that cannot easily be isolated from candidates, then it can be useful to run the candidates before the control. It is more easy to write new controls that do not have such side-effects.
1 parent b8e8188 commit 0780fdf

File tree

1 file changed

+11
-4
lines changed

1 file changed

+11
-4
lines changed

laboratory/experiment.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,15 @@ def candidate(self, cand_func, args=None, kwargs=None, name='Candidate', context
108108
'context': context or {},
109109
})
110110

111-
def conduct(self, randomize=True):
111+
def conduct(self, randomize=True, candidates_first=False):
112112
'''
113113
Run control & candidate functions and return the control's return value.
114114
``control()`` must be called first.
115115
116116
:param bool randomize: controls whether we shuffle the order
117117
of execution between control and candidate
118+
:param bool candidates_first: whether to run the candidates before the
119+
control
118120
:raise LaboratoryException: when no control case has been set
119121
:return: Control function's return value
120122
'''
@@ -135,13 +137,18 @@ def get_func_executor(obs_def, is_control):
135137
"""A lightweight wrapper around a tested function in order to retrieve state"""
136138
return lambda *a, **kw: (self._run_tested_func(raise_on_exception=is_control, **obs_def), is_control)
137139

138-
funcs = [
139-
get_func_executor(self._control, is_control=True),
140-
] + [get_func_executor(cand, is_control=False,) for cand in self._candidates]
140+
control_func = get_func_executor(self._control, is_control=True)
141+
funcs = [get_func_executor(cand, is_control=False,) for cand in self._candidates]
141142

142143
if randomize:
143144
random.shuffle(funcs)
144145

146+
# Insert the control func at a random index if randomize and candidates are not run first
147+
control_index = random.randint(0, len(funcs)) if randomize else 0
148+
if candidates_first:
149+
control_index = len(funcs)
150+
funcs.insert(control_index, control_func)
151+
145152
control = None
146153
candidates = []
147154

0 commit comments

Comments
 (0)