def conduct(self, randomize=True): ''' Run control & candidate functions and return the control's return value. ``control()`` must be called first. :param bool randomize: controls whether we shuffle the order of execution between control and candidate :raise LaboratoryException: when no control case has been set :return: Control function's return value ''' if self._control is None: raise exceptions.LaboratoryException( 'Your experiment must contain a control case') # execute control and exit if experiment is not enabled if not self.enabled(): control = self._run_tested_func(raise_on_exception=True, **self._control) return control.value # otherwise, let's wrap an executor around all of our functions and randomise the ordering def get_func_executor(obs_def, is_control): """A lightweight wrapper around a tested function in order to retrieve state""" return lambda *a, **kw: (self._run_tested_func( raise_on_exception=is_control, **obs_def), is_control) funcs = [ get_func_executor(self._control, is_control=True), ] + [ get_func_executor( cand, is_control=False, ) for cand in self._candidates ] if randomize: random.shuffle(funcs) control = None candidates = [] # go through the randomised list and execute the functions for func in funcs: observation, is_control = func() if is_control: control = observation else: candidates.append(observation) result = Result(self, control, candidates) try: self.publish(result) except Exception: msg = 'Exception occured when publishing %s experiment data' logger.exception(msg % self.name) return control.value
def result_factory(first, second): control = Observation('Control') control.set_start_time() control.record(first) control.set_end_time() candidate = Observation('Candidate') candidate.set_start_time() candidate.record(second) candidate.set_end_time() return Result(experiments.Experiment(), control, [candidate])
def run_candidates(self, control, funcs): candidates = [] for func in funcs: observation, _ = func() candidates.append(observation) result = Result(self, control, candidates) try: self.publish(result) except Exception: msg = 'Exception occured when publishing %s experiment data' logger.exception(msg % self.name)
def run(self): if self._control is None: raise exceptions.LaboratoryException( 'Your experiment must record a control case') result = Result(self, self._control, self._observations) try: self.publish(result) except Exception as e: msg = 'Exception occured when publishing %s experiment data' logger.exception(msg % self.name) return self._control.value