from otree.api import * c = cu doc = '' class C(BaseConstants): NAME_IN_URL = 'Experiment' PLAYERS_PER_GROUP = 3 NUM_ROUNDS = 10 MANAGER_ROLE = 'Manager' WORKER_A_ROLE = 'Worker_A' WORKER_B_ROLE = 'Worker_B' class Subsession(BaseSubsession): pass class Start(WaitPage): @staticmethod def creating_session(subsession): subsession.group_randomly(fixed_id_in_group=True) form_model = 'player' @staticmethod def is_displayed(player): return player.round_number != 1 class GroupAssignment(WaitPage): group_by_arrival_time = True form_model = 'player' body_text = "Please wait for your group assignment" @staticmethod def is_displayed(player): return player.round_number == 1 class Group(BaseGroup): manager_compensation = models.IntegerField(min=60, max=100, label='') worker_a_effort = models.IntegerField(min=1, max=10, label='') worker_b_effort = models.IntegerField(min=1, max=10, label='') is_bad_data = models.BooleanField(initial=False) def set_payoffs(group: Group): manager = group.get_player_by_role(C.MANAGER_ROLE) worker_a = group.get_player_by_role(C.WORKER_A_ROLE) worker_b = group.get_player_by_role(C.WORKER_B_ROLE) manager.payoff = 100 + 4 * (group.worker_a_effort + group.worker_b_effort) - group.manager_compensation worker_a.payoff = group.manager_compensation / 2 - group.worker_a_effort worker_b.payoff = group.manager_compensation / 2 - group.worker_b_effort class Player(BasePlayer): should_pay = models.BooleanField(initial=True) class Role(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): return player.round_number == 1 class ManagerSelection(Page): form_model = 'group' form_fields = ['manager_compensation'] timeout_seconds = 35 timer_text = 'Please do not drop' @staticmethod def is_displayed(player: Player): return player.role == C.MANAGER_ROLE @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group if timeout_happened: group.is_bad_data = True player.should_pay = False player.group.manager_compensation = 80 class WorkerWait(WaitPage): title_text = 'Wait for manager selection' body_text = 'Please wait for manager to finish.' @staticmethod def is_displayed(player: Player): return player.role == C.WORKER_A_ROLE or player.role == C.WORKER_B_ROLE class WorkerASelection(Page): form_model = 'group' form_fields = ['worker_a_effort'] timeout_seconds = 35 timer_text = 'Please do not drop out of the experiment' @staticmethod def is_displayed(player: Player): return player.role == C.WORKER_A_ROLE @staticmethod def vars_for_template(player: Player): session = player.session group = player.group participant = player.participant if player.id_in_group % 2: other_worker = player.group.get_player_by_id(2) else: other_worker = player.group.get_player_by_id(3) return dict( show_choice = session.config['show_choice'], is_high_dimra = player.group.get_player_by_role(C.WORKER_B_ROLE).participant.is_high_dimra, wage = player.group.manager_compensation / 2, other_id=other_worker.participant.id_in_session ) @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group if timeout_happened: group.is_bad_data = True player.should_pay = False player.group.worker_a_effort = 5 class WorkerBSelection(Page): form_model = 'group' form_fields = ['worker_b_effort'] timeout_seconds = 35 timer_text = 'Please do not drop out of the experiment' @staticmethod def is_displayed(player: Player): return player.role == C.WORKER_B_ROLE @staticmethod def vars_for_template(player: Player): session = player.session group = player.group participant = player.participant if player.id_in_group % 2: other_worker = player.group.get_player_by_id(2) else: other_worker = player.group.get_player_by_id(3) return dict( show_choice = session.config['show_choice'], is_high_dimra = player.group.get_player_by_role(C.WORKER_B_ROLE).participant.is_high_dimra, wage = player.group.manager_compensation / 2, other_id=other_worker.participant.id_in_session ) @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group if timeout_happened: group.is_bad_data = True player.should_pay = False player.group.worker_b_effort = 5 class ManagerWait(WaitPage): title_text = 'Wait for worker selection' body_text = 'Please wait for workers to finsh.' @staticmethod def is_displayed(player: Player): return player.role == C.MANAGER_ROLE class PayoffCalculation(WaitPage): after_all_players_arrive = set_payoffs # class FinalPayoff(WaitPage): # wait_for_all_groups = True # after_all_players_arrive = set_final_payoffs # @staticmethod # def is_displayed(player: Player): # return player.round_number == C.NUM_ROUNDS class PayoffWait(WaitPage): @staticmethod def after_all_players_arrive(group:Group): for player in group.get_players(): all_rounds = player.in_all_rounds() should_pay = True for p in all_rounds: if not p.should_pay: should_pay = False break first_payoff = 23 if player.participant.is_high_dimra else 27 import random player.participant.payoff = random.choice(all_rounds).payoff + first_payoff if should_pay else 0 @staticmethod def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS class Part2End(Page): pass page_sequence = [GroupAssignment, Role, ManagerSelection, WorkerWait, WorkerASelection, WorkerBSelection, ManagerWait, PayoffCalculation, PayoffWait]