from otree.api import * import random import itertools import time from random import choice doc = """ """ class C(BaseConstants): NAME_IN_URL = 'luqi' PLAYERS_PER_GROUP = 2 NUM_ROUNDS = 1 showup = 1 endowment = 800 rate = 0.001 class Subsession(BaseSubsession): pass def creating_session(subsession): # treatments for p in subsession.get_players(): p.Prolific_ID = p.participant.label if p.id_in_subsession: pressures = itertools.cycle([1,1,1,1]) for player in subsession.get_players(): player.code_treatment = next(pressures) if p.code_treatment == 1: p.treatment = "low_low" elif p.code_treatment == 2: p.treatment = "typo10" for p in subsession.get_players(): p.Prolific_ID = p.participant.label if p.id_in_subsession: pressures = itertools.cycle([1,1,1,1]) pressures2 = itertools.cycle([0, 1, 0, 1, 0, 1, 0, 2, 0, 2]) for player in subsession.get_players(): player.code_treatment = next(pressures) player.code_type = next(pressures2) if p.code_treatment == 1: p.treatment = "low_low" elif p.code_treatment == 2: p.treatment = "typo10" if p.code_type == 0: p.p2type = "" elif p.code_type == 1: p.p2type = "type1" elif p.code_type == 2: p.p2type = "type2" if p.id_in_group == 1: p.type = 'P1' elif p.id_in_group == 2: p.type = 'P2' class Group(BaseGroup): pass class Player(BasePlayer): code_treatment = models.IntegerField() code_type = models.IntegerField() p2type = models.StringField( ) treatment = models.StringField( ) type = models.StringField( ) state = models.StringField() Prolific_ID = models.StringField( label="Prolific ID", ) control_question = models.StringField( choices=[ ['1', 'I agree to take part. Take me to the study.'], ['2', 'I do not agree to take part in this study. Take me back to Prolific.'], ], label="Do you agree to participate in this study?", widget=widgets.RadioSelect ) q1_attempts = models.StringField(initial="") q2_attempts = models.StringField(initial="") q3_attempts = models.StringField(initial="") q4_attempts = models.StringField(initial="") q5a_attempts = models.StringField(initial="") q5b_attempts = models.StringField(initial="") Q1 = models.StringField( choices=[ ['1', '(a) 0'], ['2', '(b) 3/5'], ['3', '(c) 1/5'], ['4', '(d) 1'], ], label="Q1. What is the probability that Player 2’s type is I?", widget=widgets.RadioSelect ) Q2 = models.StringField( choices=[ ['1', '(a) 1/40'], ['2', '(b) 39/40'], ['3', '(c) Always 1/2'], ['4', '(d) It does not depend on the value chosen of X'], ], label="Q2. If you are Player 1 and choose 10, what is the probability that the state is RED?", widget=widgets.RadioSelect ) Q3 = models.StringField( choices=[ ['1', '(a) Player 1’s choice'], ['2', '(b) The state is RED or BLUE'], ['3', '(c) Your own type'], ['4', '(d) Both (a) and (c)'], ], label="Q3. If you are Player 2, what information do you know if Player 1 chooses not to disclose?", widget=widgets.RadioSelect ) Q4 = models.StringField( choices=[ ['1', '(a) Player 1’s choice'], ['2', '(b) The state is RED or BLUE'], ['3', '(c) Your own type'], ['4', '(d) All of the above'], ], label="Q1. If you are Player 2, what information do you know if Player 1 chooses to disclose?", widget=widgets.RadioSelect ) Q5a = models.IntegerField( min=-1000000, label="What is Player 1’s payoff, in points (excluding the initial endowment), if the state is RED?", ) Q5b = models.IntegerField( label="What is your payoff, in points (excluding the initial endowment), if the state is BLUE?", ) choice1 = models.IntegerField( min =0, max =400, label="Please indicate the value of your chosen X below:", ) choice2 = models.StringField( choices=[ ['1', 'Yes'], ['2', 'No'], ], label="Please indicate whether to disclose the realized state to Player 2:", widget=widgets.RadioSelect ) belief1 = models.StringField( choices=[ ['A', 'A'], ['B', 'B'], ], label="If Player 2's type is Type I, what do you think Player 2 will choose?", widget=widgets.RadioSelect ) belief2 = models.StringField( choices=[ ['A', 'A'], ['B', 'B'], ], label="If Player 2's type is Type II, what do you think Player 2 will choose?", widget=widgets.RadioSelect ) belief3 = models.IntegerField( min =0, max =400, label="Please indicate your estimate of Player 1’s chosen value of X below. ", ) belief4 = models.StringField( choices=[ ['Disclosure', 'Disclosure'], ['Not disclosure', 'Not disclosure'], ], label="Please indicate your estimate of Player 1’s choice of disclosure below.", widget=widgets.RadioSelect ) choice3 = models.StringField( choices=[ ['A', 'A'], ['B', 'B'], ], label="Please indicate your choice below:", widget=widgets.RadioSelect ) earn = models.FloatField() final = models.FloatField() gender = models.StringField( choices=[ ['1', 'Male'], ['2', 'Female'], ['3', 'Other'], ], label="1. What is your gender?", widget=widgets.RadioSelect ) age = models.IntegerField( label="2. What is your age?", min=0, max=120 ) language = models.StringField( choices=[ ['1', 'Yes'], ['2', 'No'], ], label="3. Is English your first language?", widget=widgets.RadioSelect ) max_income = models.StringField( choices=[ ['1', 'Very important'], ['2', 'Important'], ['3', 'Indifferent'], ['4', 'Not important'], ['5', 'Not important at all'], ], label="4. How important was it for you to maximise your own income during the experiment?", widget=widgets.RadioSelect ) trust = models.StringField( choices=[ ['1', 'Most people can be trusted'], ['2', 'You need to be very careful in dealing with people'], ], label="5. Generally speaking, would you say that most people can be trusted or that you need to be very " "careful in dealing with people?", widget=widgets.RadioSelect ) risk = models.StringField( choices=[ ['0', ''], ['1', ''], ['2', ''], ['3', ''], ['4', ''], ['5', ''], ['6', ''], ['7', ''], ['8', ''], ['9', ''], ['10', ''], ], label="", widget=widgets.RadioSelectHorizontal ) instructions = models.StringField( choices=[ ['1', 'Very difficult'], ['2', 'Difficult'], ['3', 'Neutral'], ['4', 'Easy'], ['5', 'Very easy'], ], label="7. How did you find the instructions?", widget=widgets.RadioSelect ) econ_exp = models.IntegerField( label="8. How many economics experiments have you participated in before this one? ", ) feedback = models.StringField( blank=True, label="9. Do you have any other comments or feedback regarding this experiment?", ) def control_question_error_message(player,value): correct_answer = '1' if value != correct_answer: error_message = "If you do not agree to take part in this study, please close your browser tab." return error_message def Q1_error_message(player, value): if player.q1_attempts: player.q1_attempts += f", {value}" # Append attempts else: player.q1_attempts = value # Store first attempt correct_q1 = '2' if value != correct_q1: error_q1 = "Your answer is wrong. Please select again." return error_q1 def Q2_error_message(player, value): if player.q2_attempts: player.q2_attempts += f", {value}" # Append attempts else: player.q2_attempts = value # Store first attempt correct_q2 = '1' if value != correct_q2: error_q2 = "Your answer is wrong. Please select again." return error_q2 def Q3_error_message(player, value): if player.q3_attempts: player.q3_attempts += f", {value}" # Append attempts else: player.q3_attempts = value # Store first attempt correct_q3 = '4' if value != correct_q3: error_q3 = "Your answer is wrong. Please select again." return error_q3 def Q4_error_message(player, value): if player.q4_attempts: player.q4_attempts += f", {value}" # Append attempts else: player.q4_attempts = value # Store first attempt correct_q4 = '4' if value != correct_q4: error_q4 = "Your answer is wrong. Please select again." return error_q4 def Q5a_error_message(player, value): v = str(value) if player.q5a_attempts: player.q5a_attempts += f", {value}" # Append attempts else: player.q5a_attempts = v # Store first attempt correct_q5a = -50 if value != correct_q5a: error_q5a = "Your answer is wrong. Please select again." return error_q5a def Q5b_error_message(player, value): v = str(value) if player.q5b_attempts: player.q5b_attempts += f", {value}" # Append attempts else: player.q5b_attempts = v # Store first attempt correct_q5b = 200 if value != correct_q5b: error_q5b = "Your answer is wrong. Please select again." return error_q5b class Welcome(Page): form_model = 'player' form_fields = ['control_question'] class ProlificID(Page): form_model = 'player' form_fields = ['Prolific_ID'] class General_Instructions(Page): pass class Instructions(Page): pass class Questions(Page): form_model = 'player' form_fields = ['Q1', 'Q2', 'Q3', 'Q4', 'Q5a', 'Q5b' ] class Decision1(Page): form_model = 'player' form_fields = ['choice1'] def is_displayed(player): return player.type == "P1" class Decision2(Page): form_model = 'player' form_fields = ['choice2'] def is_displayed(player): return player.type == "P1" def vars_for_template(player): x = player.choice1 u = random.random() player.state = 'RED' if u < (x / 400) else 'BLUE' class Belief1(Page): form_model = 'player' form_fields = ['belief1', 'belief2'] def is_displayed(player): return player.type == "P1" class Belief2(Page): form_model = 'player' form_fields = ['belief3', 'belief4'] def is_displayed(player): return player.type == "P2" class ResultsWaitPage(WaitPage): title_text = "Please wait" body_text = "Please wait for the matched group member to make their decisions" def after_all_players_arrive(group: Group): p1 = group.get_player_by_id(1) p2 = group.get_player_by_id(2) # copy P1 decisions into P2's storage fields p2.choice1 = p1.choice1 p2.choice2 = p1.choice2 p2.state = p1.state class Decision3(Page): form_model = 'player' form_fields = ['choice3'] def is_displayed(player): return player.type == "P2" class ResultsWaitPage2(WaitPage): title_text = "Please wait" body_text = "Please wait for the matched group member to make their decisions" def after_all_players_arrive(group: Group): p1 = group.get_player_by_id(1) p2 = group.get_player_by_id(2) p1.p2type = p2.p2type p1.choice3 = p2.choice3 X = p1.choice1 state = p1.state action = p2.choice3 t = p2.p2type if state == "RED": if action == "A": p1.earn = -10 - X p2.earn = -200 else: p1.earn = 400 - X p2.earn = -50 if t == "type1" else -350 elif state == "BLUE": if action == "A": p1.earn = -300 - X p2.earn = 200 else: p1.earn = 300 - X p2.earn = 50 if t == "type1" else 550 p1.final = C.endowment + p1.earn p2.final = C.endowment + p2.earn p1.payoff = round(C.showup + p1.final*C.rate, 2) p2.payoff = round(C.showup + p2.final*C.rate, 2) class Feedback(Page): form_model = 'player' class Questionnaire(Page): form_model = 'player' form_fields = ['gender', 'age', 'language', 'max_income', 'trust', 'risk', 'instructions', 'econ_exp', 'feedback'] class Thanks(Page): pass page_sequence = [Welcome,ProlificID,General_Instructions,Instructions,Questions,Decision1,Decision2,Belief1,Belief2, ResultsWaitPage,Decision3,ResultsWaitPage2,Feedback,Questionnaire,Thanks]