import random
from otree.api import *
class C(BaseConstants):
NAME_IN_URL = 'survey'
PLAYERS_PER_GROUP = None
NUM_ROUNDS = 1
class Subsession(BaseSubsession):
pass
class Group(BaseGroup):
pass
AGREE_CHOICES = (
(1, 'Strongly agree'),
(2, 'Agree'),
(3, 'Somewhat agree'),
(4, 'Neither agree nor disagree'),
(5, 'Somewhat disagree'),
(6, 'Disagree'),
(7, 'Strongly disagree'),
)
def make_field(label):
return models.IntegerField(
choices=AGREE_CHOICES,
label=label,
widget=widgets.RadioSelect,
)
def make_check_box(label):
return models.BooleanField(label=label, widget=widgets.CheckboxInput, blank=True)
class Player(BasePlayer):
# Demograoghics page
age = models.IntegerField(label='What is your age?', min=13, max=125)
gender = models.IntegerField(
choices=[(1, 'Male'), (2, 'Female'), (3, 'Other'), (4, 'Prefer not to say')],
label='What is your gender?',
widget=widgets.RadioSelect,
)
education = models.IntegerField(
choices=[
(1, "No formal education"),
(2, "Primary education"),
(3, "Secondary education"),
(4, "GED"),
(5, "Vocational qualification"),
(6, "Bachelor's degree"),
(7, "Master's degree"),
(8, "Doctorate or higher"),
],
label='What is the highest level of education attained?',
widget=widgets.RadioSelect,
)
work_experience = models.IntegerField(
label='How many years of work experience do you have?', min=0, max=125
)
risk = models.IntegerField(
choices=[
(0, "0 (NOT at all willing to take risks)"),
(1, "1"),
(2, "2"),
(3, "3"),
(4, "4"),
(5, "5"),
(6, "6"),
(7, "7"),
(8, "8"),
(9, "9"),
(10, "10 (VERY willing to take risks)"),
],
label='How do you see yourself: are you generally a person who is fully prepared to take RISKS or do you try to avoid taking RISKS? Please choose an option on the scale from 0 (NOT at all willing to take risks) to 10 (VERY willing to take risks).',
widget=widgets.RadioSelect,
)
why_effort = models.LongStringField(
label='How did you decide, generally, how many winning balls to buy?', blank=True
)
why_guideline_e = models.LongStringField(
blank=True,
)
# supervisor open ended
why_bonus = models.LongStringField(
label='Please explain how you decided, generally, how much bonus to award to your employee.', blank=True
)
why_guideline_s = models.LongStringField(
blank=True,
)
# manipulation check
# m = models.PositiveIntegerField(
# verbose_name="The reports presented to the supervisor when they made their bonus decision every period contained:",
# choices=[(1, 'Both the company profit level AND how many winning balls the employee bought'), (2, 'Only the company profit level (HIGH or LOW)'), (3, ' Only how many winning balls the employee bought')],
# widget=widgets.RadioSelect,
# )
# employee 1
e_expect_guideline = make_field("Before receiving the bonus in the first period, I anticipated that my supervisor will award bonuses to me in a way that conformed with Keystone’s evaluation guideline.")
e_s_folled_guideline = make_field("After 8 periods of interacting with my supervisor, I learned that my supervisor awarded bonuses to me in a way that conformed with Keystone’s evaluation guideline.")
e_b_guideline_unc = make_field("It is better for everybody if supervisors follow Keystone’s evaluation guideline because then there is less uncertainty about how bonus decisions are made.")
e_b_guideline_ethical = make_field("It is better for everybody if supervisors follow Keystone’s evaluation guideline because this is the right thing to do. ")
e_b_guideline_fair = make_field("A fair bonus was one that followed Keystone’s evaluation guideline.")
e_b_guideline_punish = make_field("If I had thought that my supervisor’s bonus decision did not conform to Keystone’s evaluation guideline, I would have reduced how many winning balls I bought in the following periods.")
# employee 2
e_anticipate_effort = models.IntegerField(min=0, max=100, blank=True)
e_anticipate_outcome = models.IntegerField(min=0, max=100, blank=True)
e_anticipate_other = models.IntegerField(min=0, max=100, blank=True)
e_anticipate_text = models.StringField(
label='Please explain what other factor influenced the bonus.', blank=True
)
e_learn_effort = models.IntegerField(min=0, max=100, blank=True)
e_learn_outcome = models.IntegerField(min=0, max=100, blank=True)
e_learn_other = models.IntegerField(min=0, max=100, blank=True)
e_learn_text = models.StringField(
label='Please explain what other factor influenced the bonus.', blank=True
)
# employee 2
# risk
# trust
# manipulation check
e_punnish_effort = make_field(
"If I thought the bonus was too low, I reduced how many winning balls I bought in the following periods."
)
e_luck = make_field("Luck played a big part in how much bonus my supervisor awarded to me.")
e_fair = make_field("The bonuses that my supervisor awarded to me were fair.")
e_predict = make_field("I was able to predict how much bonus my supervisor would award to me.")
e_uncertain = make_field("I was uncertain about how my supervisor would evaluate me.")
fair_allocation = models.PositiveIntegerField(
choices=[
(1, "Based on how many winning balls the employee has bought."),
(2, "Based on whether Keystone’s profit has been HIGH or LOW."),
(3, "Based on some combination of both."),
],
widget=widgets.RadioSelect,
label="At Keystone, a FAIR bonus is:",
)
# e_bc_effort = make_check_box("How many winning balls I bought")
# e_bc_outcome = make_check_box("Whether the company profit was HIGH or LOW")
# e_bc_confrontation = make_check_box("Whether I confronted the supervisor")
# e_bc_other = make_check_box("Other")
# e_bc_text = models.StringField (
# label='Please explain what other factor influenced you.',
# blank=True)
#supervisor 1
s_importance_guideline = make_field("I sought to award bonuses in a way that conformed with Keystone’s evaluation guideline.")
s_importance_balls = make_field("I sought to award bonuses in a way that would motivate them to buy more winning balls.")
s_importance_fair = make_field("I sought to award bonuses in a way that I considered fair.")
s_importance_e_fair = make_field("I sought to award bonuses in a way that the employee would consider fair.")
s_bi_effort = models.IntegerField(min=0, max=100, blank=True)
s_bi_outcome = models.IntegerField(min=0, max=100, blank=True)
s_bi_other = models.IntegerField(min=0, max=100, blank=True)
s_bi_text = models.StringField(
label='Please explain what other factor influenced the bonus.', blank=True
)
#supervisor 2
s_motivation_allocation = models.PositiveIntegerField(
choices=[
(1, "Based on how many winning balls the employee has bought."),
(2, "Based on whether Keystone’s profit has been HIGH or LOW."),
(3, "Based on some combination of both."),
],
widget=widgets.RadioSelect,
label="At Keystone, the best way to motivate my employee to buy more winning balls is to award bonuses to them:",
)
s_employee_expectation = models.PositiveIntegerField(
choices=[
(1, "Based on how many winning balls the employee has bought."),
(2, "Based on whether Keystone’s profit has been HIGH or LOW."),
(3, "Based on some combination of both."),
],
widget=widgets.RadioSelect,
label="At Keystone, my employee expects me to award bonuses to them:",
)
#supervisor 3
s_employee_anticipation = make_field("My employee anticipated that I would award bonuses in a way that conforms with Keystone’s evaluation guideline.")
s_employee_can_predict = make_field("My employee was able to predict how much bonus they would receive. ")
s_employee_uncertain = make_field("My employee was uncertain about how much bonus I would award to them.")
s_guidline_convention = make_field("If the employee believed that I would follow Keystone’s evaluation guideline, it was in my best interest to follow Keystone’s evaluation guideline.")
s_guideline_coordonation = make_field("It was better for everybody that I followed Keystone’s evaluation guideline because then there was less uncertainty about how the bonus decision would be made.")
s_guideline_moral = make_field("It was better for everybody that I followed Keystone’s evaluation guideline because it was the right thing to do.")
s_guidleline_fair = make_field("A fair bonus was one that followed Keystone’s evaluation guideline. ")
s_guidleline_punish = make_field("If the employee thought that my bonus decisions did not conform to Keystone’s evaluation guideline, the employee bought fewer winning balls.")
#supervisor and employee 4
assymetric_low = models.IntegerField(
choices=[
(1, "Only based on how many winning balls they have bought."),
(
2,
"Mostly based on how many winning balls they have bought and partially on whether Keystone’s profit was HIGH or LOW.",
),
(
3,
"Equally based on how many winning balls they have bought and whether Keystone’s profit has been HIGH or LOW.",
),
(
4,
"Mostly based on whether Keystone’s profit has been HIGH or LOW and partially on how many winning balls they have bought.",
),
(5, "Only based on whether Keystone’s profit has been HIGH or LOW."),
],
label='Imagine a period in which an employee has bought 5 winning balls and Keystone’s profit has been LOW. That employee would find it FAIR that their bonus is:',
widget=widgets.RadioSelect,
)
assymetric_high = models.IntegerField(
choices=[
(1, "Only based on how many winning balls they have bought."),
(
2,
"Mostly based on how many winning balls they have bought and partially on whether Keystone’s profit was HIGH or LOW.",
),
(
3,
"Equally based on how many winning balls they have bought and whether Keystone’s profit has been HIGH or LOW.",
),
(
4,
"Mostly based on whether Keystone’s profit has been HIGH or LOW and partially on how many winning balls they have bought.",
),
(5, "Only based on whether Keystone’s profit has been HIGH or LOW."),
],
label='Imagine a period in which an employee has bought 1 winning ball and Keystone’s profit has been HIGH. That employee would find it FAIR that their bonus is:',
widget=widgets.RadioSelect,
)
s_fair_without_guide = models.PositiveIntegerField(
choices=[
(1, "Based on how many winning balls the employee has bought."),
(2, "Based on whether Keystone’s profit has been HIGH or LOW."),
(3, "Based on some combination of both."),
],
widget=widgets.RadioSelect,
label="Suppose Keystone does NOT have an evaluation guideline. In this case, a FAIR bonus would be:",
)
s_motivation_allocation = models.PositiveIntegerField(
choices=[
(1, "How many winning balls the employee bought"),
(2, "Whether the company profit was HIGH or LOW"),
(3, "A combination of the two"),
],
widget=widgets.RadioSelect,
label="I think the best way to make the employee buy as many winning balls as possible was to reward them based on:",
)
s_confrontation_allocation = models.PositiveIntegerField(
choices=[
(1, "How many winning balls the employee bought"),
(2, "Whether the company profit was HIGH or LOW"),
(3, "A combination of the two"),
],
widget=widgets.RadioSelect,
label="I think the best way to make the employee not confront me was to reward them based on:",
)
ia_e_1 = models.BooleanField(
widget=widgets.RadioSelect, choices=[(0, "Option A"), (1, "Option B")]
)
ia_e_2 = models.BooleanField(
widget=widgets.RadioSelect, choices=[(0, "Option A"), (1, "Option B")]
)
ia_e_3 = models.BooleanField(
widget=widgets.RadioSelect, choices=[(0, "Option A"), (1, "Option B")]
)
ia_e_4 = models.BooleanField(
widget=widgets.RadioSelect, choices=[(0, "Option A"), (1, "Option B")]
)
ia_g_1 = models.BooleanField(
widget=widgets.RadioSelect, choices=[(0, "Option A"), (1, "Option B")]
)
ia_g_2 = models.BooleanField(
widget=widgets.RadioSelect, choices=[(0, "Option A"), (1, "Option B")]
)
ia_g_3 = models.BooleanField(
widget=widgets.RadioSelect, choices=[(0, "Option A"), (1, "Option B")]
)
ia_g_4 = models.BooleanField(
widget=widgets.RadioSelect, choices=[(0, "Option A"), (1, "Option B")]
)
#susceptability
sus_1 = make_field("I often consult other people to help choose the best alternative available from a product class.")
sus_2 = make_field("It is important that others like the products and brands I buy.")
sus_3 = make_field("To make sure I buy the right product or brand, I often observe what others are buying and using.")
sus_4 = make_field("If others can see me using a product, I often purchase the brand they expect me to buy.")
utiliterian = models.PositiveIntegerField(
choices=[
(1, "Yes, it is permissible (by hitting the switch) to take the loss of a person’s life to save the life of five people."),
(0, "No, it is not permissible (by hitting the switch) to take the loss of a person’s life to save the life of five people."),
],
widget=widgets.RadioSelect,
label="A trolley is out of control and threatens to run over five people. By hitting a switch, the trolley can be diverted to another track. Unfortunately, there is another person on that track. Is it permissible (by hitting the switch) to take the loss of a person’s life to save the life of five people?",
)
# FUNCTIONS
def get_role(player: Player):
if 'role' in player.session.config:
player.participant.vars['role']=player.session.config['role']
return player.session.config['role']
else:
return player.participant.vars['role']
def creating_session(subsession: Subsession):
for p in subsession.get_players():
if 'disaggregated' not in p.participant.vars:
p.participant.vars['disaggregated'] = subsession.session.config['disaggregated']
if 'expensive' not in p.participant.vars:
p.participant.vars['expensive'] = subsession.session.config['expensive']
# def get_treatment(self):
# return self.player.participant.vars['role']
# PAGES
class Intro(Page):
pass
class IA_E(Page):
form_model = 'player'
form_fields = ['ia_e_1', 'ia_e_2', 'ia_e_3','ia_e_4']
class IA_G(Page):
form_model = 'player'
form_fields = ['ia_g_1', 'ia_g_2', 'ia_g_3', 'ia_g_4']
class Susceptability(Page):
form_model = 'player'
form_fields = ['sus_1', 'sus_2', 'sus_3','sus_4']
class open_ended(Page):
form_model = 'player'
@staticmethod
def get_form_fields(player: Player):
if get_role(player) == "Supervisor":
if player.participant.vars['treatment_noG']==1:
return ['why_bonus'] #'instructions_clear','why_unclear']
else:
return ['why_bonus','why_guideline_s']
else:
if player.participant.vars['treatment_noG']==1:
return ['why_effort'] #'instructions_clear','why_unclear']
else:
return ['why_effort', 'why_guideline_e']
@staticmethod
def vars_for_template(player: Player):
labelGuideline = ""
if get_role(player) == "Supervisor":
if player.participant.vars['treatment_g_input']==1:
labelGuideline = 'Please explain how Keystone’s evaluation guideline ("at Keystone, we ask supervisors to use their bonus decision to reward employees only based on how many winning balls they buy") influenced your decisions on how much bonus to award to your employee.'
if player.participant.vars['treatment_g_output']==1:
labelGuideline = 'Please explain how Keystone’s evaluation guideline ("at Keystone, we ask supervisors to use their bonus decision to reward employees only based on the profit level they generate") influenced your decisions on how much bonus to award to your employee.'
else:
if player.participant.vars['treatment_g_input']==1:
labelGuideline = 'Please explain how Keystone’s evaluation guideline ("at Keystone, we ask supervisors to use their bonus decision to reward employees only based on how many winning balls they buy") influenced your decisions on how many winning balls to buy. '
if player.participant.vars['treatment_g_output']==1:
labelGuideline = 'Please explain how Keystone’s evaluation guideline ("at Keystone, we ask supervisors to use their bonus decision to reward employees only based on the profit level they generate") influenced your decisions on how many winning balls to buy.'
return dict(
question_label=labelGuideline,
#wrong_attempt=player.participant.vars['quiz_wrong_attempts'],
)
class Demographics(Page):
form_model = 'player'
form_fields = ['utiliterian','age', 'work_experience', 'gender', 'education']
class Employee_1(Page):
@staticmethod
def is_displayed(player: Player):
return get_role(player) == "Employee" and player.participant.vars['treatment_noG']==0
form_model = 'player'
form_fields = [
'e_expect_guideline',
'e_s_folled_guideline',
'e_b_guideline_unc',
'e_b_guideline_ethical',
'e_b_guideline_fair',
'e_b_guideline_punish',
]
class Employee_2(Page):
@staticmethod
def is_displayed(player: Player):
return get_role(player) == "Employee"
form_model = 'player'
form_fields = ['e_anticipate_effort', 'e_anticipate_outcome', 'e_anticipate_other','e_anticipate_text','e_learn_effort','e_learn_outcome','e_learn_other','e_learn_text']
@staticmethod
def error_message(player: Player, values):
if (
int(values['e_anticipate_effort'] or 0)
+ int(values['e_anticipate_outcome'] or 0)
+ int(values['e_anticipate_other'] or 0)
!= 100
):
return (
'Please make sure that you distributed a total of 100 for the first question. Right now the total is '
+ str(
int(values['e_anticipate_effort'] or 0)
+ int(values['e_anticipate_outcome'] or 0)
+ int(values['e_anticipate_other'] or 0)
)
)
if int(values['e_anticipate_other'] or 0) > 0 and not values['e_anticipate_text']:
return (
'Briefly describe the other factor that you think influenced your bonus'
)
if (
int(values['e_learn_effort'] or 0)
+ int(values['e_learn_outcome'] or 0)
+ int(values['e_learn_other'] or 0)
!= 100
):
return (
'Please make sure that you distributed a total of 100 for the last question. Right now the total is '
+ str(
int(values['e_learn_effort'] or 0)
+ int(values['e_learn_outcome'] or 0)
+ int(values['e_learn_other'] or 0)
)
)
if int(values['e_learn_other'] or 0) > 0 and not values['e_learn_text']:
return (
'Briefly describe the other factor that you think influenced your bonus'
)
class Employee_3(Page):
@staticmethod
def is_displayed(player: Player):
return get_role(player) == "Employee"
form_model = 'player'
form_fields = [
'risk',
'fair_allocation',
'e_punnish_effort',
'e_luck',
'e_fair',
'e_predict',
'e_uncertain',
]
class Supervisor_1(Page):
@staticmethod
def is_displayed(player: Player):
return get_role(player) == "Supervisor"
form_model = 'player'
@staticmethod
def get_form_fields(player: Player):
if player.participant.vars['treatment_noG']==1:
return ['s_importance_balls' ,
's_importance_fair' ,
's_importance_e_fair' ,
's_bi_effort',
's_bi_outcome',
's_bi_other',
's_bi_text',]
else:
return [ 's_importance_guideline',
's_importance_balls' ,
's_importance_fair' ,
's_importance_e_fair' ,
's_bi_effort',
's_bi_outcome',
's_bi_other',
's_bi_text',]
@staticmethod
def error_message(player: Player, values):
if (
int(values['s_bi_effort'] or 0)
+ int(values['s_bi_outcome'] or 0)
+ int(values['s_bi_other'] or 0)
!= 100
):
return (
'Please make sure that you distributed a total of 100 for the last question. Right now the total is '
+ str(
int(values['s_bi_effort'] or 0)
+ int(values['s_bi_outcome'] or 0)
+ int(values['s_bi_other'] or 0)
)
)
if int(values['s_bi_other'] or 0) > 0 and not values['s_bi_text']:
return (
'Briefly describe the other factor that influenced your bonus for the last question'
)
class Supervisor_2(Page):
@staticmethod
def is_displayed(player: Player):
return get_role(player) == "Supervisor"
form_model = 'player'
form_fields = ['risk','fair_allocation','s_motivation_allocation','s_employee_expectation']
class Supervisor_3(Page):
@staticmethod
def is_displayed(player: Player):
return get_role(player) == "Supervisor"
form_model = 'player'
@staticmethod
def get_form_fields(player: Player):
if player.participant.vars['treatment_noG']==1:
return [ 's_employee_can_predict' ,
's_employee_uncertain' ,
]
else:
return [ 's_employee_anticipation',
's_employee_can_predict' ,
's_employee_uncertain' ,
's_guidline_convention' ,
's_guideline_coordonation',
's_guideline_moral',
's_guidleline_fair',
's_guidleline_punish',]
class Employee_Supervisor_4(Page):
form_model = 'player'
@staticmethod
def get_form_fields(player: Player):
if player.participant.vars['treatment_noG']==1:
return [ 'assymetric_low',
'assymetric_high',
]
else:
return [ 'assymetric_low',
'assymetric_high',
's_fair_without_guide']
page_sequence = [
Intro,
open_ended,
Employee_1,
Employee_2,
Employee_3,
Supervisor_1,
Supervisor_2,
Supervisor_3,
Employee_Supervisor_4,
IA_E,
IA_G,
Susceptability,
Demographics,
]