from otree.api import Currency as c, currency_range from ._builtin import Page, WaitPage from .models import Constants class Introduction(Page): def is_displayed(self): return self.round_number == 1 class SendWaitPage(WaitPage): def after_all_players_arrive(self): pass class Send(Page): """This page is only for P1 P1 sends amount (all, some, or none) to P2 This amount is tripled by experimenter, i.e if sent amount by P1 is 5, amount received by P2 is 15""" form_model = 'player' form_fields = ['sender_allocation', 'sender_expectation'] def is_displayed(self): return self.player.role() != 'distributor' def vars_for_template(self): player = self.group.get_player_by_role('distributor') altruism = player.participant.vars['altruism_measure'] return {'altruism': altruism} class SBSelfWaitPage(WaitPage): pass class SBSelf(Page): def is_displayed(self): return self.player.role() == 'distributor' form_model = 'group' form_fields = ['kept_amount'] def kept_amount_error_message(self, value): group = self.group players = group.get_players() allocations_all = [p.sender_allocation for p in players] allocations_senders = allocations_all[0:3] self.group.total_sender_allocation = sum(allocations_senders) tripled_amount = self.group.total_sender_allocation * Constants.multiplier print('value is', value) if value > tripled_amount: return 'You may not allocate more than {} to yourself'.format(tripled_amount) if value < 0: return 'You may not allocate yourself a negative number' def vars_for_template(self): group = self.group players = group.get_players() allocations_all = [p.sender_allocation for p in players] allocations_senders = allocations_all[0:3] self.group.total_sender_allocation = sum(allocations_senders) tripled_amount = self.group.total_sender_allocation * Constants.multiplier return { 'tripled_amount': tripled_amount, 'prompt': 'Please select an amount from 0 to ' '{} to keep for yourself before redistribution to the senders'.format(tripled_amount)} def before_next_page(self): group = self.group players = group.get_players() allocations_all = [p.sender_allocation for p in players] allocations_senders = allocations_all[0:3] allocation1 = float(allocations_all[0]) allocation2 = float(allocations_all[1]) allocation3 = float(allocations_all[2]) self.group.total_sender_allocation = float(sum(allocations_senders)) total_budget = self.group.total_sender_allocation * Constants.multiplier self.group.send_back_amount1 = (total_budget - self.group.kept_amount) * \ (allocation1 / self.group.total_sender_allocation) self.group.send_back_amount2 = (total_budget - self.group.kept_amount) * \ (allocation2 / self.group.total_sender_allocation) self.group.send_back_amount3 = (total_budget - self.group.kept_amount) * \ (allocation3 / self.group.total_sender_allocation) ''' class SBRemainderWaitPage(WaitPage): pass class SBRemainder(Page): """This page is only for P2 P2 sends back some amount (of the tripled amount received) to P1""" form_model = 'group' form_fields = ['send_back_amount1', 'send_back_amount2', 'send_back_amount3'] def is_displayed(self): return self.player.role() == 'distributor' def vars_for_template(self): group = self.group players = group.get_players() allocations_all = [p.sender_allocation for p in players] allocations_senders = allocations_all[0:3] self.group.total_sender_allocation = sum(allocations_senders) remainder_allocation = (self.group.total_sender_allocation * Constants.multiplier) - self.group.kept_amount return { 'remainder_allocation': remainder_allocation, 'prompt': 'Please an amount from 0 to {}'.format(remainder_allocation)} def error_message(self, values): group = self.group players = group.get_players() allocations_all = [p.sender_allocation for p in players] allocations_senders = allocations_all[0:3] self.group.total_sender_allocation = sum(allocations_senders) tripled_amount = self.group.total_sender_allocation * Constants.endowment print('values is', values) if values["send_back_amount1"] + values["send_back_amount2"] + values["send_back_amount3"] \ != (self.group.total_sender_allocation * Constants.multiplier) - self.group.kept_amount: return 'The numbers must equal {}'.format((self.group.total_sender_allocation * Constants.multiplier) - self.group.kept_amount) def before_next_page(self): print(self.group.send_back_amount1) print(self.group.allocated_amount1) ''' class RoundResultsWaitPage(WaitPage): def after_all_players_arrive(self): pass class RoundResults(Page): def vars_for_template(self): group = self.group players = group.get_players() allocations_all = [p.sender_allocation for p in players] expectations_all = [p.sender_expectation for p in players] if self.player.role() == 'sender 1': sender_allocation = float(allocations_all[0]) allocation_currency = allocations_all[0] sender_kept = Constants.endowment - sender_allocation sender_allocation_all = float(sum(allocations_all[0:3])) total_allocated = sender_allocation_all * Constants.multiplier returned_sender = (total_allocated - self.group.kept_amount) * (sender_allocation/sender_allocation_all) payoff = Constants.endowment - sender_allocation + returned_sender allocated_low = (returned_sender - 10) allocated_high = (returned_sender + 10) e_test = expectations_all[0] if allocated_low <= expectations_all[0] <= allocated_high: e_verdict = 'You have correctly guessed the number of points allocated to you' payoff += c(40) else: e_verdict = 'You have incorrectly guessed the number of points allocated to you' return { 'allocated_low': allocated_low, 'allocated_high': allocated_high, 'e_test': e_test, 'e_verdict': e_verdict, 'total_allocated': total_allocated, 'sender_allocation_all': sender_allocation_all, 'sender_allocation': sender_allocation, 'allocation_currency': allocation_currency, 'sender_kept': sender_kept, 'returned_sender': returned_sender, 'payoff': payoff} elif self.player.role() == 'sender 2': sender_allocation = float(allocations_all[1]) allocation_currency = allocations_all[0] sender_kept = Constants.endowment - sender_allocation sender_allocation_all = float(sum(allocations_all[0:3])) total_allocated = sender_allocation_all * Constants.multiplier returned_sender = (total_allocated - self.group.kept_amount) * (sender_allocation/sender_allocation_all) payoff = Constants.endowment - sender_allocation + returned_sender allocated_low = (returned_sender - 10) allocated_high = (returned_sender + 10) e_test = expectations_all[1] if allocated_low <= expectations_all[1] <= allocated_high: e_verdict = 'You have correctly guessed the number of points allocated to you' payoff += c(40) else: e_verdict = 'You have incorrectly guessed the number of points allocated to you' return { 'allocated_low': allocated_low, 'allocated_high': allocated_high, 'e_test': e_test, 'e_verdict': e_verdict, 'total_allocated': total_allocated, 'sender_allocation_all': sender_allocation_all, 'sender_allocation': sender_allocation, 'allocation_currency': allocation_currency, 'sender_kept': sender_kept, 'returned_sender': returned_sender, 'payoff': payoff} elif self.player.role() == 'sender 3': sender_allocation = float(allocations_all[2]) allocation_currency = allocations_all[0] sender_kept = Constants.endowment - sender_allocation sender_allocation_all = float(sum(allocations_all[0:3])) total_allocated = sender_allocation_all * Constants.multiplier returned_sender = (total_allocated - self.group.kept_amount) * (sender_allocation/sender_allocation_all) payoff = Constants.endowment - sender_allocation + returned_sender allocated_low = (returned_sender - 10) allocated_high = (returned_sender + 10) e_test = expectations_all[2] if allocated_low <= expectations_all[2] <= allocated_high: e_verdict = 'You have correctly guessed the number of points allocated to you' payoff += c(40) else: e_verdict = 'You have incorrectly guessed the number of points allocated to you' return { 'allocated_low': allocated_low, 'allocated_high': allocated_high, 'e_test': e_test, 'e_verdict': e_verdict, 'total_allocated': total_allocated, 'sender_allocation_all': sender_allocation_all, 'sender_allocation': sender_allocation, 'allocation_currency': allocation_currency, 'sender_kept': sender_kept, 'returned_sender': returned_sender, 'payoff': payoff} else: group = self.group players = group.get_players() allocations_all = [p.sender_allocation for p in players] sender_allocation = allocations_all[0:3] total_allocated = sum(sender_allocation) * Constants.multiplier returned_sender = [self.group.allocated_amount1, self.group.allocated_amount3, self.group.allocated_amount3] payoff = self.group.kept_amount return { 'sender_allocation': sender_allocation, 'total_allocated': total_allocated, 'returned_sender': returned_sender, 'payoff': payoff} """ def send_back_amount1_choices(self): group = self.group players = group.get_players() allocations_all = [p.sender_allocation for p in players] allocations_senders = allocations_all[0:2] self.group.total_sender_allocation = sum(allocations_senders) return currency_range(c(0), self.group.total_sender_allocation * Constants.multiplier, c(1)) def send_back_amount2_choices(self): group = self.group players = group.get_players() allocations_all = [p.sender_allocation for p in players] allocations_senders = allocations_all[0:3 ] self.group.total_sender_allocation = sum(allocations_senders) return currency_range(c(0), self.group.total_sender_allocation * Constants.multiplier , c(1)) def send_back_amount3_choices(self): group = self.group players = group.get_players() allocations_all = [p.sender_allocation for p in players] allocations_senders = allocations_all[0:3] self.group.total_sender_allocation = sum(allocations_senders) return currency_range(c(0), self.group.total_sender_allocation * Constants.multiplier, c(1)) """ ''' class SendBack2WaitPage(WaitPage): pass class SendBack2(Page): """This page is only for P2 P2 sends back some amount (of the tripled amount received) to P1""" form_model = 'group' form_fields = ['send_back_amount2'] def is_displayed(self): return self.player.role() == 'distributor' def vars_for_template(self): group = self.group players = group.get_players() allocations_all = [p.sender_allocation for p in players] allocations_senders = allocations_all[0:3] self.group.total_sender_allocation = sum(allocations_senders) allocate_two = (self.group.total_sender_allocation * Constants.multiplier) - self.group.send_back_amount1 return { 'allocate_two': allocate_two, 'prompt': 'Please an amount from 0 to {}'.format(allocate_two)} def send_back_amount2_choices(self): group = self.group players = group.get_players() allocations_all = [p.sender_allocation for p in players] allocations_senders = allocations_all[0:3] self.group.total_sender_allocation = sum(allocations_senders) return currency_range(c(0), (self.group.total_sender_allocation * Constants.multiplier) - self.group.send_back_amount1, c(1)) class SendBack3WaitPage(WaitPage): pass class SendBack3(Page): """This page is only for P2 P2 sends back some amount (of the tripled amount received) to P1""" form_model = 'group' form_fields = ['send_back_amount3'] def is_displayed(self): return self.player.role() == 'distributor' def vars_for_template(self): group = self.group players = group.get_players() allocations_all = [p.sender_allocation for p in players] allocations_senders = allocations_all[0:3] self.group.total_sender_allocation = sum(allocations_senders) allocate_three = ( (self.group.total_sender_allocation * Constants.multiplier) - self.group.send_back_amount1 - self.group.send_back_amount2) return { 'allocate_three': allocate_three, 'prompt': 'Please an amount from 0 to {}'.format(allocate_three)} def send_back_amount3_choices(self): group = self.group players = group.get_players() allocations_all = [p.sender_allocation for p in players] allocations_senders = allocations_all[0:3] self.group.total_sender_allocation = sum(allocations_senders) return currency_range(c(0), (self.group.total_sender_allocation * Constants.multiplier) - self.group.send_back_amount1 - self.group.send_back_amount2, c(1)) ''' class ResultsWaitPage(WaitPage): def after_all_players_arrive(self): self.group.set_payoffs() class Results(Page): """This page displays the earnings of each player""" def is_displayed(self): return self.round_number == self.session.vars['random_max_round'] def vars_for_template(self): payment = self.participant.payoff_plus_participation_fee() return { 'payment': payment, 'paying_round': self.session.vars['paying_round'], 'tripled_amount': self.group.total_sender_allocation * Constants.multiplier } class Survey(Page): def is_displayed(self): return self.round_number == self.session.vars['random_max_round'] form_model = 'player' form_fields = ['survey1', 'survey2', 'survey3'] class Finished(Page): def is_displayed(self): return self.round_number == self.session.vars['random_max_round'] page_sequence = [ SendWaitPage, Send, SBSelfWaitPage, SBSelf, RoundResultsWaitPage, RoundResults, ResultsWaitPage, Results, Survey, Finished ]