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]