from otree.api import * import random doc = """ This app is to be used with the Groups of 3 Participants, with a Supervisor. """ class C(BaseConstants): NAME_IN_URL = 'l_3' PLAYERS_PER_GROUP = 3 NUM_ROUNDS = 3 WORKER_1_ROLE = 'worker_1' SUPERVISOR_ROLE = 'supervisor' WORKER_2_ROLE = 'worker_2' class Subsession(BaseSubsession): pass class Group(BaseGroup): total_claims_group = models.IntegerField(initial=0) collective_sanction = models.BooleanField(initial=False) success_probability = models.FloatField(initial=0.00) payoff_round_part_1 = models.IntegerField(initial=0) supervisor_message = models.IntegerField(min=1, max=6, blank=True) class Player(BasePlayer): zeroth_roll_report = models.IntegerField(min=1, max=6,) first_roll_report = models.IntegerField(min=1, max=6,) second_roll_report = models.IntegerField(min=1, max=6,) third_roll_report = models.IntegerField(min=1, max=6,) payoff_for_round = models.IntegerField(initial=0) total_claims_participant = models.IntegerField(initial=0) quiz_status = models.BooleanField(initial=False) estimation_roll_1 = models.FloatField(decimal_places=2, label="What percentage of participants do you think reported 1 as their die roll outcome?") estimation_roll_2 = models.FloatField(decimal_places=2, label="What percentage of participants do you think reported 2 as their die roll outcome?") estimation_roll_3 = models.FloatField(decimal_places=2, label="What percentage of participants do you think reported 3 as their die roll outcome?") estimation_roll_4 = models.FloatField(decimal_places=2, label="What percentage of participants do you think reported 4 as their die roll outcome?") estimation_roll_5 = models.FloatField(decimal_places=2, label="What percentage of participants do you think reported 5 as their die roll outcome?") estimation_roll_6 = models.FloatField(decimal_places=2, label="What percentage of participants do you think reported 6 as their die roll outcome?") # PAGES class welcome(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 and player.quiz_status == False class quiz_page(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 and player.quiz_status == False @staticmethod def before_next_page(player: Player, timeout_happened): player.quiz_status = True class part_1_welcome(Page): @staticmethod def is_displayed(player): return player.round_number == 1 class round_0_page(Page): form_model = "player" form_fields = ['zeroth_roll_report', ] @staticmethod def is_displayed(player): return player.round_number == 1 class estimation_report(Page): form_model = "player" form_fields = ['estimation_roll_1', 'estimation_roll_2', 'estimation_roll_3', 'estimation_roll_4', 'estimation_roll_5', 'estimation_roll_6', ] @staticmethod def error_message(player: Player, values): estimation_total = values['estimation_roll_1'] + values['estimation_roll_2'] + values['estimation_roll_3'] + \ values['estimation_roll_4'] + \ values['estimation_roll_5'] + values['estimation_roll_6'] print(estimation_total) if estimation_total != 100.00: return 'Your total is not 100.00%' @staticmethod def is_displayed(player): return player.round_number == 1 class results_round_0(Page): @staticmethod def vars_for_template(player: Player): zeroth_roll_payoff = (player.zeroth_roll_report) return{ 'zeroth_roll_report': player.zeroth_roll_report, 'zeroth_roll_payoff': zeroth_roll_payoff, } @staticmethod def is_displayed(player): return player.round_number == 1 class message_instructions_supervisor(Page): @staticmethod def is_displayed(player): return player.round_number == 1 and player.role == 'supervisor' class message_instructions_worker(Page): @staticmethod def is_displayed(player): return player.round_number == 1 and (player.role == 'worker_1' or player.role == 'worker_2') class message_sender_supervisor(Page): form_model = "group" form_fields = ['supervisor_message', ] @staticmethod def is_displayed(player): return player.role == 'supervisor' class message_receiver_worker(Page): @staticmethod def is_displayed(player): return not(player.role == 'supervisor') def vars_for_template(player: Player): try: if player.group.supervisor_message: supervisor_message = player.group.supervisor_message else: supervisor_message = 0 except: supervisor_message = 0 return { 'supervisor_message': supervisor_message } class wait_for_message(WaitPage): template_name = "l_3/wait_for_message.html" def is_displayed(player): return not(player.role == 'supervisor') class wait_for_round(WaitPage): template_name = "l_3/wait_for_message.html" class part_2_welcome(Page): @staticmethod def is_displayed(player): return player.round_number == 1 class round_1_page(Page): form_model = "player" form_fields = ['first_roll_report', ] class round_2_page(Page): form_model = "player" form_fields = ['second_roll_report', ] class round_3_page(Page): form_model = "player" form_fields = ['third_roll_report', ] class ResultsWaitPage(WaitPage): @staticmethod def after_all_players_arrive(group: Group): players_list = group.get_players() player_1 = players_list[0] player_2 = players_list[1] player_3 = players_list[2] player_1_total = player_1.first_roll_report + \ player_1.second_roll_report + player_1.third_roll_report player_2_total = player_2.first_roll_report + \ player_2.second_roll_report + player_2.third_roll_report player_3_total = player_3.first_roll_report + \ player_3.second_roll_report + player_3.third_roll_report group.total_claims_group = player_1_total + player_2_total + player_3_total if group.total_claims_group >= 36: group.collective_sanction = True group.success_probability = round(random.uniform(0, 1), 4) if group.success_probability > 0.6: player_1.payoff_for_round = player_1_total player_2.payoff_for_round = player_2_total player_3.payoff_for_round = player_3_total elif group.success_probability <= 0.6: player_1.payoff_for_round = 0 player_2.payoff_for_round = 0 player_3.payoff_for_round = 0 else: group.collective_sanction = False player_1.payoff_for_round = player_1_total player_2.payoff_for_round = player_2_total player_3.payoff_for_round = player_3_total if group.round_number == 3: group.payoff_round_part_1 = random.randint(1, 3) class Results(Page): @staticmethod def vars_for_template(player: Player): player_payoff_round = player.payoff_for_round player.total_claims_participant = player.total_claims_participant + player_payoff_round player.zeroth_roll_report = player.in_round(1).zeroth_roll_report if player.round_number == 3: payoff_temp = player.group.payoff_round_part_1 part_1_payoff = player.in_round( payoff_temp).total_claims_participant player.payoff = player.in_round( payoff_temp).total_claims_participant + player.zeroth_roll_report player.participant.part_0_payoff = player.zeroth_roll_report player.participant.part_1_payoff = part_1_payoff player.participant.part_1_payoff_round = player.group.payoff_round_part_1 return { 'player_payoff_round': player_payoff_round, } page_sequence = [welcome, quiz_page, part_1_welcome, round_0_page, estimation_report, results_round_0, part_2_welcome, message_instructions_supervisor, message_instructions_worker, message_sender_supervisor, wait_for_message, message_receiver_worker, wait_for_round, round_1_page, round_2_page, round_3_page, ResultsWaitPage, Results, ]