from otree.api import Currency as c, currency_range from ._builtin import Page, WaitPage from .models import Constants from time import time from random import choice, uniform class FirstWaitPage(WaitPage): group_by_arrival_time = True template_name = 'trust/FirstWaitingPage.html' def is_displayed(self): # After max waiting time has expired mark player as unmatched self.participant.vars.setdefault('start_waiting_for_partners', time()) if self.request: if self.request.method == 'POST': self.participant.vars['unmatched'] = True return True def get_players_for_group(self, waiting_players): for p in waiting_players: p.refresh_from_db() # Move forward unmatched players unmatched = [p for p in waiting_players if p.participant.vars.get('unmatched')] for p in unmatched: p.trust_partner = 'ctrl' if len(unmatched) == 1: return unmatched[:1] elif unmatched: return unmatched[:2] # Group players still waiting for partner(s) still_waiting = [p for p in waiting_players if not p.participant.vars.get('unmatched')] if len(still_waiting) >= 2: return self.subsession.set_partner_based_on_identity(still_waiting, 'trust', 2) def after_all_players_arrive(self): players = self.group.get_players() # Handle potential race condition causing 'unmatched' players to actually be grouped if len(players) > 1: for p in players: if p.participant.vars.get('unmatched'): p.participant.vars.pop('unmatched', None) class TaskTrsInstructions(Page): template_name = 'trust/Instructions.html' timeout_seconds = 60 * 4 def vars_for_template(self): partner_treatment = self.player.trust_partner if partner_treatment == 'name': partner_name = self.player.get_others_in_group()[0].participant.vars['data']['first_name'] self.player.trust_partner_name = partner_name partner = f"The second participant is called {partner_name}." elif partner_treatment == 'same_class': partner = "The second participant is also in your house." elif partner_treatment == 'other_house': partner = "The second participant is from another house." elif partner_treatment == 'other_region': partner = "The second participant comes from another house/section in the Civil Service Academy." else: partner = '' if self.participant.vars.get('is_teacher'): partner = '' return {'partner': partner} def is_displayed(self): # Erase start_waiting_for_partners self.participant.vars.pop('start_waiting_for_partners', None) return True class TaskTrsSend(Page): template_name = 'trust/Send.html' timeout_seconds = 60 form_model = 'player' form_fields = ['trust_send'] def before_next_page(self): if self.participant.vars.get('unmatched'): self.participant.vars['other_sent'] = choice([c//10 for c in range(0, Constants.endowment*10, int(Constants.step*10))]) if self.timeout_happened: self.player.trust_send = choice([c//10 for c in range(0, Constants.endowment*10, int(Constants.step*10))]) self.player.timeout_send = True class TaskTrsSendAfter(Page): template_name = 'trust/Empathy.html' timeout_seconds = 60 form_model = 'player' form_fields = ['empathy'] class ReturnWaitPage(WaitPage): def after_all_players_arrive(self): pass class TaskTrsReturn(Page): template_name = 'trust/Return.html' timeout_seconds = 60 form_model = 'player' form_fields = ['trust_return', 'empathy_self'] def vars_for_template(self): other_sent_tripled = self.player.trust_return_max() return { 'other_sent': other_sent_tripled//Constants.multiplier, 'sent_by_other_tripled': other_sent_tripled } def before_next_page(self): if self.participant.vars.get('unmatched'): self.participant.vars['other_return'] = round(uniform(0, self.player.trust_send * Constants.multiplier), 1) if self.timeout_happened: self.player.trust_return = 0 # TODO: make decision random? self.player.timeout_return = True class ResultsWaitPage(WaitPage): def after_all_players_arrive(self): for p in self.group.get_players(): p.set_payoff() class TaskTrsResults(Page): template_name = 'trust/Results.html' timeout_seconds = 60 def vars_for_template(self): if self.participant.vars.get('unmatched'): other_send = self.participant.vars['other_sent'] other_return = self.participant.vars['other_return'] else: other_send = self.player.other_player().trust_send other_return = self.player.other_player().trust_return return { 'other_send': other_send, 'other_return': other_return } def before_next_page(self): if self.round_number == Constants.num_rounds: self.participant.vars['unmatched'] = False page_sequence = [ FirstWaitPage, TaskTrsInstructions, TaskTrsSend, TaskTrsSendAfter, ReturnWaitPage, TaskTrsReturn, ResultsWaitPage, TaskTrsResults ]