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' num_rounds = 2 instructions_template = 'school_choice/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): number = models.IntegerField() chosen_bet = models.CharField( choices=[['A', 'Bet A'], ['B', 'Bet B']], widget=widgets.RadioSelect ) guess_a = models.IntegerField(min=0, max=100) guess_b = models.IntegerField(min=0, max=100) # FUNCTIONS def creating_session(subsession: Subsession): subsession.group_randomly(fixed_id_in_group=True) def set_payoffs(group: Group): all_players = group.get_players() for player in all_players: if player.id_in_group in [1, 2]: player.number_JP = choice([5, 10]) elif player.id_in_group in [3, 4]: player.number_JP = choice([7, 12]) else: player.number_JP = choice([10, 15]) 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] if group.subsession.round_number + 1 == Constants.chosen_round: for player in top_a: player.payoff = 10 for player in top_b: player.payoff = 7 elif group.subsession.round_number + 20 == Constants.chosen_round: for player in all_players: if player.id_in_group == 1 and player in top_guessa1: player.payoff = player.guess_a_JP elif player.id_in_group == 2 and player in top_guessa2: player.payoff = player.guess_a_JP elif player.id_in_group == 3 and player in top_guessa3: player.payoff = player.guess_a_JP elif player.id_in_group == 4 and player in top_guessa4: player.payoff = player.guess_a_JP elif player.id_in_group == 5 and player in top_guessa5: player.payoff = player.guess_a_JP elif player.id_in_group == 6 and player in top_guessa6: player.payoff = player.guess_a_JP elif group.subsession.round_number + 40 == Constants.chosen_round: for player in all_players: if player.id_in_group == 1 and player in top_guessb1: player.payoff = player.guess_b_JP elif player.id_in_group == 2 and player in top_guessb2: player.payoff = player.guess_b_JP elif player.id_in_group == 3 and player in top_guessb3: player.payoff = player.guess_b_JP elif player.id_in_group == 4 and player in top_guessb4: player.payoff = player.guess_b_JP elif player.id_in_group == 5 and player in top_guessb5: player.payoff = player.guess_b_JP elif player.id_in_group == 6 and player in top_guessb6: player.payoff = player.guess_b_JP # PAGES class Introduction(Page): pass class ChoosingBet(Page): form_model = 'player' form_fields = ['chosen_bet'] class GuessingA(Page): form_model = 'player' form_fields = ['guess_a'] class GuessingB(Page): form_model = 'player' form_fields = ['guess_b'] class ResultsWaitPage(WaitPage): after_all_players_arrive = 'set_payoffs' 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] return { 'top_a': top_a, 'top_b': top_b, } pass class Payout(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 2 class Intro3(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): return player.round_number == 1 class Pose(WaitPage): wait_for_all_groups = True @staticmethod def is_displayed(player: Player): if player.round_number == 1: return page_sequence = [Introduction, Intro3, GuessingA, GuessingB, ChoosingBet, ResultsWaitPage, Results, Pose]