from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) from ._builtin import Page, WaitPage from statistics import mean class C(BaseConstants): NAME_IN_URL = 'public_goods_simple' PLAYERS_PER_GROUP = 3 NUM_ROUNDS = 1 ENDOWMENT= c(10) MULTIPLIER = 2 class Subsession(BaseSubsession): pass class Group(BaseGroup): total_contribution = models.CurrencyField() individual_share = models.CurrencyField() average_contribution = models.CurrencyField() # FUNCTIONS def set_payoffs(group): players = group.get_players() contributions = [p.contribution for p in players] group.total_contribution = sum(contributions) group.average_contribution = group.total_contribution / len(group.get_players()) 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 class Player(BasePlayer): question1 = models.IntegerField(label="How many rounds are there in this game?") question2 = models.IntegerField(label=" What is the multiplier used in this game?") question3 = models.IntegerField(label ="What is an endowment in this game?") contribution = models.CurrencyField(min=0, max=C.ENDOWMENT, label='How much do you want to contribute?') class Instructions(Page): pass class Contribute1(Page): form_model = 'player' form_fields = ['contribution'] class Contribute2(Page): form_model = 'player' form_fields = ['contribution'] class Contribute3(Page): form_model = 'player' form_fields = ['contribution'] class Contribute4(Page): form_model = 'player' form_fields = ['contribution'] class Contribute5(Page): form_model = 'player' form_fields = ['contribution'] class UnderstandingCheck(Page): form_model = 'player' form_fields = ['question1', 'question2', 'question3'] def error_message(self, values): if values['question1'] != 5 or values['question2'] != 2 or values[ 'question3'] != 10: return 'One or more of your answers is incorrect. Please make sure you understand the instructions before proceeding.' class ResultsWaitPage1 (WaitPage): def after_all_players_arrive(group): group.set_payoffs() body_text = 'Waiting for other participants to contribute.' class ResultsWaitPage2 (WaitPage): def after_all_players_arrive(group): group.set_payoffs() body_text = 'Waiting for other participants to contribute.' class ResultsWaitPage3(WaitPage): def after_all_players_arrive(group): group.set_payoffs() body_text = 'Waiting for other participants to contribute.' class ResultsWaitPage4 (WaitPage): def after_all_players_arrive(group): group.set_payoffs() body_text = 'Waiting for other participants to contribute.' class ResultsWaitPage5 (WaitPage): def after_all_players_arrive(group): group.set_payoffs() body_text = 'Waiting for other participants to contribute.' class Results_Round1(Page): pass class Results_Round2(Page): pass class Results_Round3(Page): pass class Results_Round4(Page): pass class Results_Round5(Page): pass class Survey(Page): q1 = models.TextField() q2 = models.TextField() q3 = models.CharField(max_length=1) q4 = models.CharField(max_length=3) q5 = models.CharField(max_length=3) page_sequence = [ Instructions, UnderstandingCheck, Contribute1, ResultsWaitPage1, Results_Round1, Contribute2, ResultsWaitPage2, Results_Round2, Contribute3, ResultsWaitPage3, Results_Round3, Contribute4, ResultsWaitPage4, Results_Round4, Contribute5, ResultsWaitPage5, Results_Round5, Survey ]