from otree.api import * doc = """ Your app description """ class Constants(BaseConstants): name_in_url = 'information_cascade_treatment' players_per_group = None num_rounds = 30 instructions_template = 'information_cascade_treatment/instructions.html' max_players = 17 earnings_multiplier = 0.25 main_template = __name__ + '/Prediction.html' class Subsession(BaseSubsession): pass class Group(BaseGroup): world_state = models.IntegerField( doc="""The urn can be A(=1) or B(=2), random for each round""" ) string_state = models.StringField() class Player(BasePlayer): made_decision = models.BooleanField(initial=False) # Indicates has made choice for calling completed group string_choice = models.StringField( doc="""Makes it easier to print prediction""" ) player_id = models.IntegerField( doc="""Draw order in the cascade""" ) color_of_ball_signal = models.IntegerField( doc="""The color of ball drawn (black=A=1 white=B=2)""" ) state_of_world_guess = models.IntegerField( doc="""Selected Urn prediction""", choices=[['1', 'Urn A'], ['2', 'Urn B']], label='Which urn do you think was selected this round?', widget=widgets.RadioSelect, ) earnings_from_guess = models.IntegerField( doc="""Earnings from the IC""" ) # Functions # These two functions come from the trust metric to set the state of the world 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)) if g.world_state == 1: g.string_state = 'Urn A' else: g.string_state = 'Urn B' from itertools import cycle from random import shuffle ps = subsession.get_players() # Get list of players and shuffle it shuffle(ps) # Change the max to the number of experiment players slots = [*range(1, 17, 1)] shuffled_slots = cycle(slots) # shuffle the slot order for p in ps: # Assign the shuffled players to the shuffled positions p.player_id = next(shuffled_slots) def generate_signal_received(group: Group): import random if group.world_state == 1: # Set proportion of black balls based on experiment signal precision proportion_black = 0.6 else: proportion_black = 0.4 draw_received = random.uniform(0, 1) # Simulating a draw if draw_received <= proportion_black: # Assigning the result based on the defined proportions ball_color = 1 else: ball_color = 2 return ball_color def other_players(player: Player): return sorted(player.get_others_in_group()[0]) def set_payoffs(group: Group): players = group.get_players() for player in players: if player.state_of_world_guess == group.world_state: # Give 1 EU if guessed correctly player.payoff = 1 else: player.payoff = 0 # PAGES class BeforeWaitPage(WaitPage): pass class Introduction(Page): @staticmethod def is_displayed(player): # Only show this page the first round return player.round_number == 1 class Ordering(Page): @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group player.color_of_ball_signal = generate_signal_received(group) # Assign ball signal print('set_ball_signal', player.player_id) class IntroductionWaitPage(WaitPage): pass class P1(Page): form_model = 'player' form_fields = ['state_of_world_guess'] template_name = Constants.main_template @staticmethod def is_displayed(player: Player): return player.player_id == 1 # Only unlock page for each person by id for round @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group if player.player_id == 1: player.made_decision = True # Indicates they completed turn if player.state_of_world_guess == 1: # Matching integer guess with string output player.string_choice = 'Urn A' else: player.string_choice = 'Urn B' if player.state_of_world_guess == group.world_state: # Keep track of earnings in data- may not be needed player.earnings_from_guess = 1 else: player.earnings_from_guess = 0 class P1WaitPage(WaitPage): template_name = 'area_exam/CascadeWaitPage.html' @staticmethod def is_displayed(player: Player): return player.player_id != 1 @staticmethod def vars_for_template(player: Player): others = [player for player in player.group.get_players() if player.made_decision] sorted_players = sorted(others, key=lambda player: player.player_id) return dict(others=sorted_players) class P2(Page): form_model = 'player' form_fields = ['state_of_world_guess'] template_name = Constants.main_template @staticmethod def is_displayed(player: Player): return player.player_id == 2 @staticmethod def vars_for_template(player: Player): others = [player for player in player.get_others_in_group() if player.made_decision] sorted_players = sorted(others, key=lambda player: player.player_id) return dict(others=sorted_players) @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group if player.player_id == 2: player.made_decision = True if player.state_of_world_guess == 1: player.string_choice = 'Urn A' else: player.string_choice = 'Urn B' if player.state_of_world_guess == group.world_state: player.earnings_from_guess = 1 else: player.earnings_from_guess = 0 class P2WaitPage(WaitPage): template_name = 'area_exam/CascadeWaitPage.html' @staticmethod def is_displayed(player: Player): return player.player_id != 2 @staticmethod def vars_for_template(player: Player): others = [player for player in player.group.get_players() if player.made_decision] sorted_players = sorted(others, key=lambda player: player.player_id) return dict(others=sorted_players) class P3(Page): form_model = 'player' form_fields = ['state_of_world_guess'] template_name = Constants.main_template @staticmethod def is_displayed(player: Player): return player.player_id == 3 @staticmethod def vars_for_template(player: Player): others = [player for player in player.get_others_in_group() if player.made_decision] sorted_players = sorted(others, key=lambda player: player.player_id) return dict(others=sorted_players) @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group if player.player_id == 3: player.made_decision = True if player.state_of_world_guess == 1: player.string_choice = 'Urn A' else: player.string_choice = 'Urn B' if player.state_of_world_guess == group.world_state: player.earnings_from_guess = 1 else: player.earnings_from_guess = 0 class P3WaitPage(WaitPage): template_name = 'area_exam/CascadeWaitPage.html' @staticmethod def is_displayed(player: Player): return player.player_id != 3 @staticmethod def vars_for_template(player: Player): others = [player for player in player.group.get_players() if player.made_decision] sorted_players = sorted(others, key=lambda player: player.player_id) return dict(others=sorted_players) class P4(Page): form_model = 'player' form_fields = ['state_of_world_guess'] template_name = Constants.main_template @staticmethod def is_displayed(player: Player): return player.player_id == 4 @staticmethod def vars_for_template(player: Player): others = [player for player in player.get_others_in_group() if player.made_decision] sorted_players = sorted(others, key=lambda player: player.player_id) return dict(others=sorted_players) @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group if player.player_id == 4: player.made_decision = True if player.state_of_world_guess == 1: player.string_choice = 'Urn A' else: player.string_choice = 'Urn B' if player.state_of_world_guess == group.world_state: player.earnings_from_guess = 1 else: player.earnings_from_guess = 0 class P4WaitPage(WaitPage): template_name = 'area_exam/CascadeWaitPage.html' @staticmethod def is_displayed(player: Player): return player.player_id != 4 @staticmethod def vars_for_template(player: Player): others = [player for player in player.group.get_players() if player.made_decision] sorted_players = sorted(others, key=lambda player: player.player_id) return dict(others=sorted_players) class P5(Page): form_model = 'player' form_fields = ['state_of_world_guess'] template_name = Constants.main_template @staticmethod def is_displayed(player: Player): return player.player_id == 5 @staticmethod def vars_for_template(player: Player): others = [player for player in player.get_others_in_group() if player.made_decision] sorted_players = sorted(others, key=lambda player: player.player_id) return dict(others=sorted_players) @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group if player.player_id == 5: player.made_decision = True if player.state_of_world_guess == 1: player.string_choice = 'Urn A' else: player.string_choice = 'Urn B' if player.state_of_world_guess == group.world_state: player.earnings_from_guess = 1 else: player.earnings_from_guess = 0 class P5WaitPage(WaitPage): template_name = 'area_exam/CascadeWaitPage.html' @staticmethod def is_displayed(player: Player): return player.player_id != 5 @staticmethod def vars_for_template(player: Player): others = [player for player in player.group.get_players() if player.made_decision] sorted_players = sorted(others, key=lambda player: player.player_id) return dict(others=sorted_players) class P6(Page): form_model = 'player' form_fields = ['state_of_world_guess'] template_name = Constants.main_template @staticmethod def is_displayed(player: Player): return player.player_id == 6 @staticmethod def vars_for_template(player: Player): others = [player for player in player.get_others_in_group() if player.made_decision] sorted_players = sorted(others, key=lambda player: player.player_id) return dict(others=sorted_players) @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group if player.player_id == 6: player.made_decision = True if player.state_of_world_guess == 1: player.string_choice = 'Urn A' else: player.string_choice = 'Urn B' if player.state_of_world_guess == group.world_state: player.earnings_from_guess = 1 else: player.earnings_from_guess = 0 class P6WaitPage(WaitPage): template_name = 'area_exam/CascadeWaitPage.html' @staticmethod def is_displayed(player: Player): return player.player_id != 6 @staticmethod def vars_for_template(player: Player): others = [player for player in player.group.get_players() if player.made_decision] sorted_players = sorted(others, key=lambda player: player.player_id) return dict(others=sorted_players) class P7(Page): form_model = 'player' form_fields = ['state_of_world_guess'] template_name = Constants.main_template @staticmethod def is_displayed(player: Player): return player.player_id == 7 @staticmethod def vars_for_template(player: Player): others = [player for player in player.get_others_in_group() if player.made_decision] sorted_players = sorted(others, key=lambda player: player.player_id) return dict(others=sorted_players) @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group if player.player_id == 7: player.made_decision = True if player.state_of_world_guess == 1: player.string_choice = 'Urn A' else: player.string_choice = 'Urn B' if player.state_of_world_guess == group.world_state: player.earnings_from_guess = 1 else: player.earnings_from_guess = 0 class P7WaitPage(WaitPage): template_name = 'area_exam/CascadeWaitPage.html' @staticmethod def is_displayed(player: Player): return player.player_id != 7 @staticmethod def vars_for_template(player: Player): others = [player for player in player.group.get_players() if player.made_decision] sorted_players = sorted(others, key=lambda player: player.player_id) return dict(others=sorted_players) class P8(Page): form_model = 'player' form_fields = ['state_of_world_guess'] template_name = Constants.main_template @staticmethod def is_displayed(player: Player): return player.player_id == 8 @staticmethod def vars_for_template(player: Player): others = [player for player in player.get_others_in_group() if player.made_decision] sorted_players = sorted(others, key=lambda player: player.player_id) return dict(others=sorted_players) @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group if player.player_id == 8: player.made_decision = True if player.state_of_world_guess == 1: player.string_choice = 'Urn A' else: player.string_choice = 'Urn B' if player.state_of_world_guess == group.world_state: player.earnings_from_guess = 1 else: player.earnings_from_guess = 0 class P8WaitPage(WaitPage): template_name = 'area_exam/CascadeWaitPage.html' @staticmethod def is_displayed(player: Player): return player.player_id != 8 @staticmethod def vars_for_template(player: Player): others = [player for player in player.group.get_players() if player.made_decision] sorted_players = sorted(others, key=lambda player: player.player_id) return dict(others=sorted_players) class P9(Page): form_model = 'player' form_fields = ['state_of_world_guess'] template_name = Constants.main_template @staticmethod def is_displayed(player: Player): return player.player_id == 9 @staticmethod def vars_for_template(player: Player): others = [player for player in player.get_others_in_group() if player.made_decision] sorted_players = sorted(others, key=lambda player: player.player_id) return dict(others=sorted_players) @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group if player.player_id == 9: player.made_decision = True if player.state_of_world_guess == 1: player.string_choice = 'Urn A' else: player.string_choice = 'Urn B' if player.state_of_world_guess == group.world_state: player.earnings_from_guess = 1 else: player.earnings_from_guess = 0 class P9WaitPage(WaitPage): template_name = 'area_exam/CascadeWaitPage.html' @staticmethod def is_displayed(player: Player): return player.player_id != 9 @staticmethod def vars_for_template(player: Player): others = [player for player in player.group.get_players() if player.made_decision] sorted_players = sorted(others, key=lambda player: player.player_id) return dict(others=sorted_players) class P10(Page): form_model = 'player' form_fields = ['state_of_world_guess'] template_name = Constants.main_template @staticmethod def is_displayed(player: Player): return player.player_id == 10 @staticmethod def vars_for_template(player: Player): others = [player for player in player.get_others_in_group() if player.made_decision] sorted_players = sorted(others, key=lambda player: player.player_id) return dict(others=sorted_players) @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group if player.player_id == 10: player.made_decision = True if player.state_of_world_guess == 1: player.string_choice = 'Urn A' else: player.string_choice = 'Urn B' if player.state_of_world_guess == group.world_state: player.earnings_from_guess = 1 else: player.earnings_from_guess = 0 class P10WaitPage(WaitPage): template_name = 'area_exam/CascadeWaitPage.html' @staticmethod def is_displayed(player: Player): return player.player_id != 10 @staticmethod def vars_for_template(player: Player): others = [player for player in player.group.get_players() if player.made_decision] sorted_players = sorted(others, key=lambda player: player.player_id) return dict(others=sorted_players) class P11(Page): form_model = 'player' form_fields = ['state_of_world_guess'] template_name = Constants.main_template @staticmethod def is_displayed(player: Player): return player.player_id == 11 @staticmethod def vars_for_template(player: Player): others = [player for player in player.get_others_in_group() if player.made_decision] sorted_players = sorted(others, key=lambda player: player.player_id) return dict(others=sorted_players) @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group if player.player_id == 11: player.made_decision = True if player.state_of_world_guess == 1: player.string_choice = 'Urn A' else: player.string_choice = 'Urn B' if player.state_of_world_guess == group.world_state: player.earnings_from_guess = 1 else: player.earnings_from_guess = 0 class P11WaitPage(WaitPage): pass class P12(Page): form_model = 'player' form_fields = ['state_of_world_guess'] template_name = Constants.main_template @staticmethod def is_displayed(player: Player): return player.player_id == 12 @staticmethod def vars_for_template(player: Player): others = [player for player in player.get_others_in_group() if player.made_decision] sorted_players = sorted(others, key=lambda player: player.player_id) return dict(others=sorted_players) @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group if player.player_id == 12: player.made_decision = True if player.state_of_world_guess == 1: player.string_choice = 'Urn A' else: player.string_choice = 'Urn B' if player.state_of_world_guess == group.world_state: player.earnings_from_guess = 1 else: player.earnings_from_guess = 0 class P12WaitPage(WaitPage): pass class P13(Page): form_model = 'player' form_fields = ['state_of_world_guess'] template_name = Constants.main_template @staticmethod def is_displayed(player: Player): return player.player_id == 13 @staticmethod def vars_for_template(player: Player): others = [player for player in player.get_others_in_group() if player.made_decision] sorted_players = sorted(others, key=lambda player: player.player_id) return dict(others=sorted_players) @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group if player.player_id == 13: player.made_decision = True if player.state_of_world_guess == 1: player.string_choice = 'Urn A' else: player.string_choice = 'Urn B' if player.state_of_world_guess == group.world_state: player.earnings_from_guess = 1 else: player.earnings_from_guess = 0 class P13WaitPage(WaitPage): pass class P14(Page): form_model = 'player' form_fields = ['state_of_world_guess'] template_name = Constants.main_template @staticmethod def is_displayed(player: Player): return player.player_id == 14 @staticmethod def vars_for_template(player: Player): others = [player for player in player.get_others_in_group() if player.made_decision] sorted_players = sorted(others, key=lambda player: player.player_id) return dict(others=sorted_players) @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group if player.player_id == 14: player.made_decision = True if player.state_of_world_guess == 1: player.string_choice = 'Urn A' else: player.string_choice = 'Urn B' if player.state_of_world_guess == group.world_state: player.earnings_from_guess = 1 else: player.earnings_from_guess = 0 class P14WaitPage(WaitPage): pass class P15(Page): form_model = 'player' form_fields = ['state_of_world_guess'] template_name = Constants.main_template @staticmethod def is_displayed(player: Player): return player.player_id == 15 @staticmethod def vars_for_template(player: Player): others = [player for player in player.get_others_in_group() if player.made_decision] sorted_players = sorted(others, key=lambda player: player.player_id) return dict(others=sorted_players) @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group if player.player_id == 15: player.made_decision = True if player.state_of_world_guess == 1: player.string_choice = 'Urn A' else: player.string_choice = 'Urn B' if player.state_of_world_guess == group.world_state: player.earnings_from_guess = 1 else: player.earnings_from_guess = 0 class P15WaitPage(WaitPage): pass class P16(Page): form_model = 'player' form_fields = ['state_of_world_guess'] template_name = Constants.main_template @staticmethod def is_displayed(player: Player): return player.player_id == 16 @staticmethod def vars_for_template(player: Player): others = [player for player in player.get_others_in_group() if player.made_decision] sorted_players = sorted(others, key=lambda player: player.player_id) return dict(others=sorted_players) @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group if player.player_id == 16: player.made_decision = True if player.state_of_world_guess == 1: player.string_choice = 'Urn A' else: player.string_choice = 'Urn B' if player.state_of_world_guess == group.world_state: player.earnings_from_guess = 1 else: player.earnings_from_guess = 0 class P16WaitPage(WaitPage): after_all_players_arrive = set_payoffs # Set payoffs for result class Results(Page): @staticmethod def vars_for_template(player: Player): group = player.group others = [p for p in group.get_players()] sorted_players = sorted(others, key=lambda player: player.player_id) return dict(others=sorted_players) @staticmethod def before_next_page(player: Player, timeout_happened): if player.round_number == Constants.num_rounds: participant = player.participant total_payoff = sum([p.earnings_from_guess for p in player.in_all_rounds()]) participant.cascade_earnings = total_payoff/4 print('Total cascade earnings', participant.cascade_earnings) class ResultsWaitPage(WaitPage): @staticmethod def is_displayed(player): # Only show this page the first round return player.round_number == Constants.num_rounds page_sequence = [BeforeWaitPage, Introduction, Ordering, IntroductionWaitPage, P1, P1WaitPage, P2, P2WaitPage, P3, P3WaitPage, P4, P4WaitPage, P5, P5WaitPage, P6, P6WaitPage, P7, P7WaitPage, P8, P8WaitPage, P9, P9WaitPage, P10, P10WaitPage, P11, P11WaitPage, P12, P12WaitPage, P13, P13WaitPage, P14, P14WaitPage, P15, P15WaitPage, P16, P16WaitPage, Results, ResultsWaitPage]