import random from otree.api import * # Trying to fix plates here author = 'Gabriel Pensamiento' doc = """ Main Task of the Social Audit experiment. """ class C(BaseConstants): NAME_IN_URL = 'Task1' PLAYERS_PER_GROUP = 4 NUM_ROUNDS = 6 # Auditor 1 Group ID is 1 AUDITORX_ROLE = 'Auditor X' # Firm 1 Group ID is 2 Firm1_ROLE = '1st Firm' AUDITORY_ROLE = 'Auditor Y' Firm2_ROLE = '2nd Firm' # oTree automatically assigns each role to a different player sequentially by id_in_group, # so all Auditors are odd and all Firms are even BROKENA = 20 BROKENB = 50 TPLATES = 100 UNBROKENA = TPLATES - BROKENA UNBROKENB = TPLATES - BROKENB chance = 5 MAXDICE = 100/chance INSTRUCTIONS_TEMPLATE = 'Task1/instructions.html' # Initial amount allocated to each player ENDOWMENT_AUDITOR = cu(60) endowment_auditor = 60 AUDIT_COST = cu(50) audit_cost = 50 AUDIT_FEE = cu(60) audit_fee = 60 AUDIT_PENALTY = cu(25) audit_penalty = 25 RIGHT_BELIEF = cu(20) right_belief = 20 ENDOWMENT_FIRM = cu(70) endowment_firm = 70 RECEIVES = ENDOWMENT_FIRM+AUDIT_FEE REWARD_FIRM = cu(25) reward_firm = 25 ENDOWMENT_NPO = cu(30) endowment_npo = 30 REWARD_NPO = cu(25) reward_npo = 25 PENALTY_NPO = cu(25) penalty_npo = 25 NPO = ['HumanRightsWatch', 'CARE'] #chatGPT generated to make groups according to group assignments class Subsession(BaseSubsession): pass def creating_session(Subsession): import random paying_round = random.randint(1, C.NUM_ROUNDS) r_1 = random.randint(1, 100) r_2 = random.randint(1, 100) dice = random.randint(1, C.MAXDICE) AORDER = [1, 2] FORDER = [1, 2] session = Subsession.session # must also change Treatment value in Task1 and in SurveyandResults session.vars['Treatment'] = 'P' session.vars['Type'] = 'Heroku' #Heroku or Lab session.vars['r_1'] = r_1 session.vars['r_2'] = r_2 session.vars['dice'] = dice session.vars['paying_round'] = paying_round session.vars['AORDER'] = AORDER session.vars['FORDER'] = FORDER session.vars['PLATES'] = [1, 0, 1, 1, 0, 1, 1, 1] random.shuffle(session.vars['PLATES']) #def group_by_arrival_time_method(subsession: Subsession, waiting_players): # session = subsession.session class ShuffleWaitPage(WaitPage): wait_for_all_groups = True @staticmethod def after_all_players_arrive(subsession): session = subsession.session num_participants = session.num_participants if num_participants == 12: if subsession.round_number == 1: new_structure = [[1, 7, 4, 12], [5, 8, 2, 10], [3, 9, 6, 11]] if subsession.round_number == 2: new_structure = [[5, 11, 1, 8], [2, 12, 6, 9], [4, 10, 3, 7]] if subsession.round_number == 3: new_structure = [[6, 9, 1, 11], [2, 7, 4, 10], [3, 8, 5, 12]] if subsession.round_number == 4: new_structure = [[1, 10, 4, 7], [5, 11, 2, 8], [6, 12, 3, 9]] if subsession.round_number == 5: new_structure = [[1, 8, 5, 10], [6, 9, 2, 12], [3, 11, 4, 7]] if subsession.round_number == 6: new_structure = [[6, 12, 1, 9], [2, 7, 4, 11], [5, 10, 3, 8]] # else: # subsession.group_randomly() subsession.set_group_matrix(new_structure) if num_participants == 16: if subsession.round_number == 1: new_structure = [[1, 9, 8, 16], [7, 10, 2, 15], [3, 11, 6, 14], [4, 12, 5, 13]] if subsession.round_number == 2: new_structure = [[7, 13, 1, 10], [2, 14, 6, 11], [5, 12, 3, 9], [8, 16, 4, 15]] if subsession.round_number == 3: new_structure = [[6, 16, 1, 11], [2, 9, 5, 12], [3, 10, 8, 14], [4, 15, 7, 13]] if subsession.round_number == 4: new_structure = [[1, 15, 5, 9], [8, 13, 2, 10], [7, 16, 3, 11], [6, 14, 4, 12]] if subsession.round_number == 5: new_structure = [[1, 10, 8, 14], [7, 11, 2, 16], [3, 9, 6, 12], [4, 15, 5, 13]] if subsession.round_number == 6: new_structure = [[7, 11, 1, 15], [2, 12, 6, 9], [5, 13, 3, 10], [8, 14, 4, 16]] # else: # subsession.group_randomly() subsession.set_group_matrix(new_structure) if num_participants == 20: if subsession.round_number == 1: new_structure = [1, 11, 9, 19], [8, 12, 2, 18], [3, 13, 7, 17], [4, 14, 6, 16], [10, 20, 5, 15] if subsession.round_number == 2: new_structure = [8, 18, 1, 12], [2, 17, 7, 13], [6, 14, 3, 11], [5, 15, 4, 20], [10, 16, 9, 19] if subsession.round_number == 3: new_structure = [7, 17, 1, 13], [2, 11, 6, 14], [3, 12, 5, 15], [4, 20, 10, 16], [9, 19, 8, 18] if subsession.round_number == 4: new_structure = [1, 16, 6, 11], [5, 15, 2, 12], [10, 20, 3, 13], [9, 19, 4, 14], [7, 17, 8, 18] if subsession.round_number == 5: new_structure = [1, 12, 5, 15], [10, 13, 2, 20], [3, 11, 9, 14], [4, 18, 8, 17], [6, 19, 7, 16] if subsession.round_number == 6: new_structure = [10, 13, 1, 20], [2, 14, 9, 11], [8, 18, 3, 12], [7, 16, 4, 19], [5, 15, 6, 17] # else: # subsession.group_randomly() subsession.set_group_matrix(new_structure) if num_participants == 24: if subsession.round_number == 1: new_structure = [1, 13, 9, 21], [11, 14, 2, 23], [3, 15, 10, 22], [4, 16, 12, 24], [8, 20, 5, 17], [6, 18, 7, 19] if subsession.round_number == 2: new_structure = [11, 23, 1, 14], [2, 22, 10, 15], [12, 16, 3, 13], [8, 17, 4, 20], [5, 19, 7, 18], [9, 24, 6, 21] if subsession.round_number == 3: new_structure = [10, 22, 1, 15], [2, 13, 9, 16], [3, 14, 8, 17], [4, 19, 7, 20], [5, 21, 12, 24], [11, 23, 6, 18] if subsession.round_number == 4: new_structure = [1, 24, 12, 13], [8, 17, 2, 14], [7, 19, 3, 15], [9, 18, 4, 16], [11, 20, 5, 23], [6, 21, 10, 22] if subsession.round_number == 5: new_structure = [1, 14, 8, 17], [7, 15, 2, 19], [3, 13, 9, 16], [4, 21, 11, 23], [10, 18, 5, 20], [6, 24, 12, 22] if subsession.round_number == 6: new_structure = [7, 15, 1, 19], [2, 16, 12, 13], [11, 23, 3, 14], [10, 22, 4, 24], [5, 17, 9, 21], [8, 20, 6, 18] # else: # subsession.group_randomly() subsession.set_group_matrix(new_structure) # else: # subsession.group_randomly() class Player(BasePlayer): Treatment = models.CharField(initial='HP') q1 = models.IntegerField( choices=[ [1, 'True'], [2, 'False'] ], label="1. At the beginning of each round, the Firm knows its true type.", widget=widgets.RadioSelect, ) q2 = models.IntegerField( choices=[ [1, 'True'], [2, 'False'] ], label="2. The Auditor learns the true type of the Firm at the end of each round.", widget=widgets.RadioSelect, ) q3 = models.IntegerField( choices=[ [1, 'True'], [2, 'False'] ], label="3. The Auditor only learns whether they incurred a penalty at the end of the study.", widget=widgets.RadioSelect, ) q4 = models.IntegerField( choices=[ [1, 'A randomly selected round.'], [2, 'The round where the highest payment was achieved.'], [3, 'The round where the lowest payment was achieved. '], [4, 'Every round.'] ], label="4. The final earnings from Task 1 depend on the tokens earned in:", widget=widgets.RadioSelect, ) q5 = models.IntegerField( choices=[ [1, "In each round, each of the two nonprofits is matched with exactly one Auditor-Firm pair in each group."], [2, "The type of a Firm is constant across all rounds."], [3, "If the Auditor's report differs from the Firm's type, then there is a {Var}% chance the Auditor pays a penalty.".format(Var=C.chance)] ], label="5. Which of the following statements is incorrect?", widget=widgets.RadioSelect, ) #{Receives}.".format(Receives=C.RECEIVES) q6 = models.IntegerField( choices=[ [1, 'The Firm that the Auditor is matched with.'], [2, 'The Auditor’s Report Decision'], [3, 'The number of plates that the Auditor sees. '] ], label="6. What does the Audit Cost depend on?", widget=widgets.RadioSelect, ) q7 = models.IntegerField( choices=[ [1, 'Their type (A or B).'], [2, 'The Auditor’s Report Decision.'], [3, 'A combination of the Firm’s type and the Auditor’s Report Decision.'], [4, 'None of the above. '] ], label="7. What determines the payment for the Firm? ", widget=widgets.RadioSelect, ) q8 = models.IntegerField( choices=[ [1, 'The Firm’s type (A or B).'], [2, 'The Auditor’s Report Decision.'], [3, 'A combination of the Firm’s type and the Auditor’s Report Decision.'], [4, 'None of the above. '] ], label="8. What determines the payment for the Nonprofit? ", widget=widgets.RadioSelect, ) q9 = models.IntegerField( choices=[ [1, '0'], [2, '{Var}'.format(Var=C.reward_firm)], [3, '{Var}'.format(Var=2*C.reward_firm)], [4, 'We need more information'] ], label="9. How many more tokens does a Firm earn when reported as Type A, compared to when reported as Type B? ", widget=widgets.RadioSelect, ) q10 = models.IntegerField( choices=[ [1, '0'], [2, '{Var}'.format(Var=C.reward_npo)], [3, '{Var}'.format(Var=2*C.reward_npo)], [4, 'We need more information'] ], label="10. How many more tokens does a Nonprofit earn when the Auditor’s report is correct, compared to when it is incorrect?", widget=widgets.RadioSelect, ) q11 = models.IntegerField( choices=[ [1, '0'], [2, '{Var}'.format(Var=C.audit_cost/2)], [3, '{Var}'.format(Var=C.audit_cost)], [4, 'We need more information'] ], label="11. How many more tokens does an Auditor earn when matched with the 1st Firm, compared to when matched with the 2nd Firm? ", widget=widgets.RadioSelect, ) q12 = models.IntegerField( choices=[ [1, '{Var} tokens for sure.'.format(Var=C.audit_penalty)], [2, '{Var} tokens for sure.'.format(Var=C.audit_penalty/C.MAXDICE)], [3, '{Var} tokens with a {chance}% chance.'.format(Var=C.audit_penalty,chance=C.chance)], [4, 'No chance of penalty.'] ], label="12. Suppose an Auditor reports its matched Firm as Type B. The Firm’s true type was A. If this round is selected for payment, then what is the chance and value of the Auditor’s penalty?" , widget=widgets.RadioSelect, ) q13 = models.IntegerField( choices=[ [1, 'True'], [2, 'False'] ], label= "13. The Firm pays the audit fee ({AuditFee}) to the Auditor out of the Firm's initial {Receives}.".format(Receives=C.ENDOWMENT_FIRM,AuditFee=C.AUDIT_FEE) if Treatment =="R" else "13. The Firm pays the audit fee ({AuditFee}) to the Auditor out of the Firm's initial {Receives}.".format(Receives=C.RECEIVES,AuditFee=C.AUDIT_FEE), widget=widgets.RadioSelect, ) q132 = models.IntegerField( choices=[ [1, 'True'], [2, 'False'] ], label= "13. The Firm pays the audit fee ({AuditFee}) to the Auditor out of the Firm's initial {Receives}.".format(Receives=C.ENDOWMENT_FIRM,AuditFee=C.AUDIT_FEE) if Treatment =="R" else "13. The Firm pays the audit fee ({AuditFee}) to the Auditor out of the Firm's initial {Receives}.".format(Receives=C.RECEIVES,AuditFee=C.AUDIT_FEE), widget=widgets.RadioSelect, ) num_failed_attempts = models.IntegerField(initial=0) # num_failed_attempts2 = models.IntegerField(initial=0) REPORTA = models.BooleanField(label="Please select one of the options below:", choices=[[True, 'Type A'], [False, 'Type B']]) BELIEFA = models.IntegerField(initial=1) PROBBELIEF = models.IntegerField( min=0, max=100, label="Question: How likely do you think it is that the Firm's type is Type A? Specifically, with what probability (in percentage points) do you believe this to be the case? Please enter a whole number, which we call p, between 0 and 100 in the space below:") ORDER = models.IntegerField(min=1, max=2, initial=0) AUDIT_COST = models.CurrencyField() TYPE = models.IntegerField(initial=-1) SEQ = models.IntegerField(initial=0) RIGHT = models.BooleanField(initial=False) LUCK = models.BooleanField(initial=False) SELECTXY = models.IntegerField( choices=[ [1, 'Auditor X'], [2, 'Auditor Y'], ], label="In this round, you have been randomly assigned the role of 1st Firm. Please select one of the two Auditors below:", widget=widgets.RadioSelect, ) NPO_IMPACT = models.CurrencyField() PENALIZED = models.IntegerField(initial=0) RESULT = models.CurrencyField() DAMAGED = models.IntegerField() UNDAMAGED = models.IntegerField() PAYOFF_ROUND = models.IntegerField() true_count = models.IntegerField(initial=0) false_count = models.IntegerField(initial=0) class Group(BaseGroup): FIRST = models.IntegerField(initial=0) SECOND = models.IntegerField(initial=0) class Task1s1(Page): def is_displayed(player: Player): return player.round_number == 1 def vars_for_template(player: Player): session = player.session Treatment = session.vars['Treatment'] if Treatment == 'R': receives = C.ENDOWMENT_FIRM else: receives = C.ENDOWMENT_FIRM + C.AUDIT_FEE return dict(image_steps="step1.jpg", receives=receives) class Task1s2(Page): def is_displayed(player: Player): return player.round_number == 1 def vars_for_template(player: Player): cost2 = C.audit_cost + 5 cost1 = 5 return dict(image_steps="step2.jpg", cost2=cost2, cost1=cost1) class Task1s2b(Page): def is_displayed(player: Player): return player.round_number == 1 def vars_for_template(player: Player): cost2 = C.audit_cost + 5 cost1 = 5 return dict(image_steps="step2.jpg", cost2=cost2, cost1=cost1) class Task1s3(Page): def is_displayed(player: Player): return player.round_number == 1 def vars_for_template(player: Player): session = player.session if session.Treatment == 'R': receives = C.endowment_firm else: receives = C.endowment_firm + C.audit_fee FirmReceivesA = C.ENDOWMENT_FIRM + C.REWARD_FIRM FirmReceivesB = C.ENDOWMENT_FIRM - C.REWARD_FIRM NPOReceivesAA = C.ENDOWMENT_NPO + C.REWARD_NPO NPOReceivesAB = C.ENDOWMENT_NPO - C.PENALTY_NPO return dict(image_steps="step3.jpg", receives=receives, FirmReceivesA=FirmReceivesA, FirmReceivesB=FirmReceivesB, NPOReceivesAB=NPOReceivesAB, NPOReceivesAA=NPOReceivesAA) class Task1s3a(Page): def is_displayed(player: Player): return player.round_number == 1 def vars_for_template(player: Player): session = player.session if session.Treatment == 'R': receives = C.endowment_firm else: receives = C.endowment_firm + C.audit_fee FirmReceivesA = C.ENDOWMENT_FIRM + C.REWARD_FIRM FirmReceivesB = C.ENDOWMENT_FIRM - C.REWARD_FIRM NPOReceivesAA = C.ENDOWMENT_NPO + C.REWARD_NPO NPOReceivesAB = C.ENDOWMENT_NPO - C.PENALTY_NPO return dict(image_steps="step3.jpg", receives=receives, FirmReceivesA=FirmReceivesA, FirmReceivesB=FirmReceivesB, NPOReceivesAB=NPOReceivesAB, NPOReceivesAA=NPOReceivesAA) class Task1s3b(Page): def is_displayed(player: Player): return player.round_number == 1 def vars_for_template(player: Player): return dict(image_steps="step3.jpg") class Task1s3c(Page): def is_displayed(player: Player): return player.round_number == 1 def vars_for_template(player: Player): cost2 = C.audit_cost + 5 cost1 = 5 result1np= C.ENDOWMENT_AUDITOR+C.AUDIT_FEE - cost1 result1p= C.ENDOWMENT_AUDITOR+C.AUDIT_FEE - cost1 - C.AUDIT_PENALTY result2np= C.ENDOWMENT_AUDITOR+C.AUDIT_FEE - cost2 result2p= C.ENDOWMENT_AUDITOR+C.AUDIT_FEE - cost2 - C.AUDIT_PENALTY return dict(image_steps="step3.jpg", cost2=cost2, cost1=cost1, result1p=result1p, result1np=result1np, result2p=result2p, result2np=result2np) class Task1s4(Page): def is_displayed(player: Player): return player.round_number == 1 def vars_for_template(player: Player): return dict(image_steps="step4.jpg") def before_next_page(player: Player, timeout_happened): session = player.session random.shuffle(session.vars['PLATES']) class Task1sb(Page): def is_displayed(player: Player): return player.round_number == 1 class Task1se1(Page): def is_displayed(player: Player): return player.round_number == 1 def vars_for_template(player: Player): session = player.session session.vars['PLATES'] = [1, 0, 0, 1, 0, 1, 1, 1] PLATES = session.vars['PLATES'] receives = C.endowment_firm + C.audit_fee cost2 = C.audit_cost + 5 cost1 = 5 auditortotal = C.endowment_auditor + C.audit_fee - cost2 firmtotal = C.endowment_firm - C.reward_firm npototal = C.endowment_npo + C.reward_npo return dict(image_damaged="dam.jpg", image_undamaged="displayed_image/unda.jpg", plates=PLATES, receives=receives, audit_cost1=cost1, audit_cost2=cost2, auditortotal=auditortotal, firmtotal=firmtotal, npototal=npototal) class Task1se2(Page): def is_displayed(player: Player): return player.round_number == 1 def vars_for_template(player: Player): session = player.session session.vars['PLATES'] = [0, 1, 0, 0] PLATES = session.vars['PLATES'] receives = C.endowment_firm + C.audit_fee cost2 = C.audit_cost + 5 cost1 = 5 auditortotal = C.endowment_auditor + C.audit_fee - cost1 - C.audit_penalty firmtotal = C.endowment_firm + C.reward_firm npototal = C.endowment_npo - C.reward_npo return dict(image_damaged="dam.jpg", image_undamaged="displayed_image/unda.jpg", plates=PLATES, receives=receives, audit_cost1=cost1, audit_cost2=cost2, auditortotal=auditortotal, firmtotal=firmtotal, npototal=npototal) class Task1sq1(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): return player.round_number == 1 def get_form_fields(player): session = player.session Treatment = session.vars['Treatment'] return ['q1', 'q2', 'q3', 'q4', 'q5', 'q6', 'q7', 'q8', 'q9', 'q10', 'q11','q12','q13'] # f02 is for HP only def error_message(player, values): session = player.session Treatment = session.vars['Treatment'] if Treatment != 'R': solutions = dict(q1=2, q2=2, q3=1, q4=1, q5=2, q6=1, q7=2, q8=3, q9=3, q10=3, q11=3, q12=3, q13=1) if Treatment == 'R': solutions = dict(q1=2, q2=2, q3=1, q4=1, q5=2, q6=1, q7=2, q8=3, q9=3, q10=3, q11=3, q12=3, q13=2) error_messages = dict() for field_name in solutions: if values[field_name] != solutions[field_name]: player.num_failed_attempts += 1 error_messages[field_name] = 'Wrong answer' return error_messages class IntroWaitPage(WaitPage): @staticmethod def after_all_players_arrive(group: Group): session = group.session class StartMatchWaitPage(WaitPage): def is_displayed(player: Player): session = player.session return session.Treatment == "HP" @staticmethod def after_all_players_arrive(group: Group): session = group.session def vars_for_template(player): session = player.session if player.role == C.Firm1_ROLE: body_text = "Please wait for the other participants" title_text = "Waiting" if player.role == C.Firm2_ROLE: body_text = "Please wait for the 1st Firm to select an Auditor to be matched with." title_text = "Waiting to select" if player.role == C.AUDITORX_ROLE or player.role == C.AUDITORY_ROLE: body_text = "Please wait while the 1st Firm selects an Auditor to be matched with." title_text = "Waiting to be matched" return dict(body_text=body_text, title_text=title_text) # FUNCTIONS # PAGES class Introduction(Page): def is_displayed(player: Player): return player.round_number == 1 def vars_for_template(player: Player): group = player.group player_list = group.get_players() AuditorX = player_list[0] AuditorY = player_list[2] class Round(Page): def vars_for_template(player: Player): import random group = player.group player_list = group.get_players() session = player.session participant = player.participant player.PAYOFF_ROUND = session.vars['paying_round'] Treatment = session.vars['Treatment'] AORDER = session.vars['AORDER'] FORDER = session.vars['FORDER'] AuditorX = player_list[0] AuditorY = player_list[2] Firm1 = player_list[1] Firm2 = player_list[3] # AuditorX.ORDER = AORDER[0] # AuditorY.ORDER = AORDER[1] Firm1.ORDER = FORDER[0] Firm2.ORDER = FORDER[1] if player.round_number == 1: participant.true_count=0 participant.false_count = 0 if Treatment == 'R': receives = C.ENDOWMENT_FIRM else: receives = C.ENDOWMENT_FIRM + C.AUDIT_FEE if player.round_number != 1: return dict(AXtrue=AuditorX.participant.true_count, AYtrue=AuditorY.participant.true_count, AXfalse=AuditorX.participant.false_count, AYfalse=AuditorY.participant.false_count, receives=receives) else: return dict(receives=receives) # names must correspond to fields in models.py class SelectingXY(Page): form_model = 'player' form_fields = ['SELECTXY'] def is_displayed(player: Player): session = player.session group = player.group player_list = group.get_players() FORDER = session.vars['FORDER'] Firm1 = player_list[1] Firm2 = player_list[3] Firm1.ORDER = FORDER[0] Firm2.ORDER = FORDER[1] return session.Treatment == "HP" and player.role == C.Firm1_ROLE def vars_for_template(player: Player): import random session = player.session group = player.group player_list = group.get_players() FORDER = session.vars['FORDER'] Firm1 = player_list[1] Firm2 = player_list[3] Firm1.ORDER = FORDER[0] Firm2.ORDER = FORDER[1] player.AUDIT_COST = 5 + (player.ORDER - 1) * C.AUDIT_COST if player.ORDER == 1: textorder = "first" if player.ORDER == 2: textorder = "second" player.PAYOFF_ROUND = session.vars['paying_round'] AuditorX = player_list[0] AuditorY = player_list[2] participant = player.participant if player.round_number != 1: return dict(AXtrue=AuditorX.participant.true_count, AYtrue=AuditorY.participant.true_count, AXfalse=AuditorX.participant.false_count, AYfalse=AuditorY.participant.false_count, order=textorder) if player.round_number == 1: return dict(order=textorder) def before_next_page(player: Player, timeout_happened): session = player.session group = player.group player_list = group.get_players() AORDER = session.vars['AORDER'] AuditorX = player_list[0] AuditorY = player_list[2] if player.SELECTXY == 1: AuditorX.ORDER = 1 AuditorY.ORDER = 2 if player.SELECTXY == 2: AuditorY.ORDER = 1 AuditorX.ORDER = 2 # partner=player.get_others_in_group()[0], class MatchWaitPage(WaitPage): def vars_for_template(player): session = player.session participant = player.participant # Assigning one sequence to each group: if player.role == C.AUDITORX_ROLE or player.role == C.AUDITORY_ROLE: if session.Treatment == "HP": body_text = "Please wait while the 1st Firm selects an Auditor to be matched with." title_text = "Waiting to be matched" else: body_text = "Please wait while you are randomly matched with a Firm." title_text = "Waiting to be matched" else: if session.Treatment == "HP": if player.role == C.Firm1_ROLE: body_text = "Please wait for the other participants" title_text = "Waiting" if player.role == C.Firm2_ROLE: body_text = "In this round, you have been randomly assigned the role of 2nd Firm. Please wait for the 1st Firm to select an Auditor." title_text = "Waiting" else: if player.role == C.Firm1_ROLE: body_text = "In this round, you have been randomly assigned the role of 1st Firm. Please wait while you are randomly matched with an Auditor." title_text = "Waiting" if player.role == C.Firm2_ROLE: body_text = "In this round, you have been randomly assigned the role of 2nd Firm. Please wait while you are randomly matched with an Auditor." title_text = "Waiting" return dict(body_text=body_text, title_text=title_text) @staticmethod def after_all_players_arrive(group: Group): session = group.session random.shuffle(session.vars['PLATES']) class Matching(Page): def vars_for_template(player: Player): import random session = player.session participant = player.participant player_list = player.get_others_in_subsession() groupnumber = player.group_id - min([p.group_id for p in player_list]) + 1 if groupnumber == 1: player.SEQ = 1 if groupnumber == 2: player.SEQ = 2 if groupnumber == 3: player.SEQ = 3 if groupnumber == 4: player.SEQ = 4 if groupnumber == 5: num_participants = session.num_participants if num_participants == 20: player.SEQ = 52 else: player.SEQ = 5 if groupnumber == 6: player.SEQ = 6 group = player.group player_list = group.get_players() if session.Treatment != 'HP': AORDER = session.vars['AORDER'] AuditorX = player_list[0] AuditorY = player_list[2] AuditorX.ORDER = AORDER[0] AuditorY.ORDER = AORDER[1] FORDER = session.vars['FORDER'] Firm1 = player_list[1] Firm2 = player_list[3] Firm1.ORDER = FORDER[0] Firm2.ORDER = FORDER[1] if player.ORDER == 1: textorder = "first" if player.ORDER == 2: textorder = "second" if player.ORDER == 3: textorder = "third" potential_partners = player.get_others_in_group() for p in potential_partners: if player.ORDER == p.ORDER: partner = p form_fields = ['REPORTA'] partner = partner # if player.role == C.Firm1_ROLE or player.role == C.Firm2_ROLE: # player.SEQ = partner.SEQ player.AUDIT_COST = 5 + (player.ORDER - 1) * C.AUDIT_COST participant = player.participant P5 = [2, 1, 0] plates5 = [1, 0, 1] P3A = [1, 2, 1] P3B = [1, 2, 0] plates3 = [0, 1, 0] P10 = [0, 3, 1] plates10 = [0, 0, 0] P1 = [2, 3, 1] plates1 = [0, 1, 0, 0, 1] P7 = [1, 4, 0] plates7 = [0, 0, 1, 0, 0] P9 = [3, 4, 0] plates9 = [1, 0, 0, 1, 0, 1, 0] P4 = [2, 5, 1] plates4 = [0, 0, 1, 0, 0, 1, 0] P8 = [4, 5, 0] plates8 = [0, 1, 0, 0, 1, 1, 0, 1, 0] P6A = [3, 6, 1] P6B = [3, 6, 0] plates6 = [1, 0, 0, 0, 1, 0, 0, 1, 0] P2 = [2, 7, 1] plates2 = [0, 0, 0, 1, 0, 0, 1, 0, 0] # Assigning one sequence to each group: if player.SEQ == 1: if player.round_number == 1: P = P1 plates = plates1 if player.round_number == 2: P = P3B plates = plates3 if player.round_number == 3: P = P5 plates = plates5 if player.round_number == 4: P = P7 plates = plates7 if player.round_number == 5: P = P9 plates = plates9 if player.round_number == 6: P = P8 plates = plates8 if player.SEQ == 2: if player.round_number == 1: P = P2 plates = plates2 if player.round_number == 2: P = P4 plates = plates4 if player.round_number == 3: P = P6B plates = plates6 if player.round_number == 4: P = P8 plates = plates8 if player.round_number == 5: P = P7 plates = plates7 if player.round_number == 6: P = P10 plates = plates10 if player.SEQ == 3: if player.round_number == 1: P = P6A plates = plates6 if player.round_number == 2: P = P5 plates = plates5 if player.round_number == 3: P = P10 plates = plates10 if player.round_number == 4: P = P9 plates = plates9 if player.round_number == 5: P = P2 plates = plates2 if player.round_number == 6: P = P4 plates = plates4 if player.SEQ == 4: if player.round_number == 1: P = P9 plates = plates9 if player.round_number == 2: P = P6B plates = plates6 if player.round_number == 3: P = P1 plates = plates1 if player.round_number == 4: P = P7 plates = plates7 if player.round_number == 5: P = P10 plates = plates10 if player.round_number == 6: P = P2 plates = plates2 if player.SEQ == 5: if player.round_number == 1: P = P2 plates = plates2 if player.round_number == 2: P = P4 plates = plates4 if player.round_number == 3: P = P6B plates = plates6 if player.round_number == 4: P = P8 plates = plates8 if player.round_number == 5: P = P10 plates = plates10 if player.round_number == 6: P = P3A plates = plates3 if player.SEQ == 52: if player.round_number == 1: P = P2 plates = plates2 if player.round_number == 2: P = P6B plates = plates6 if player.round_number == 3: P = P10 plates = plates10 if player.round_number == 4: P = P8 plates = plates8 if player.round_number == 5: P = P9 plates = plates9 if player.round_number == 6: P = P3A plates = plates3 if player.SEQ == 6: if player.round_number == 1: P = P2 plates = plates2 if player.round_number == 2: P = P4 plates = plates4 if player.round_number == 3: P = P6B plates = plates6 if player.round_number == 4: P = P8 plates = plates8 if player.round_number == 5: P = P1 plates = plates1 if player.round_number == 6: P = P3A plates = plates3 i = player.round_number - 1 player.DAMAGED = P[0] player.UNDAMAGED = P[1] player.TYPE = P[2] participant.plates = plates return dict(partner=partner, order=textorder, auditcost=player.AUDIT_COST) class SelectWaitPage(WaitPage): def is_displayed(player: Player): session = player.session group = player.group player_list = group.get_players() FORDER = session.vars['FORDER'] Firm1 = player_list[1] Firm2 = player_list[3] Firm1.ORDER = FORDER[0] Firm2.ORDER = FORDER[1] return session.Treatment == "HP" and player.ORDER != 1 and ( player.role == C.Firm1_ROLE or player.role == C.Firm2_ROLE) def vars_for_template(player): body_text = "Please wait for your turn to select an Auditor to be matched with." return dict(body_text=body_text, title_text="Waiting to select") @staticmethod def after_all_players_arrive(group: Group): session = group.session class Select2WaitPage(WaitPage): def is_displayed(player: Player): session = player.session group = player.group player_list = group.get_players() FORDER = session.vars['FORDER'] Firm1 = player_list[1] Firm2 = player_list[3] Firm1.ORDER = FORDER[0] Firm2.ORDER = FORDER[1] return session.Treatment == "HP" and player.ORDER == 3 and ( player.role == C.Firm1_ROLE or player.role == C.Firm2_ROLE) def vars_for_template(player): body_text = "Please wait for your turn to select an Auditor to be matched with" return dict(body_text=body_text, title_text="Waiting to select") @staticmethod def after_all_players_arrive(group: Group): session = group.session class PayWaitPage(WaitPage): def is_displayed(player: Player): session = player.session # broken, unbroken, type return session.Treatment != "R" def vars_for_template(player): if player.role == C.AUDITORX_ROLE or player.role == C.AUDITORY_ROLE: session = player.session group = player.group player_list = group.get_players() player.AUDIT_COST = 5 + (player.ORDER - 1) * C.AUDIT_COST if player.ORDER == 1: textorder = "first" if player.ORDER == 2: textorder = "second" if player.ORDER == 3: textorder = "third" potential_partners = player.get_others_in_group() for p in potential_partners: if player.ORDER == p.ORDER: partner = p body_text = "Please wait while you are paid by the " + partner.role + "." title_text = "Waiting for payment" return dict(partner=partner, body_text=body_text, title_text=title_text) else: potential_partners = player.get_others_in_group() for p in potential_partners: if player.ORDER == p.ORDER: partner = p if player.role == C.Firm1_ROLE or player.role == C.Firm2_ROLE: player.SEQ = partner.SEQ body_text = "Waiting for the other participants." title_text = "Please wait" return dict(body_text=body_text, title_text=title_text) class Paying(Page): def is_displayed(player: Player): session = player.session return session.Treatment != "R" def vars_for_template(player: Player): import random session = player.session group = player.group player_list = group.get_players() if session.Treatment != 'HP': AORDER = session.vars['AORDER'] AuditorX = player_list[0] AuditorY = player_list[2] AuditorX.ORDER = AORDER[0] AuditorY.ORDER = AORDER[1] FORDER = session.vars['FORDER'] Firm1 = player_list[1] Firm2 = player_list[3] Firm1.ORDER = FORDER[0] Firm2.ORDER = FORDER[1] player.AUDIT_COST = 5 + (player.ORDER - 1) * C.AUDIT_COST if player.ORDER == 1: textorder = "first" if player.ORDER == 2: textorder = "second" potential_partners = player.get_others_in_group() for p in potential_partners: if player.ORDER == p.ORDER: partner = p return dict(partner=partner, order=textorder, auditcost=player.AUDIT_COST) class Report(Page): form_model = 'player' form_fields = ['REPORTA'] def vars_for_template(player: Player): session = player.session participant = player.participant # plates = session.vars['PLATES'] # Assigning one sequence to each group: player_list = player.get_others_in_subsession() groupnumber = player.group_id - min([p.group_id for p in player_list]) + 1 i = player.round_number - 1 # damaged = SEQ[i][0] # undamaged = SEQ[i][1] # player.TYPE = SEQ[i][2] # player.DAMAGED = damaged # player.UNDAMAGED = undamaged damaged = player.DAMAGED undamaged = player.UNDAMAGED plates = participant.plates total = damaged + undamaged # plates = session.vars['PLATES'] return dict(damaged=damaged, undamaged=undamaged, total=total, groupnumber=groupnumber, image_damaged="displayed_image/dam.jpg", image_undamaged="displayed_image/unda.jpg", plates=plates) def before_next_page(player,timeout_happened): participant = player.participant if player.REPORTA==True: participant.true_count += 1 player.true_count = participant.true_count else: participant.false_count += 1 player.false_count = participant.false_count class Belief(Page): form_model = 'player' form_fields = ['PROBBELIEF'] def vars_for_template(player: Player): session = player.session # plates = session.vars['PLATES'] i = player.round_number - 1 damaged = player.DAMAGED undamaged = player.UNDAMAGED total = damaged + undamaged plates = session.vars['PLATES'] return dict(damaged=damaged, undamaged=undamaged, total=total, image_damaged="displayed_image/dam.jpg", image_undamaged="displayed_image/unda.jpg", plates=plates) def before_next_page(player: Player, timeout_happened): session = player.session if session.vars['r_1'] < player.PROBBELIEF: if player.BELIEFA == player.TYPE: player.RIGHT = 1 player.LUCK = 0 else: player.RIGHT = 0 player.LUCK = 0 else: if session.vars['r_1'] < session.vars['r_2']: player.LUCK = 1 player.RIGHT = 0 else: player.LUCK = 0 player.RIGHT = 0 class ResultWaitPage(WaitPage): @staticmethod def after_all_players_arrive(group: Group): session = group.session def vars_for_template(player): title_text = "Please wait." body_text = "Waiting for the other participants to complete the round. " return dict(body_text=body_text, title_text=title_text) class Results(Page): def vars_for_template(player: Player): potential_partners = player.get_others_in_group() for p in potential_partners: if player.ORDER == p.ORDER: partner = p return dict(partner=partner) def before_next_page(player: Player, timeout_happened): import random participant = player.participant group = player.group session = group.session player_list = group.get_players() potential_partners = player.get_others_in_group() for p in potential_partners: if player.ORDER == p.ORDER: partner = p if player.role == C.AUDITORX_ROLE or player.role == C.AUDITORY_ROLE: if session.vars['dice'] == 1 and partner.TYPE != player.REPORTA: player.PENALIZED = 1 player.RESULT = C.ENDOWMENT_AUDITOR + C.AUDIT_FEE - player.AUDIT_COST + C.RIGHT_BELIEF * ( player.RIGHT + player.LUCK) \ - C.AUDIT_PENALTY else: player.RESULT = C.ENDOWMENT_AUDITOR + C.AUDIT_FEE - player.AUDIT_COST + C.RIGHT_BELIEF * ( player.RIGHT + player.LUCK) if player.role == C.Firm1_ROLE or player.role == C.Firm2_ROLE: if partner.REPORTA == 1: player.RESULT = C.ENDOWMENT_FIRM + C.REWARD_FIRM + C.RIGHT_BELIEF * ( player.RIGHT + player.LUCK) if player.TYPE == 1: player.NPO_IMPACT = C.ENDOWMENT_NPO + C.REWARD_NPO else: player.NPO_IMPACT = C.ENDOWMENT_NPO - C.PENALTY_NPO if partner.REPORTA == 0: player.RESULT = C.ENDOWMENT_FIRM - C.REWARD_FIRM + C.RIGHT_BELIEF * ( player.RIGHT + player.LUCK) if player.TYPE == 0: player.NPO_IMPACT = C.ENDOWMENT_NPO + C.REWARD_NPO else: player.NPO_IMPACT = C.ENDOWMENT_NPO - C.PENALTY_NPO partner.NPO_IMPACT = player.NPO_IMPACT # if it's the last round class FinalWaitPage(WaitPage): def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS class FinalResults(Page): def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS def vars_for_template(player: Player): session = player.session participant = player.participant participant.selected_round = session.vars['paying_round'] selected_round = participant.selected_round player.PAYOFF_ROUND = selected_round playerthen = player.in_round(selected_round) potential_partners = playerthen.get_others_in_group() NPO = C.NPO[player.ORDER - 1] for p in potential_partners: if playerthen.ORDER == p.ORDER: partnerthen = p if player.role == C.AUDITORX_ROLE or player.role == C.AUDITORY_ROLE: auditorthen = playerthen firmthen = partnerthen else: auditorthen = partnerthen firmthen = playerthen if player.round_number == C.NUM_ROUNDS: random_round = session.vars['paying_round'] # random_round = random.randint(1, C.NUM_ROUNDS) player_in_selected_round = player.in_round(random_round) player.payoff = player_in_selected_round.RESULT participant.T1role = playerthen.role participant.T1partner = partnerthen.role participant.T1report = auditorthen.REPORTA participant.T1belief = playerthen.BELIEFA participant.T1probbelief = playerthen.PROBBELIEF participant.T1payoff = player.payoff participant.T1npo = NPO participant.T1type = firmthen.TYPE participant.T1right = playerthen.RIGHT participant.T1luck = playerthen.LUCK participant.T1npoimpact = playerthen.NPO_IMPACT return dict(playerthen=playerthen, partnerthen=partnerthen, r_1=session.vars['r_1'], r_2=session.vars['r_2'], dice=session.vars['dice'], NPO=NPO, payoffround=selected_round) # the order in which pages are displayed # just for testing: # page_sequence = [Introduction, Round, MatchWaitPage, Paying, PayWaitPage, Matching, Report, Belief, ResultWaitPage, Results, FinalWaitPage,FinalResults] # page_sequence = [IntroWaitPage, Introduction, Round, StartMatchWaitPage, Selecting, SelectWaitPage, SelectingXY, SelectingXZ, SelectingYZ, Select2WaitPage, MatchWaitPage, Paying, PayWaitPage, Matching, Report, Belief, ResultWaitPage, Results, FinalWaitPage,FinalResults] # main one: page_sequence = [Task1s1, Task1s2, Task1s2b, Task1s3, Task1s3a, Task1s3b, Task1s3c, Task1s4, Task1sb, Task1se1, Task1se2, Task1sq1, ShuffleWaitPage, IntroWaitPage, Introduction, Round, SelectingXY, MatchWaitPage, Paying, PayWaitPage, Matching, Report, Belief, ResultWaitPage, Results, FinalWaitPage, FinalResults] #just for testing #page_sequence = [ShuffleWaitPage, IntroWaitPage, Introduction, Round, SelectingXY, MatchWaitPage, Paying, PayWaitPage, Matching, Report, Belief, ResultWaitPage, Results, FinalWaitPage, FinalResults] #Just for testing shuffling: #page_sequence = [ShuffleWaitPage, IntroWaitPage, Introduction, Round]