from otree.api import * import random from utils.live_utils import live_page, live_method from time import time doc = """ Intro for Bandit Game, include control question. Steps before lobby. """ def track(page_name): def _track(cls): orig_get = cls.get orig_post = cls.post def _tracking_get(page): now = int(time()) page.participant.vars[f'_tracking_get_timestamp_{page_name}'] = now if f'_tracking_first_timestamp_{page_name}' not in page.participant.vars: page.participant.vars[f'_tracking_first_timestamp_{page_name}'] = now if f'_tracking_post_timestamp_{page_name}' in page.participant.vars: del page.participant.vars[f'_tracking_post_timestamp_{page_name}'] return orig_get(page) def _tracking_post(page): page.participant.vars[f'_tracking_post_timestamp_{page_name}'] = int(time()) return orig_post(page) cls.get = _tracking_get cls.post = _tracking_post return cls return _track def last(participant, page_name): return participant.vars[f'_tracking_post_timestamp_{page_name}'] - participant.vars[f'_tracking_get_timestamp_{page_name}'] class C(BaseConstants): NAME_IN_URL = 'intro' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): dynamic_label = models.StringField() terminated = models.BooleanField(initial=False) control_question_1 = models.IntegerField( choices=[ [10, '10'], [2, '2'], [6, '6'] ], widget=widgets.RadioSelect, label="Player A will gain" ) control_question_2 = models.IntegerField( choices=[ [0, '0'], [6, '6'], [2, '2'] ], widget=widgets.RadioSelect, label="Player B will gain" ) control_question_1_initial = models.BooleanField(initial=True) control_question_2_initial = models.BooleanField(initial=True) control_question_1_correct = models.BooleanField(initial=False) control_question_2_correct = models.BooleanField(initial=False) # Time tracking fields time_intro = models.FloatField() time_control_q = models.FloatField() time_total = models.FloatField() #### INIT #### def creating_session(self): for player in self.get_players(): player.time_total = 0 # PAGES @track("Intro") class Intro(Page): pass def before_next_page(player: Player, timeout_happened): player.time_intro = last(player.participant, "Intro") player.time_total += last(player.participant, "Intro") @track("ControlQ") class ControlQ(Page): page_name = "ControlQ" form_model = 'player' form_fields = ['control_question_1', 'control_question_2'] def error_message(player, values): errors = {} if values["control_question_1"] != 2: errors["control_question_1"] = 'Player A would receive a total payoff of 2 points (100% of 2 points).' player.control_question_1_initial = False if values["control_question_2"] != 0: errors["control_question_2"] = 'Player B would receive a total payoff of 0 points (2 – 2 = 0 points).' player.control_question_2_initial = False return errors def before_next_page(player: Player, timeout_happened): player.control_question_1_correct = player.control_question_1 == 2 player.control_question_2_correct = player.control_question_2 == 0 player.time_control_q = last(player.participant, "ControlQ") player.time_total += last(player.participant, "ControlQ") page_sequence = [ Intro, ControlQ ]