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 TASKS = [1, 2, 3, 4, 5, 6, 7, 8, 9] timeout = 15 # CHANGE ACCORDINGLY surveys = ['10', '11', '12'] DC_tasks = ['1', '2', '3', '4', '5', '6', '7', '8', '9'] NUM_ROUNDS = len(DC_tasks) + len(surveys) #Randomizing discrete choice task #Order of tuples: (good 1, its price, good 2, its price) #Code for goods: 1 = black public, 2 = black private, 3 = green public, 4 = green private, 5 - black, 6 - green # Winning option - 4 (green + stress free zone (4), black (5)) DC_scenarios = [(2, 5.5, 5, 4.5), (1, 6, 4, 4), (5, 4.5, 3, 5.5), (4, 5, 5, 4.5), (3, 4, 2, 6), (6, 4.5, 1, 5), (1, 4, 6, 5.5), (2, 5, 3, 5), (6, 5.5, 2, 4)] # Experimental budget budget = 6 budget_T2 = 6 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') DC_list = models.LongStringField() DC_list_aux = models.LongStringField() 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ì"]]) dospert_1 = models.IntegerField(widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7], label='Scommettere la paga di un giorno alle corse dei cavalli') dospert_2 = models.IntegerField(widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7], label='Investire il 10% del proprio reddito annuo in un fondo d’investimento diversificato a crescita moderata') dospert_3 = models.IntegerField(widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7], label='Scommettere la paga di un giorno, giocando a carte o al videopoker') dospert_4 = models.IntegerField(widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7], label='Investire il 5% del proprio reddito annuo in azioni molto speculative') dospert_5 = models.IntegerField(widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7], label='Scommettere la paga di un giorno sull’esito di un evento sportivo') dospert_6 = models.IntegerField(widget=widgets.RadioSelectHorizontal, choices=[1, 2, 3, 4, 5, 6, 7], label='Investire il 10% del proprio reddito annuo in una nuova impresa') payoff_bonus = models.FloatField() pounds = models.FloatField() choice = models.IntegerField() level1 = models.FloatField() level2 = models.FloatField() product_1 = models.IntegerField() product_2 = models.IntegerField() age = models.IntegerField(label="La tua età") gender = models.IntegerField(label="Sesso ufficiale (alla nascita)", widget=widgets.RadioSelect, choices=[[0, 'F'], [1, 'M']]) occupation = models.IntegerField(widget=widgets.RadioSelect, choices=[[1, 'Studente'], [2, 'Lavoratore'], [3, 'Studente e lavoratore (allo stesso tempo)'], [4, 'Disoccupato']], label='Qual’è la tua occupazione?') income = models.BooleanField(widget=widgets.RadioSelect, choices=[[0, "Si"], [1, 'No']], label='Hai un tuo reddito personale (non quello della tua famiglia)?') income2 = models.IntegerField(label='Qual’è il tuo reddito lordo personale nel 2022 (non quello della tua famiglia)?', choices=[ [1, 'Meno di 11 461 Eur'], [2, '11 461 Eur - 22 919 Eur'], [3, '22 920 Eur - 34 377 Eur'], [4, '34 378 Eur - 45 838 Eur'], [5, '45 839 Eur - 57 297 Eur'], [6, '57 298 Eur- 68 748 Eur'], [7, '68 747 Eur- 80 204 Eur'], [8, '80 205 Eur - 91 687 Eur'], [9, '91 688 Eur - 103 132 Eur'], [10, '103 133 Eur - 114 587 Eur'], [11, '114 588 Eur- 171 898 Eur'], [12, 'Più di 171 899 Eur'], [13, 'Preferisco non dirlo'] ], widget=widgets.RadioSelect) crt1 = models.StringField(label="Se stai correndo una gara e sorpassi la persona al secondo posto, " "in che posizione ti trovi? Scrivi il posto come numero.") crt2 = models.StringField(label="Un contadino aveva 15 pecore e tutte, tranne 8, sono morte. " "Quante ne sono rimaste?") crt3 = models.StringField(label="Una mazza e una palla costano complessivamente 1,10 euro. " "La mazza costa 1,00 euro in più della palla. Quanto costa la palla?") # Functions def creating_session(subsession: Subsession): if subsession.round_number == 1: for p in subsession.get_players(): p.participant.exchange_pounds = subsession.session.config['exchange_pounds'] p.participant.completion_code = subsession.session.config['completion_code'] p.participant.is_dropout = False # RESTORE THIS IF DRAW IS RANDOM # random_draw = random.randint(1, len(C.TASKS)) random_draw = 4 p.participant.random_draw = random_draw rounds_1 = list(range(1, len(C.DC_tasks) + 1)) rounds_2 = list(range((len(C.TASKS) + 1), C.NUM_ROUNDS + 1)) random.shuffle(rounds_1) random.shuffle(rounds_2) rounds_total = rounds_1 + rounds_2 rounds_order = C.DC_tasks + C.surveys p.participant.page_order = dict(zip(rounds_order, rounds_total)) p.participant.num_rounds = C.NUM_ROUNDS ##################################### 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.scenario_list) player.random_draw = int(participant.random_draw) class DCE_1(Page): @staticmethod def is_displayed(player: Player): return player.round_number == player.participant.page_order['1'] form_model = 'player' form_fields = ['CE_choice_1'] def vars_for_template(player: Player): tuple_list = C.DC_scenarios scenario = tuple_list[0] product_1 = scenario[0] level1 = scenario[1] product_2 = scenario[2] level2 = scenario[3] return dict(level1=level1, level2=level2, product_1=product_1, product_2=product_2) def before_next_page(player: Player, timeout_happened): player.participant.CE_choice_1 = player.CE_choice_1 player.participant.page_no_1 = player.round_number class DCE_2(Page): @staticmethod def is_displayed(player: Player): return player.round_number == player.participant.page_order['2'] form_model = 'player' form_fields = ['CE_choice_2'] def vars_for_template(player: Player): tuple_list = C.DC_scenarios scenario = tuple_list[1] product_1 = scenario[0] level1 = scenario[1] product_2 = scenario[2] level2 = scenario[3] return dict(level1=level1, level2=level2, product_1=product_1, product_2=product_2) def before_next_page(player: Player, timeout_happened): player.participant.CE_choice_2 = player.CE_choice_2 player.participant.page_no_2 = player.round_number class DCE_3(Page): @staticmethod def is_displayed(player: Player): return player.round_number == player.participant.page_order['3'] form_model = 'player' form_fields = ['CE_choice_3'] def vars_for_template(player: Player): tuple_list = C.DC_scenarios scenario = tuple_list[2] product_1 = scenario[0] level1 = scenario[1] product_2 = scenario[2] level2 = scenario[3] return dict(level1=level1, level2=level2, product_1=product_1, product_2=product_2) def before_next_page(player: Player, timeout_happened): player.participant.CE_choice_3 = player.CE_choice_3 player.participant.page_no_3 = player.round_number class DCE_4(Page): @staticmethod def is_displayed(player: Player): return player.round_number == player.participant.page_order['4'] form_model = 'player' form_fields = ['CE_choice_4'] def vars_for_template(player: Player): tuple_list = C.DC_scenarios scenario = tuple_list[3] product_1 = scenario[0] level1 = scenario[1] product_2 = scenario[2] level2 = scenario[3] return dict(level1=level1, level2=level2, product_1=product_1, product_2=product_2) def before_next_page(player: Player, timeout_happened): player.participant.CE_choice_4 = player.CE_choice_4 player.participant.page_no_4 = player.round_number class DCE_5(Page): @staticmethod def is_displayed(player: Player): return player.round_number == player.participant.page_order['5'] form_model = 'player' form_fields = ['CE_choice_5'] def vars_for_template(player: Player): tuple_list = C.DC_scenarios scenario = tuple_list[4] product_1 = scenario[0] level1 = scenario[1] product_2 = scenario[2] level2 = scenario[3] return dict(level1=level1, level2=level2, product_1=product_1, product_2=product_2) def before_next_page(player: Player, timeout_happened): player.participant.CE_choice_5 = player.CE_choice_5 player.participant.page_no_5 = player.round_number class DCE_6(Page): @staticmethod def is_displayed(player: Player): return player.round_number == player.participant.page_order['6'] form_model = 'player' form_fields = ['CE_choice_6'] def vars_for_template(player: Player): tuple_list = C.DC_scenarios scenario = tuple_list[5] product_1 = scenario[0] level1 = scenario[1] product_2 = scenario[2] level2 = scenario[3] return dict(level1=level1, level2=level2, product_1=product_1, product_2=product_2) def before_next_page(player: Player, timeout_happened): player.participant.CE_choice_6 = player.CE_choice_6 player.participant.page_no_6 = player.round_number class DCE_7(Page): @staticmethod def is_displayed(player: Player): return player.round_number == player.participant.page_order['7'] form_model = 'player' form_fields = ['CE_choice_7'] def vars_for_template(player: Player): tuple_list = C.DC_scenarios scenario = tuple_list[6] product_1 = scenario[0] level1 = scenario[1] product_2 = scenario[2] level2 = scenario[3] return dict(level1=level1, level2=level2, product_1=product_1, product_2=product_2) def before_next_page(player: Player, timeout_happened): player.participant.CE_choice_7 = player.CE_choice_7 player.participant.page_no_7 = player.round_number class DCE_8(Page): @staticmethod def is_displayed(player: Player): return player.round_number == player.participant.page_order['8'] form_model = 'player' form_fields = ['CE_choice_8'] def vars_for_template(player: Player): tuple_list = C.DC_scenarios scenario = tuple_list[7] product_1 = scenario[0] level1 = scenario[1] product_2 = scenario[2] level2 = scenario[3] return dict(level1=level1, level2=level2, product_1=product_1, product_2=product_2) def before_next_page(player: Player, timeout_happened): player.participant.CE_choice_8 = player.CE_choice_8 player.participant.page_no_8 = player.round_number class DCE_9(Page): @staticmethod def is_displayed(player: Player): return player.round_number == player.participant.page_order['9'] form_model = 'player' form_fields = ['CE_choice_9'] def vars_for_template(player: Player): tuple_list = C.DC_scenarios scenario = tuple_list[8] product_1 = scenario[0] level1 = scenario[1] product_2 = scenario[2] level2 = scenario[3] return dict(level1=level1, level2=level2, product_1=product_1, product_2=product_2) def before_next_page(player: Player, timeout_happened): player.participant.CE_choice_9 = player.CE_choice_9 player.participant.page_no_9 = player.round_number class DCE_10(Page): @staticmethod def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS form_model = 'player' form_fields = ['CE_choice_10'] def vars_for_template(player: Player): tuple_list = C.DC_scenarios scenario = tuple_list[5] # Random choice product_1 = 5 level1 = 4.5 product_2 = 6 level2 = 5 return dict(level1=level1, level2=level2, product_1=product_1, product_2=product_2) def before_next_page(player: Player, timeout_happened): player.participant.CE_choice_10 = player.CE_choice_10 player.participant.page_no_10 = player.round_number class Questionnaire_1(Page): # RESTORE TO THIS def is_displayed(player: Player): return player.round_number == player.participant.page_order['10'] # def is_displayed(player: Player): # return player.round_number == C.NUM_ROUNDS form_model = 'player' form_fields = ['risk_1'] class Questionnaire_2(Page): # RESTORE TO THIS def is_displayed(player: Player): return player.round_number == player.participant.page_order['11'] # def is_displayed(player: Player): # return player.round_number == C.NUM_ROUNDS form_model = 'player' @staticmethod def get_form_fields(player: Player): form_fields = ['dospert_1', 'dospert_2', 'dospert_3', 'dospert_4', 'dospert_5', 'dospert_6'] random.shuffle(form_fields) return form_fields class Questionnaire_3(Page): # RESTORE TO THIS def is_displayed(player: Player): return player.round_number == player.participant.page_order['12'] # @staticmethod # def is_displayed(player: Player): # return player.round_number == C.NUM_ROUNDS form_model = 'player' @staticmethod def get_form_fields(player: Player): form_fields = ['crt1', 'crt2', 'crt3'] random.shuffle(form_fields) return form_fields class Demographics(Page): def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS form_model = 'player' form_fields = ['age', 'gender', 'occupation', 'income2'] class Outcome(Page): def is_displayed(player: Player): return player.participant.treatment_p == 2 and player.round_number == C.NUM_ROUNDS def vars_for_template(player: Player): # participant = player.participant # print("winning choice is", player.participant.random_draw) winning_choice_number = [player.participant.page_no_1, player.participant.page_no_2, player.participant.page_no_3, player.participant.page_no_4, player.participant.page_no_5, player.participant.page_no_6, player.participant.page_no_7, player.participant.page_no_8, player.participant.page_no_9] # print("choice is", winning_choice_number) # print("scenarios are", C.DC_scenarios) if player.participant.random_draw == 1: winning_choice_screen = winning_choice_number[0] tuple_list = C.DC_scenarios scenario = tuple_list[0] product_1 = scenario[0] level1 = scenario[1] product_2 = scenario[2] level2 = scenario[3] choice = player.participant.CE_choice_1 else: if player.participant.random_draw == 2: winning_choice_screen = winning_choice_number[1] tuple_list = C.DC_scenarios scenario = tuple_list[1] product_1 = scenario[0] level1 = scenario[1] product_2 = scenario[2] level2 = scenario[3] choice = player.participant.CE_choice_2 else: if player.participant.random_draw == 3: winning_choice_screen = winning_choice_number[2] tuple_list = C.DC_scenarios scenario = tuple_list[3] product_1 = scenario[0] level1 = scenario[1] product_2 = scenario[2] level2 = scenario[3] choice = player.participant.CE_choice_3 else: if player.participant.random_draw == 4: winning_choice_screen = winning_choice_number[3] tuple_list = C.DC_scenarios scenario = tuple_list[3] product_1 = scenario[0] level1 = scenario[1] product_2 = scenario[2] level2 = scenario[3] choice = player.participant.CE_choice_4 else: if player.participant.random_draw == 5: winning_choice_screen = winning_choice_number[4] tuple_list = C.DC_scenarios scenario = tuple_list[4] product_1 = scenario[0] level1 = scenario[1] product_2 = scenario[2] level2 = scenario[3] choice = player.participant.CE_choice_5 else: if player.participant.random_draw == 6: winning_choice_screen = winning_choice_number[5] tuple_list = C.DC_scenarios scenario = tuple_list[5] product_1 = scenario[0] level1 = scenario[1] product_2 = scenario[2] level2 = scenario[3] choice = player.participant.CE_choice_6 else: if player.participant.random_draw == 7: winning_choice_screen = winning_choice_number[6] tuple_list = C.DC_scenarios scenario = tuple_list[6] product_1 = scenario[0] level1 = scenario[1] product_2 = scenario[2] level2 = scenario[3] choice = player.participant.CE_choice_7 else: if player.participant.random_draw == 8: winning_choice_screen = winning_choice_number[7] tuple_list = C.DC_scenarios scenario = tuple_list[7] product_1 = scenario[0] level1 = scenario[1] product_2 = scenario[2] level2 = scenario[3] choice = player.participant.CE_choice_8 else: winning_choice_screen = winning_choice_number[8] tuple_list = C.DC_scenarios scenario = tuple_list[8] product_1 = scenario[0] level1 = scenario[1] product_2 = scenario[2] level2 = scenario[3] choice = player.participant.CE_choice_9 player.choice = choice player.level1 = level1 player.level2 = level2 player.product_1 = product_1 player.product_2 = product_2 return dict(level1=level1, level2=level2, random=winning_choice_screen, choice=choice, product_1=product_1, product_2=product_2) @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 * player.participant.exchange_pounds, 2) class Final_1(Page): def is_displayed(player: Player): return player.participant.treatment_p == 1 and player.round_number == C.NUM_ROUNDS class Final_2(Page): def is_displayed(player: Player): return player.participant.treatment_p == 2 and player.round_number == C.NUM_ROUNDS 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, Questionnaire_1, Questionnaire_2, Questionnaire_3, # Demographics, Outcome, Final_1, Final_2 ]