from otree.api import * doc = """ Choice matching experiment, September 2022 """ class C(BaseConstants): NAME_IN_URL = 'CM_instr' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 level1 = 4 level2 = 4.5 level3 = 5 level4 = 5.5 level5 = 6 # Examples total_players = 10 # make sure it corresponds to the actual group size example = total_players - 1 choices = 10 # NUMERICAL EXAMPLES input1 = 3 # Example 1 table 4 (main example) input2 = 4 # Example table 4 (main example) input3 = 2 # Example table 4 (main example) input1_similar = 4 # Example 1 table 4 (main example) input2_similar = 3 # Example table 4 (main example) input3_similar = 2 # Example table 4 (main example) input1_diff = 1 # Example 1 table 4 (main example) input2_diff = 1 # Example table 4 (main example) input3_diff = 7 # Example table 4 (main example) input1_2 = 1 # Example table 4 (extra example) input2_2 = total_players - 2 # Example table 4 (extra example) input3_2 = 0 # Example table 4 (extra example) quadratic_score_A = 2 quadratic_score_B = 2 # Bonus table 4 main example bonus1 = round(quadratic_score_A+quadratic_score_B*(2*(input1/example) - ((input1/example)*(input1/example)+(input2/example)*(input2/example)+(input3/example)*(input3/example))), 2) bonus2 = round(quadratic_score_A+quadratic_score_B*(2*(input2/example) - ((input1/example)*(input1/example)+(input2/example)*(input2/example)+(input3/example)*(input3/example))), 2) bonus3 = round(quadratic_score_A+quadratic_score_B*(2*(input3/example) - ((input1/example)*(input1/example)+(input2/example)*(input2/example)+(input3/example)*(input3/example))), 2) bonus1_similar = round(quadratic_score_A+quadratic_score_B*(2*(input1_similar/example) - ((input1_similar/example)*(input1_similar/example)+(input2_similar/example)*(input2_similar/example)+(input3_similar/example)*(input3_similar/example))), 2) bonus2_similar = round(quadratic_score_A+quadratic_score_B*(2*(input2_similar/example) - ((input1_similar/example)*(input1_similar/example)+(input2_similar/example)*(input2_similar/example)+(input3_similar/example)*(input3_similar/example))), 2) bonus3_similar = round(quadratic_score_A+quadratic_score_B*(2*(input3_similar/example) - ((input1_similar/example)*(input1_similar/example)+(input2_similar/example)*(input2_similar/example)+(input3_similar/example)*(input3_similar/example))), 2) bonus1_diff = round(quadratic_score_A+quadratic_score_B*(2*(input1_diff/example) - ((input1_diff/example)*(input1_diff/example)+(input2_diff/example)*(input2_diff/example)+(input3_diff/example)*(input3_diff/example))), 2) bonus2_diff = round(quadratic_score_A+quadratic_score_B*(2*(input2_diff/example) - ((input1_diff/example)*(input1_diff/example)+(input2_diff/example)*(input2_diff/example)+(input3_diff/example)*(input3_diff/example))), 2) bonus3_diff = round(quadratic_score_A+quadratic_score_B*(2*(input3_diff/example) - ((input1_diff/example)*(input1_diff/example)+(input2_diff/example)*(input2_diff/example)+(input3_diff/example)*(input3_diff/example))), 2) # Bonus table 4 main example when making wrong decisions bonus1_2 = round(quadratic_score_A+quadratic_score_B*(2*(input1_2/example) - ((input1/example)*(input1/example)+(input2/example)*(input2/example)+(input3/example)*(input3/example))), 2) bonus2_2 = round(quadratic_score_A+quadratic_score_B*(2*(input2_2/example) - ((input1/example)*(input1/example)+(input2/example)*(input2/example)+(input3/example)*(input3/example))), 2) bonus3_2 = round(quadratic_score_A+quadratic_score_B*(2*(input3_2/example) - ((input1/example)*(input1/example)+(input2/example)*(input2/example)+(input3/example)*(input3/example))), 2) # Frequency method bonus freq_bonus = 4 # Price levels level1_cost = 4 level2_cost = 4.5 level3_cost = 5 level4_cost = 5.5 level5_cost = 6 # Probabilities prob_l = 60 prob_m = 75 prob_h = 90 budget = 6 budget_T2 = 8 resto1 = budget - level1 resto1_T2 = budget_T2 - level1 resto2 = budget - level2 resto2_T2 = budget_T2 - level2 class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): treatment_p = models.IntegerField() # group_size = models.IntegerField() nome = models.StringField(label="Nome e cognome") via = models.StringField(label="Indirizzo") cap = models.IntegerField(label="CAP") localita = models.StringField(label="Città") provincia = models.StringField(label="Provincia") # Choices in each choice situation CE_choice_practice = models.IntegerField( choices=[[1, "A"], [2, "B"], [3, "Nessun"]], label="Practice Choice situation", widget=widgets.RadioSelect, blank=False, ) CM_instr_A_1 = models.IntegerField() CM_instr_B_1 = models.IntegerField() CM_instr_C_1 = models.IntegerField() payoff_instr_1_A = models.CurrencyField() payoff_instr_1_B = models.CurrencyField() payoff_instr_1_C = models.CurrencyField() CM_instr_A_2 = models.IntegerField() CM_instr_B_2 = models.IntegerField() CM_instr_C_2 = models.IntegerField() payoff_instr_2_A = models.CurrencyField() payoff_instr_2_B = models.CurrencyField() payoff_instr_2_C = models.CurrencyField() ################################# PAGES ######################################################## class Study_structure(Page): @staticmethod def before_next_page(player: Player, timeout_happened): player.treatment_p = player.participant.treatment_p @staticmethod def vars_for_template(player: Player): if player.participant.treatment_p == 2: progress = 33 else: if player.participant.treatment_p == 3 or player.participant.treatment_p == 4 or player.participant.treatment_p == 5: progress = 7 else: if player.participant.treatment_p == 6 or player.participant.treatment_p == 7 or player.participant.treatment_p == 8: progress = 9 else: progress = 10 return dict(progress=progress) class Part_1(Page): @staticmethod def app_after_this_page(player: Player, upcoming_apps): # print('upcoming app is', upcoming_apps) if player.participant.treatment_p == 1: return upcoming_apps[-4] # skip to the hypothetical DCE @staticmethod def vars_for_template(player: Player): if player.participant.treatment_p == 2: progress = 66 else: if player.participant.treatment_p == 3 or player.participant.treatment_p == 4 or player.participant.treatment_p == 5: progress = 14 else: if player.participant.treatment_p == 6 or player.participant.treatment_p == 7 or player.participant.treatment_p == 8: progress = 18 else: progress = 20 return dict(progress=progress) class Part_2_1a(Page): def is_displayed(player: Player): return player.participant.treatment_p == 3 or player.participant.treatment_p == 4 or \ player.participant.treatment_p == 5 or player.participant.treatment_p == 6 or \ player.participant.treatment_p == 7 or player.participant.treatment_p == 8 @staticmethod def vars_for_template(player: Player): if player.participant.treatment_p == 3 or player.participant.treatment_p == 4 or player.participant.treatment_p == 5: progress = 21 else: if player.participant.treatment_p == 6 or player.participant.treatment_p == 7 or player.participant.treatment_p == 8: progress = 27 else: progress = 30 return dict(progress=progress) class Part_2_1b(Page): def is_displayed(player: Player): return player.participant.treatment_p == 3 or player.participant.treatment_p == 4 or \ player.participant.treatment_p == 5 form_model = 'player' form_fields = ['CM_instr_A_1', 'CM_instr_B_1', 'CM_instr_C_1'] @staticmethod def live_method(player: Player, data): if data['clicked_button'] == 1: a = float(data['fieldA']) / C.example b = float(data['fieldB']) / C.example c = float(data['fieldC']) / C.example factor1 = a * a + b * b + c * c payoff_a = round(C.quadratic_score_A + C.quadratic_score_B * (2 * a - factor1), 2) payoff_b = round(C.quadratic_score_A + C.quadratic_score_B * (2 * b - factor1), 2) payoff_c = round(C.quadratic_score_A + C.quadratic_score_B * (2 * c - factor1), 2) response = dict(payoff_a=payoff_a, payoff_b=payoff_b, payoff_c=payoff_c, ) player.payoff_instr_1_A = payoff_a player.payoff_instr_1_B = payoff_b player.payoff_instr_1_C = payoff_c return {player.id_in_group: response} # Passing data from Python to JavaScript (js_vars) @staticmethod def js_vars(player): return dict(number_players=C.total_players, tempA=0, tempB=0, tempC=0) @staticmethod def error_message(player, values): if values['CM_instr_A_1'] + values['CM_instr_B_1'] + values['CM_instr_C_1'] != C.example: return 'La somma delle predizioni deve essere uguale a ' + str(C.example) @staticmethod def vars_for_template(player): cost_2 = str(C.level2) cost_1 = str(C.level1) if player.participant.treatment_p > 2 or player.participant.treatment_p < 6: progress = 28 return dict(costs1=cost_1, costs2=cost_2, group_size=C.example, progress=progress) class Part_2_1c(Page): def is_displayed(player: Player): return player.participant.treatment_p == 3 or player.participant.treatment_p == 4 or \ player.participant.treatment_p == 5 form_model = 'player' form_fields = ['CM_instr_A_2', 'CM_instr_B_2', 'CM_instr_C_2'] @staticmethod def live_method(player: Player, data): if data['clicked_button'] == 1: a = float(data['fieldA']) / C.example b = float(data['fieldB']) / C.example c = float(data['fieldC']) / C.example factor1 = a * a + b * b + c * c payoff_a = round(C.quadratic_score_A + C.quadratic_score_B * (2 * a - factor1), 2) payoff_b = round(C.quadratic_score_A + C.quadratic_score_B * (2 * b - factor1), 2) payoff_c = round(C.quadratic_score_A + C.quadratic_score_B * (2 * c - factor1), 2) response = dict(payoff_a=payoff_a, payoff_b=payoff_b, payoff_c=payoff_c, ) player.payoff_instr_2_A = payoff_a player.payoff_instr_2_B = payoff_b player.payoff_instr_2_C = payoff_c return {player.id_in_group: response} # Passing data from Python to JavaScript (js_vars) @staticmethod def js_vars(player): return dict(number_players=C.total_players, tempA=0, tempB=0, tempC=0) @staticmethod def error_message(player, values): if values['CM_instr_A_2'] + values['CM_instr_B_2'] + values['CM_instr_C_2'] != C.example: return 'La somma delle predizioni deve essere uguale a ' + str(C.example) @staticmethod def vars_for_template(player): cost_2 = str(C.level2) cost_1 = str(C.level1) if player.participant.treatment_p > 2 or player.participant.treatment_p < 6: progress = 35 else: progress = 10 return dict(costs1=cost_1, costs2=cost_2, group_size=C.example, progress=progress) class Part_2_1d(Page): def is_displayed(player: Player): return player.participant.treatment_p == 3 or player.participant.treatment_p == 4 or \ player.participant.treatment_p == 5 or player.participant.treatment_p == 6 or \ player.participant.treatment_p == 7 or player.participant.treatment_p == 8 @staticmethod def vars_for_template(player: Player): if player.participant.treatment_p == 3 or player.participant.treatment_p == 4 or player.participant.treatment_p == 5: progress = 42 else: if player.participant.treatment_p == 6 or player.participant.treatment_p == 7 or player.participant.treatment_p == 8: progress = 45 else: progress = 10 return dict(progress=progress) class Part_2_2(Page): def is_displayed(player: Player): return player.participant.treatment_p == 6 or player.participant.treatment_p == 7 or player.participant.treatment_p == 8 def vars_for_template(player: Player): return dict(group_size=C.example, progress=36) class Part_2_3a(Page): def is_displayed(player: Player): return player.participant.treatment_p == 9 @staticmethod def vars_for_template(player: Player): return dict(progress=30) class Part_2_3b(Page): def is_displayed(player: Player): return player.participant.treatment_p == 9 @staticmethod def vars_for_template(player: Player): return dict(progress=40) class Payment_1_1(Page): def is_displayed(player: Player): return player.participant.treatment_p == 2 @staticmethod def vars_for_template(player: Player): if player.participant.treatment_p == 2: progress = 99 else: progress = 10 return dict(progress=progress) class Payment_1_2a(Page): def is_displayed(player: Player): return player.participant.treatment_p == 3 or player.participant.treatment_p == 4 \ or player.participant.treatment_p == 5 or player.participant.treatment_p == 6 \ or player.participant.treatment_p == 7 or player.participant.treatment_p == 8 @staticmethod def vars_for_template(player: Player): if player.participant.treatment_p == 3 or player.participant.treatment_p == 4 or player.participant.treatment_p == 5: progress = 49 else: if player.participant.treatment_p == 6 or player.participant.treatment_p == 7 or player.participant.treatment_p == 8: progress = 54 else: progress = 10 return dict(progress=progress) class Payment_1_2b(Page): def is_displayed(player: Player): return player.participant.treatment_p == 3 or player.participant.treatment_p == 4 \ or player.participant.treatment_p == 5 or player.participant.treatment_p == 6 \ or player.participant.treatment_p == 7 or player.participant.treatment_p == 8 @staticmethod def vars_for_template(player: Player): if player.participant.treatment_p == 3 or player.participant.treatment_p == 4 or player.participant.treatment_p == 5: progress = 56 else: if player.participant.treatment_p == 6 or player.participant.treatment_p == 7 or player.participant.treatment_p == 8: progress = 63 else: progress = 10 return dict(progress=progress) class Payment_1_3a(Page): def is_displayed(player: Player): return player.participant.treatment_p == 9 @staticmethod def vars_for_template(player: Player): return dict(progress=50) class Payment_1_3b(Page): def is_displayed(player: Player): return player.participant.treatment_p == 9 @staticmethod def vars_for_template(player: Player): return dict(progress=60) class Payment_2_1a(Page): def is_displayed(player: Player): return player.participant.treatment_p == 3 or player.participant.treatment_p == 4 or \ player.participant.treatment_p == 5 @staticmethod def vars_for_template(player: Player): if player.participant.treatment_p > 2 and player.participant.treatment_p < 6: progress = 63 return dict(progress=progress) class Payment_2_1b(Page): def is_displayed(player: Player): return player.participant.treatment_p == 3 or player.participant.treatment_p == 4 or \ player.participant.treatment_p == 5 @staticmethod def vars_for_template(player: Player): if player.participant.treatment_p > 2 and player.participant.treatment_p < 6: progress = 70 return dict(progress=progress) class Payment_2_2(Page): def is_displayed(player: Player): return player.participant.treatment_p == 9 # FOR TREATMENTS T3-T8 class Payment_3_1a_a(Page): #Fase 3 (Page 1) def is_displayed(player: Player): return player.participant.treatment_p == 3 or player.participant.treatment_p == 4 \ or player.participant.treatment_p == 5 or player.participant.treatment_p == 6 \ or player.participant.treatment_p == 7 or player.participant.treatment_p == 8 @staticmethod def vars_for_template(player: Player): if player.participant.treatment_p == 3 or player.participant.treatment_p == 4 or player.participant.treatment_p == 5: progress = 77 else: if player.participant.treatment_p == 6 or player.participant.treatment_p == 7 or player.participant.treatment_p == 8: progress = 72 else: progress = 10 return dict(progress=progress) class Payment_3_1a_b(Page): #Fase 3 (Fortune wheel)_ def is_displayed(player: Player): return player.participant.treatment_p == 3 or player.participant.treatment_p == 4 \ or player.participant.treatment_p == 5 or player.participant.treatment_p == 6 \ or player.participant.treatment_p == 7 or player.participant.treatment_p == 8 @staticmethod def vars_for_template(player: Player): if player.participant.treatment_p == 3 or player.participant.treatment_p == 4 or player.participant.treatment_p == 5: progress = 84 else: if player.participant.treatment_p == 6 or player.participant.treatment_p == 7 or player.participant.treatment_p == 8: progress = 81 else: progress = 10 return dict(progress=progress) class Payment_3_1a_c(Page): #Fase 3 (Fortune wheel - 2 cases) def is_displayed(player: Player): return player.participant.treatment_p == 3 or player.participant.treatment_p == 4 \ or player.participant.treatment_p == 5 or player.participant.treatment_p == 6 \ or player.participant.treatment_p == 7 or player.participant.treatment_p == 8 @staticmethod def vars_for_template(player: Player): if player.participant.treatment_p == 3 or player.participant.treatment_p == 4 or player.participant.treatment_p == 5: progress = 91 else: if player.participant.treatment_p == 6 or player.participant.treatment_p == 7 or player.participant.treatment_p == 8: progress = 90 else: progress = 10 return dict(progress=progress) class Payment_3_1a_d(Page): # Fase 3 (Fortune wheel - 2 cases) def is_displayed(player: Player): return player.participant.treatment_p == 3 or player.participant.treatment_p == 4 \ or player.participant.treatment_p == 5 or player.participant.treatment_p == 6 \ or player.participant.treatment_p == 7 or player.participant.treatment_p == 8 @staticmethod def vars_for_template(player: Player): if player.participant.treatment_p == 3 or player.participant.treatment_p == 4 or player.participant.treatment_p == 5: progress = 98 else: if player.participant.treatment_p == 6 or player.participant.treatment_p == 7 or player.participant.treatment_p == 8: progress = 99 else: progress = 10 return dict(progress=progress) class Payment_3_1b_a(Page): # Umbrella example def is_displayed(player: Player): return player.participant.treatment_p == 3 or player.participant.treatment_p == 4 \ or player.participant.treatment_p == 5 or player.participant.treatment_p == 6 \ or player.participant.treatment_p == 7 or player.participant.treatment_p == 8 class Payment_3_1b_b(Page): # Substituting answers example def is_displayed(player: Player): return player.participant.treatment_p == 3 or player.participant.treatment_p == 4 \ or player.participant.treatment_p == 5 or player.participant.treatment_p == 6 \ or player.participant.treatment_p == 7 or player.participant.treatment_p == 8 class Payment_3_1c_a(Page): # Substituting answers example def is_displayed(player: Player): return player.participant.treatment_p == 3 or player.participant.treatment_p == 4 \ or player.participant.treatment_p == 5 or player.participant.treatment_p == 6 \ or player.participant.treatment_p == 7 or player.participant.treatment_p == 8 class Payment_3_1c_b(Page): # Substituting answers example def is_displayed(player: Player): return player.participant.treatment_p == 3 or player.participant.treatment_p == 4 \ or player.participant.treatment_p == 5 or player.participant.treatment_p == 6 \ or player.participant.treatment_p == 7 or player.participant.treatment_p == 8 class Payment_3_1d_a(Page): # Substituting answers example when you don't pay attention def is_displayed(player: Player): return player.participant.treatment_p == 3 or player.participant.treatment_p == 4 \ or player.participant.treatment_p == 5 or player.participant.treatment_p == 6 \ or player.participant.treatment_p == 7 or player.participant.treatment_p == 8 class Payment_3_1d_b(Page): # Substituting answers example when you don't pay attention def is_displayed(player: Player): return player.participant.treatment_p == 3 or player.participant.treatment_p == 4 \ or player.participant.treatment_p == 5 or player.participant.treatment_p == 6 \ or player.participant.treatment_p == 7 or player.participant.treatment_p == 8 class Trial_1(Page): def is_displayed(player: Player): return player.participant.treatment_p > 2 class Trial_2(Page): @staticmethod def is_displayed(player: Player): return player.participant.treatment_p == 3 or player.participant.treatment_p == 4 \ or player.participant.treatment_p == 5 or player.participant.treatment_p == 6 \ or player.participant.treatment_p == 7 or player.participant.treatment_p == 8 \ or player.participant.treatment_p == 9 form_model = 'player' form_fields = ['CE_choice_practice'] @staticmethod def before_next_page(player: Player, timeout_happened): player.participant.CE_choice_practice = player.CE_choice_practice # @staticmethod # def app_after_this_page(player: Player, upcoming_apps): # # print('upcoming app is', upcoming_apps) # if player.participant.treatment_p > 2: # return "CM_trial" # FOR TREATMENT T9 class Payment_3_2a_a(Page): def is_displayed(player: Player): return player.participant.treatment_p == 9 @staticmethod def vars_for_template(player: Player): return dict(progress=70) class Payment_3_2a_b(Page): def is_displayed(player: Player): return player.participant.treatment_p == 9 @staticmethod def vars_for_template(player: Player): return dict(progress=80) class Payment_3_2a_c(Page): def is_displayed(player: Player): return player.participant.treatment_p == 9 @staticmethod def vars_for_template(player: Player): return dict(progress=90) class Payment_3_2b_a(Page): def is_displayed(player: Player): return player.participant.treatment_p == 9 @staticmethod def vars_for_template(player: Player): return dict(progress=99) class Payment_3_2b_b(Page): def is_displayed(player: Player): return player.participant.treatment_p == 9 class Payment_3_2c_a(Page): def is_displayed(player: Player): return player.participant.treatment_p == 9 class Payment_3_2c_b(Page): def is_displayed(player: Player): return player.participant.treatment_p == 9 class Payment_3_2d_a(Page): def is_displayed(player: Player): return player.participant.treatment_p == 9 class Payment_3_2d_b(Page): def is_displayed(player: Player): return player.participant.treatment_p == 9 ####################################### class Final_waiting_page(Page): def is_displayed(player: Player): return player.participant.treatment_p > 2 class Address(Page): def is_displayed(player: Player): return player.participant.treatment_p == 2 or player.participant.treatment_p == 9 form_model = 'player' form_fields = ['nome', 'via', 'cap', 'localita', 'provincia'] def before_next_page(player: Player, timeout_happened): player.participant.nome = player.nome player.participant.via = player.via player.participant.cap = player.cap player.participant.localita = player.localita player.participant.provincia = player.provincia @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[-4] # skip to the last app page_sequence = [ # InstrWaitPage, Study_structure, Part_1, Part_2_1a, Part_2_1b, Part_2_1c, Part_2_2, Part_2_1d, Part_2_3a, Part_2_3b, Payment_1_1, Payment_1_2a, Payment_1_2b, Payment_1_3a, Payment_1_3b, Payment_2_1a, Payment_2_1b, # Payment_2_2, Payment_3_1a_a, #T3-T6 Payment_3_1a_b, #T3-T8 Payment_3_1a_c, #T3-T6 Payment_3_1a_d, #T3-T6 # Payment_3_1a_c, #T3-T8 # Payment_3_1b_a, #T3-T8 # Payment_3_1b_b, # T3-T8 # Payment_3_1c_a, #T3-T8 # Payment_3_1c_b, # T3-T8 # Payment_3_1d_a, #T3-T8 # Payment_3_1d_b, # T3-T8 Payment_3_2a_a, #T9 Payment_3_2a_b, #T9 Payment_3_2a_c, #T9 Payment_3_2b_a, #T9 # Payment_3_2b_b, #T9 # Payment_3_2c_a, #T9 # Payment_3_2c_b, #T9 # Payment_3_2d_a, #T9 # Payment_3_2d_b, #T9 Address, Final_waiting_page, Trial_1, Trial_2, ] pages_per_round = len(page_sequence) tot_pages = pages_per_round * C.NUM_ROUNDS