import random
from otree.api import *
doc = """
This is a pilot version of inference-Self in the Failures of Strategic Thinking project.
"""
class C(BaseConstants):
NAME_IN_URL = 'inference'
PLAYERS_PER_GROUP = None
NUM_ROUNDS = 1
MIN_TIME = 15 # in minutes
MAX_TIME = 25 # in minutes
NUMBER_OF_MISTAKES = 1
RATE_OF_MISTAKES = 2
RATE_OF_MISTAKES2 = 1
BONUS_PER_CORRECT_TASK_PART1 = cu(0.15)
BONUS_PER_CORRECT_TASK_PART2 = cu(0.25)
OUTSIDE_OPTION = cu(1.5)
OUTSIDE_OPTION2 = cu(1)
NUMBER_OF_TASKS_PART1 = 2
NUMBER_OF_TASKS_PART2 = 10
PROBABILITY_OF_SWITCH = 0.25
PART1_MAX_BONUS = cu(BONUS_PER_CORRECT_TASK_PART1 * NUMBER_OF_TASKS_PART1)
PART2_MAX_BONUS = cu(BONUS_PER_CORRECT_TASK_PART2 * NUMBER_OF_TASKS_PART2)
PART1_TEMPLATE = 'inference/part1.html'
PART2_TEMPLATE = 'inference/part2.html'
BONUS_TEMPLATE = 'inference/bonus.html'
COMPUTER_TYPES = 'inference/computerTypes.html'
REVIEW_INSTRUCTIONS = 'inference/reviewInstructions.html'
PART12_TEMPLATE = 'inference/part12.html'
PART22_TEMPLATE = 'inference/part22.html'
BONUS2_TEMPLATE = 'inference/bonus2.html'
SOFTWARE_TYPES = 'inference/softwareTypes.html'
REVIEW_INSTRUCTIONS2 = 'inference/reviewInstructions2.html'
NUMBER_OF_STAGES = 6 # modify jointly with word below
NUMBER_OF_STAGES_WORD = 'six' # modify jointly with number above
class Subsession(BaseSubsession):
pass
def creating_session(subsession: Subsession):
for p in subsession.get_players():
p.treatment = random.choices(['baseline', 'naive', 'soph'], weights=subsession.session.config['weights'])[0]
stages_list = [*range(1, C.NUMBER_OF_STAGES + 1)]
p.stageCounts = random.choices(stages_list, weights=[1/C.NUMBER_OF_STAGES, 1/C.NUMBER_OF_STAGES,
1/C.NUMBER_OF_STAGES, 1/C.NUMBER_OF_STAGES,
1/C.NUMBER_OF_STAGES, 1/C.NUMBER_OF_STAGES])[0]
# All stages given equal weight in line above. Modify there if we want different weights.
if p.treatment == 'naive':
p.naive = True
elif p.treatment == 'soph':
p.soph = True
else:
p.baseline = True
p.compType = random.choice([0, 1])
p.compType_stage2 = random.choice([0, 1])
p.compType2 = random.choice([0, 1])
p.compType2_stage2 = random.choice([0, 1])
# print(p.treatment, 'CompType: (0 is Bad)', p.compType)
p.currentStage = 1
print(p.stageCounts)
class Group(BaseGroup):
pass
def make_field_bonusChoiceEasy():
return models.IntegerField(blank=True,
choices=[
[1, str(C.BONUS_PER_CORRECT_TASK_PART2) + ' for each task the computer solves '
'correctly '
'in this '
'part.'],
[2, str(C.OUTSIDE_OPTION) + ' independently of how many tasks the computer solves '
'in this part.']
],
widget=widgets.RadioSelect,
label='If the computer faces easy tasks in part 1 (and hence you observe no '
'mistakes):')
def make_field_bonusChoiceEasy2():
return models.IntegerField(blank=True,
choices=[
[1, str(C.PART2_MAX_BONUS) + ' minus ' + str(C.BONUS_PER_CORRECT_TASK_PART2)
+ ' for each mistake that the software makes.'],
[2, str(C.PART2_MAX_BONUS) + ' minus ' + str(C.OUTSIDE_OPTION2)
+ ' independently of how many tasks the software solves in this part.']
],
widget=widgets.RadioSelect,
label='If the software faces Landscape recognition tasks in part 1 '
'(and hence you observe no mistakes):')
def make_field_bonusChoiceHardGood():
return models.IntegerField(blank=True,
choices=[
[1, str(C.BONUS_PER_CORRECT_TASK_PART2) + ' for each task the computer solves '
'correctly in this part.'],
[2, str(C.OUTSIDE_OPTION) + ' independently of how many tasks the computer solves in'
' this part.']
],
widget=widgets.RadioSelect,
label='If the computer faces hard tasks in part 1 and you observe no mistakes:'
'')
def make_field_bonusChoiceHardGood2():
return models.IntegerField(blank=True,
choices=[
[1, str(C.PART2_MAX_BONUS) + ' minus ' + str(C.BONUS_PER_CORRECT_TASK_PART2)
+ ' for each mistake that the software makes.'],
[2, str(C.PART2_MAX_BONUS) + ' minus ' + str(C.OUTSIDE_OPTION2)
+ ' independently of how many tasks the software solves in this part.']
],
widget=widgets.RadioSelect,
label='If the software faces People recognition tasks in part 1 and you observe '
'no mistakes:')
def make_field_bonusChoiceHardBad():
return models.IntegerField(blank=True,
choices=[
[1, str(C.BONUS_PER_CORRECT_TASK_PART2) + ' for each task the computer solves '
'correctly in this part.'],
[2, str(C.OUTSIDE_OPTION) + ' independently of how many tasks the computer solves '
'in this part.']
],
widget=widgets.RadioSelect,
label='If the computer faces hard tasks in part 1 and you observe mistakes:'
'')
def make_field_bonusChoiceHardBad2():
return models.IntegerField(blank=True,
choices=[
[1, str(C.PART2_MAX_BONUS) + ' minus ' + str(C.BONUS_PER_CORRECT_TASK_PART2)
+ ' for each mistake that the software makes.'],
[2, str(C.PART2_MAX_BONUS) + ' minus ' + str(C.OUTSIDE_OPTION2)
+ ' independently of how many tasks the software solves in this part.']
],
widget=widgets.RadioSelect,
label='If the computer faces People recognition tasks in part 1 and you observe '
'mistakes:')
class Player(BasePlayer):
naive = models.BooleanField(initial=False)
soph = models.BooleanField(initial=False)
baseline = models.BooleanField(initial=False)
treatment = models.StringField()
stageCounts = models.IntegerField()
currentStage = models.IntegerField()
cq1 = models.IntegerField(blank=True,
choices=[
[1, 'It does not do anything.'],
[2, 'It solves math tasks that can be easy or hard.'],
[3, 'It decides whether the math tasks are easy or hard.']
],
widget=widgets.RadioSelect,
label='What does the Computer do?'
)
cq2 = models.IntegerField(blank=True,
choices=[
[1, 'Only one, which can be of the Good or the Bad type.'],
[2, 'Two, one of the Good type and one of the Bad type.'],
[3, 'There are many computers.']
],
widget=widgets.RadioSelect,
label='How many Computers are there in this stage?'
)
cq3 = 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 type in parts 1 and part 2.'],
[2, 'No, there are two computers, one for each part.'],
[3, 'Yes, there is only one computer in each stage which solves tasks in both part 1 '
'and part 2, and the computer can only be of one type throughout the stage.']
],
widget=widgets.RadioSelect,
label='Is the Computer that solves tasks in part 1 the same as the one that solves tasks'
' in part 2 of this stage?'
)
cq_stage2 = models.IntegerField(blank=True,
choices=[
[1, 'Yes, this is the same computer, so it is of the same type.'],
[2, 'No, this is a different computer which is unique to this stage. '
'It can be of the same or a different type than the one in stage 1.'],
[3, 'No, this is a different computer which is unique to this stage, but it is '
'of the same type as the computer in stage 1.']
],
widget=widgets.RadioSelect,
label='Is the Computer that solves tasks in this stage the same as the one that '
'solves tasks in stage 1?'
)
cq4 = models.IntegerField(blank=True,
choices=[
[1, 'It makes no mistakes in easy or hard tasks.'],
[2, 'It makes ' + str(C.NUMBER_OF_MISTAKES) + ' mistake every ' +
str(C.RATE_OF_MISTAKES) + ' easy tasks.'],
[3, 'It makes ' + str(C.NUMBER_OF_MISTAKES) + ' mistake every ' +
str(C.RATE_OF_MISTAKES) + ' hard tasks.']
],
widget=widgets.RadioSelect,
label='How many mistakes does a computer make if it is of the Good type?'
)
cq5 = models.IntegerField(blank=True,
choices=[
[1, 'It makes no mistakes in easy or hard tasks.'],
[2, 'It makes ' + str(C.NUMBER_OF_MISTAKES) + ' mistake every ' +
str(C.RATE_OF_MISTAKES) + ' easy tasks.'],
[3, 'It makes ' + str(C.NUMBER_OF_MISTAKES) + ' mistake every ' +
str(C.RATE_OF_MISTAKES) + ' hard tasks.']
],
widget=widgets.RadioSelect,
label='How many mistakes does a computer make if it is of the Bad type?'
)
cq5_stage2 = models.IntegerField(blank=True,
choices=[
[1, 'It makes no mistakes in easy or hard tasks.'],
[2, 'It makes mistakes in every hard task it faces.'],
[3, 'It makes ' + str(C.NUMBER_OF_MISTAKES) + ' mistake every ' +
str(C.RATE_OF_MISTAKES) + ' hard tasks.']
],
widget=widgets.RadioSelect,
label='How many mistakes does a computer make if it is of the Bad type?'
)
cq6 = models.IntegerField(blank=True,
widget=widgets.RadioSelect,
label='Does the computer face easy or hard tasks?'
)
cq7 = models.IntegerField(blank=True,
choices=[
[1, 'It faces ' + str(C.NUMBER_OF_TASKS_PART2) + ' easy and ' + str(
C.NUMBER_OF_TASKS_PART2)
+ ' hard tasks, for a total of ' + str(C.NUMBER_OF_TASKS_PART2 * 2) + '.'],
[2, 'It has not yet been decided. It is your task to decide it.'],
[3, 'It faces ' + str(C.NUMBER_OF_TASKS_PART2) + ' hard tasks.']
],
widget=widgets.RadioSelect,
label='In part 2, does the computer face ' + str(C.NUMBER_OF_TASKS_PART2) + ' easy or ' +
str(C.NUMBER_OF_TASKS_PART2) + ' hard tasks?'
)
cq8 = models.IntegerField(blank=True,
choices=[
[1, 'For each task that the computer solves correctly, you get ' +
str(C.BONUS_PER_CORRECT_TASK_PART1) + '. This applies to both tasks.'],
[2, 'For each task that the computer solves correctly in part 1, you get ' +
str(C.BONUS_PER_CORRECT_TASK_PART1) + '. '
'You can choose your bonus for part 2 to be '
+ str(C.BONUS_PER_CORRECT_TASK_PART2)
+ ' for each correctly solved task, or a fixed bonus of ' + str(C.OUTSIDE_OPTION)
+ '.'],
[3, 'For each task that the computer solves correctly, you get ' +
str(C.BONUS_PER_CORRECT_TASK_PART1) + ' in part 1, and ' +
str(C.BONUS_PER_CORRECT_TASK_PART2) + ' in part 2. '
'This applies to both tasks, and you get ' +
str(C.OUTSIDE_OPTION) + ' on top of it.']
],
widget=widgets.RadioSelect,
label='How is your bonus determined?'
)
cq8_naive = models.IntegerField(blank=True,
choices=[
[1, 'For each task that the computer solves incorrectly, you get ' +
str(C.BONUS_PER_CORRECT_TASK_PART1) + '.'],
[2, 'For each task that the computer solves correctly, you get ' +
str(C.BONUS_PER_CORRECT_TASK_PART1) + '.'],
[3, 'For each task, independent of whether the solution is correct or not, you'
' get ' + str(C.BONUS_PER_CORRECT_TASK_PART1) + '.']
],
widget=widgets.RadioSelect,
label='How is your bonus determined?'
)
cq9 = models.IntegerField(blank=True,
choices=[
[1, 'Only one.'],
[2, 'Two decisions.'],
[3, 'I do not have to make any decisions.']
],
widget=widgets.RadioSelect,
label='How many decisions will you make in this stage?'
)
cq9_soph = models.IntegerField(blank=True,
choices=[
[1, 'Two decisions, one decision about the task the computer faces in part 1, and one'
' decision on how the bonus is determined for part 2.'],
[2, 'Only one decision about the task the computer faces in part 1.'],
[3, 'Only one decision on how the bonus is determined for part 2.'],
[4, 'I do not have to make any decisions.']
],
widget=widgets.RadioSelect,
label='How many decisions will you make in this stage?'
)
cq10 = models.IntegerField(blank=True,
choices=[
[1, 'No, you will never learn exactly how many mistakes it made.'],
[2, 'Yes, you will learn about it but only once the experiment ends and you get your'
' bonus payment.'],
[3, 'Yes, you will learn about it before part 2.'],
],
widget=widgets.RadioSelect,
label='Will you learn the number of mistakes that the computer makes in part 1, if any?'
)
for j in range(1, 11):
locals()['cq' + str(j) + '_mistakes'] = models.IntegerField(blank=True, initial=0)
del j
cq9_soph_mistakes = models.IntegerField(blank=True, initial=0)
cq8_naive_mistakes = models.IntegerField(blank=True, initial=0)
cq5_stage2_mistakes = models.IntegerField(blank=True, initial=0)
cq_stage2_mistakes = models.IntegerField(blank=True, initial=0)
mistakes = models.IntegerField(blank=True)
mistakes2 = models.IntegerField(blank=True)
mistakes_stage2 = models.IntegerField(blank=True)
mistakes2_stage2 = models.IntegerField(blank=True)
payoffPart2 = models.CurrencyField(blank=True)
payoffPart22 = models.CurrencyField(blank=True)
payoffPart12 = models.CurrencyField(blank=True)
taskDifficulty = models.IntegerField(choices=[
[1, 'Easy'],
[2, 'Hard']
],
widget=widgets.RadioSelect,
blank=True)
taskDifficulty_stage2 = models.IntegerField(choices=[
[1, 'Easy'],
[2, 'Hard']
],
widget=widgets.RadioSelect,
blank=True)
taskDifficulty2 = models.IntegerField(choices=[
[1, 'Landscapes'],
[2, 'People']
],
widget=widgets.RadioSelect,
blank=True)
taskDifficulty2_stage2 = models.IntegerField(choices=[
[1, 'Landscapes'],
[2, 'People']
],
widget=widgets.RadioSelect,
blank=True)
bonusChoice = models.IntegerField(blank=True,
choices=[
[1, str(C.BONUS_PER_CORRECT_TASK_PART2) + ' for each task the computer '
'solves correctly in this part.'],
[2, str(C.OUTSIDE_OPTION) + ' independently of how many tasks the computer '
'solves in this part.']
],
widget=widgets.RadioSelect,
label='How do we determine your bonus for part 2?')
bonusChoice_stage2 = models.IntegerField(blank=True,
choices=[
[1, str(C.BONUS_PER_CORRECT_TASK_PART2) + ' for each task the computer'
' solves correctly in this'
' part.'],
[2, str(C.OUTSIDE_OPTION) + ' independently of how many tasks the '
'computer solves in this part.']
],
widget=widgets.RadioSelect,
label='How do we determine your bonus for part 2?')
bonusChoice2 = models.IntegerField(blank=True,
choices=[
[1, 'subtract ' + str(C.BONUS_PER_CORRECT_TASK_PART2) + ' for each image the'
' software '
'recognizes '
'incorrectly in '
'this part.'],
[2, 'subtract ' + str(C.PART2_MAX_BONUS - C.OUTSIDE_OPTION) +
' independently of how many images the software recognizes correctly in '
'this part.']
],
widget=widgets.RadioSelect,
label='How do we determine the penalty in part 2 to be subtracted'
' from the maximum bonus of ' + str(C.PART2_MAX_BONUS) + '?')
bonusChoice2_stage2 = models.IntegerField(blank=True,
choices=[
[1, 'subtract ' + str(C.BONUS_PER_CORRECT_TASK_PART2) +
' for each image the software recognizes incorrectly in this part.'],
[2, 'subtract ' + str(C.PART2_MAX_BONUS - C.OUTSIDE_OPTION) +
' independently of how many images the software recognizes correctly'
' in this part.']
],
widget=widgets.RadioSelect,
label='How do we determine the penalty in part 2 to be subtracted'
' from the maximum bonus of ' + str(C.PART2_MAX_BONUS) +
'?')
bonusChoiceEasy = make_field_bonusChoiceEasy()
bonusChoiceEasy2 = make_field_bonusChoiceEasy2()
bonusChoiceEasy_stage2 = make_field_bonusChoiceEasy()
bonusChoiceEasy2_stage2 = make_field_bonusChoiceEasy2()
bonusChoiceHardBad = make_field_bonusChoiceHardBad()
bonusChoiceHardBad_stage2 = make_field_bonusChoiceHardBad()
bonusChoiceHardBad2 = make_field_bonusChoiceHardBad2()
bonusChoiceHardBad2_stage2 = make_field_bonusChoiceHardBad2()
bonusChoiceHardGood = make_field_bonusChoiceHardGood()
bonusChoiceHardGood_stage2 = make_field_bonusChoiceHardGood()
bonusChoiceHardGood2 = make_field_bonusChoiceHardGood2()
bonusChoiceHardGood2_stage2 = make_field_bonusChoiceHardGood2()
bonusChoiceGoodType = models.IntegerField(blank=True,
choices=[
[1, str(C.BONUS_PER_CORRECT_TASK_PART2) +
' for each task the computer solves correctly in this part.'],
[2, str(C.OUTSIDE_OPTION) +
' independently of how many tasks the computer solves in this part.']
],
widget=widgets.RadioSelect,
label="If you do not know the computer's type:")
bonusChoiceBadType = models.IntegerField(blank=True,
choices=[
[1, str(C.BONUS_PER_CORRECT_TASK_PART2) +
' for each task the computer solves correctly in this part.'],
[2, str(C.OUTSIDE_OPTION) +
' independently of how many tasks the computer solves in this part.']
],
widget=widgets.RadioSelect,
label="If you know the computer is Good:")
bonusChoiceUnknownType = models.IntegerField(blank=True,
choices=[
[1, str(C.BONUS_PER_CORRECT_TASK_PART2) +
' for each task the computer solves correctly in this part.'],
[2, str(C.OUTSIDE_OPTION) +
' independently of how many tasks the computer solves in this '
'part.']],
widget=widgets.RadioSelect,
label="If you know the computer is Bad:")
feedback = models.LongStringField(label='Feedback:', blank=True)
feedbackDifficulty = models.IntegerField(label="How difficult were the instructions? Please answer on a scale of 1 "
"to 10 with 10 being the most difficult",
blank=True,
choices=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
widget=widgets.RadioSelectHorizontal)
feedbackUnderstanding = models.IntegerField(label="How well did you understand what you were asked to do?"
" Please answer on a scale of 1 to 10 with 10 being the case when"
" you understood perfectly",
blank=True,
choices=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
widget=widgets.RadioSelectHorizontal)
feedbackSatisfied = models.IntegerField(label="How satisfied are you with this study overall?"
" Please answer on a scale of 1 to 10 with 10 being the most "
"satisfied",
blank=True,
choices=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
widget=widgets.RadioSelectHorizontal)
feedbackPay = models.IntegerField(label="How appropriate do you think the payment for this study is relative to "
"other ones on Prolific? Please answer on a scale of 1 to 10 with 10 being "
"the most appropriate",
blank=True,
choices=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
widget=widgets.RadioSelectHorizontal)
explain = models.LongStringField(label='When you chose, did you choose to have the computer face the easy '
'or the hard tasks? Why?',
blank=True)
explain2 = models.LongStringField(label='When you chose, did you choose to have the software face the '
'Landscape or the People images? Why?',
blank=True)
compType = models.FloatField()
compType_stage2 = models.FloatField()
compType2 = models.FloatField()
compType2_stage2 = models.FloatField()
lottery = models.IntegerField(blank=True,
choices=[
[1, '50% chance of getting ' +
str(C.BONUS_PER_CORRECT_TASK_PART1 * C.NUMBER_OF_TASKS_PART1 *
(1 - C.NUMBER_OF_MISTAKES / C.RATE_OF_MISTAKES) +
C.OUTSIDE_OPTION) + ' and 50% chance of getting ' +
str(C.BONUS_PER_CORRECT_TASK_PART1 * C.NUMBER_OF_TASKS_PART1 +
C.BONUS_PER_CORRECT_TASK_PART2 * C.NUMBER_OF_TASKS_PART2) + '.'],
[2,
str(C.OUTSIDE_OPTION + C.BONUS_PER_CORRECT_TASK_PART1 * C.NUMBER_OF_TASKS_PART1)
+ ' for sure.']
],
widget=widgets.RadioSelect,
label='Given the chance, please choose which of the options below you would'
' prefer to receive:')
lottery2 = models.IntegerField(blank=True,
choices=[
[1, '50% chance of getting ' +
str(C.BONUS_PER_CORRECT_TASK_PART1 * C.NUMBER_OF_TASKS_PART1 *
(1 - C.NUMBER_OF_MISTAKES / C.RATE_OF_MISTAKES2) +
C.OUTSIDE_OPTION) + ' and 50% chance of getting ' +
str(C.BONUS_PER_CORRECT_TASK_PART1 * C.NUMBER_OF_TASKS_PART1 +
C.BONUS_PER_CORRECT_TASK_PART2 * C.NUMBER_OF_TASKS_PART2) + '.'],
[2,
str(C.OUTSIDE_OPTION + C.BONUS_PER_CORRECT_TASK_PART1 * C.NUMBER_OF_TASKS_PART1)
+ ' for sure.']
],
widget=widgets.RadioSelect,
label='Given the chance, please choose which of the options below you would'
' prefer to receive:')
advice = models.IntegerField(blank=True,
choices=[
[1, 'Advise that the computer faces easy tasks.'],
[2, 'Advise that the computer faces hard tasks.']
],
widget=widgets.RadioSelect,
label='If you could advise another participant on their decision of whether '
'the computer faces easy or hard tasks, which would you advise them to choose?'
'')
advice2 = models.IntegerField(blank=True,
choices=[
[1, 'Advise that the software faces Landscape images.'],
[2, 'Advise that the software faces People images.']
],
widget=widgets.RadioSelect,
label='If you could advise them on their decision of whether '
'the software faces Landscape or People images, which would you advise them to '
'choose?')
probabilistic = models.FloatField()
probabilistic2 = models.FloatField()
probabilistic_stage2 = models.FloatField()
probabilistic2_stage2 = models.FloatField()
risky_part2 = models.BooleanField()
# FUNCTIONS
def cq10_error_message(player, value):
if not player.session.config['development']:
if value is None:
return 'Please, answer the question.'
elif value != 3:
player.cq10_mistakes += 1
return 'Your answer is incorrect. You will learn how many mistakes the computer made, if any, before part' \
' 2.'
def cq6_choices(player):
if player.naive:
choices = [
[1, 'It has not yet been decided. It is randomly determined, nothing you do can affect it.'],
[2, 'It has not yet been decided. You will decide it, and there is a small chance that it is randomly '
'determined instead.'],
[3, 'It faces ' + str(C.NUMBER_OF_TASKS_PART1) + ' hard tasks.']
]
else:
choices = [
[1, 'It has not yet been decided. It is randomly determined for both tasks, nothing you do can affect it.'],
[2, 'For Part 1 it has not yet been decided; you will decide it, and there is a small chance that it is '
'randomly determined instead. In Part 2 the computer faces ' + str(C.NUMBER_OF_TASKS_PART2)
+ ' hard tasks for sure.'],
[3, 'It faces ' + str(C.NUMBER_OF_TASKS_PART1) + ' hard tasks in both parts.']
]
return choices
# PAGES
class Welcome(Page):
pass
class Consent(Page):
pass
class Instructions(Page):
pass
class IntroduceStages(Page):
@staticmethod
def is_displayed(player):
return player.baseline or player.soph
class Instructions1(Page):
@staticmethod
def vars_for_template(player):
return dict(
currentStage=player.currentStage,
)
class Instructions12(Page):
@staticmethod
def is_displayed(player):
return player.baseline or player.soph
@staticmethod
def vars_for_template(player):
part22_outside_bonus_penalty = C.PART2_MAX_BONUS - C.OUTSIDE_OPTION
return dict(
part22_outside_bonus_penalty=part22_outside_bonus_penalty,
currentStage=player.currentStage
)
class CQ(Page):
form_model = 'player'
@staticmethod
def get_form_fields(player):
if player.currentStage == 1:
questions = ['cq1', 'cq2', 'cq4', 'cq5', 'cq6']
if player.naive:
questions += ['cq9', 'cq8_naive']
elif player.baseline:
questions += ['cq9', 'cq3', 'cq7', 'cq8']
else:
questions += ['cq9_soph', 'cq3', 'cq7', 'cq8']
else:
# questions = ['cq4', 'cq5_stage2', 'cq6', 'cq9', 'cq_stage2', 'cq3', 'cq7']
questions = ['cq4', 'cq5_stage2', 'cq6', 'cq_stage2', 'cq3', 'cq7']
player.cq4 = None
player.cq6 = None
player.cq3 = None
player.cq7 = None
return questions
@staticmethod
def error_message(player, values):
if not player.session.config['development']:
if player.currentStage == 1:
solutions = dict(baseline=dict(cq1=2,
cq2=1,
cq3=3,
cq4=1,
cq5=3,
cq6=2,
cq7=3,
cq8=2,
cq9=2),
naive=dict(cq1=2,
cq2=1,
cq4=1,
cq5=3,
cq6=2,
cq8_naive=2,
cq9=1),
soph=dict(cq1=2,
cq2=1,
cq3=3,
cq4=1,
cq5=3,
cq6=2,
cq7=3,
cq8=2,
cq9_soph=1)
)
else:
solutions = dict(baseline=dict(cq4=1,
cq5_stage2=2,
cq6=2,
cq7=3,
cq3=3,
# cq9=2,
cq_stage2=2),
naive=dict(cq1=2, # review stage2 for this treatment
cq2=1,
cq4=1,
cq5_stage2=2,
cq6=2,
cq8_naive=2,
cq3=3,
cq_stage2=2),
soph=dict(cq4=1,
cq5_stage2=2,
cq6=2,
cq7=3,
cq3=3,
cq_stage2=2),
)
error_messages = dict()
for field_name in solutions[player.treatment]:
if values[field_name] is None:
error_messages[field_name] = 'Please, answer the question.'
elif values[field_name] != solutions[player.treatment][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 vars_for_template(player):
return dict(
currentStage=player.currentStage,
# nextStage=player.currentStage + 1
)
class Instructions2(Page):
@staticmethod
def vars_for_template(player):
return dict(
currentStage=player.currentStage,
)
class EnvironmentStage(Page):
form_model = 'player'
@staticmethod
def get_form_fields(player):
if player.currentStage == 1:
fields = ['taskDifficulty']
else:
fields = ['taskDifficulty_stage2']
return fields
@staticmethod
def error_message(player, values):
if not player.session.config['development']:
if (player.currentStage == 1 and values['taskDifficulty'] is None) or \
(player.currentStage == 2 and values['taskDifficulty_stage2'] is None) or \
(player.currentStage == 3 and values['taskDifficulty2'] is None) or \
(player.currentStage == 4 and values['taskDifficulty2_stage2'] is None):
return 'Please, answer the question.'
@staticmethod
def before_next_page(player, timeout_happened):
if player.currentStage == 1:
taskDifficultyMaybeNone = player.field_maybe_none('taskDifficulty')
if player.session.config['development'] and taskDifficultyMaybeNone is None:
player.taskDifficulty = 1
player.probabilistic = random.random()
if player.probabilistic < C.PROBABILITY_OF_SWITCH:
if player.taskDifficulty == 2:
player.taskDifficulty = 1
else:
player.taskDifficulty = 2
# print('PROBABILISTIC SWITCH TRIGGERED')
else:
taskDifficulty_stage2_MaybeNone = player.field_maybe_none('taskDifficulty_stage2')
if player.session.config['development'] and taskDifficulty_stage2_MaybeNone is None:
player.taskDifficulty_stage2 = 1
player.probabilistic_stage2 = random.random()
# print(player.probabilistic_stage2)
if player.probabilistic_stage2 < C.PROBABILITY_OF_SWITCH:
if player.taskDifficulty_stage2 == 2:
player.taskDifficulty_stage2 = 1
else:
player.taskDifficulty_stage2 = 2
# print('PROBABILISTIC SWITCH TRIGGERED')
@staticmethod
def vars_for_template(player):
if player.naive:
label = 'What type of task does the computer face?'
else:
label = 'What type of task does the computer face in part 1?'
return dict(
taskDifficulty_label=label,
currentStage=player.currentStage
)
class PostDifficultyChoice(Page):
form_model = 'player'
@staticmethod
def get_form_fields(player):
if player.currentStage == 1 and player.baseline:
fields = ['cq10']
else:
fields = []
return fields
@staticmethod
def before_next_page(player, timeout_happened):
if player.currentStage == 1:
if player.taskDifficulty == 1:
player.mistakes = 0
else:
if player.compType < 0.5:
player.mistakes = int(C.NUMBER_OF_MISTAKES * C.NUMBER_OF_TASKS_PART1 / C.RATE_OF_MISTAKES)
else:
player.mistakes = 0
player.payoff = C.BONUS_PER_CORRECT_TASK_PART1 * (C.NUMBER_OF_TASKS_PART1 - player.mistakes)
else:
if player.taskDifficulty_stage2 == 1:
player.mistakes_stage2 = 0
else:
if player.compType_stage2 < 0.5:
player.mistakes_stage2 = int(C.NUMBER_OF_TASKS_PART1)
else:
player.mistakes_stage2 = 0
if player.stageCounts == 2:
player.payoff = C.BONUS_PER_CORRECT_TASK_PART1 * (C.NUMBER_OF_TASKS_PART1 - player.mistakes_stage2)
@staticmethod
def vars_for_template(player):
return dict(
currentStage=player.currentStage,
)
class ObserveMistakes(Page):
@staticmethod
def before_next_page(player, timeout_happened):
if player.soph: # I think there are mistakes in both hard and easy parts of this
if player.currentStage == 1:
taskDifficulty = player.field_maybe_none('taskDifficulty')
if taskDifficulty == 2: # if task is hard
if player.compType > 0.5:
if player.bonusChoiceHardGood == 1:
player.risky_part2 = True
player.payoffPart2 = C.BONUS_PER_CORRECT_TASK_PART2 * C.NUMBER_OF_TASKS_PART2
else:
player.risky_part2 = False
player.payoffPart2 = C.OUTSIDE_OPTION
else:
if player.bonusChoiceHardBad == 1:
player.risky_part2 = True
player.mistakes = int(C.NUMBER_OF_MISTAKES * C.NUMBER_OF_TASKS_PART2 / C.RATE_OF_MISTAKES)
player.payoffPart2 = C.BONUS_PER_CORRECT_TASK_PART2 * (C.NUMBER_OF_TASKS_PART2 -
player.mistakes)
else:
player.risky_part2 = False
player.payoffPart2 = C.OUTSIDE_OPTION
else: # if task is easy
if player.bonusChoiceEasy == 1:
player.risky_part2 = True
if player.compType <= 0.5: # if task is easy and comp is bad
player.mistakes = int(C.NUMBER_OF_MISTAKES * C.NUMBER_OF_TASKS_PART2 / C.RATE_OF_MISTAKES)
player.payoffPart2 = C.BONUS_PER_CORRECT_TASK_PART2 * (C.NUMBER_OF_TASKS_PART2 -
player.mistakes)
else: # if task is easy and comp is good
player.payoffPart2 = C.BONUS_PER_CORRECT_TASK_PART2 * C.NUMBER_OF_TASKS_PART2
else:
player.risky_part2 = False
player.payoffPart2 = C.OUTSIDE_OPTION
if player.stageCounts == 1:
player.payoff += player.payoffPart2
else:
taskDifficulty = player.field_maybe_none('taskDifficulty_stage2')
if taskDifficulty == 2: # if task is hard
if player.compType_stage2 > 0.5: # if task is hard and comp is good
if player.bonusChoiceHardGood_stage2 == 1:
player.risky_part2 = True
player.payoffPart2 = C.BONUS_PER_CORRECT_TASK_PART2 * C.NUMBER_OF_TASKS_PART2
else:
player.risky_part2 = False
player.payoffPart2 = C.OUTSIDE_OPTION
else: # if task is hard and comp is bad
if player.bonusChoiceHardBad_stage2 == 1:
player.risky_part2 = True
player.mistakes_stage2 = int(C.NUMBER_OF_MISTAKES * C.NUMBER_OF_TASKS_PART2 /
C.RATE_OF_MISTAKES)
player.payoffPart2 = C.BONUS_PER_CORRECT_TASK_PART2 * (C.NUMBER_OF_TASKS_PART2 -
player.mistakes_stage2)
else:
player.risky_part2 = False
player.payoffPart2 = C.OUTSIDE_OPTION
else: # if task is easy
if player.bonusChoiceEasy_stage2 == 1:
player.risky_part2 = True
if player.compType_stage2 <= 0.5: # if task is easy and comp is bad
player.mistakes_stage2 = int(C.NUMBER_OF_MISTAKES * C.NUMBER_OF_TASKS_PART2 /
C.RATE_OF_MISTAKES2)
player.payoffPart2 = C.BONUS_PER_CORRECT_TASK_PART2 * (C.NUMBER_OF_TASKS_PART2 -
player.mistakes_stage2)
else: # if task is easy and comp is good
player.payoffPart2 = C.BONUS_PER_CORRECT_TASK_PART2 * C.NUMBER_OF_TASKS_PART2
else:
player.risky_part2 = False
player.payoffPart2 = C.OUTSIDE_OPTION
if player.stageCounts == 2:
player.payoff += player.payoffPart2
@staticmethod
def vars_for_template(player):
if player.currentStage == 2:
return dict(
currentStage=player.currentStage,
payoffStage2=C.BONUS_PER_CORRECT_TASK_PART1 * (C.NUMBER_OF_TASKS_PART1 - player.mistakes_stage2)
)
else:
return dict(
currentStage=player.currentStage
)
# class PayoffSoph(Page):
# @staticmethod
# def vars_for_template(player):
# return dict(
# payoffPart2=player.payoffPart2,
# currentStage=player.currentStage
# )
#
# @staticmethod
# def is_displayed(player):
# return player.soph
class BonusChoice(Page):
form_model = 'player'
@staticmethod
def get_form_fields(player):
if player.baseline and player.currentStage == 1:
fields = ['bonusChoice']
elif player.baseline and player.currentStage == 2:
fields = ['bonusChoice_stage2']
else:
fields = []
return fields
@staticmethod
def before_next_page(player, timeout_happened):
if player.baseline:
if player.currentStage == 1:
bonusChoiceMaybeNone = player.field_maybe_none('bonusChoice')
if bonusChoiceMaybeNone == 1:
player.risky_part2 = True
if player.compType < 0.5:
player.mistakes = int(C.NUMBER_OF_MISTAKES * C.NUMBER_OF_TASKS_PART2 / C.RATE_OF_MISTAKES)
else:
player.mistakes = 0
player.payoffPart2 = C.BONUS_PER_CORRECT_TASK_PART2 * (C.NUMBER_OF_TASKS_PART2 - player.mistakes)
else:
player.risky_part2 = False
player.bonusChoice = 2
player.payoffPart2 = C.OUTSIDE_OPTION
if player.stageCounts == 1:
player.payoff += player.payoffPart2
else:
bonusChoice_stage2MaybeNone = player.field_maybe_none('bonusChoice_stage2')
if bonusChoice_stage2MaybeNone == 1:
player.risky_part2 = True
if player.compType_stage2 < 0.5:
player.mistakes_stage2 = int(C.NUMBER_OF_MISTAKES * C.NUMBER_OF_TASKS_PART2 / C.RATE_OF_MISTAKES2)
else:
player.mistakes_stage2 = 0
player.payoffPart2 = C.BONUS_PER_CORRECT_TASK_PART2 * (C.NUMBER_OF_TASKS_PART2 - player.mistakes_stage2)
else:
player.risky_part2 = False
player.bonusChoice_stage2 = 2
player.payoffPart2 = C.OUTSIDE_OPTION
if player.stageCounts == 2:
player.payoff += player.payoffPart2
@staticmethod
def error_message(player, values):
if player.baseline and not player.session.config['development']:
if player.currentStage == 1 and values['bonusChoice'] is None:
return 'Please, answer the question.'
elif player.currentStage == 2 and values['bonusChoice_stage2'] is None:
return 'Please, answer the question.'
@staticmethod
def vars_for_template(player):
if player.currentStage == 1:
taskDiff_stageless = player.taskDifficulty
mistakes_stageless = player.mistakes
if player.compType < 0.5:
compType_stageless = 'Bad'
else:
compType_stageless = 'Good'
else:
taskDiff_stageless = player.taskDifficulty_stage2
mistakes_stageless = player.mistakes_stage2
if player.compType_stage2 < 0.5:
compType_stageless = 'Bad'
else:
compType_stageless = 'Good'
return dict(
currentStage=player.currentStage,
taskDiff_stageless=taskDiff_stageless,
compType_stageless=compType_stageless,
mistakes_stageless=mistakes_stageless
)
class BonusChoiceSoph(Page):
form_model = 'player'
# form_fields = ['bonusChoiceGoodType', 'bonusChoiceBadType', 'bonusChoiceUnknownType']
@staticmethod
def get_form_fields(player):
if player.currentStage == 1:
fields = ['bonusChoiceEasy', 'bonusChoiceHardBad', 'bonusChoiceHardGood']
elif player.currentStage == 2:
fields = ['bonusChoiceEasy_stage2', 'bonusChoiceHardBad_stage2', 'bonusChoiceHardGood_stage2']
elif player.currentStage == 3:
fields = ['bonusChoiceEasy2', 'bonusChoiceHardBad2', 'bonusChoiceHardGood2']
else:
fields = ['bonusChoiceEasy2_stage2', 'bonusChoiceHardBad2_stage2', 'bonusChoiceHardGood2_stage2']
random.shuffle(fields)
return fields
@staticmethod
def error_message(player, values):
if not player.session.config['development']:
if (player.currentStage == 1 and any([values['bonusChoiceEasy'] is None,
values['bonusChoiceHardBad'] is None,
values['bonusChoiceHardGood'] is None])) or\
(player.currentStage == 2 and any([values['bonusChoiceEasy_stage2'] is None,
values['bonusChoiceHardBad_stage2'] is None,
values['bonusChoiceHardGood_stage2'] is None])) or\
(player.currentStage == 3 and any([values['bonusChoiceEasy2'] is None,
values['bonusChoiceHardBad2'] is None,
values['bonusChoiceHardGood2'] is None])) or\
(player.currentStage == 4 and any([values['bonusChoiceEasy2_stage2'] is None,
values['bonusChoiceHardBad2_stage2'] is None,
values['bonusChoiceHardGood2_stage2'] is None])):
return 'Please, answer the question.'
@staticmethod
def is_displayed(player):
return player.soph
@staticmethod # This allows us to go through pages in dev mode without having to respond
def before_next_page(player, timeout_happened):
if player.session.config['development']:
if player.currentStage == 1:
bonusChoiceEasyMaybeNone = player.field_maybe_none('bonusChoiceEasy')
bonusChoiceHardBadMaybeNone = player.field_maybe_none('bonusChoiceHardBad')
bonusChoiceHardGoodMaybeNone = player.field_maybe_none('bonusChoiceHardGood')
if bonusChoiceEasyMaybeNone is None:
player.bonusChoiceEasy = 1
if bonusChoiceHardBadMaybeNone is None:
player.bonusChoiceHardBad = 1
if bonusChoiceHardGoodMaybeNone is None:
player.bonusChoiceHardGood = 1
elif player.currentStage == 2:
bonusChoiceEasyMaybeNone = player.field_maybe_none('bonusChoiceEasy_stage2')
bonusChoiceHardBadMaybeNone = player.field_maybe_none('bonusChoiceHardBad_stage2')
bonusChoiceHardGoodMaybeNone = player.field_maybe_none('bonusChoiceHardGood_stage2')
if bonusChoiceEasyMaybeNone is None:
player.bonusChoiceEasy_stage2 = 1
if bonusChoiceHardBadMaybeNone is None:
player.bonusChoiceHardBad_stage2 = 1
if bonusChoiceHardGoodMaybeNone is None:
player.bonusChoiceHardGood_stage2 = 1
elif player.currentStage == 3:
bonusChoiceEasyMaybeNone = player.field_maybe_none('bonusChoiceEasy2')
bonusChoiceHardBadMaybeNone = player.field_maybe_none('bonusChoiceHardBad2')
bonusChoiceHardGoodMaybeNone = player.field_maybe_none('bonusChoiceHardGood2')
if bonusChoiceEasyMaybeNone is None:
player.bonusChoiceEasy2 = 1
if bonusChoiceHardBadMaybeNone is None:
player.bonusChoiceHardBad2 = 1
if bonusChoiceHardGoodMaybeNone is None:
player.bonusChoiceHardGood2 = 1
else:
bonusChoiceEasyMaybeNone = player.field_maybe_none('bonusChoiceEasy2_stage2')
bonusChoiceHardBadMaybeNone = player.field_maybe_none('bonusChoiceHardBad2_stage2')
bonusChoiceHardGoodMaybeNone = player.field_maybe_none('bonusChoiceHardGood2_stage2')
if bonusChoiceEasyMaybeNone is None:
player.bonusChoiceEasy2_stage2 = 1
if bonusChoiceHardBadMaybeNone is None:
player.bonusChoiceHardBad2_stage2 = 1
if bonusChoiceHardGoodMaybeNone is None:
player.bonusChoiceHardGood2_stage2 = 1
@staticmethod
def vars_for_template(player):
part22_outside_bonus_penalty = C.PART2_MAX_BONUS - C.OUTSIDE_OPTION
return dict(
part22_outside_bonus_penalty=part22_outside_bonus_penalty,
currentStage=player.currentStage
)
class PostBonusChoice(Page):
@staticmethod
def is_displayed(player):
return player.baseline
@staticmethod
def vars_for_template(player):
return dict(
payoffPart2=player.payoffPart2,
currentStage=player.currentStage
)
class PostBonusChoiceSoph(Page):
@staticmethod
def is_displayed(player):
return player.soph
@staticmethod
def vars_for_template(player):
part22_outside_bonus_penalty = C.PART2_MAX_BONUS - C.OUTSIDE_OPTION
return dict(
part22_outside_bonus_penalty=part22_outside_bonus_penalty,
currentStage=player.currentStage
)
#############################################################
class Transition(Page):
@staticmethod
def before_next_page(player, timeout_happened):
player.currentStage += 1
@staticmethod
def vars_for_template(player):
return dict(
currentStage=player.currentStage,
nextStage=player.currentStage+1
)
################### Second stage of the study ###########
################### THIRD STAGE ##########################
# class Instructions22(Page):
# pass
class EnvironmentStage2(Page):
form_model = 'player'
@staticmethod
def get_form_fields(player):
if player.currentStage == 3:
fields = ['taskDifficulty2']
else:
fields = ['taskDifficulty2_stage2']
return fields
@staticmethod
def error_message(player, values):
if not player.session.config['development']:
if (player.currentStage == 3 and values['taskDifficulty2'] is None) or \
(player.currentStage == 4 and values['taskDifficulty2_stage2'] is None):
return 'Please, answer the question.'
@staticmethod
def before_next_page(player, timeout_happened):
if player.currentStage == 3:
taskDifficultyMaybeNone2 = player.field_maybe_none('taskDifficulty2')
if player.session.config['development'] and taskDifficultyMaybeNone2 is None:
player.taskDifficulty2 = 1
player.probabilistic2 = random.random()
# print(player.probabilistic)
if player.probabilistic2 < C.PROBABILITY_OF_SWITCH:
if player.taskDifficulty2 == 2:
player.taskDifficulty2 = 1
else:
player.taskDifficulty2 = 2
# print('PROBABILISTIC SWITCH TRIGGERED')
else:
taskDifficulty_stage2MaybeNone2 = player.field_maybe_none('taskDifficulty2_stage2')
if player.session.config['development'] and taskDifficulty_stage2MaybeNone2 is None:
player.taskDifficulty2_stage2 = 1
player.probabilistic2_stage2 = random.random()
# print(player.probabilistic)
if player.probabilistic2_stage2 < C.PROBABILITY_OF_SWITCH:
if player.taskDifficulty2_stage2 == 2:
player.taskDifficulty2_stage2 = 1
else:
player.taskDifficulty2_stage2 = 2
# print('PROBABILISTIC SWITCH TRIGGERED')
@staticmethod
def vars_for_template(player):
part22_outside_bonus_penalty = C.PART2_MAX_BONUS - C.OUTSIDE_OPTION
if player.naive:
label = 'What type of images does the software face?'
else:
label = 'What type of images does the software face in part 1?'
return dict(
taskDifficulty2_label=label,
part22_outside_bonus_penalty=part22_outside_bonus_penalty,
currentStage=player.currentStage
)
class PostDifficultyChoice2(Page):
form_model = 'player'
@staticmethod
def before_next_page(player, timeout_happened):
if player.currentStage == 3:
if player.taskDifficulty2 == 1:
player.mistakes2 = 0
else:
if player.compType2 < 0.5:
player.mistakes2 = int(C.NUMBER_OF_MISTAKES * C.NUMBER_OF_TASKS_PART1 / C.RATE_OF_MISTAKES)
else:
player.mistakes2 = 0
player.payoffPart12 = C.BONUS_PER_CORRECT_TASK_PART1 * (C.NUMBER_OF_TASKS_PART1 - player.mistakes2)
else:
if player.taskDifficulty2_stage2 == 1:
player.mistakes2_stage2 = 0
else:
if player.compType2_stage2 < 0.5:
player.mistakes2_stage2 = int(C.NUMBER_OF_MISTAKES * C.NUMBER_OF_TASKS_PART1 / C.RATE_OF_MISTAKES2)
else:
player.mistakes2_stage2 = 0
player.payoffPart12 = C.BONUS_PER_CORRECT_TASK_PART1 * (C.NUMBER_OF_TASKS_PART1 - player.mistakes2_stage2)
@staticmethod
def vars_for_template(player):
return dict(
currentStage=player.currentStage
)
class ObserveMistakes2(Page):
@staticmethod
def before_next_page(player, timeout_happened):
if player.soph:
if player.currentStage == 3:
taskDifficulty = player.field_maybe_none('taskDifficulty2')
if taskDifficulty == 2: # if task is hard
if player.compType2 > 0.5: # if task is hard and comp is good
if player.bonusChoiceHardGood2 == 1:
player.risky_part2 = True
player.payoffPart22 = C.BONUS_PER_CORRECT_TASK_PART2 * C.NUMBER_OF_TASKS_PART2
else:
player.risky_part2 = False
player.payoffPart22 = C.OUTSIDE_OPTION
else: # if task is hard and comp is bad
if player.bonusChoiceHardBad2 == 1:
player.risky_part2 = True
player.mistakes2 = int(C.NUMBER_OF_MISTAKES * C.NUMBER_OF_TASKS_PART2 / C.RATE_OF_MISTAKES)
player.payoffPart22 = C.BONUS_PER_CORRECT_TASK_PART2 * (C.NUMBER_OF_TASKS_PART2 -
player.mistakes2)
else:
player.risky_part2 = False
player.payoffPart22 = C.OUTSIDE_OPTION
else: # if task is easy
if player.bonusChoiceEasy2 == 1:
player.risky_part2 = True
if player.compType2 <= 0.5: # if task is easy and comp is bad
player.mistakes2 = int(C.NUMBER_OF_MISTAKES * C.NUMBER_OF_TASKS_PART2 / C.RATE_OF_MISTAKES)
player.payoffPart22 = C.BONUS_PER_CORRECT_TASK_PART2 * (C.NUMBER_OF_TASKS_PART2 -
player.mistakes2)
else: # if task is easy and comp is good
player.payoffPart22 = C.BONUS_PER_CORRECT_TASK_PART2 * C.NUMBER_OF_TASKS_PART2
else:
player.risky_part2 = False
player.payoffPart22 = C.OUTSIDE_OPTION
if player.stageCounts == 3:
player.payoff = player.payoffPart12 + player.payoffPart22
else:
taskDifficulty = player.field_maybe_none('taskDifficulty2_stage2')
if taskDifficulty == 2: # if task is hard
if player.compType2_stage2 > 0.5: # if task is hard and comp is good
if player.bonusChoiceHardGood2_stage2 == 1:
player.risky_part2 = True
player.payoffPart22 = C.BONUS_PER_CORRECT_TASK_PART2 * C.NUMBER_OF_TASKS_PART2
else:
player.risky_part2 = False
player.payoffPart22 = C.OUTSIDE_OPTION
else: # if task is hard and comp is bad
if player.bonusChoiceHardBad2_stage2 == 1:
player.risky_part2 = True
player.mistakes2_stage2 = int(C.NUMBER_OF_MISTAKES * C.NUMBER_OF_TASKS_PART2 /
C.RATE_OF_MISTAKES2)
player.payoffPart22 = C.BONUS_PER_CORRECT_TASK_PART2 * (C.NUMBER_OF_TASKS_PART2 -
player.mistakes2_stage2)
else:
player.risky_part2 = False
player.payoffPart22 = C.OUTSIDE_OPTION
else: # if task is easy
if player.bonusChoiceEasy2_stage2 == 1:
player.risky_part2 = True
if player.compType2_stage2 <= 0.5: # if task is easy and comp is bad
player.mistakes2_stage2 = int(C.NUMBER_OF_MISTAKES * C.NUMBER_OF_TASKS_PART2 /
C.RATE_OF_MISTAKES2)
player.payoffPart22 = C.BONUS_PER_CORRECT_TASK_PART2 * (C.NUMBER_OF_TASKS_PART2 -
player.mistakes2_stage2)
else: # if task is easy and comp is good
player.payoffPart22 = C.BONUS_PER_CORRECT_TASK_PART2 * C.NUMBER_OF_TASKS_PART2
else:
player.risky_part2 = False
player.payoffPart22 = C.OUTSIDE_OPTION
if player.stageCounts == 4:
player.payoff = player.payoffPart12 + player.payoffPart22
@staticmethod
def vars_for_template(player):
return dict(
currentStage=player.currentStage
)
class BonusChoice2(Page):
form_model = 'player'
@staticmethod
def get_form_fields(player):
if player.baseline and player.currentStage == 3:
fields = ['bonusChoice2']
elif player.baseline and player.currentStage == 4:
fields = ['bonusChoice2_stage2']
else:
fields = []
return fields
@staticmethod
def is_displayed(player):
return player.baseline or player.soph
@staticmethod
def before_next_page(player, timeout_happened):
if player.baseline:
if player.currentStage == 3:
bonusChoiceMaybeNone2 = player.field_maybe_none('bonusChoice2')
if bonusChoiceMaybeNone2 == 1:
player.risky_part2 = True
if player.compType2 < 0.5:
player.mistakes2 = int(C.NUMBER_OF_MISTAKES * C.NUMBER_OF_TASKS_PART2 / C.RATE_OF_MISTAKES)
else:
player.mistakes2 = 0
player.payoffPart22 = C.BONUS_PER_CORRECT_TASK_PART2 * (C.NUMBER_OF_TASKS_PART2 - player.mistakes2)
else:
player.risky_part2 = False
player.bonusChoice2 = 2
player.payoffPart22 = C.OUTSIDE_OPTION
if player.stageCounts == 3:
player.payoff = player.payoffPart12 + player.payoffPart22
else:
bonusChoice_stage2MaybeNone2 = player.field_maybe_none('bonusChoice2_stage2')
if bonusChoice_stage2MaybeNone2 == 1:
player.risky_part2 = True
if player.compType2_stage2 < 0.5:
player.mistakes2_stage2 = int(C.NUMBER_OF_MISTAKES * C.NUMBER_OF_TASKS_PART2 / C.RATE_OF_MISTAKES2)
else:
player.mistakes2_stage2 = 0
player.payoffPart22 = C.BONUS_PER_CORRECT_TASK_PART2 * (C.NUMBER_OF_TASKS_PART2 - player.mistakes2_stage2)
else:
player.risky_part2 = False
player.bonusChoice2_stage2 = 2
player.payoffPart22 = C.OUTSIDE_OPTION
if player.stageCounts == 4:
player.payoff = player.payoffPart12 + player.payoffPart22
@staticmethod
def error_message(player, values):
if player.baseline and not player.session.config['development']:
if player.currentStage == 3 and values['bonusChoice2'] is None:
return 'Please, answer the question.'
elif player.currentStage == 4 and values['bonusChoice2_stage2'] is None:
return 'Please, answer the question.'
@staticmethod
def vars_for_template(player):
part22_outside_bonus_penalty = C.PART2_MAX_BONUS - C.OUTSIDE_OPTION
if player.currentStage == 3:
taskDiff_stageless = player.taskDifficulty2
mistakes_stageless = player.mistakes2
if player.compType2 < 0.5:
compType_stageless = 'Bad'
else:
compType_stageless = 'Good'
else:
taskDiff_stageless = player.taskDifficulty2_stage2
mistakes_stageless = player.mistakes2_stage2
if player.compType2_stage2 < 0.5:
compType_stageless = 'Bad'
else:
compType_stageless = 'Good'
return dict(
currentStage=player.currentStage,
taskDiff_stageless=taskDiff_stageless,
compType_stageless=compType_stageless,
mistakes_stageless=mistakes_stageless,
part22_outside_bonus_penalty=part22_outside_bonus_penalty,
)
class PostBonusChoice2(Page):
@staticmethod
def is_displayed(player):
return player.baseline
@staticmethod
def vars_for_template(player):
part22_outside_bonus_penalty = C.PART2_MAX_BONUS - C.OUTSIDE_OPTION
return dict(
payoffPart22=player.payoffPart22,
part22_outside_bonus_penalty=part22_outside_bonus_penalty,
currentStage=player.currentStage
)
class Lottery(Page):
form_model = 'player'
form_fields = ['lottery']
@staticmethod
def before_next_page(player, timeout_happened):
lotteryMaybeNone = player.field_maybe_none('lottery')
if player.session.config['development'] and lotteryMaybeNone is None:
player.lottery = 1
if player.stageCounts == 5:
if player.lottery == 2:
player.payoff = C.OUTSIDE_OPTION + C.BONUS_PER_CORRECT_TASK_PART1 * C.NUMBER_OF_TASKS_PART1
else:
player.payoff = random.choices([C.BONUS_PER_CORRECT_TASK_PART1 * C.NUMBER_OF_TASKS_PART1 *
(1 - C.NUMBER_OF_MISTAKES / C.RATE_OF_MISTAKES) +
C.OUTSIDE_OPTION,
C.BONUS_PER_CORRECT_TASK_PART1 * C.NUMBER_OF_TASKS_PART1 +
C.BONUS_PER_CORRECT_TASK_PART2 * C.NUMBER_OF_TASKS_PART2],
weights=[0.5, 0.5])[0]
@staticmethod
def error_message(player, values):
if not player.session.config['development'] and values['lottery'] is None:
return 'Please, answer the question.'
@staticmethod
def vars_for_template(player):
return dict(
currentStage=player.currentStage
)
class Lottery2(Page):
form_model = 'player'
form_fields = ['lottery2']
@staticmethod
def before_next_page(player, timeout_happened):
lottery2MaybeNone = player.field_maybe_none('lottery2')
if player.session.config['development'] and lottery2MaybeNone is None:
player.lottery2 = 1
if player.stageCounts == 6:
if player.lottery2 == 2:
player.payoff = C.OUTSIDE_OPTION + C.BONUS_PER_CORRECT_TASK_PART1 * C.NUMBER_OF_TASKS_PART1
else:
player.payoff = random.choices([C.BONUS_PER_CORRECT_TASK_PART1 * C.NUMBER_OF_TASKS_PART1 *
(1 - C.NUMBER_OF_MISTAKES / C.RATE_OF_MISTAKES2) +
C.OUTSIDE_OPTION,
C.BONUS_PER_CORRECT_TASK_PART1 * C.NUMBER_OF_TASKS_PART1 +
C.BONUS_PER_CORRECT_TASK_PART2 * C.NUMBER_OF_TASKS_PART2],
weights=[0.5, 0.5])[0]
@staticmethod
def error_message(player, values):
if not player.session.config['development'] and values['lottery2'] is None:
return 'Please, answer the question.'
@staticmethod
def vars_for_template(player):
return dict(
currentStage=player.currentStage
)
class Hypothetical(Page):
form_model = 'player'
form_fields = ['advice', 'advice2', 'explain', 'explain2']
@staticmethod
def error_message(player, values):
if not player.session.config['development'] and (values['advice'] is None or not
values['explain'] or not values['explain'] or values['advice2'] is None):
return 'Please, answer the questions.'
class End(Page):
form_model = 'player'
form_fields = ['feedback', 'feedbackDifficulty', 'feedbackUnderstanding', 'feedbackSatisfied', 'feedbackPay']
@staticmethod
def before_next_page(player, timeout_happened):
player.participant.finished = True
class Redirect(Page):
pass
page_sequence = [
Welcome,
Consent,
Instructions,
IntroduceStages,
Instructions1,
CQ,
Instructions2,
BonusChoiceSoph,
PostBonusChoiceSoph,
EnvironmentStage,
PostDifficultyChoice,
ObserveMistakes,
BonusChoice,
PostBonusChoice,
Transition,
Instructions1,
CQ,
Instructions2,
BonusChoiceSoph,
PostBonusChoiceSoph,
EnvironmentStage,
PostDifficultyChoice,
ObserveMistakes,
BonusChoice,
PostBonusChoice,
Transition,
Instructions12,
Instructions2,
BonusChoiceSoph,
PostBonusChoiceSoph,
EnvironmentStage2,
PostDifficultyChoice2,
ObserveMistakes2,
BonusChoice2,
PostBonusChoice2,
Transition,
Instructions12,
Instructions2,
BonusChoiceSoph,
PostBonusChoiceSoph,
EnvironmentStage2,
PostDifficultyChoice2,
ObserveMistakes2,
BonusChoice2,
PostBonusChoice2,
Transition,
Lottery,
Transition,
Lottery2,
Hypothetical,
End,
Redirect
]