import random
import numpy as np
from otree.api import *
doc = """
Informational Cost of Interventions - baseline & deterministic app with 10 rounds.
In base its 5 Part 1s, 1 Part 2, 5 Part 1s and 1 Part 2.
In Det its 5 Treatments, 5 Part 1s, and 1 Part 2.
"""
class C(BaseConstants):
NAME_IN_URL = 'strategy_method'
PLAYERS_PER_GROUP = None
PARAMETERIZATIONS = list(range(1, 11))
NUM_ROUNDS = len(PARAMETERIZATIONS)
OUTSIDE_OPTION = cu(2.2)
PROBABILITY_OF_SWITCH = 0.25
REVIEW_INSTRUCTIONS = 'informational_cost/reviewInstructions.html'
COMPUTER_INTRO_TYPES = 'informational_cost/computerTypes.html'
COMPUTER_INTRO_TYPES_INTRO = 'intro/computerTypes.html'
PART1_TEMPLATE = 'intro/part1.html' # this comes from the other app
PART2_TEMPLATE = 'informational_cost/part2.html'
BONUS_PART1_TEMPLATE = 'informational_cost/bonus_part1.html'
BONUS_PART2_TEMPLATE = 'informational_cost/bonus_part2.html'
INSTRUCTIONS1_TEMPLATE = 'informational_cost/instructions1_template.html'
PART1_INTRO_TEMPLATE = 'intro/part1.html'
PART2_INTRO_TEMPLATE = 'intro/part2.html'
BONUS_INTRO_TEMPLATE = 'intro/bonus.html'
# Each of the 5 stages corresponds to our parameterization as in the overleaf document
LABEL_POOL = ['Green', 'Blue', 'Orange', 'Purple', 'Gray', 'Black', 'Gold', 'Silver', 'Navy', 'Indigo']
LABEL_SEP = ['Yellow', 'Red', 'Violet', 'Pink', 'Brown', 'Beige', 'White', 'Maroon', 'Burgundy', 'Olive']
class Subsession(BaseSubsession):
pass
# def make_field_bonusChoice_sep():
# choices = [
# [1, 'The amount produced by the Good computer.'],
# [2, 'The amount produced by the Bad computer.'],
# [3, 'The fixed payment, independent of how much the computers produce.']
# ]
# random.shuffle(choices)
# return models.IntegerField(blank=True,
# choices=choices,
# widget=widgets.RadioSelect)
#
# def make_field_bonusChoice_pool():
# x = random.randint(1, 2)
# print('x='+str(x))
# choices = [
# [x, 'The amount produced by the computer of unknown quality.'],
# # [2, 'The amount produced by the computer of unknown quality.'],
# [3, 'The fixed payment, independent of how much the computers produce.']
# ]
# random.shuffle(choices)
# return models.IntegerField(blank=True,
# choices=choices,
# widget=widgets.RadioSelect)
class Group(BaseGroup):
pass
class Player(BasePlayer):
timeSpent = models.FloatField() # one unit is 100 milliseconds (a decimal of a second): 96 means 9.6 secs
timeSpentBonus = models.FloatField() # one unit is 100 milliseconds (a decimal of a second): 96 means 9.6 secs
cq1_intro = models.IntegerField(blank=True,
choices=[
[1, 'It does not do anything.'],
[2, 'It solves different tasks.'],
[3, 'It decides what task it solves.']
],
widget=widgets.RadioSelect,
label='What does the computer do?'
)
cq2_intro = models.IntegerField(blank=True,
choices=[
[1, 'Only one, which can be of Good or the Bad quality.'],
[2, 'Two, one of Good quality and one of Bad quality.'],
[3, 'There are no computers.']
],
widget=widgets.RadioSelect,
label='How many computers are there in this decision?'
)
cq3_intro = models.IntegerField(blank=True,
choices=[
[1, 'Yes, there is only one computer which solves tasks in both part 1 '
'and part 2, but the computer can be of a different quality in part 1 and part 2.'],
[2, 'No, there are two computers, one for each part.'],
[3, 'Yes, there is only one computer in this decision which solves tasks in both '
'part 1 and part 2, and the computer is of the same quality in both parts.']
],
widget=widgets.RadioSelect,
label='Is the computer that solves the task in part 1 the same as the one that '
'solves the task in part 2 in this decision?'
)
cq1_intro_det = models.IntegerField(blank=True,
choices=[
[1, 'They do not do anything.'],
[2, 'They solve tasks.'],
[3, 'They decide what task they solve.']
],
widget=widgets.RadioSelect,
label='What do the computers do?'
)
cq2_intro_det = models.IntegerField(blank=True,
choices=[
[1, 'Only one, which can be of Good or the Bad quality.'],
[2, 'Two, one of Good quality and one of Bad quality.'],
[3, 'There are no computers.']
],
widget=widgets.RadioSelect,
label='How many computers are there in this decision?'
)
cq3_intro_det = models.IntegerField(blank=True,
choices=[
[1, 'Yes, there are two computers which solve tasks in both part 1 '
'and part 2, but the computers can be of different quality in part 1 and part 2.'],
[2, 'No, there are four computers, two for each part.'],
[3,
'Yes, there are two computers in this decision which solve tasks in both '
'part 1 and part 2, and the computers are of the same quality in both parts.']
],
widget=widgets.RadioSelect,
label='Are the computers that solve the task in part 1 the same as the ones '
'that solve the task in part 2 in this decision?'
)
cq1 = models.IntegerField(blank=True,
widget=widgets.RadioSelect,
label='In part 2 of this decision, which type of task does the computer solve?'
)
cq2 = models.IntegerField(blank=True,
widget=widgets.RadioSelect,
label='How is your bonus determined in this decision?'
)
# cq3 = models.IntegerField(blank=True,
# widget=widgets.RadioSelect,
# label=" Which task allows you to tell the computer's quality after part 1? "
# ""
# )
# cq_part2 = models.IntegerField(blank=True,
# widget=widgets.RadioSelect)
for j in range(1, 4):
locals()['cq' + str(j) + '_intro_mistakes'] = models.IntegerField(blank=True, initial=0)
del j
for j in range(1, 4):
locals()['cq' + str(j) + '_intro_det_mistakes'] = models.IntegerField(blank=True, initial=0)
del j
intro_cq_mistakes = models.IntegerField(blank=True)
for j in range(1, 4):
locals()['cq' + str(j) + '_mistakes'] = models.IntegerField(blank=True, initial=0)
del j
# cq_part2_mistakes = models.IntegerField(blank=True, initial=0)
info_cost_cq_mistakes = models.IntegerField(blank=True, initial=0)
bonusChoice = models.IntegerField(blank=True,
widget=widgets.RadioSelect,
label='How do you want your bonus for part 2 to be determined?')
environment_choice = models.BooleanField(
widget=widgets.RadioSelect,
blank=True)
message = models.LongStringField(blank=True, label='What approach did you use in the last 5 decisions?')
explain = models.LongStringField(blank=True)
approach = models.LongStringField(blank=True, label= 'Throughout this study, what was your approach to choosing the task? Did it change over time?')
advice = models.IntegerField(blank=True,
widget=widgets.RadioSelect
)
change = models.IntegerField(blank=True,
choices=[
[1, 'Yes'],
[2, 'No']
],
widget=widgets.RadioSelect
)
sep_task = models.IntegerField(blank=True,
widget=widgets.RadioSelect
)
bonusChoicePool = models.IntegerField(blank=True,
widget=widgets.RadioSelect)
bonusChoiceSep = models.IntegerField(blank=True,
widget=widgets.RadioSelect)
# bonusChoiceSepBad = make_field_bonusChoice()
bonus_guess_plan = models.FloatField(blank=True, label='Average bonus of participants with the planning tool:')
bonus_guess_no_plan = models.FloatField(blank=True, label='Average bonus of participants without the planning tool:')
# FUNCTIONS
def environment_choice_choices(player):
pp = player.participant
ps = player.session
current_parameterization = pp.param_rounds[player.round_number - 1]
part1_bonus = ps.parameterization[current_parameterization - 1][:3]
part2_bonus = ps.parameterization[current_parameterization - 1][-2:]
comp_type = pp.compType[player.round_number - 1]
if player.participant.treatment == 'strategy':
if player.bonusChoicePool == 3: # if in pooling they chose outside option
choices = [
[True, C.LABEL_POOL[player.round_number - 1] + " task. The computers produce " + str(cu(part1_bonus[0]*2)) +
" and you get a " + str(C.OUTSIDE_OPTION) + " bonus in part 2, as you selected."]]
else:
choices = [
[True, C.LABEL_POOL[player.round_number - 1] + " task. You get a " + str(cu(part1_bonus[0]*2)) +
' bonus in part 1. If you chose the Good computer, you get a ' + str(cu(part2_bonus[0])) + " bonus in part 2."
" If you chose the Bad computer, you get a " + str(cu(part2_bonus[1])) + " bonus in part 2."]]
# part_1_bonus = str(cu(part1_bonus[1])) if comp_type == 1 else str(cu(part1_bonus[2]))
if player.bonusChoiceSep == 3: # if in separating they chose outside option
choices.append([False, C.LABEL_SEP[player.round_number-1] + " task. You "
"get a " + str(cu(part1_bonus[1]+part1_bonus[2])) +
' bonus in part 1, and a ' + str(C.OUTSIDE_OPTION) + " bonus in part 2."])
if player.bonusChoiceSep == 1: # if in separating they chose Good
choices.append([False, C.LABEL_SEP[
player.round_number - 1] + " task. You "
"get a " + str(cu(part1_bonus[1] + part1_bonus[2])) +
' bonus in part 1, and a ' + str(cu(part2_bonus[0])) + " bonus in part 2."])
if player.bonusChoiceSep == 2:
choices.append([False, C.LABEL_SEP[
player.round_number - 1] + " task. You "
"get a " + str(cu(part1_bonus[1] + part1_bonus[2])) +
' bonus in part 1, and a ' + str(
cu(part2_bonus[1])) + " bonus in part 2."])
else:
choices = [
[True, C.LABEL_POOL[player.round_number - 1] + ' task.'],
[False, C.LABEL_SEP[player.round_number - 1] + ' task.']]
# elif player.bonusChoiceSepBad == 3: # if in separating-bad they chose outside option
# choices.append([False, C.LABEL_SEP[player.round_number-1] + " task. If the computer is of the Good quality, you "
# "get a " + str(cu(part1_bonus[1])) +
# ' bonus in part 1, and a ' + str(C.OUTSIDE_OPTION) + " bonus in part 2. If it is of the Bad quality, "
# "you get a " + str(cu(part1_bonus[2])) +
# ' bonus in part 1, and a ' + str(C.OUTSIDE_OPTION) + " bonus in part 2."])
# elif player.bonusChoiceSepGood == 1: # if in separating-good they chose hire
# if player.bonusChoiceSepBad == 1: # if in separating-bad they chose hire
# choices.append([False, C.LABEL_SEP[player.round_number-1] + " task. If the computer is of the Good quality, you "
# "get a " + str(cu(part1_bonus[1])) +
# ' bonus in part 1, and a ' + str(cu(part2_bonus[0])) +
# " bonus in part 2. If it is of the Bad quality, you get a " + str(cu(part1_bonus[2])) +
# ' bonus in part 1, and a ' + str(cu(part2_bonus[1])) + " bonus in part 2."])
# elif player.bonusChoiceSepBad == 3: # if in separating-bad they chose outside option
# choices.append([False, C.LABEL_SEP[player.round_number-1] + " task. If the computer is of the Good quality, you "
# "get a " + str(cu(part1_bonus[1])) +
# ' bonus in part 1, and a ' + str(cu(part2_bonus[0])) +
# " bonus in part 2. If it is of the Bad quality, you get a " + str(cu(part1_bonus[2])) +
# ' bonus in part 1, and a ' + str(C.OUTSIDE_OPTION) + " bonus in part 2."])
random.shuffle(choices)
return choices
def sep_task_choices(player):
choices = [
[1, C.LABEL_SEP[-1]],
[2, C.LABEL_POOL[-1]]
]
random.shuffle(choices)
return choices
# def cq_part2_choices(player):
# pp = player.participant
# chosen_decision_index = pp.chosen_decisions
# if pp.treatment == 'deterministic' and chosen_decision_index < 6:
# choices = [
# [1, 'No, I will never learn exactly how much each computer produced.'],
# [2, 'Yes, I will learn about it, but only once the experiment ends and I get my bonus payment.'],
# [3, 'Yes, I will learn how much each computer produced before part 2.']
# ]
# elif pp.treatment == 'salient' and chosen_decision_index < 6:
# if player.environment_choice:
# choices = [
# [3, "No, we will not tell you the computer's quality."],
# [2, "Yes, we will tell you the computer's quality, but only once the experiment ends and you get "
# "your bonus payment."],
# [1, "Yes, we will tell you the computer's quality before part 2."],
# ]
# else:
# choices = [
# [1, "No, we will not tell you the computer's quality."],
# [2, "Yes, we will tell you the computer's quality, but only once the experiment ends and you get "
# "your bonus payment."],
# [3, "Yes, we will tell you the computer's quality before part 2."],
# ]
# else:
# choices = [
# [1, 'No, I will never learn exactly how much the computer produced.'],
# [2, 'Yes, I will learn about it, but only once the experiment ends and I get '
# 'my bonus payment.'],
# [3, 'Yes, I will learn how much the computer produced before part 2.'],
# ]
# return choices
# def cq_part2_error_message(player, value):
# if not player.session.config['development']:
# if value is None:
# return 'Please, answer the question.'
# elif value != 3:
# player.cq_part2_mistakes += 1
# return 'Your answer is incorrect.'
def cq1_choices(player):
pp = player.participant
if not pp.base:
choices = [
[1, 'They solve the ' + C.LABEL_POOL[player.round_number-1] + ' task, and the '
+ C.LABEL_SEP[player.round_number-1] + ' task, for a total of two tasks.'],
[2, 'It has not yet been decided. It is my task to decide it.'],
[3, 'They solve the ' + C.LABEL_SEP[player.round_number-1] + ' task.'],
[4, 'They solve the ' + C.LABEL_POOL[player.round_number - 1] + ' task.']
]
else:
choices = [
[1, 'It solves the ' + C.LABEL_POOL[player.round_number-1] + ' task, and the '
+ C.LABEL_SEP[player.round_number-1] + ' task, for a total of two tasks.'],
[2, 'It has not yet been decided. It is my task to decide it.'],
[3, 'It solves the ' + C.LABEL_SEP[player.round_number-1] + ' task.'],
[4, 'It solves the ' + C.LABEL_POOL[player.round_number - 1] + ' task.']
]
random.shuffle(choices)
return choices
def cq1_error_message(player, value):
if not player.session.config['development']:
if value is None:
return 'Please, answer the question.'
elif value != 3:
player.cq1_mistakes += 1
return 'Your answer is incorrect. Please review the instructions for this decision.'
def cq2_choices(player):
pp = player.participant
if not pp.base:
choices = [
[1, 'For each task that the computers solve, I get ' +
str(cu(player.session.parameterization[player.participant.param_rounds[player.round_number-1] - 1][0])
) + '. This applies to both tasks.'],
[2, "In part 1, I get whatever amount the computers produce in that part's tasks. "
"I can choose my bonus for part 2 to be whatever amount the computer of my choice"
" produces in that part's task or a fixed bonus of " + str(C.OUTSIDE_OPTION) + '.'],
[3, 'For each task the computers solve, I get the amount they produce.'
' This applies to both tasks, and I get ' + str(C.OUTSIDE_OPTION) + ' on top of it.']
]
else:
choices = [
[1, 'For each task that the computer solves, I get ' +
str(cu(player.session.parameterization[player.participant.param_rounds[player.round_number-1] - 1][0])
) + '. This applies to both tasks.'],
[2, "In part 1, I get whatever amount the computer produces in that part's task. "
"I can choose my bonus for part 2 to be whatever amount the computer produces in that part's "
"task or a fixed bonus of " + str(C.OUTSIDE_OPTION) + '.'],
[3, 'For each task the computer solves, I get the amount it produces.'
' This applies to both tasks, and I get ' + str(C.OUTSIDE_OPTION) + ' on top of it.']
]
random.shuffle(choices)
return choices
def cq2_error_message(player, value):
if not player.session.config['development']:
if value is None:
return 'Please, answer the question.'
elif value != 2:
player.cq2_mistakes += 1
return 'Your answer is incorrect. Please review the instructions for this decision.'
# def cq3_choices(player):
# pp = player.participant
# choices = [
# [1, C.LABEL_POOL[player.round_number-1] + ' task.'],
# [2, C.LABEL_SEP[player.round_number-1] + ' task.']
# ]
# random.shuffle(choices)
# return choices
# def cq3_error_message(player, value):
# if not player.session.config['development']:
# if value is None:
# return 'Please, answer the question.'
# elif value != 2:
# player.cq3_mistakes += 1
# return 'Your answer is incorrect. Please review the instructions for this decision.'
def bonusChoicePool_choices(player):
pp = player.participant
ps = player.session
# chosen_decision_index = pp.chosen_decisions
part1_bonus = ps.parameterization[pp.param_rounds[player.round_number - 1] - 1][:3]
part1_bonus_pool = cu(part1_bonus[0])
x = player.participant.pool_choice[player.round_number-1]
if player.participant.treatment == 'strategy':
choices = [
[x, 'Both computers are of unknown quality. I want to get what one of them, chosen randomly, produces in part 2 as my bonus.'],
# [2, 'The amount produced by the computer of unknown quality.'],
[3, 'I want to get the fixed payment as my bonus.']
]
else:
choices = [
[x, 'Both computers produce '+ str(part1_bonus_pool) + ' in the ' + str(C.LABEL_POOL[player.round_number - 1]) +' task in part 1. I want to get what one of them, chosen randomly, produces in part 2 as my bonus.'],
# [2, 'The amount produced by the computer of unknown quality.'],
[3, 'I want to get the fixed payment as my bonus.']
]
random.shuffle(choices)
return choices
def bonusChoiceSep_choices(player):
pp = player.participant
ps = player.session
# chosen_decision_index = pp.chosen_decisions
part1_bonus = ps.parameterization[pp.param_rounds[player.round_number - 1] - 1][:3]
part1_bonus_good_sep = cu(part1_bonus[1])
part1_bonus_bad_sep = cu(part1_bonus[2])
# chosen_decision_index = pp.chosen_decisions
if player.participant.treatment == 'strategy':
choices = [
[1, 'This computer is Good. I want to get what it produces in part 2 as my bonus.'],
[2, 'This computer is Bad. I want to get what it produces in part 2 as my bonus.'],
[3, 'I want to get the fixed payment as my bonus.']
]
else:
choices = [
[1, 'This computer produces '+ str(part1_bonus_good_sep) + ' in the ' + str(C.LABEL_SEP[player.round_number - 1]) +' task in part 1. I want to get what it produces in part 2 as my bonus.'],
[2, 'This computer produces '+ str(part1_bonus_bad_sep) + ' in the ' + str(C.LABEL_SEP[player.round_number - 1]) +' task in part 1. I want to get what it produces in part 2 as my bonus.'],
[3, 'I want to get the fixed payment as my bonus.']
]
random.shuffle(choices)
return choices
def bonusChoice_error_message(player, value):
if not player.session.config['development'] and value is None:
return 'Please, answer the question.'
def environment_choice_error_message(player, value):
if not player.session.config['development'] and value is None:
return 'Please, answer the question.'
def vars_for_template1(player: Player):
pp = player.participant
ps = player.session
current_parameterization = pp.param_rounds[player.round_number - 1]
# chosen_decision_index = pp.chosen_decisions
# chosen_decision = chosen_decision_index if chosen_decision_index < 6 else chosen_decision_index - 5
part2_bonus = ps.parameterization[current_parameterization - 1][-2:]
part1_bonus = ps.parameterization[current_parameterization - 1][:3]
return dict(
comp_type=pp.compType[player.round_number-1],
part2_bonus_good=cu(part2_bonus[0]),
part2_bonus_bad=cu(part2_bonus[1]),
part1_bonus_pool=cu(part1_bonus[0]),
part1_bonus_good_sep=cu(part1_bonus[1]),
part1_bonus_bad_sep=cu(part1_bonus[2]),
current_parameterization=current_parameterization,
# chosen_decision=chosen_decision,
label_pool=C.LABEL_POOL[player.round_number-1],
label_sep=C.LABEL_SEP[player.round_number-1],
stage2_rounds=player.round_number - 5,
# stage_of_chosen_decision=1 if chosen_decision_index < 6 else 2,
decision_name = C.LABEL_POOL[player.round_number - 1] + '/' + C.LABEL_SEP[player.round_number - 1]
)
def advice_choices(player):
choices = [
[1, 'Advise that the computer solves the ' + C.LABEL_POOL[-1] + ' task.'],
[2, 'Advise that the computer solves the ' + C.LABEL_SEP[-1] + ' task.']
]
return choices
# PAGES
class Parameterization(Page):
vars_for_template = vars_for_template1
@staticmethod
def before_next_page(player: Player, timeout_happened):
print(player.participant.param_rounds[player.round_number-1])
class CQIntro(Page):
form_model = 'player'
@staticmethod
def is_displayed(player: Player):
return player.round_number == 1
@staticmethod
def get_form_fields(player):
questions = ['cq1_intro', 'cq2_intro', 'cq3_intro']
if not player.participant.base:
questions = [x + '_det' for x in questions]
return questions
@staticmethod
def error_message(player, values):
if not player.session.config['development']:
if player.participant.base:
solutions = dict(cq1_intro=2,
cq2_intro=1,
cq3_intro=3
)
else:
solutions = dict(cq1_intro_det=2,
cq2_intro_det=2,
cq3_intro_det=3
)
error_messages = dict()
for field_name in solutions:
if values[field_name] is None:
error_messages[field_name] = 'Please, answer the question.'
elif values[field_name] != solutions[field_name]:
error_messages[field_name] = 'Please, correct your answer!'
name = 'player.' + str(field_name) + '_mistakes'
exec("%s += 1" % name)
return error_messages
@staticmethod
def before_next_page(player: Player, timeout_happened):
if not player.participant.base:
player.intro_cq_mistakes = player.cq1_intro_det_mistakes + player.cq2_intro_det_mistakes + player.cq3_intro_det_mistakes
else:
player.intro_cq_mistakes = player.cq1_intro_mistakes + player.cq2_intro_mistakes + player.cq3_intro_mistakes
player.participant.pool_choice = random.choices([1, 2], k=C.NUM_ROUNDS)
# + player.cq4_mistakes + player.cq5_mistakes + player.cq1_det_mistakes + player.cq2_det_mistakes + \
# player.cq3_det_mistakes + player.cq4_det_mistakes
@staticmethod
def vars_for_template(player):
pp = player.participant
ps = player.session
# chosen_decision_index = pp.chosen_decisions
current_parameterization = pp.param_rounds[player.round_number - 1]
part2_bonus = ps.parameterization[current_parameterization - 1][-2:]
part1_bonus = ps.parameterization[current_parameterization - 1][:3]
return dict(
label_pool=C.LABEL_POOL[player.round_number - 1],
label_sep=C.LABEL_SEP[player.round_number - 1],
# stage_of_chosen_decision=1 if chosen_decision_index < 6 else 2,
current_parameterization=current_parameterization,
part2_bonus_good=cu(part2_bonus[0]),
part2_bonus_bad=cu(part2_bonus[1]),
part1_bonus_pool=cu(part1_bonus[0]),
part1_bonus_good_sep=cu(part1_bonus[1]),
part1_bonus_bad_sep=cu(part1_bonus[2]),
)
class CQ(Page):
form_model = 'player'
@staticmethod
def get_form_fields(player):
form_fields = ['cq1']
if player.round_number == 1:
form_fields += ['cq2']
return form_fields
@staticmethod
def before_next_page(player: Player, timeout_happened):
player.info_cost_cq_mistakes = player.cq1_mistakes + player.cq2_mistakes
@staticmethod
def vars_for_template(player):
pp = player.participant
ps = player.session
current_parameterization = pp.param_rounds[player.round_number - 1]
# chosen_decision_index = pp.chosen_decisions
# chosen_decision = chosen_decision_index if chosen_decision_index < 6 else chosen_decision_index - 5
part2_bonus = ps.parameterization[current_parameterization - 1][-2:]
part1_bonus = ps.parameterization[current_parameterization - 1][:3]
if not player.participant.base:
cq1_label = 'In part 2 of this decision, which task do the computers solve?'
else:
cq1_label = 'In part 2 of this decision, which task does the computer solve?'
cq2_label = 'How is your bonus determined in this decision?'
return dict(
comp_type=pp.compType[player.round_number - 1],
part2_bonus_good=cu(part2_bonus[0]),
part2_bonus_bad=cu(part2_bonus[1]),
part1_bonus_pool=cu(part1_bonus[0]),
part1_bonus_good_sep=cu(part1_bonus[1]),
part1_bonus_bad_sep=cu(part1_bonus[2]),
current_parameterization=current_parameterization,
# chosen_decision=chosen_decision,
label_pool=C.LABEL_POOL[player.round_number - 1],
label_sep=C.LABEL_SEP[player.round_number - 1],
stage2_rounds=player.round_number - 5,
# stage_of_chosen_decision=1 if chosen_decision_index < 6 else 2,
cq1_label=cq1_label,
cq2_label=cq2_label,
current_round = player.round_number
)
class EnvironmentStage(Page):
form_model = 'player'
form_fields = ['environment_choice', 'timeSpent']
def vars_for_template(player: Player):
pp = player.participant
ps = player.session
current_parameterization = pp.param_rounds[player.round_number - 1]
# chosen_decision_index = pp.chosen_decisions
# chosen_decision = chosen_decision_index if chosen_decision_index < 6 else chosen_decision_index - 5
part2_bonus = ps.parameterization[current_parameterization - 1][-2:]
part1_bonus = ps.parameterization[current_parameterization - 1][:3]
label = 'Which task do you want the computers to solve in part 1?' if not pp.base \
else 'Which task do you want the computer to solve in part 1?'
return dict(
comp_type=pp.compType[player.round_number - 1],
part2_bonus_good=cu(part2_bonus[0]),
part2_bonus_bad=cu(part2_bonus[1]),
part1_bonus_pool=cu(part1_bonus[0]),
part1_bonus_good_sep=cu(part1_bonus[1]),
part1_bonus_bad_sep=cu(part1_bonus[2]),
current_parameterization=current_parameterization,
# chosen_decision=chosen_decision,
label_pool=C.LABEL_POOL[player.round_number-1],
label_sep=C.LABEL_SEP[player.round_number-1],
label=label,
stage2_rounds=player.round_number - 5,
# stage_of_chosen_decision=1 if chosen_decision_index < 6 else 2,
decision_name = C.LABEL_POOL[player.round_number - 1] + '/' + C.LABEL_SEP[player.round_number - 1]
)
@staticmethod
def error_message(player, values):
if player.session.config['development']:
values['environment_choice'] = True
player.environment_choice = True
elif values['environment_choice'] is None:
return 'Please, answer the question.'
@staticmethod
def before_next_page(player, timeout_happened):
environment_choice_MaybeNone = player.field_maybe_none('environment_choice')
if player.session.config['development'] and environment_choice_MaybeNone is None:
player.environment_choice = True
@staticmethod
def is_displayed(player: Player):
return player.participant.treatment == 'strategy'
# if player.participant.det and player.round_number == 5:
# player.participant.det = False
# player.participant.base = True
# if player.participant.salient and player.round_number == 5:
# player.participant.salient = False
# player.participant.base = True
# class PostDifficultyChoice(Page):
# form_model = 'player'
# form_fields = ['cq_part2']
#
# def vars_for_template(player: Player):
# pp = player.participant
# chosen_decision_index = pp.chosen_decisions
# chosen_decision = chosen_decision_index if chosen_decision_index < 6 else chosen_decision_index - 5
# current_parameterization = pp.param_rounds[player.round_number - 1]
# if pp.treatment == 'deterministic' and chosen_decision_index < 6:
# label = 'Will you learn how much money each computer produced in part 1?'
# elif pp.treatment == 'salient' and chosen_decision_index < 6:
# label = "Will we tell you the computer's quality?"
# else:
# label = 'Will you learn how much money the computer produced in part 1?'
# return dict(
# comp_type=player.participant.compType[player.round_number - 1],
# current_parameterization=current_parameterization,
# chosen_decision=chosen_decision,
# label_pool=C.LABEL_POOL[player.round_number - 1],
# label_sep=C.LABEL_SEP[player.round_number - 1],
# label=label,
# environment_chosen_decision=player.environment_choice,
# )
# class ObserveMistakes(Page):
# @staticmethod
# def vars_for_template(player: Player):
# pp = player.participant
# ps = player.session
# chosen_decision_index = pp.chosen_decisions
# chosen_decision = chosen_decision_index if chosen_decision_index < 6 else chosen_decision_index - 5
# part1_bonus = ps.parameterization[player.participant.param_rounds[player.round_number - 1] - 1][:3]
# myDict = dict(chosen_decision=chosen_decision,
# environment_chosen_decision=player.environment_choice,
# label_pool=C.LABEL_POOL[player.round_number - 1],
# label_sep=C.LABEL_SEP[player.round_number - 1],
# stage_of_chosen_decision=1 if chosen_decision_index < 6 else 2,
# part1_bonus_pool=cu(part1_bonus[0]),
# part1_bonus_good_sep=cu(part1_bonus[1]),
# part1_bonus_bad_sep=cu(part1_bonus[2]),
# current_parameterization=pp.param_rounds[player.round_number - 1],
# comp_type=pp.compType[player.round_number - 1],
# )
# # Below we compute payoffs
# # if pp.treatment == 'deterministic' and chosen_decision_index < 6:
# # if environment_chosen_decision: # pooling chosen
# # payoff_part1 = ps.parameterization[pp.param_rounds[chosen_decision_index - 1] - 1][0] * 2
# # pp.part1_payoffs.append(payoff_part1)
# # else: # separating chosen
# # payoff_part1_good = ps.parameterization[pp.param_rounds[chosen_decision_index - 1] - 1][1]
# # payoff_part1_bad = ps.parameterization[pp.param_rounds[chosen_decision_index - 1] - 1][2]
# # payoff_part1 = payoff_part1_good + payoff_part1_bad
# # pp.part1_payoffs.append(payoff_part1)
# # myDict.update(payoff_part1_good=cu(payoff_part1_good),
# # payoff_part1_bad=cu(payoff_part1_bad))
# # else:
# if player.environment_choice: # pooling chosen
# payoff_part1 = ps.parameterization[pp.param_rounds[player.round_number - 1] - 1][0]
# else: # separating chosen
# if pp.compType[player.round_number - 1] == 1: # if comp is Good
# payoff_part1 = ps.parameterization[pp.param_rounds[player.round_number - 1] - 1][1]
# else: # if comp is Bad
# payoff_part1 = ps.parameterization[pp.param_rounds[player.round_number - 1] - 1][2]
# pp.part1_payoffs.append(payoff_part1)
# myDict.update(payoff_part1=cu(payoff_part1))
# # if not pp.treatment == 'base':
# # pp.part1_payoffs.append(payoff_part1)
# return myDict
class BonusChoice(Page):
form_model = 'player'
@staticmethod
def get_form_fields(player):
questions = ['bonusChoicePool', 'bonusChoiceSep', 'timeSpentBonus']
if player.participant.treatment == 'plan':
questions += ['environment_choice']
return questions
def vars_for_template(player: Player):
pp = player.participant
ps = player.session
# chosen_decision_index = pp.chosen_decisions
# chosen_decision = chosen_decision_index if chosen_decision_index < 6 else chosen_decision_index - 5
part2_bonus = ps.parameterization[pp.param_rounds[player.round_number - 1] - 1][-2:]
part1_bonus = ps.parameterization[pp.param_rounds[player.round_number - 1] - 1][:3]
if player.participant.treatment=='strategy':
label_Pool = 'If the computers solve the ' + str(C.LABEL_POOL[player.round_number - 1]) + \
' task in part 1 (and hence you will not know their quality):'
label_Sep = 'If the computers solve the ' + str(C.LABEL_SEP[player.round_number - 1]) + \
' task in part 1 (and hence you will know their quality):'
else:
label_Pool = 'If the computers solve the ' + str(C.LABEL_POOL[player.round_number - 1]) + \
' task in part 1:'
label_Sep = 'If the computers solve the ' + str(C.LABEL_SEP[player.round_number - 1]) + \
' task in part 1:'
label_env = 'Which task do you want the computers to solve in part 1?'
# environment_chosen_decision = player.environment_choice
payoff_part1_good = ps.parameterization[pp.param_rounds[player.round_number - 1] - 1][1]
payoff_part1_bad = ps.parameterization[pp.param_rounds[player.round_number - 1] - 1][2]
# stage_of_chosen_decision = 1 if chosen_decision_index < 6 else 2
return dict(
comp_type=pp.compType[player.round_number - 1],
part2_bonus_good=cu(part2_bonus[0]),
part2_bonus_bad=cu(part2_bonus[1]),
part1_bonus_pool=cu(part1_bonus[0]),
part1_bonus_good_sep=cu(part1_bonus[1]),
part1_bonus_bad_sep=cu(part1_bonus[2]),
current_parameterization=pp.param_rounds[player.round_number - 1],
# chosen_decision=chosen_decision,
label_pool=C.LABEL_POOL[player.round_number - 1],
label_sep=C.LABEL_SEP[player.round_number - 1],
label_env=label_env,
# stage_of_chosen_decision=stage_of_chosen_decision,
# environment_chosen_decision=environment_chosen_decision,
# payoff_part1=cu(pp.part1_payoffs[player.round_number-1]),
# payoff_part1_indiv=cu(pp.part1_payoffs[player.round_number-1]/2),
# payoff_part1_good=cu(payoff_part1_good),
# payoff_part1_bad=cu(payoff_part1_bad),
label_Pool=label_Pool,
label_Sep=label_Sep,
# label_Sep_Bad='If the computer faces the ' + str(C.LABEL_SEP[player.round_number - 1]) +
# ' task in part 1 and is of the Bad Quality:',
decision_name=C.LABEL_POOL[player.round_number - 1] + '/' + C.LABEL_SEP[player.round_number - 1]
)
@staticmethod
def before_next_page(player, timeout_happened):
bonusChoicePool_MaybeNone = player.field_maybe_none('bonusChoicePool')
bonusChoiceSep_MaybeNone = player.field_maybe_none('bonusChoiceSep')
environment_choice_MaybeNone = player.field_maybe_none('environment_choice')
# bonusChoiceSepBad_MaybeNone = player.field_maybe_none('bonusChoiceSepBad')
if player.session.config['development'] and bonusChoicePool_MaybeNone is None:
player.bonusChoicePool = 1
if player.session.config['development'] and bonusChoiceSep_MaybeNone is None:
player.bonusChoiceSep = 1
if player.session.config['development'] and environment_choice_MaybeNone is None and player.participant.treatment=='plan':
player.environment_choice = True
# if player.participant.treatment == 'strategy':
# player.environment_choice = True
# if player.session.config['development'] and bonusChoiceSepBad_MaybeNone is None:
# player.bonusChoiceSepBad = 1
@staticmethod
def error_message(player, values):
if not player.session.config['development'] and values['bonusChoicePool'] is None:
return 'Please, answer the question.'
if not player.session.config['development'] and values['bonusChoiceSep'] is None:
return 'Please, answer the question.'
if player.participant.treatment == 'plan' and not player.session.config['development'] and values['environment_choice'] is None:
return 'Please, answer the question.'
# if not player.session.config['development'] and values['bonusChoiceSepBad'] is None:
# return 'Please, answer the question.'
class PostBonusChoice(Page):
@staticmethod
def vars_for_template(player: Player):
pp = player.participant
ps = player.session
if player.environment_choice: # pooling chosen
payoff_part1 = cu(ps.parameterization[pp.param_rounds[player.round_number - 1] - 1][0]*2)
if player.bonusChoicePool == 1: # if variable payment is chosen and computer is good
payoff_part2 = cu(ps.parameterization[pp.param_rounds[player.round_number - 1] - 1][3])
elif player.bonusChoicePool == 2: # variable payment chosen and computer is bad
payoff_part2 = cu(ps.parameterization[pp.param_rounds[player.round_number - 1] - 1][4])
else: # if outside option is chosen
payoff_part2 = C.OUTSIDE_OPTION
# if player.bonusChoicePool == 1: # if variable payment is chosen
# if pp.compType[player.round_number - 1] == 1: # variable payment chosen and computer is good
# payoff_part2 = cu(ps.parameterization[pp.param_rounds[player.round_number - 1] - 1][3])
# else: # variable payment chosen and computer is bad
# payoff_part2 = cu(ps.parameterization[pp.param_rounds[player.round_number - 1] - 1][4])
# else: # if outside option is chosen
# payoff_part2 = C.OUTSIDE_OPTION
else: # separating chosen
payoff_part1 = cu(ps.parameterization[pp.param_rounds[player.round_number - 1] - 1][1]+ps.parameterization[pp.param_rounds[player.round_number - 1] - 1][2])
if player.bonusChoiceSep == 1: # if variable payment is chosen and computer is good
payoff_part2 = cu(ps.parameterization[pp.param_rounds[player.round_number - 1] - 1][3])
elif player.bonusChoiceSep == 2: # variable payment chosen and computer is bad
payoff_part2 = cu(ps.parameterization[pp.param_rounds[player.round_number - 1] - 1][4])
else: # if outside option is chosen
payoff_part2 = C.OUTSIDE_OPTION
# if pp.compType[player.round_number - 1] == 1: # if comp is Good
# payoff_part1 = cu(ps.parameterization[pp.param_rounds[player.round_number - 1] - 1][1])
# if player.bonusChoiceSepGood == 1: # if variable payment is chosen
# payoff_part2 = cu(ps.parameterization[pp.param_rounds[player.round_number - 1] - 1][3])
# else: # if outside option is chosen
# payoff_part2 = C.OUTSIDE_OPTION
# else: # if comp is Bad
# payoff_part1 = cu(ps.parameterization[pp.param_rounds[player.round_number - 1] - 1][2])
# if player.bonusChoiceSepBad == 1: # if variable payment is chosen
# payoff_part2 = cu(ps.parameterization[pp.param_rounds[player.round_number - 1] - 1][4])
# else: # if outside option is chosen
# payoff_part2 = C.OUTSIDE_OPTION
pp.part1_payoffs.append(payoff_part1)
pp.part2_payoffs.append(payoff_part2)
part2_sep = True if (player.environment_choice and not player.bonusChoicePool == 3) or \
(not player.environment_choice and not player.bonusChoiceSep == 3) else False
# if not pp.treatment == 'base':
# pp.part2_payoffs.append(payoff_part2)
return dict(
payoff_part2=payoff_part2,
payoff_part1=payoff_part1,
payoff_total = payoff_part1+payoff_part2,
part2_sep = part2_sep,
label_pool=C.LABEL_POOL[player.round_number - 1],
label_sep=C.LABEL_SEP[player.round_number - 1],
decision_name=C.LABEL_POOL[player.round_number - 1] + '/' + C.LABEL_SEP[player.round_number - 1],
progress=int(player.round_number / C.NUM_ROUNDS * 100),
part2_unknown=player.environment_choice,
part2_good = True if (not player.environment_choice and player.bonusChoiceSep == 1) else False
)
# @staticmethod
# def before_next_page(player: Player, timeout_happened):
# pp = player.participant
# all_participant_choices = []
# all_bonus_participant_choices = []
# if not pp.treatment == 'base': # in these treatments we only record the last bonusChoice since its the only one elicited
# pp.environment_choice = player.environment_choice
# pp.bonus_choices = player.bonusChoice
# else:
# if player.round_number == C.NUM_ROUNDS: # in baseline we record the last bonusChoice and the one in round 5, which are the two we elicit
# all_participant_choices.append(player.in_round(5).environment_choice)
# all_participant_choices.append(player.environment_choice)
# pp.environment_choice = all_participant_choices
# all_bonus_participant_choices.append(player.in_round(5).bonusChoice)
# all_bonus_participant_choices.append(player.bonusChoice)
# pp.bonus_choices = all_bonus_participant_choices
class Transition(Page):
@staticmethod
def is_displayed(player: Player):
return player.round_number == C.NUM_ROUNDS
# class TransitionDet(Page):
# vars_for_template = vars_for_template1
#
# @staticmethod
# def is_displayed(player: Player):
# return player.round_number == 5 and player.participant.treatment == 'deterministic'
class TransitionSalient(Page):
vars_for_template = vars_for_template1
@staticmethod
def is_displayed(player: Player):
return player.round_number == 5 and player.participant.treatment == 'salient'
class Message(Page):
form_model = 'player'
form_fields = ['message']
# @staticmethod
# def vars_for_template(player):
# ps = player.session
# # if player.environment_choice:
# # label = 'In part 1 of the last decision, you chose the ' + \
# # C.LABEL_POOL[-1] + ' task. Why did you choose this task?'
# # change_label = 'In part 1 of the last decision, you chose the ' + \
# # C.LABEL_POOL[-1] + ' task. If you had a chance to revise your choice, would you prefer to choose the '+ C.LABEL_SEP[-1] + ' task instead?'
# # else:
# # label = 'In part 1 of the last decision, you chose the ' + \
# # C.LABEL_SEP[-1] + ' task. Why did you choose this task?'
# # change_label = 'In part 1 of the last decision, you chose the ' + \
# # C.LABEL_SEP[-1] + ' task. If you had a chance to revise your choice, would you prefer to choose the ' + C.LABEL_POOL[
# # -1] + ' task instead?'
# # if not player.participant.base:
# # adv_label = 'If you could advise another participant on the last decision of whether the computers ' \
# # 'solve the ' + C.LABEL_POOL[-1] + ' or the ' + C.LABEL_SEP[
# # -1] + ' task, which would you advise ' \
# # 'them to choose?'
# # sep_task_label = 'In part 1 of the last decision, which task allows you to learn the quality of the computers?'
# # else:
# # adv_label = 'If you could advise another participant on the last decision of whether the computer ' \
# # 'solves the ' + C.LABEL_POOL[-1] + ' or the ' + C.LABEL_SEP[-1] + ' task, which would you advise ' \
# # 'them to choose?'
# # sep_task_label= 'In part 1 of the last decision, which task allows you to learn the quality of the computer?'
# current_parameterization = player.participant.param_rounds[- 1]
# part2_bonus = ps.parameterization[current_parameterization - 1][-2:]
# part1_bonus = ps.parameterization[current_parameterization - 1][:3]
# return dict(
# # explain_label=label,
# # advice_label=adv_label,
# # change_label = change_label,
# # sep_task_label=sep_task_label,
# label_pool=C.LABEL_POOL[- 1],
# label_sep=C.LABEL_SEP[- 1],
# # # stage_of_chosen_decision=2,
# current_parameterization=current_parameterization,
# part2_bonus_good=cu(part2_bonus[0]),
# part2_bonus_bad=cu(part2_bonus[1]),
# part1_bonus_pool=cu(part1_bonus[0]),
# part1_bonus_good_sep=cu(part1_bonus[1]),
# part1_bonus_bad_sep=cu(part1_bonus[2])
# )
@staticmethod
def error_message(player, values):
if not player.session.config['development'] and (values['message']==''):
return 'Please, answer the questions.'
@staticmethod
def is_displayed(player: Player):
return player.round_number == C.NUM_ROUNDS
class GuessBonus(Page):
form_model = 'player'
form_fields = ['bonus_guess_plan', 'bonus_guess_no_plan']
@staticmethod
def error_message(player, values):
if not player.session.config['development'] and (values['bonus_guess_plan'] is None or values['bonus_guess_no_plan'] is None):
return 'Please, answer the questions.'
@staticmethod
def is_displayed(player: Player):
return player.round_number == C.NUM_ROUNDS and player.participant.treatment == 'plan'
class Hypothetical(Page):
form_model = 'player'
# form_fields = ['explain', 'approach', 'advice', 'change', 'sep_task']
form_fields = ['explain', 'advice', 'change', 'sep_task']
@staticmethod
def vars_for_template(player):
ps = player.session
if player.environment_choice:
label = 'In part 1 of the last decision, you chose the ' + \
C.LABEL_POOL[-1] + ' task. Why did you choose this task?'
change_label = 'In part 1 of the last decision, you chose the ' + \
C.LABEL_POOL[-1] + ' task. If you had a chance to revise your choice, would you prefer to choose the ' + C.LABEL_SEP[
-1] + ' task instead?'
else:
label = 'In part 1 of the last decision, you chose the ' + \
C.LABEL_SEP[-1] + ' task. Why did you choose this task?'
change_label = 'In part 1 of the last decision, you chose the ' + \
C.LABEL_SEP[-1] + ' task. If you had a chance to revise your choice, would you prefer to choose the ' + C.LABEL_POOL[
-1] + ' task instead?'
adv_label = 'If you could advise another participant on the last decision of whether the computer ' \
'solves the ' + C.LABEL_POOL[-1] + ' or the ' + C.LABEL_SEP[-1] + ' task, which would you advise ' \
'them to choose?'
sep_task_label = 'In part 1 of the last decision, which task allows you to learn the quality of the computers?'
current_parameterization = player.participant.param_rounds[- 1]
part2_bonus = ps.parameterization[current_parameterization - 1][-2:]
part1_bonus = ps.parameterization[current_parameterization - 1][:3]
return dict(
explain_label=label,
advice_label=adv_label,
change_label=change_label,
sep_task_label=sep_task_label,
label_pool=C.LABEL_POOL[- 1],
label_sep=C.LABEL_SEP[- 1],
stage_of_chosen_decision=2,
current_parameterization=current_parameterization,
part2_bonus_good=cu(part2_bonus[0]),
part2_bonus_bad=cu(part2_bonus[1]),
part1_bonus_pool=cu(part1_bonus[0]),
part1_bonus_good_sep=cu(part1_bonus[1]),
part1_bonus_bad_sep=cu(part1_bonus[2]),
)
@staticmethod
def error_message(player, values):
# if not player.session.config['development'] and (values['advice'] is None or values['change'] is None or values['sep_task'] is None or values['explain']=='' or values['approach']==''):
if not player.session.config['development'] and (values['advice'] is None or values['change'] is None or values['sep_task'] is None or values['explain']==''):
return 'Please, answer the questions.'
@staticmethod
def is_displayed(player: Player):
return player.round_number == C.NUM_ROUNDS
page_sequence = [
Parameterization,
CQIntro,
CQ,
# PostDifficultyChoice,
# ObserveMistakes,
BonusChoice,
EnvironmentStage,
PostBonusChoice,
Message,
GuessBonus,
Hypothetical
# Transition
# TransitionDet,
# TransitionSalient
]