from otree.api import * doc = """ Simple trust game """ totalAmountP1 = [] totalAmountP2 = [] class C(BaseConstants): NAME_IN_URL = 'trust_simple' PLAYERS_PER_GROUP = 2 NUM_ROUNDS = 5 ENDOWMENT = cu(10) MULTIPLIER = 3 INSTRUCTIONS_TEMPLATE = 'trust_simple/instructions.html' class Subsession(BaseSubsession): pass class Group(BaseGroup): sent_amount = models.CurrencyField( min=cu(0), max=C.ENDOWMENT, doc="""Amount sent by P1""", label="How much do you want to send to participant B?", ) sent_back_amount = models.CurrencyField( doc="""Amount sent back by P2""", label="How much do you want to send back?" ) gender = models.StringField( choices=[['Male', 'Male'], ['Female', 'Female']], label='Please indicate your gender', widget=widgets.RadioSelect, ) age = models.StringField( choices=[['Under 18', 'Under 18'], ['18 - 25', '18 - 25'], ['25 - 45', '25 - 45'], ['45 more', '45 more']], label='Please indicate your age:', widget=widgets.RadioSelect, ) hea = models.StringField( choices=[['High school diploma', 'High school diploma'], ['Bachelor\'s Degree', 'Bachelor\'s Degree'], ['Master\'s Degree', 'Master\'s Degree'], ['College/Vacational Training', 'College/Vacational Training']], label='What is your highest educational attainment?', widget=widgets.RadioSelect, ) desiredEndowments = models.StringField( label=''' What motivated you to share your endowments?''' ) nonDesiredEndowments = models.StringField( label=''' What motivated you to not share your endowments?''' ) MIN_SENT = models.FloatField(doc="Min amount sent by Participant A") MIN_SENT_BACK = models.FloatField(doc="Min amount sent back by Participant B") if len(totalAmountP1) == 0: AVERAGE_ONE = models.FloatField(initial=0) else: AVERAGE_ONE = models.FloatField(initial=(sum(totalAmountP1) / len(totalAmountP1))) if len(totalAmountP2) == 0: AVERAGE_TWO = models.FloatField(initial=0) else: AVERAGE_TWO = models.FloatField(initial=(sum(totalAmountP2) / len(totalAmountP2))) class Player(BasePlayer): answer1 = models.IntegerField(label="What is the initial endowment of participant A?") answer2 = models.IntegerField(label="What amount will participant B receive, if participant A decides to share 10 somoni?") answer3 = models.IntegerField(label="If participant B received 30 and decides to give back half of it, how much will participant A receive?") answer4 = models.IntegerField(label="How many people does our group have?") pass # FUNCTIONS def sent_back_amount_choices(group: Group): return currency_range(0, group.sent_amount * C.MULTIPLIER, 1) def set_payoffs(group: Group): global totalAmountP1, totalAmountP2 p1 = group.get_player_by_id(1) p2 = group.get_player_by_id(2) p1.payoff = C.ENDOWMENT - group.sent_amount + group.sent_back_amount p2.payoff = group.sent_amount * C.MULTIPLIER - group.sent_back_amount totalAmountP1.append(group.sent_amount) totalAmountP2.append(group.sent_back_amount) group.MIN_SENT = min(group.field_maybe_none('MIN_SENT'), int(group.sent_amount)) if group.field_maybe_none('MIN_SENT') else int(group.sent_amount) group.MIN_SENT_BACK = min(group.field_maybe_none('MIN_SENT_BACK'), int(group.sent_back_amount)) if group.field_maybe_none('MIN_SENT_BACK') else int(group.sent_back_amount) group.AVERAGE_ONE = float(sum(totalAmountP1) / len(totalAmountP1)) group.AVERAGE_TWO = float(sum(totalAmountP2) / len(totalAmountP2)) # PAGES class SeparateInstructions(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 class Understanding_Questions(Page): form_model = 'player' form_fields = ['answer1', 'answer2', 'answer3', 'answer4'] def error_message(self, values): solutions = dict(answer1=10, answer2=30, answer3=15, answer4=3) if values != solutions: return 'One or more answers were incorrect.' def is_displayed(player): return player.round_number == 1 class Send(Page): form_model = 'group' form_fields = ['sent_amount'] @staticmethod def is_displayed(player: Player): return player.id_in_group == 1 class WaitForP1(WaitPage): pass class SendBack(Page): form_model = 'group' form_fields = ['sent_back_amount'] @staticmethod def is_displayed(player: Player): return player.id_in_group == 2 @staticmethod def vars_for_template(player: Player): group = player.group return dict(tripled_amount=group.sent_amount * C.MULTIPLIER) class ResultsWaitPage(WaitPage): after_all_players_arrive = set_payoffs class Results(Page): pass class Results_Questions(Page): def is_displayed(player): return player.round_number == 1 pass class Survey(Page): form_model = 'group' form_fields = ['gender', 'age', 'hea', 'desiredEndowments', 'nonDesiredEndowments'] def is_displayed(self): return self.subsession.round_number == 5 page_sequence = [SeparateInstructions, Understanding_Questions, Results_Questions, Send, WaitForP1, SendBack, ResultsWaitPage, Results, Survey]