예제 #1
0
    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
예제 #2
0
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])
예제 #3
0
    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)
예제 #4
0
    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