from otree.api import * doc = """ Players are allocated 10 tokens and must bet those tokens on themselves or an anonymous randomized partner. They then watch a ball drawn from an urn to indicate the state of the world. 1 token=1EU if invested in a person that guesses correctly. """ class Constants(BaseConstants): name_in_url = 'part_1' players_per_group = 2 num_rounds = 1 endowment = 10 part_1_multiplier = 1 / 4 instructions_template = 'trust_metric/instructions.html' states = ['Up', 'Down'] class Subsession(BaseSubsession): pass class Group(BaseGroup): world_state = models.IntegerField( doc="""The world can be Up(=1) or Down(=2), random for each group""" ) class Player(BasePlayer): question_1 = models.StringField(label='The number of tokens you invest in your partner and yourself will always ' 'add up to 10.', choices=['True', 'False']) question_2 = models.IntegerField(label='How many urns are there?') question_3 = models.IntegerField(label='If you invest 8 tokens in your partner, how many does that mean you ' 'invested in yourself?') question_4 = models.IntegerField(label='If you invested 1 token in your partner, how many does that mean you ' 'invested in yourself?') question_5 = models.IntegerField(label='You invested 6 tokens in your partner. You guessed the randomly chosen urn ' 'correctly and your partner guessed the urn correctly. ' 'How many experimental dollars will you receive?') question_6 = models.IntegerField(label='You invested 3 tokens in your partner. You guessed the randomly chosen urn ' 'correctly and your partner guessed the urn incorrectly. ' 'How many experimental dollars will you receive?') question_7 = models.IntegerField(label='You invested 7 tokens in your partner. You guessed the randomly chosen urn ' 'incorrectly and your partner guessed the urn correctly. ' 'How many experimental dollars will you receive?') question_8 = models.IntegerField(label='You invested 9 tokens in your partner. You guessed the randomly chosen urn ' 'incorrectly and your partner guessed the urn incorrectly. ' 'How many experimental dollars will you receive?') invested_in_partner = models.IntegerField( min=0, max=Constants.endowment, doc="""Amount invested in partner""", label="Please enter the number of tokens you want to invest in your partner (from 0 to 10):", ) color_of_ball_signal = models.IntegerField( doc="""The color of ball drawn (black=A=1 white=B=2)""" ) state_of_world_guess = models.IntegerField( choices=[['1', 'Urn A'], ['2', 'Urn B']], label='What do you think the chosen urn is?', widget=widgets.RadioSelect, ) part_1_profit = models.CurrencyField( label='Part 1 profit' ) # Functions def creating_session(subsession: Subsession): # Setting the state of the world for g in subsession.get_groups(): import random world_state = random.uniform(1, 2) # Randomly choosing up or down g.world_state = int(round(world_state, 0)) def generate_signal_received(group: Group): import random if group.world_state == 1: proportion_black = 60 else: proportion_black = 40 draw_received = random.randint(1, 100) if draw_received <= proportion_black: ball_color = 1 else: ball_color = 2 return ball_color def other_player(player: Player): return player.get_others_in_group()[0] def set_payoffs(group: Group): print('set_payoffs') p1 = group.get_player_by_id(1) p2 = group.get_player_by_id(2) # Setting payoffs based on different scenarios from profit if p1.state_of_world_guess == group.world_state and p2.state_of_world_guess == group.world_state: p1.payoff = Constants.endowment * Constants.part_1_multiplier p2.payoff = Constants.endowment * Constants.part_1_multiplier elif p1.state_of_world_guess != group.world_state and p2.state_of_world_guess == group.world_state: p1.payoff = p1.invested_in_partner * Constants.part_1_multiplier p2.payoff = (Constants.endowment - p2.invested_in_partner) * Constants.part_1_multiplier elif p1.state_of_world_guess == group.world_state and p2.state_of_world_guess != group.world_state: p1.payoff = (Constants.endowment - p1.invested_in_partner) * Constants.part_1_multiplier p2.payoff = p2.invested_in_partner * Constants.part_1_multiplier else: p1.payoff = 0 p2.payoff = 0 p1.part_1_profit = p1.payoff p2.part_1_profit = p2.payoff # PAGES class Introduction(Page): pass class QuizP1(Page): form_model = 'player' form_fields = ['question_1'] @staticmethod def error_message(player: Player, values): solution = dict(question_1='True') errors = {f: 'Wrong: please reread the instructions' for f in solution if values[f] != solution[f]} if errors: return errors class QuizP2(Page): form_model = 'player' form_fields = ['question_2'] @staticmethod def error_message(player: Player, values): solution = dict(question_2=2) errors = {f: 'Wrong: please reread the instructions' for f in solution if values[f] != solution[f]} if errors: return errors class QuizP3(Page): form_model = 'player' form_fields = ['question_3'] @staticmethod def error_message(player: Player, values): solution = dict(question_3=2) errors = {f: 'Wrong: please reread the instructions' for f in solution if values[f] != solution[f]} if errors: return errors class QuizP4(Page): form_model = 'player' form_fields = ['question_4'] @staticmethod def error_message(player: Player, values): solution = dict(question_4=9) errors = {f: 'Wrong: please reread the instructions' for f in solution if values[f] != solution[f]} if errors: return errors class QuizP5(Page): form_model = 'player' form_fields = ['question_5'] @staticmethod def error_message(player: Player, values): solution = dict(question_5=10) errors = {f: 'Wrong: please reread the instructions' for f in solution if values[f] != solution[f]} if errors: return errors class QuizP6(Page): form_model = 'player' form_fields = ['question_6'] @staticmethod def error_message(player: Player, values): solution = dict(question_6=7) errors = {f: 'Wrong: please reread the instructions' for f in solution if values[f] != solution[f]} if errors: return errors class QuizP7(Page): form_model = 'player' form_fields = ['question_7'] @staticmethod def error_message(player: Player, values): solution = dict(question_7=7) errors = {f: 'Wrong: please reread the instructions' for f in solution if values[f] != solution[f]} if errors: return errors class QuizP8(Page): form_model = 'player' form_fields = ['question_8'] @staticmethod def error_message(player: Player, values): solution = dict(question_8=0) errors = {f: 'Wrong: please reread the instructions' for f in solution if values[f] != solution[f]} if errors: return errors class QuizWaitPage(WaitPage): pass class Investment(Page): form_model = 'player' form_fields = ['invested_in_partner'] class Confirmation(Page): @staticmethod def vars_for_template(player: Player): return dict(invested_in_self=Constants.endowment - player.invested_in_partner) @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group player.color_of_ball_signal = generate_signal_received(group) print('player invested', player.invested_in_partner) class Draw(Page): pass class Decision(Page): @staticmethod def observable_ball(player: Player): if player.ball_color == 1: return player.computer_ball_description == "Black" else: return player.computer_ball_description == "White" form_model = 'player' form_fields = ['state_of_world_guess'] class ResultsWaitPage(WaitPage): after_all_players_arrive = 'set_payoffs' class Results(Page): @staticmethod def before_next_page(player: Player, timeout_happened): participant = player.participant other = other_player(player) group = player.group if player.state_of_world_guess == group.world_state: participant.payoff_self = (Constants.endowment - player.invested_in_partner) * Constants.part_1_multiplier else: participant.payoff_self = 0 if other.state_of_world_guess == group.world_state: participant.payoff_partner = round(player.invested_in_partner * Constants.part_1_multiplier, 2) else: participant.payoff_partner = 0 print('self payoff', participant.payoff_self) print('partner payoff', participant.payoff_partner) page_sequence = [Introduction, QuizP1, QuizP2, QuizP3, QuizP4, QuizP5, QuizP6, QuizP7, QuizP8, QuizWaitPage, Investment, Confirmation, Decision, ResultsWaitPage, Results]