import random from otree.api import * doc = """ Public good experiment with information treatment and survey """ class C(BaseConstants): NAME_IN_URL = 'public_good_treatment' PLAYERS_PER_GROUP = 3 ENDOWMENT = cu(100) MULTIPLIER = 0.7 TREATMENT = ['A', 'B', 'C', 'D'] NUM_ROUNDS = len(TREATMENT) # MAX_NOISE = 10 # BOTS_PER_GROUP = 25 # AGENTS_PER_GROUP = BOTS_PER_GROUP + 1 class Subsession(BaseSubsession): pass def creating_session(subsession: Subsession): if subsession.round_number == 1: subsession.group_randomly() for p in subsession.get_players(): round_numbers = list(range(1, C.NUM_ROUNDS + 1)) random.shuffle(round_numbers) task_rounds = dict(zip(C.TREATMENT, round_numbers)) p.participant.task_rounds = task_rounds #def creating_session(subsession: Subsession): # for p in subsession.get_players(): # for i in range(C.BOTS_PER_GROUP): # MyBot.create(player=p, agent_id=i + 1) class Group(BaseGroup): total_contribution = models.CurrencyField() individual_share = models.CurrencyField() class Player(BasePlayer): age = models.IntegerField( label='How old are you?', max=100, min=16, ) gender = 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, ) wtp = models.StringField( label='Would you spend some of your income in order to prevent environmental pollution?', choices=['Strongly agree', 'Agree', 'Neither agree nor disagree', 'Disagree', 'Strongly Disagree'], widget=widgets.RadioSelect, ) personality = models.StringField( label='How similar are you to a person who cares greatly about nature and the environment?', choices=['Very similar', 'Similar', 'Somewhat similar', 'Hardly similar', 'Not similar', 'Not similar at all'], widget=widgets.RadioSelect, ) perc_wtp = models.IntegerField( min=0, max=100, label='Out of 100 people in Austria, how many do you think will do without some of their income in order to save nature and the environment?' ) perc_personality = models.IntegerField( min=0, max=100, label='Out of 100 people in Austria, how many stated that they are similar to a person, who cares greatly about nature and the environmnent?' ) contribution = models.CurrencyField( min=0, max=C.ENDOWMENT, label='With the above dilemma in mind, how much would you be willing to contribute?', ) control = models.StringField ( label='Is that correct?', choices=['Yes', 'No'], widget=widgets.RadioSelect, ) descriptive = models.StringField ( label='Is that correct?', choices=['Yes', 'No'], widget=widgets.RadioSelect, ) injunctive = models.StringField ( label='Is that correct?', choices=['Yes', 'No'], widget=widgets.RadioSelect, ) combined = models.StringField ( label='Is that correct?', choices=['Yes', 'No'], widget=widgets.RadioSelect, ) adaption = models.StringField( label='Making the consequences of climate change more bearable' ' (e.g., by installing an air conditioning system) is referred to as adaption?', choices=['True', 'False'], widget=widgets.RadioSelect, ) mitigation = models.StringField( label='Is addressing the root causes of climate change' ' (e.g., by improving the energy efficiency of a building) referred to as mitigation?', choices=['True', 'False'], widget=widgets.RadioSelect, ) #agent_id = models.IntegerField(initial=1) #group_total_contribution = models.CurrencyField() #group_individual_share = models.CurrencyField() #class MyBot(ExtraModel): # player = models.Link(Player) # contribution = models.CurrencyField( # min=0, # max=C.ENDOWMENT, # label='With the above dilemma in mind, how much would you be willing to contribute?', #) #payoff = models.CurrencyField() #agent_id = models.IntegerField() # FUNCTIONS #def generate_contrib(mean): # import random # contribution = mean + random.randint(-C.MAX_NOISE, C.MAX_NOISE) # return max(0, min(contribution, C.ENDOWMENT)) #def get_agents(player: Player): # return [player] + MyBot.filter(player=player) #def set_payoffs(player: Player): # bots = MyBot.filter(player=player) # mean = C.ENDOWMENT/2 # for bot in bots: # bot.contribution = generate_contrib(mean) #agents = bots + [player] #contributions = [p.contribution for p in agents] #player.group_total_contribution = sum(contributions) #player.group_individual_share = ( # player.group_total_contribution*C.MULTIPLIER/C.AGENTS_PER_GROUP #) #for ag in agents: # ag.payoff = C.ENDOWMENT - ag.contribution + player.group_individual_share def set_payoffs(group: Group): players = group.get_players() contributions = [p.contribution for p in players] group.total_contribution = sum(contributions) group.individual_share = ( group.total_contribution * C.MULTIPLIER / C.PLAYERS_PER_GROUP ) for p in players: p.payoff = C.ENDOWMENT - p.contribution + group.individual_share #def set_payoffs(player): # N = 50 # player.total_contribution = C.TOTAL_CONTRIBUTION # player.individual_share = ( # C.TOTAL_CONTRIBUTION*C.MULTIPLIER/N #) #player.payoff=C.ENDOWMENT-player.contribution+player.individual_share #def set_payoffs(player: Player): # player.players = 50 # # player.total_contribution = 25705 # player.individual_share = ( # player.total_contribution * C.MULTIPLIER / player.players #) #for p in players: # p.payoff = C.ENDOWMENT - p.contribution + player.individual_share # PAGES class Agreement(Page): form_model = 'player' #form_fields = [] @staticmethod def is_displayed(player: Player): return player.round_number == 1 class Survey(Page): form_model = 'player' form_fields = ['age', 'gender', 'wtp', 'personality'] @staticmethod def is_displayed(player: Player): return player.round_number == 1 class Perceptions(Page): form_model = 'player' form_fields = ['perc_wtp', 'perc_personality'] @staticmethod def is_displayed(player: Player): return player.round_number == 1 class Info1(Page): form_model = 'player' form_fields = ['control'] @staticmethod def is_displayed(player: Player): if player.round_number == 1: participant = player.participant return player.round_number == participant.task_rounds['A'] else: pass class Info2(Page): form_model = 'player' form_fields = ['descriptive'] @staticmethod def is_displayed(player: Player): if player.round_number == 1: participant = player.participant return player.round_number == participant.task_rounds['B'] else: pass class Info3(Page): form_model = 'player' form_fields = ['injunctive'] @staticmethod def is_displayed(player: Player): if player.round_number == 1: participant = player.participant return player.round_number == participant.task_rounds['C'] else: pass class Info4(Page): form_model = 'player' form_fields = ['combined'] @staticmethod def is_displayed(player: Player): if player.round_number == 1: participant = player.participant return player.round_number == participant.task_rounds['D'] else: pass class Description(Page): form_model = 'player' form_fields = ['mitigation'] @staticmethod def is_displayed(player: Player): return player.round_number == 1 class Contribution(Page): form_model = 'player' form_fields = ['contribution'] #@staticmethod #def before_next_page(player:Player, timeout_happened): # set_payoffs(player) def is_displayed(player: Player): return player.round_number == 1 #class WaitForBots(Page): # @staticmethod # def get_timeout_seconds(player: Player): # return random.randint(1, 5) #def is_displayed(player: Player): # return player.round_number == 1 # @staticmethod # def is_displayed(player: Player): # return player.round_number == 1 class ResultsWaitPage(WaitPage): after_all_players_arrive = set_payoffs @staticmethod def is_displayed(player: Player): return player.round_number == 1 class Results(Page): @staticmethod #def vars_for_template(player: Player): # return dict(agents=get_agents(player)) def is_displayed(player: Player): return player.round_number == 1 page_sequence = [Agreement, Survey, Perceptions, Info1, Info2, Info3, Info4, Description, Contribution, ResultsWaitPage, Results]