from otree.api import ( Page, WaitPage, models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range, ) from random import choice import random from random import randint doc = """ 2 firms complete in a market by setting prices for homogenous goods. See "Kruse, J. B., Rassenti, S., Reynolds, S. S., & Smith, V. L. (1994). Bertrand-Edgeworth competition in experimental markets. Econometrica: Journal of the Econometric Society, 343-371." """ class Constants(BaseConstants): players_per_group = 6 name_in_url = 'school_choice_JP' num_rounds = 11 instructions_template = 'school_choice_JP/instructions.html' chosen_round = 41 class Subsession(BaseSubsession): def after_all_players_arrive(self, players): if self.round_number == 1: random.shuffle(players) return players pass class Group(BaseGroup): pass class Player(BasePlayer): major_JP = models.StringField( label='what is your major?' ) age_JP = models.IntegerField(label='What is your age?', min=13, max=125) gender_JP = models.StringField( choices=[['Male', 'Male'], ['Female', 'Female'],['other', 'other'], ['prefer not to say', 'prefer not to say']], label='What is your gender?', widget=widgets.RadioSelect, ) random_number_JP = models.IntegerField() slider_value_JP = models.IntegerField(min=0, max=100) number_JP = models.IntegerField() chosen_betJP = models.CharField( choices=[['A', 'School A (E$110)'], ['B', 'School B (E$70)']], widget=widgets.RadioSelect, verbose_name="Please select a school to apply" ) accept_JP = models.StringField() student_1JP = models.BooleanField(blank=True) student_2JP = models.BooleanField(blank=True) student_3JP = models.BooleanField(blank=True) student_4JP = models.BooleanField(blank=True) student_5JP = models.BooleanField(blank=True) student_6JP = models.BooleanField(blank=True) student1JP = models.BooleanField(blank=True) student2JP = models.BooleanField(blank=True) student3JP = models.BooleanField(blank=True) student4JP = models.BooleanField(blank=True) student5JP = models.BooleanField(blank=True) student6JP = models.BooleanField(blank=True) PercentageA_JP = models.IntegerField(label='What is the likelihood of winning E$110 in the lottery?', min=0, max=100) PercentageB_JP = models.IntegerField(label='What is the likelihood of winning E$110 in the lottery?', min=0, max=100) guess_a_JP = models.IntegerField(min=0, max=100) guess_b_JP = models.IntegerField(min=0, max=100) guess_am_JP = models.IntegerField(min=0, max=100) guess_bm_JP = models.IntegerField(min=0, max=100) belief_a_JP = models.IntegerField() winA_JP = models.IntegerField(default=0) belief_b_JP = models.IntegerField() winB_JP = models.IntegerField(default=0) # FUNCTIONS def creating_session(subsession: Subsession): subsession.group_randomly(fixed_id_in_group=True) def set_winner(group: Group): all_players = group.get_players() for player in all_players: if player.id_in_group in [1, 2]: player.number_JP = choice([100, 90, 75]) elif player.id_in_group in [3, 4]: player.number_JP = choice([95, 80, 65]) else: player.number_JP = choice([85, 70, 60]) chosen_a = [p for p in all_players if p.chosen_betJP == 'A'] chosen_b = [p for p in all_players if p.chosen_betJP == 'B'] top_a = sorted(chosen_a, key=lambda x: x.number_JP, reverse=True)[:2] top_b = sorted(chosen_b, key=lambda x: x.number_JP, reverse=True)[:2] guessa1 = [p for p in all_players if p.chosen_betJP == 'A' or p.id_in_group == 1] guessb1 = [p for p in all_players if p.chosen_betJP == 'B' or p.id_in_group == 1] top_guessa1 = sorted(guessa1, key=lambda x: x.number_JP, reverse=True)[:2] top_guessb1 = sorted(guessb1, key=lambda x: x.number_JP, reverse=True)[:2] guessa2 = [p for p in all_players if p.chosen_betJP == 'A' or p.id_in_group == 2] guessb2 = [p for p in all_players if p.chosen_betJP == 'B' or p.id_in_group == 2] top_guessa2 = sorted(guessa2, key=lambda x: x.number_JP, reverse=True)[:2] top_guessb2 = sorted(guessb2, key=lambda x: x.number_JP, reverse=True)[:2] guessa3 = [p for p in all_players if p.chosen_betJP == 'A' or p.id_in_group == 3] guessb3 = [p for p in all_players if p.chosen_betJP == 'B' or p.id_in_group == 3] top_guessa3 = sorted(guessa3, key=lambda x: x.number_JP, reverse=True)[:2] top_guessb3 = sorted(guessb3, key=lambda x: x.number_JP, reverse=True)[:2] guessa4 = [p for p in all_players if p.chosen_betJP == 'A' or p.id_in_group == 4] guessb4 = [p for p in all_players if p.chosen_betJP == 'B' or p.id_in_group == 4] top_guessa4 = sorted(guessa4, key=lambda x: x.number_JP, reverse=True)[:2] top_guessb4 = sorted(guessb4, key=lambda x: x.number_JP, reverse=True)[:2] guessa5 = [p for p in all_players if p.chosen_betJP == 'A' or p.id_in_group == 5] guessb5 = [p for p in all_players if p.chosen_betJP == 'B' or p.id_in_group == 5] top_guessa5 = sorted(guessa5, key=lambda x: x.number_JP, reverse=True)[:2] top_guessb5 = sorted(guessb5, key=lambda x: x.number_JP, reverse=True)[:2] guessa6 = [p for p in all_players if p.chosen_betJP == 'A' or p.id_in_group == 6] guessb6 = [p for p in all_players if p.chosen_betJP == 'B' or p.id_in_group == 6] top_guessa6 = sorted(guessa6, key=lambda x: x.number_JP, reverse=True)[:2] top_guessb6 = sorted(guessb6, key=lambda x: x.number_JP, reverse=True)[:2] for player in top_a: player.winA_JP = 11 for player in top_b: player.winB_JP = 7 for player in all_players: if player.id_in_group == 1 and player in top_guessa1: player.belief_a_JP = 1 elif player.id_in_group == 2 and player in top_guessa2: player.belief_a_JP = 1 elif player.id_in_group == 3 and player in top_guessa3: player.belief_a_JP = 1 elif player.id_in_group == 4 and player in top_guessa4: player.belief_a_JP = 1 elif player.id_in_group == 5 and player in top_guessa5: player.belief_a_JP = 1 elif player.id_in_group == 6 and player in top_guessa6: player.belief_a_JP = 1 for player in all_players: if player.id_in_group == 1 and player in top_guessb1: player.belief_b = 1 elif player.id_in_group == 2 and player in top_guessb2: player.belief_b = 1 elif player.id_in_group == 3 and player in top_guessb3: player.belief_b = 1 elif player.id_in_group == 4 and player in top_guessb4: player.belief_b = 1 elif player.id_in_group == 5 and player in top_guessb5: player.belief_b = 1 elif player.id_in_group == 6 and player in top_guessb6: player.belief_b = 1 for player in all_players: if player in top_a or player in top_b: player.accept_JP = 'accepted' else: player.accept_JP = 'rejected' def set_payoffs(group: Group): for player in group.get_players(): if player.random_number_JP ==1: player.payoff = player.in_round(1).winA_JP + player.in_round(1).winB_JP elif player.random_number_JP == 2: player.payoff = player.in_round(2).winA_JP + player.in_round(2).winB_JP elif player.random_number_JP == 3: if player.in_round(2).belief_a_JP ==1: player.payoff = player.in_round(2).guess_a_JP else: player.payoff = 100-player.in_round(2).guess_a_JP else: if player.in_round(2).belief_a_JP ==1: player.payoff = player.in_round(2).guess_b_JP else: player.payoff = 100-player.in_round(2).guess_b_JP # PAGES class Start(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 class Intro1(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 class Intro1_1(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 class Intro2(Page): form_model = 'player' form_fields = ['student_1JP', 'student_2JP', 'student_3JP','student_4JP', 'student_5JP', 'student_6JP'] @staticmethod def is_displayed(player: Player): return player.round_number == 1 class WrongA(Page): @staticmethod def is_displayed(player: Player): return player.field_maybe_none('student_1JP')==None or player.field_maybe_none('student_3JP')==None or player.field_maybe_none('student_4JP')==True form_model = 'player' form_fields = ['student_2JP', 'student_5JP', 'student_6JP'] @staticmethod def is_displayed(player: Player): return player.round_number == 1 form_model = 'player' form_fields = ['student_2JP', 'student_5JP', 'student_6JP'] @staticmethod def is_displayed(player: Player): return player.round_number == 1 class WrongB(Page): @staticmethod def is_displayed(player: Player): if player.round_number == 1: return player.field_maybe_none('student_2JP')==0 or player.field_maybe_none('student_5JP')==1 or player.field_maybe_none('student_6JP')==0 form_model = 'player' form_fields = ['student1JP', 'student2JP', 'student3JP','student4JP', 'student5JP', 'student6JP'] class WrongB2(Page): @staticmethod def is_displayed(player: Player): if player.round_number == 1: if player.field_maybe_none('student_2JP')!=1 and player.field_maybe_none( 'student_5JP')!=0 and player.field_maybe_none( 'student_6JP')!=1: return player.field_maybe_none('student1JP') == 0 or player.field_maybe_none( 'student2JP') == 0 or player.field_maybe_none( 'student3JP') == 0 or player.field_maybe_none( 'student4JP') == 1 or player.field_maybe_none( 'student5JP') == 1 or player.field_maybe_none( 'student6JP') == 0 class Intro4_1(Page): form_model = 'player' form_fields = ['PercentageA_JP'] @staticmethod def is_displayed(player: Player): return player.round_number == 1 pass class Intro4wrong(Page): pass @staticmethod def is_displayed(player: Player): if player.round_number == 1: return player.field_maybe_none('PercentageA_JP') != 88 class Intro4wrong2(Page): form_model = 'player' form_fields = ['PercentageB_JP'] @staticmethod def is_displayed(player: Player): if player.round_number == 1: return player.field_maybe_none('PercentageA_JP') != 88 class Intro4wrongRight(Page): @staticmethod def is_displayed(player: Player): if player.round_number == 1: return player.field_maybe_none('PercentageB_JP') == 51 class Intro4wrongWrong(Page): @staticmethod def is_displayed(player: Player): if player.round_number == 1: if player.field_maybe_none('PercentageA_JP') != 88: return player.field_maybe_none('PercentageB_JP') != 51 class Intro4right(Page): @staticmethod def is_displayed(player: Player): if player.round_number == 1: return player.field_maybe_none('PercentageA_JP') == 88 class Intro5(Page): pass @staticmethod def is_displayed(player: Player): return player.round_number == 1 class ChoosingBet(Page): form_model = 'player' form_fields = ['chosen_betJP'] class GuessingA(Page): form_model = 'player' form_fields = ['guess_a_JP','guess_am_JP'] @staticmethod def is_displayed(player: Player): return player.round_number == 2 or player.round_number == 7 class GuessingB(Page): form_model = 'player' form_fields = ['guess_b_JP','guess_bm_JP'] @staticmethod def is_displayed(player: Player): return player.round_number == 2 or player.round_number == 7 class ResultsWaitPage(WaitPage): after_all_players_arrive = 'set_winner' class Results(Page): @staticmethod def vars_for_template(player: Player): group = player.group all_players = group.get_players() top_a = sorted( [p for p in all_players if p.chosen_betJP == 'A'], key=lambda x: x.number_JP, reverse=True)[:2] top_b = sorted( [p for p in all_players if p.chosen_betJP == 'B'], key=lambda x: x.number_JP, reverse=True)[:2] top_guessa1 = sorted( [p for p in all_players if p.chosen_betJP == 'A' or p.id_in_group == 1], key=lambda x: x.number_JP, reverse=True)[:2] top_guessb1 = sorted( [p for p in all_players if p.chosen_betJP == 'B' or p.id_in_group == 1], key=lambda x: x.number_JP, reverse=True)[:2] top_guessa2 = sorted( [p for p in all_players if p.chosen_betJP == 'A' or p.id_in_group == 2], key=lambda x: x.number_JP, reverse=True)[:2] top_guessb2 = sorted( [p for p in all_players if p.chosen_betJP == 'B' or p.id_in_group == 2], key=lambda x: x.number_JP, reverse=True)[:2] top_guessa3 = sorted( [p for p in all_players if p.chosen_betJP == 'A' or p.id_in_group == 3], key=lambda x: x.number_JP, reverse=True)[:2] top_guessb3 = sorted( [p for p in all_players if p.chosen_betJP == 'B' or p.id_in_group == 3], key=lambda x: x.number_JP, reverse=True)[:2] top_guessa4 = sorted( [p for p in all_players if p.chosen_betJP == 'A' or p.id_in_group == 4], key=lambda x: x.number_JP, reverse=True)[:2] top_guessb4 = sorted( [p for p in all_players if p.chosen_betJP == 'B' or p.id_in_group == 4], key=lambda x: x.number_JP, reverse=True)[:2] top_guessa5 = sorted( [p for p in all_players if p.chosen_betJP == 'A' or p.id_in_group == 5], key=lambda x: x.number_JP, reverse=True)[:2] top_guessb5 = sorted( [p for p in all_players if p.chosen_betJP == 'B' or p.id_in_group == 5], key=lambda x: x.number_JP, reverse=True)[:2] top_guessa6 = sorted( [p for p in all_players if p.chosen_betJP == 'A' or p.id_in_group == 6], key=lambda x: x.number_JP, reverse=True)[:2] top_guessb6 = sorted( [p for p in all_players if p.chosen_betJP == 'B' or p.id_in_group == 6], key=lambda x: x.number_JP, reverse=True)[:2] return { 'top_a': top_a, 'top_b': top_b, 'top_guessa1': top_guessa1, 'top_guessb1': top_guessb1, 'top_guessa2': top_guessa2, 'top_guessb2': top_guessb2, 'top_guessa3': top_guessa3, 'top_guessb3': top_guessb3, 'top_guessa4': top_guessa4, 'top_guessb4': top_guessb4, 'top_guessa5': top_guessa5, 'top_guessb5': top_guessb5, 'top_guessa6': top_guessa6, 'top_guessb6': top_guessb6, } pass class Payout1(ResultsWaitPage): after_all_players_arrive = 'set_payoffs' @staticmethod def is_displayed(player: Player): return player.round_number == 11 class Payout(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 11 class Intro3(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): return player.round_number == 1 class Intro3_half(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): return player.round_number == 1 class Intro3_1(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): return player.round_number == 1 class Pose(WaitPage): wait_for_all_groups = True class Number (Page): form_model = 'player' form_fields = ['random_number_JP'] @staticmethod def is_displayed(player: Player): return player.round_number == 11 class Practice1_rev (Page): timeout_seconds = 300 @staticmethod def is_displayed(player: Player): return player.round_number == 1 pass class Practice_start (Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 pass class Demographics(Page): form_model = 'player' form_fields = ['age', 'gender', 'major'] @staticmethod def is_displayed(player: Player): return player.round_number == 11 page_sequence = [Start,Intro1,Intro1_1, Intro2, WrongB, WrongB2, Intro3,Intro3_half,Intro3_1,Intro4_1, Intro4right, Intro4wrong,Intro4wrong2, Intro4wrongRight, Intro4wrongWrong, Practice_start, Practice1_rev, Intro5, GuessingA, GuessingB,ChoosingBet, ResultsWaitPage, Results, Pose, Number,Payout1,Payout]