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 ]