from otree.api import Currency as c, currency_range from ._builtin import Page, WaitPage from .models import Constants import random class SendWaitPage(WaitPage): wait_for_all_groups = True def after_all_players_arrive(self): self.subsession.dice = random.randint(1, 3) print('this round the dice is', self.subsession.dice) if self.subsession.dice == 3: self.session.vars['first_max_round'] = self.subsession.round_number print('the final round is', self.session.vars['first_max_round']) self.session.vars['paying_round1'] = random.randint(1, self.session.vars['first_max_round']) print('the first payment round is', self.session.vars['paying_round1']) 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' 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): allocations = [] players = self.player.get_others_in_group() for p in players: allocations.append(p.sender_allocation) print(allocations) self.group.total_sender_allocation = sum(allocations) 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} class Dice(Page): def vars_for_template(self): return {'dice': self.subsession.dice} class ShuffleWaitPage(WaitPage): def is_displayed(self): if self.subsession.dice == 3: return True else: return False def after_all_players_arrive(self): self.group.set_payoffs() class Shuffle(Page): def is_displayed(self): if self.subsession.dice == 3: return True else: return False def app_after_this_page(self, upcoming_apps): print('upcoming_apps is', upcoming_apps) if self.subsession.dice == 3: return "multi_trust_proportionNI2" page_sequence = [ SendWaitPage, Send, SBSelfWaitPage, SBSelf, RoundResultsWaitPage, RoundResults, Dice, ShuffleWaitPage, Shuffle, ]