from otree.api import * import random import itertools doc = """ CM experiment. Discrete choice task for T1 (hypothetical DCE) and T2 (incentivized DCE). """ class C(BaseConstants): NAME_IN_URL = 'CM_DCE_1' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 TASKS = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] price_1 = [4, 4.5, 5, 5.5, 6] price_2 = [4, 4.5, 5, 5.5, 6] timeout = 15 # CHANGE ACCORDINGLY #ANOTHER EXAMPLE OF RANDOMIZING THE LIST # price_list_example = [(4, 5), (4.5, 5), (5, 5.5), (5.5, 4)] # Experimental budget budget = 6 budget_T2 = 8 # Exchange rate exchange_pounds = 0.87 class Subsession(BaseSubsession): pass class Group(BaseGroup): pass def make_field(label): return models.IntegerField( choices=[[1, "A"], [2, "B"], [3, "Nessun"]], label=label, widget=widgets.RadioSelect, blank=False, ) class Player(BasePlayer): CE_choice_1 = make_field('Scelta') CE_choice_2 = make_field('Scelta') CE_choice_3 = make_field('Scelta') CE_choice_4 = make_field('Scelta') CE_choice_5 = make_field('Scelta') CE_choice_6 = make_field('Scelta') CE_choice_7 = make_field('Scelta') CE_choice_8 = make_field('Scelta') CE_choice_9 = make_field('Scelta') CE_choice_10 = make_field('Scelta') price_list = models.LongStringField() price_list_aux = models.LongStringField() random_draw = models.IntegerField() risk_1 = models.IntegerField(widget=widgets.RadioSelectHorizontal, choices=[[1, "Decisamente no"], [2, '2'], [3, '3'], [4, '4'], [5, "Decisamente sì"]]) risk_2 = models.IntegerField(widget=widgets.RadioSelectHorizontal, choices=[[1, "Decisamente no"], [2, '2'], [3, '3'], [4, '4'], [5, "Decisamente sì"]]) payoff_bonus = models.FloatField() pounds = models.FloatField() choice = models.IntegerField() level1 = models.FloatField() level2 = models.FloatField() # Functions def creating_session(subsession: Subsession): if subsession.round_number == 1: for p in subsession.get_players(): p.participant.is_dropout = False #Mug price pairs for each player pairs = itertools.product(C.price_1, C.price_2) result = [pair for pair in pairs if pair[0] != pair[1]] # CAN THEY BE EQUAL TO EACH OTHER? price_list = random.sample(result, 10) # in case I randomize price list order also for bottles # price_list_aux = random.sample(price_list, 10) p.participant.price_list = price_list p.participant.price_list_aux = price_list #ANOTHER OPTION OF RANDOMIZING THE LIST # example = random.shuffle(C.price_list_example) # p.participant.price_list_example = example random_draw = random.randint(1, len(C.TASKS)) p.participant.random_draw = random_draw ##################################### PAGES #################################################### class Introduction(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 @staticmethod def before_next_page(player, timeout_happened): participant = player.participant player.price_list = str(participant.price_list) player.random_draw = int(participant.random_draw) class DCE_1(Page): form_model = 'player' form_fields = ['CE_choice_1'] def vars_for_template(player: Player): price_pair = player.participant.price_list[0] level1 = price_pair[0] level2 = price_pair[1] return dict(level1=level1, level2=level2) class DCE_2(Page): form_model = 'player' form_fields = ['CE_choice_2'] def vars_for_template(player: Player): price_pair = player.participant.price_list[1] level1 = price_pair[0] level2 = price_pair[1] return dict(level1=level1, level2=level2) class DCE_3(Page): form_model = 'player' form_fields = ['CE_choice_3'] def vars_for_template(player: Player): price_pair = player.participant.price_list[2] level1 = price_pair[0] level2 = price_pair[1] return dict(level1=level1, level2=level2) class DCE_4(Page): form_model = 'player' form_fields = ['CE_choice_4'] def vars_for_template(player: Player): price_pair = player.participant.price_list[3] level1 = price_pair[0] level2 = price_pair[1] return dict(level1=level1, level2=level2) class DCE_5(Page): form_model = 'player' form_fields = ['CE_choice_5'] def vars_for_template(player: Player): price_pair = player.participant.price_list[4] level1 = price_pair[0] level2 = price_pair[1] return dict(level1=level1, level2=level2) class DCE_6(Page): form_model = 'player' form_fields = ['CE_choice_6'] def vars_for_template(player: Player): price_pair = player.participant.price_list[5] level1 = price_pair[0] level2 = price_pair[1] return dict(level1=level1, level2=level2) class DCE_7(Page): form_model = 'player' form_fields = ['CE_choice_7'] def vars_for_template(player: Player): price_pair = player.participant.price_list[6] level1 = price_pair[0] level2 = price_pair[1] return dict(level1=level1, level2=level2) class DCE_8(Page): form_model = 'player' form_fields = ['CE_choice_8'] def vars_for_template(player: Player): price_pair = player.participant.price_list[7] level1 = price_pair[0] level2 = price_pair[1] return dict(level1=level1, level2=level2) class DCE_9(Page): form_model = 'player' form_fields = ['CE_choice_9'] def vars_for_template(player: Player): price_pair = player.participant.price_list[8] level1 = price_pair[0] level2 = price_pair[1] return dict(level1=level1, level2=level2) class DCE_10(Page): form_model = 'player' form_fields = ['CE_choice_10'] def vars_for_template(player: Player): price_pair = player.participant.price_list[9] level1 = price_pair[0] level2 = price_pair[1] return dict(level1=level1, level2=level2) def before_next_page(player: Player, timeout_happened): participant = player.participant if player.participant.random_draw == 1: mug_payoff = player.CE_choice_1 else: if player.participant.random_draw == 2: mug_payoff = player.CE_choice_2 else: if player.participant.random_draw == 3: mug_payoff = player.CE_choice_3 else: if player.participant.random_draw == 4: mug_payoff = player.CE_choice_4 else: if player.participant.random_draw == 5: mug_payoff = player.CE_choice_5 else: if player.participant.random_draw == 6: mug_payoff = player.CE_choice_6 else: if player.participant.random_draw == 7: mug_payoff = player.CE_choice_7 else: if player.participant.random_draw == 8: mug_payoff = player.CE_choice_8 else: if player.participant.random_draw == 9: mug_payoff = player.CE_choice_9 else: mug_payoff = player.CE_choice_10 participant.mug_payoff = mug_payoff participant.CE_choice_1 = player.CE_choice_1 participant.CE_choice_2 = player.CE_choice_2 participant.CE_choice_3 = player.CE_choice_3 participant.CE_choice_4 = player.CE_choice_4 participant.CE_choice_5 = player.CE_choice_5 participant.CE_choice_6 = player.CE_choice_6 participant.CE_choice_7 = player.CE_choice_7 participant.CE_choice_8 = player.CE_choice_8 participant.CE_choice_9 = player.CE_choice_9 participant.CE_choice_10 = player.CE_choice_10 class Pre_CM(Page): def is_displayed(player: Player): return player.participant.treatment_p > 2 @staticmethod def app_after_this_page(player: Player, upcoming_apps): # print('upcoming app is', upcoming_apps) if player.participant.treatment_p > 2: return upcoming_apps[-1] # skip to the last app class Questionnaire(Page): def is_displayed(player: Player): return player.participant.treatment_p == 1 or player.participant.treatment_p == 2 form_model = 'player' form_fields = ['risk_1', 'risk_2'] class Outcome(Page): def is_displayed(player: Player): return player.participant.treatment_p == 2 def vars_for_template(player: Player): # participant = player.participant if player.participant.random_draw == 1: price_pair = player.participant.price_list[0] level1 = price_pair[0] level2 = price_pair[1] choice = player.participant.CE_choice_1 else: if player.participant.random_draw == 2: price_pair = player.participant.price_list[1] level1 = price_pair[0] level2 = price_pair[1] choice = player.participant.CE_choice_2 else: if player.participant.random_draw == 3: price_pair = player.participant.price_list[2] level1 = price_pair[0] level2 = price_pair[1] choice = player.participant.CE_choice_3 else: if player.participant.random_draw == 4: price_pair = player.participant.price_list[3] level1 = price_pair[0] level2 = price_pair[1] choice = player.participant.CE_choice_4 else: if player.participant.random_draw == 5: price_pair = player.participant.price_list[4] level1 = price_pair[0] level2 = price_pair[1] choice = player.participant.CE_choice_5 else: if player.participant.random_draw == 6: price_pair = player.participant.price_list[5] level1 = price_pair[0] level2 = price_pair[1] choice = player.participant.CE_choice_6 else: if player.participant.random_draw == 7: price_pair = player.participant.price_list[6] level1 = price_pair[0] level2 = price_pair[1] choice = player.participant.CE_choice_7 else: if player.participant.random_draw == 8: price_pair = player.participant.price_list[7] level1 = price_pair[0] level2 = price_pair[1] choice = player.participant.CE_choice_8 else: if player.participant.random_draw == 9: price_pair = player.participant.price_list[8] level1 = price_pair[0] level2 = price_pair[1] choice = player.participant.CE_choice_9 else: price_pair = player.participant.price_list[9] level1 = price_pair[0] level2 = price_pair[1] choice = player.participant.CE_choice_10 player.choice = choice player.level1 = level1 player.level2 = level2 return dict(level1=level1, level2=level2, random=player.participant.random_draw, choice=choice) @staticmethod def before_next_page(player, timeout_happened): if player.choice == 1: player.payoff_bonus = C.budget_T2 - player.level1 else: if player.choice == 2: player.payoff_bonus = C.budget_T2 - player.level2 else: player.payoff_bonus = C.budget_T2 player.pounds = round(player.payoff_bonus * C.exchange_pounds, 1) class Final_1(Page): def is_displayed(player: Player): return player.participant.treatment_p == 1 class Final_2(Page): def is_displayed(player: Player): return player.participant.treatment_p == 2 def vars_for_template(player: Player): return dict(payoff=player.payoff_bonus, bonus_pounds=player.pounds, choice=player.choice, level1=player.level1, level2=player.level2, nome=player.participant.nome, via=player.participant.via, cap=player.participant.cap, localita=player.participant.localita, provincia=player.participant.provincia) page_sequence = [ Introduction, DCE_1, DCE_2, DCE_3, DCE_4, DCE_5, DCE_6, DCE_7, DCE_8, DCE_9, DCE_10, Pre_CM, Questionnaire, Outcome, Final_1, Final_2 ]