from otree.api import * doc = """ Public goods with punishment, roughly based on Fehr & Gaechter 2000. """ class C(BaseConstants): NAME_IN_URL = 'public_goods' PLAYERS_PER_GROUP = 3 NUM_ROUNDS = 10 ENDOWMENT = cu(100) MULTIPLIER = 0.4 class Subsession(BaseSubsession): pass class Group(BaseGroup): tot_contribution = models.CurrencyField() ind_share = models.CurrencyField() class Player(BasePlayer): contribution = models.CurrencyField( min=0, max=C.ENDOWMENT, label="Quanto é que quer investir no projecto comunitário?" ) einverstaendnis = models.BooleanField(choices=[ [True, "Sim"], [False, "Não (não participar)"] ], label='Confirmo que tenho pelo menos 18 anos de idade e que li e compreendi o formulário de consentimento.') def set_payoffs(group: Group): players = group.get_players() contributions = [p.contribution for p in players] group.tot_contribution = sum(contributions) group.ind_share = group.tot_contribution * C.MULTIPLIER for p in players: p.payoff = C.ENDOWMENT - p.contribution + group.ind_share # PAGES class Aufklaerung(Page): form_model = 'player' form_fields = ['einverstaendnis'] @staticmethod def is_displayed(player): return player.round_number == 1 class Contribute(Page): form_model = 'player' form_fields = ['contribution'] timeout_seconds = 180 class Instruktionen(Page): timeout_seconds = 300 @staticmethod def is_displayed(player): return player.round_number == 1 class WaitPage1(WaitPage): after_all_players_arrive = set_payoffs pass class WaitPage2(WaitPage): pass class WaitPage3(WaitPage): pass class Punish(Page): form_model = 'player' timeout_seconds = 120 @staticmethod def vars_for_template(player: Player): return dict( other_players=player.get_others_in_group(), ) class Code(Page): form_model = 'player' @staticmethod def vars_for_template(player): player_1 = player.in_round(1) player_2 = player.in_round(2) player_3 = player.in_round(3) player_4 = player.in_round(4) player_5 = player.in_round(5) player_6 = player.in_round(6) player_7 = player.in_round(7) player_8 = player.in_round(8) player_9 = player.in_round(9) player_10 = player.in_round(10) ges_payoff = player_1.payoff + player_2.payoff + player_3.payoff + player_4.payoff + player_5.payoff + player_6.payoff + player_7.payoff + player_8.payoff + player_9.payoff + player_10.payoff display_payoff = int(ges_payoff) * 43 return dict( ges_payoff=ges_payoff, code=display_payoff ) @staticmethod def is_displayed(player): return player.round_number == 10 class Erinnerung(Page): pass @staticmethod def is_displayed(player): return player.round_number == 1 page_sequence = [ Aufklaerung, Erinnerung, WaitPage2, Instruktionen, Contribute, WaitPage1, Punish, Code]