def experiment(parser, token): """ Split Testing experiment tag has the following syntax : {% experiment <experiment_name> <alternative> %} experiment content goes here {% endexperiment %} If the alternative name is neither 'test' nor 'control' an exception is raised during rendering. """ try: token_contents = token.split_contents() experiment_name, alternative, weight, user_variable = _parse_token_contents(token_contents) node_list = parser.parse(('endexperiment', )) parser.delete_first_token() except ValueError: raise template.TemplateSyntaxError("Syntax should be like :" "{% experiment experiment_name alternative [weight=val] [user=val] %}") experiment = experiment_manager.get(experiment_name, None) if experiment: experiment.ensure_alternative_exists(alternative, weight) return ExperimentNode(node_list, experiment_name, alternative, user_variable)
def confirm_human(self): if self.session.get('experiments_verified_human', False): return self.session['experiments_verified_human'] = True # Replay enrollments for enrollment in self._get_all_enrollments(): enrollment.experiment.increment_participant_count( enrollment.alternative, self._participant_identifier()) # Replay goals if 'experiments_goals' in self.session: try: for experiment_name, alternative, goal_name, count in self.session[ 'experiments_goals']: experiment = experiment_manager.get(experiment_name, None) if experiment: experiment.increment_goal_count( alternative, goal_name, self._participant_identifier(), count) except ValueError: pass # Values from older version finally: del self.session['experiments_goals']
def enroll(self, experiment_name, alternatives): """Enroll this user in the experiment if they are not already part of it. Returns the selected alternative""" chosen_alternative = conf.CONTROL_GROUP experiment = experiment_manager.get(experiment_name, None) if experiment and experiment.is_displaying_alternatives(): if isinstance(alternatives, collections.Mapping): if conf.CONTROL_GROUP not in alternatives: experiment.ensure_alternative_exists(conf.CONTROL_GROUP, 1) for alternative, weight in alternatives.items(): experiment.ensure_alternative_exists(alternative, weight) else: alternatives_including_control = alternatives + [ conf.CONTROL_GROUP ] for alternative in alternatives_including_control: experiment.ensure_alternative_exists(alternative) assigned_alternative = self._get_enrollment(experiment) if assigned_alternative: chosen_alternative = assigned_alternative elif experiment.is_accepting_new_users(self._gargoyle_key()): chosen_alternative = experiment.random_alternative() self._set_enrollment(experiment, chosen_alternative) return chosen_alternative
def experiment(parser, token): """ Split Testing experiment tag has the following syntax : {% experiment <experiment_name> <alternative> [weight=val] [user=val] %} experiment content goes here {% endexperiment %} One alternative should be called "control" """ logger.debug('Entering "experiment" templatetag processor.') try: token_contents = token.split_contents() experiment_name, alternative, weight, user_variable = _parse_token_contents(token_contents) node_list = parser.parse(('endexperiment', )) parser.delete_first_token() except ValueError: raise template.TemplateSyntaxError( "Syntax should be like :{% experiment experiment_name alternative [weight=val] [user=val] %}") experiment = experiment_manager.get(experiment_name, None) if experiment: experiment.ensure_alternative_exists(alternative, weight) return ExperimentNode(node_list, experiment_name, alternative, user_variable)
def enroll(self, experiment_name, alternatives, force_alternative=None): """ Enroll this user in the experiment if they are not already part of it. Returns the selected alternative force_alternative: Optionally force a user in an alternative at enrollment time """ chosen_alternative = conf.CONTROL_GROUP experiment = experiment_manager.get(experiment_name, None) if experiment and experiment.is_displaying_alternatives(): if isinstance(alternatives, collections.Mapping): if conf.CONTROL_GROUP not in alternatives: experiment.ensure_alternative_exists(conf.CONTROL_GROUP, 1) for alternative, weight in alternatives.items(): experiment.ensure_alternative_exists(alternative, weight) else: alternatives_including_control = alternatives + [conf.CONTROL_GROUP] for alternative in alternatives_including_control: experiment.ensure_alternative_exists(alternative) assigned_alternative = self._get_enrollment(experiment) if assigned_alternative: chosen_alternative = assigned_alternative elif experiment.is_accepting_new_users(): if force_alternative: chosen_alternative = force_alternative else: chosen_alternative = experiment.random_alternative() self._set_enrollment(experiment, chosen_alternative) return chosen_alternative
def experiment(parser, token): """ Split Testing experiment tag has the following syntax : {% experiment <experiment_name> <alternative> %} experiment content goes here {% endexperiment %} If the alternative name is neither 'test' nor 'control' an exception is raised during rendering. """ try: token_contents = token.split_contents() experiment_name, alternative, weight, user_variable = _parse_token_contents( token_contents) node_list = parser.parse(('endexperiment', )) parser.delete_first_token() except ValueError: raise template.TemplateSyntaxError( "Syntax should be like :" "{% experiment experiment_name alternative [weight=val] [user=val] %}" ) experiment = experiment_manager.get(experiment_name, None) if experiment: experiment.ensure_alternative_exists(alternative, weight) return ExperimentNode(node_list, experiment_name, alternative, user_variable)
def confirm_human(self): self.session[conf.CONFIRM_HUMAN_SESSION_KEY] = True logger.info( json.dumps({ 'type': 'confirm_human', 'participant': self._participant_identifier() })) # Replay enrollments for enrollment in self._get_all_enrollments(): self.experiment_counter.increment_participant_count( enrollment.experiment, enrollment.alternative, self._participant_identifier()) # Replay goals if 'experiments_goals' in self.session: try: for experiment_name, alternative, goal_name, count in self.session[ 'experiments_goals']: experiment = experiment_manager.get(experiment_name, None) if experiment: self.experiment_counter.increment_goal_count( experiment, alternative, goal_name, self._participant_identifier(), count) except ValueError: pass # Values from older version finally: del self.session['experiments_goals']
def _get_all_enrollments(self): enrollments = self.session.get('experiments_enrollments', None) if enrollments: for experiment_name, data in enrollments.items(): alternative, _ = data experiment = experiment_manager.get(experiment_name, None) if experiment: yield experiment, alternative
def _get_all_enrollments(self): enrollments = self.session.get('experiments_enrollments', None) if enrollments: for experiment_name, data in enrollments.items(): alternative, _, enrollment_date, last_seen = _session_enrollment_latest_version(data) experiment = experiment_manager.get(experiment_name, None) if experiment: yield EnrollmentData(experiment, alternative, enrollment_date, last_seen)
def get_alternative(self, experiment_name): """Get the alternative this user is enrolled in. If not enrolled in the experiment returns 'control'""" experiment = experiment_manager.get(experiment_name, None) if experiment and experiment.is_displaying_alternatives(): alternative = self._get_enrollment(experiment) if alternative is not None: return alternative return "control"
def _get_all_enrollments(self): enrollments = self.session.get("experiments_enrollments", None) if enrollments: for experiment_name, data in enrollments.items(): alternative, _, enrollment_date, last_seen = _session_enrollment_latest_version(data) experiment = experiment_manager.get(experiment_name, None) if experiment: yield EnrollmentData(experiment, alternative, enrollment_date, last_seen)
def get_alternative(self, experiment_name): """Get the alternative this user is enrolled in. If not enrolled in the experiment returns 'control'""" experiment = experiment_manager.get(experiment_name, None) if experiment and experiment.is_displaying_alternatives(): alternative = self._get_enrollment(experiment) if alternative is not None: return alternative return 'control'
def set_alternative(self, experiment_name, alternative): """Explicitly set the alternative the user is enrolled in for the specified experiment. This allows you to change a user between alternatives. The user and goal counts for the new alternative will be increment, but those for the old one will not be decremented. The user will be enrolled in the experiment even if the experiment would not normally accept this user.""" experiment = experiment_manager.get(experiment_name, None) if experiment: self._set_enrollment(experiment, alternative)
def record_goal(self, goal_name): if self._is_verified_human(): enrollments = self.session.get('experiments_enrollments', None) if not enrollments: return for experiment_name, (alternative, goals) in enrollments.items(): experiment = experiment_manager.get(experiment_name, None) if experiment and experiment.is_displaying_alternatives(): experiment.increment_goal_count(alternative, goal_name, self._participant_identifier()) return else: goals = self.session.get('experiments_goals', []) goals.append(goal_name) # Note, duplicates are allowed self.session['experiments_goals'] = goals
def record_goal(self, goal_name): if self._is_verified_human(): enrollments = self.session.get('experiments_enrollments', None) if not enrollments: return for experiment_name, (alternative, goals) in enrollments.items(): experiment = experiment_manager.get(experiment_name, None) if experiment and experiment.is_displaying_alternatives(): experiment.increment_goal_count(alternative, goal_name, self._participant_identifier()) return else: # TODO: store temp goals and convert later when is_human is triggered # if verify human is called quick enough this should rarely happen. pass
def record_goal(self, goal_name): if self._is_verified_human(): enrollments = self.session.get('experiments_enrollments', None) if not enrollments: return for experiment_name, (alternative, goals) in enrollments.items(): experiment = experiment_manager.get(experiment_name, None) if experiment and experiment.is_displaying_alternatives(): experiment.increment_goal_count( alternative, goal_name, self._participant_identifier()) return else: goals = self.session.get('experiments_goals', []) goals.append(goal_name) # Note, duplicates are allowed self.session['experiments_goals'] = goals
def confirm_human(self): if self.session.get('experiments_verified_human', False): return self.session['experiments_verified_human'] = True enrollments = self.session.get('experiments_enrollments', None) if not enrollments: return for experiment_name, data in enrollments.items(): alternative, goals = data experiment = experiment_manager.get(experiment_name, None) if experiment: experiment.increment_participant_count(alternative, self._participant_identifier())
def is_enrolled(self, experiment_name, alternative, request): """Test if the user is enrolled in the supplied alternative for the given experiment. The supplied alternative will be added to the list of possible alternatives for the experiment if it is not already there. If the user is not yet enrolled in the supplied experiment they will be enrolled, and an alternative chosen at random.""" chosen_alternative = CONTROL_GROUP experiment = experiment_manager.get(experiment_name, None) if experiment and experiment.is_displaying_alternatives(): experiment.ensure_alternative_exists(alternative) assigned_alternative = self.get_enrollment(experiment) if assigned_alternative: chosen_alternative = assigned_alternative elif experiment.is_accepting_new_users(request): chosen_alternative = experiment.random_alternative() self.set_enrollment(experiment, chosen_alternative) return alternative == chosen_alternative
def render(self, context): experiment = experiment_manager.get(self.experiment_name, None) if experiment: experiment.ensure_alternative_exists(self.alternative, self.weight) # Get User object if self.user_variable: auth_user = self.user_variable.resolve(context) user = participant(user=auth_user) else: request = context.get('request', None) user = participant(request) # Should we render? if user.is_enrolled(self.experiment_name, self.alternative): response = self.node_list.render(context) else: response = "" return response
def confirm_human(self): if self.session.get('experiments_verified_human', False): return self.session['experiments_verified_human'] = True # Replay enrollments for enrollment in self._get_all_enrollments(): enrollment.experiment.increment_participant_count(enrollment.alternative, self._participant_identifier()) # Replay goals if 'experiments_goals' in self.session: try: for experiment_name, alternative, goal_name, count in self.session['experiments_goals']: experiment = experiment_manager.get(experiment_name, None) if experiment: experiment.increment_goal_count(alternative, goal_name, self._participant_identifier(), count) except ValueError: pass # Values from older version finally: del self.session['experiments_goals']
def confirm_human(self): if self.session.get('experiments_verified_human', False): return self.session['experiments_verified_human'] = True enrollments = self.session.get('experiments_enrollments', None) if not enrollments: return # Replay enrollments for experiment_name, data in enrollments.items(): alternative, goals = data experiment = experiment_manager.get(experiment_name, None) if experiment: experiment.increment_participant_count(alternative, self._participant_identifier()) # Replay goals if 'experiments_goals' in self.session: for goal_name in self.session['experiments_goals']: self.record_goal(goal_name) # Now we have verified human, these will be set del self.session['experiments_goals']
def confirm_human(self): self.session[conf.CONFIRM_HUMAN_SESSION_KEY] = True logger.info(json.dumps({"type": "confirm_human", "participant": self._participant_identifier()})) # Replay enrollments for enrollment in self._get_all_enrollments(): self.experiment_counter.increment_participant_count( enrollment.experiment, enrollment.alternative, self._participant_identifier() ) # Replay goals if "experiments_goals" in self.session: try: for experiment_name, alternative, goal_name, count in self.session["experiments_goals"]: experiment = experiment_manager.get(experiment_name, None) if experiment: self.experiment_counter.increment_goal_count( experiment, alternative, goal_name, self._participant_identifier(), count ) except ValueError: pass # Values from older version finally: del self.session["experiments_goals"]
def confirm_human(self): if self.session.get('experiments_verified_human', False): return self.session['experiments_verified_human'] = True enrollments = self.session.get('experiments_enrollments', None) if not enrollments: return # Replay enrollments for experiment_name, data in enrollments.items(): alternative, goals = data experiment = experiment_manager.get(experiment_name, None) if experiment: experiment.increment_participant_count( alternative, self._participant_identifier()) # Replay goals if 'experiments_goals' in self.session: for goal_name in self.session['experiments_goals']: self.record_goal( goal_name) # Now we have verified human, these will be set del self.session['experiments_goals']