from otree.api import * c = cu import math doc = '' class C(BaseConstants): NAME_IN_URL = 'Experiment' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): points = models.IntegerField(initial=0) pay = models.FloatField(inital=0) total_pay = models.IntegerField(initial=5) push = models.IntegerField(initial=None) other = models.IntegerField(initial=None) Success = models.IntegerField( choices=[[1, 'Success'], [0, 'Failure']], label='Please choose a condition', widget=widgets.RadioSelect) Accountability = models.IntegerField( choices=[[1, 'Accountability Present'], [0, 'Accountability Absent ']], label='Please choose a condition', widget=widgets.RadioSelect) CC1 = models.IntegerField( choices=[[1, 'TRUE'], [0, 'FALSE']], label='Your firm will have 8 employees, 4 of which were selected by the experimenters, ' 'and you will select the other 4', widget=widgets.RadioSelect) CC2 = models.IntegerField( choices=[[1, 'Screening Task #1: Letter count Task'], [2, 'Screening Task #2: Word Jumble Task'], [3, 'Screening Task #3: Synonym Task'], [4, 'Word Search Task']], label='The 8 selected employees’ performance on which one of the below tasks will affect your ' 'additional compensation?', widget=widgets.RadioSelect) CC3 = models.IntegerField( choices=[[1, 'TRUE'], [0, 'FALSE']], label='Participants’ performance on the three screening tasks could be helpful in predicting how well ' 'participants will perform on the word search task', widget=widgets.RadioSelect) CC4 = models.IntegerField( choices=[[1, 'TRUE'], [0, 'FALSE']], label='You will be presented with 2 of the 8 employees. Your second decision involves promoting only 1 of ' 'the 2 employees to a higher-level position', widget=widgets.RadioSelect) CC5 = models.IntegerField( choices=[[1, 'TRUE'], [0, 'FALSE']], label='The promoted employee will perform a new task – math slider task. You will earn an additional ' '300 points if the promoted employee’s performance on the math-slider is above 10, which is considered ' 'strong performance', widget=widgets.RadioSelect) CC6 = models.IntegerField( choices=[[1, 'TRUE'], [0, 'FALSE']], label='An external evaluator will review your promotion decision and your report justifying the ' 'promotion decision', widget=widgets.RadioSelect) CC7_Success = models.IntegerField( choices=[[1, 'A strong performer '], [2, 'A weak performer ']], label='Your previously promoted employee was considered as', widget=widgets.RadioSelect) CC7_Failure = models.IntegerField( choices=[[1, 'A strong performer '], [2, 'A weak performer ']], label='Your previously promoted employee was considered as', widget=widgets.RadioSelect) CC8 = models.IntegerField( choices=[[1, 'TRUE'], [0, 'FALSE']], label='The promoted employee will perform a new task – math slider task. You will earn an additional 300 ' 'points if the promoted employee’s performance on the math-slider is above 10, which is considered ' 'strong performance', widget=widgets.RadioSelect) CC9 = models.IntegerField( choices=[[1, 'TRUE'], [0, 'FALSE']], label='The external evaluator will review your promotion decision and your reporting justifying the ' 'promotion decision', widget=widgets.RadioSelect) Purple = models.IntegerField(label=' ') Purple2 = models.IntegerField(label=' ') Blue = models.IntegerField(label=' ') Blue2 = models.IntegerField(label=' ') Green = models.IntegerField(label=' ') Green2 = models.IntegerField(label=' ') Promotion1_Success = models.IntegerField( choices=[[1, 'Purple (Hired by you)'], [2, 'Blue (Hired by the experimenters)']], initial=None, label='(3) Please promote one of the two employees to the higher-level position.', widget=widgets.RadioSelect) Promotion1_Failure = models.IntegerField( choices=[[1, 'Green (Hired by you)'], [2, 'Blue (Hired by the experimenters) ']], initial=None, label='(3) Please promote one of the two employees to the higher-level position.', widget=widgets.RadioSelect) Promotion2_Success = models.IntegerField( choices=[[1, 'Green (Hired by you)'], [2, 'Blue (Hired by the experimenters) ']], initial=None, label='(3) Please promote one of the two employees to the higher-level position.', widget=widgets.RadioSelect) Promotion2_Failure = models.IntegerField( choices=[[1, 'Purple (Hired by you)'], [2, 'Blue (Hired by the experimenters)']], initial=None, label='(3) Please promote one of the two employees to the higher-level position.', widget=widgets.RadioSelect) Promotion2_Other = models.IntegerField( choices=[[1, 'Purple (Hired by you)'], [2, 'Green (Hired by you)']], initial=None, label='(3) Please promote one of the two employees to the higher-level position.', widget=widgets.RadioSelect) Report1 = models.LongStringField(label='Please type your report in the space below (Minimum of 50 words)') Report2 = models.LongStringField(label='Please type your report in the space below (Minimum of 50 words)') GreenChosen = models.BooleanField(widget=widgets.CheckboxInput, initial=False, blank=True) PurpleChosen = models.BooleanField(widget=widgets.CheckboxInput, initial=False, blank=True) MaroonChosen = models.BooleanField(widget=widgets.CheckboxInput, initial=False, blank=True) IndigoChosen = models.BooleanField(widget=widgets.CheckboxInput, initial=False, blank=True) VioletChosen = models.BooleanField(widget=widgets.CheckboxInput, initial=False, blank=True) LimeChosen = models.BooleanField(widget=widgets.CheckboxInput, initial=False, blank=True) TealChosen = models.BooleanField(widget=widgets.CheckboxInput, initial=False, blank=True) letter_count_task_points = models.IntegerField(min=0, max=100, label='Screening Task #1: Letter count Task') word_jumble_task_points = models.IntegerField(min=0, max=100, label='Screening Task #2: Word Jumble Task') synonym_task_points = models.IntegerField(min=0, max=100, label='Screening Task #3: Synonym Task') average_performance_points = models.IntegerField(min=0, max=100, label='Average Performance (Across 3 Tasks)') word_search_points = models.IntegerField(min=0, max=120, label='Word Search Task Performance') math_experience_points = models.IntegerField(min=0, max=120, label='Math Experience') math_skills_points = models.IntegerField(min=0, max=120, label='Math Skills') creativity_level_points = models.IntegerField(min=0, max=120, label='Creativity Level') trivia_points = models.IntegerField(min=0, max=120, label='Trivia Task Performance') sudoku_points = models.IntegerField(min=0, max=120, label='Sudoku Task Performance') word_search_points2 = models.IntegerField(min=0, max=120, label='Word Search Task Performance') math_experience_points2 = models.IntegerField(min=0, max=120, label='Math Experience') math_skills_points2 = models.IntegerField(min=0, max=120, label='Math Skills') creativity_level_points2 = models.IntegerField(min=0, max=120, label='Creativity Level') trivia_points2 = models.IntegerField(min=0, max=120, label='Trivia Task Performance') sudoku_points2 = models.IntegerField(min=0, max=120, label='Sudoku Task Performance') # confidence = models.IntegerField( # choices=[ # [1, 'Not Confident at All'], # [2, '2'], # [3, '3'], # [4, 'Somewhat Confident'], # [5, '5'], # [6, '6'], # [7, 'Very Confident'] # ], # widget=widgets.RadioSelectHorizontal, # label='How confident are you in your promotion decision?' # ) # PEQs # def make_field(label): return models.IntegerField( choices=[ [1, 'Strongly Agree'], [2, 'Agree'], [3, 'Somewhat Agree'], [4, 'Neither Agree nor Disagree'], [5, 'Somewhat Disagree'], [6, 'Disagree'], [7, 'Strongly Disagree'], ], label=label, widget=widgets.RadioSelectHorizontal, ) important_first = make_field('It was important that I made the right decision about who I promoted for my ' 'first promotion decision.') important_second = make_field('It was important that I made the right decision about who I promoted for my ' 'second promotion decision.') easy_case = make_field('The case was easy to understand.') realistic_case = make_field('The case was very realistic.') responsible_first = make_field('I feel responsible for the outcome of my first promotion decision.') responsible_second = make_field('I feel responsible for the outcome of my second promotion decision.') pressure = make_field('During the session I felt pressure to make good promotion decisions.') sorry_success_first_blue = make_field('I feel sorry for not choosing Blue for my first promotion decision.') sorry_success_first_purple = make_field('I feel sorry for not choosing Purple for my first promotion decision.') sorry_failure_first_blue = make_field('I feel sorry for not choosing Blue for my first promotion decision.') sorry_failure_first_green = make_field('I feel sorry for not choosing Green for my first promotion decision.') regret_success_first_blue = make_field('I regret not choosing Blue for my first promotion decision.') regret_success_first_purple = make_field('I regret not choosing Purple for my first promotion decision.') regret_failure_first_blue = make_field('I regret not choosing Blue for my first promotion decision.') regret_failure_first_green = make_field('I regret not choosing Green for my first promotion decision.') sorry_success_second_blue = make_field('I feel sorry for not choosing Blue for my second promotion decision.') sorry_success_second_green = make_field('I feel sorry for not choosing Green for my second promotion decision.') sorry_failure_second_blue = make_field('I feel sorry for not choosing Blue for my second promotion decision.') sorry_failure_second_purple = make_field('I feel sorry for not choosing Purple for my second promotion decision.') regret_success_second_blue = make_field('I regret not choosing Blue for my second promotion decision.') regret_success_second_green = make_field('I regret not choosing Green for my second promotion decision.') regret_failure_second_blue = make_field('I regret not choosing Blue for my second promotion decision.') regret_failure_second_purple = make_field('I regret not choosing Purple for my second promotion decision.') age = models.IntegerField(min=0, max=120) gender = models.StringField(choices=[ ['Male', 'Male'], ['Female', 'Female'], ['Other', 'Other'], ['Prefer not to answer', 'Prefer not to answer'] ], widget=widgets.RadioSelect) work_experience = models.IntegerField(min=0, max=100, label="How many years of work experience do you have?") def CC1_error_message(player: Player, value): if value != 1: return "INCORRECT! Please try again." def CC2_error_message(player: Player, value): if value != 4: return "INCORRECT! Please try again." def CC3_error_message(player: Player, value): if value != 1: return "INCORRECT! Please try again." def CC4_error_message(player: Player, value): if value != 1: return "INCORRECT! Please try again." def CC5_error_message(player: Player, value): if value != 1: return "INCORRECT! Please try again." def CC6_error_message(player: Player, value): if value != 1: return "INCORRECT! Please try again." def CC7_Success_error_message(player: Player, value): if value != 1: return "INCORRECT! Please try again." def CC7_Failure_error_message(player: Player, value): if value != 2: return "INCORRECT! Please try again." def CC8_error_message(player: Player, value): if value != 1: return "INCORRECT! Please try again." def CC9_error_message(player: Player, value): if value != 1: return "INCORRECT! Please try again." class Condition(Page): form_model = 'player' form_fields = ['Success', 'Accountability'] class Gen_Info(Page): pass class Study_BG(Page): pass class Study_BG2(Page): pass class First_Decision(Page): pass class First_Decision2(Page): pass class First_Decision3(Page): pass class CC1(Page): form_model = 'player' form_fields = ['CC1', 'CC2', 'CC3'] class First_Decision4(Page): form_model = 'player' form_fields = ['GreenChosen', 'PurpleChosen', 'MaroonChosen', 'IndigoChosen', 'VioletChosen', 'LimeChosen', 'TealChosen', 'letter_count_task_points', 'word_jumble_task_points', 'synonym_task_points', 'average_performance_points'] COLOR_POINTS = { 'GreenChosen': 11, 'PurpleChosen': 10, 'MaroonChosen': 10, 'IndigoChosen': 7, 'VioletChosen': 8, 'LimeChosen': 7, 'TealChosen': 7 } @staticmethod def before_next_page(player: Player, timeout_happened): # Calculate the total points based on the chosen colors. chosen_points = sum([First_Decision4.COLOR_POINTS[color] for color, is_chosen in player.__dict__.items() if is_chosen and color in First_Decision4.COLOR_POINTS]) # Add to the baseline. player.points = chosen_points + 36 if not player.PurpleChosen or not player.GreenChosen: player.push = 1 else: player.push = 0 @staticmethod def error_message(player: Player, values): if sum([values[color] for color in First_Decision4.COLOR_POINTS.keys()]) != 4: return 'You must select exactly 4 participants.' total_points = sum( [values['letter_count_task_points'], values['word_jumble_task_points'], values['synonym_task_points'], values['average_performance_points']]) if total_points != 100: return 'The total points allocated to all four categories must add up to 100 points.' class Results_1(Page): pass class Second_Decision(Page): def is_displayed(player): return player.push == 0 class Second_Decision2(Page): def is_displayed(player): return player.push == 0 class CC2(Page): def is_displayed(player): return player.push == 0 form_model = 'player' form_fields = ['CC4', 'CC5', 'CC6'] class Second_Decision3_Success(Page): def is_displayed(player): return player.push == 0 and player.Success == 1 form_model = 'player' form_fields = ['Purple', 'Blue', 'Promotion1_Success', 'Report1', 'word_search_points', 'math_experience_points', 'math_skills_points', 'creativity_level_points', 'trivia_points', 'sudoku_points'] @staticmethod def error_message(player: Player, values): total_points = sum( [values['word_search_points'], values['math_experience_points'], values['math_skills_points'], values['creativity_level_points'], values['trivia_points'], values['sudoku_points']]) if total_points != 120: return 'The total points allocated to all four categories must add up to 120 points.' report = values['Report1'] if len(report.split()) < 50: return 'Your report should have a minimum of 50 words.' # Check if Purple and Blue values are between 1 and 10 if not (1 <= values.get('Purple', 0) <= 10): return 'Please input an integer between 1 to 10 for question (1).' if not (1 <= values.get('Blue', 0) <= 10): return 'Please input an integer between 1 to 10 for question (2).' def before_next_page(player: Player, timeout_happened): # If player chooses Blue (Hired by Experimenters) if player.Promotion1_Success == 2: player.other = 1 else: player.other = 0 player.points += 300 print("Points:", player.points) class Second_Decision3_Failure(Page): def is_displayed(player): return player.push == 0 and player.Success == 0 form_model = 'player' form_fields = ['Green', 'Blue', 'Promotion1_Failure', 'Report1', 'word_search_points', 'math_experience_points', 'math_skills_points', 'creativity_level_points', 'trivia_points', 'sudoku_points'] @staticmethod def error_message(player: Player, values): total_points = sum( [values['word_search_points'], values['math_experience_points'], values['math_skills_points'], values['creativity_level_points'], values['trivia_points'], values['sudoku_points']]) if total_points != 120: return 'The total points allocated to all four categories must add up to 120 points.' report = values['Report1'] if len(report.split()) < 50: return 'Your report should have a minimum of 50 words.' # Check if Green and Blue values are between 1 and 10 if not (1 <= values.get('Green', 0) <= 10): return 'Please input an integer between 1 to 10 for question (1).' if not (1 <= values.get('Blue', 0) <= 10): return 'Please input an integer between 1 to 10 for question (2).' def before_next_page(player: Player, timeout_happened): # If player chooses Blue (Hired by Experimenters) if player.Promotion1_Failure == 2: player.other = 1 else: player.other = 0 print("player.other", player.other) class Third_Decision(Page): def is_displayed(player): return player.push == 0 class Third_Decision2(Page): def is_displayed(player): return player.push == 0 class CC3(Page): def is_displayed(player): return player.push == 0 form_model = 'player' form_fields = ['CC7_Success', 'CC7_Failure', 'CC8', 'CC9'] class Third_Decision3_Success(Page): def is_displayed(player): return player.push == 0 and player.Success == 1 and player.other == 0 form_model = 'player' form_fields = ['Green', 'Blue2', 'Promotion2_Success', 'Report2', 'word_search_points2', 'math_experience_points2', 'math_skills_points2', 'creativity_level_points2', 'trivia_points2', 'sudoku_points2'] @staticmethod def error_message(player: Player, values): total_points = sum( [values['word_search_points2'], values['math_experience_points2'], values['math_skills_points2'], values['creativity_level_points2'], values['trivia_points2'], values['sudoku_points2']]) if total_points != 120: return 'The total points allocated to all four categories must add up to 120 points.' report = values['Report2'] if len(report.split()) < 50: return 'Your report should have a minimum of 50 words.' # Check if Green and Blue2 values are between 1 and 10 if not (1 <= values.get('Green', 0) <= 10): return 'Please input an integer between 1 to 10 for question (1).' if not (1 <= values.get('Blue2', 0) <= 10): return 'Please input an integer between 1 to 10 for question (2).' class Third_Decision3_Other(Page): def is_displayed(player): return player.push == 0 and player.other == 1 form_model = 'player' form_fields = ['Purple2', 'Green2', 'Promotion2_Other', 'Report2', 'word_search_points2', 'math_experience_points2', 'math_skills_points2', 'creativity_level_points2', 'trivia_points2', 'sudoku_points2'] @staticmethod def error_message(player: Player, values): total_points = sum( [values['word_search_points2'], values['math_experience_points2'], values['math_skills_points2'], values['creativity_level_points2'], values['trivia_points2'], values['sudoku_points2']]) if total_points != 120: return 'The total points allocated to all four categories must add up to 120 points.' report = values['Report2'] if len(report.split()) < 50: return 'Your report should have a minimum of 50 words.' def before_next_page(player: Player, timeout_happened): if player.Promotion2_Other == 1: player.points += 300 print("Points:", player.points) class Third_Decision3_Failure(Page): def is_displayed(player): return player.push == 0 and player.Success == 0 and player.other == 0 form_model = 'player' form_fields = ['Purple', 'Blue2', 'Promotion2_Failure', 'Report2', 'word_search_points2', 'math_experience_points2', 'math_skills_points2', 'creativity_level_points2', 'trivia_points2', 'sudoku_points2'] @staticmethod def error_message(player: Player, values): total_points = sum( [values['word_search_points2'], values['math_experience_points2'], values['math_skills_points2'], values['creativity_level_points2'], values['trivia_points2'], values['sudoku_points2']]) if total_points != 120: return 'The total points allocated to all four categories must add up to 120 points.' report = values['Report2'] if len(report.split()) < 50: return 'Your report should have a minimum of 50 words.' # Check if Purple and Blue2 values are between 1 and 10 if not (1 <= values.get('Purple', 0) <= 10): return 'Please input an integer between 1 to 10 for question (1).' if not (1 <= values.get('Blue2', 0) <= 10): return 'Please input an integer between 1 to 10 for question (2).' def before_next_page(player: Player, timeout_happened): if player.Promotion2_Failure == 1: player.points += 300 print("Points:", player.points) class AlternateTask(Page): def is_displayed(player): return player.push == 1 class Slider(Page): def is_displayed(player: Player): return player.push == 1 timeout_seconds = 25 def live_method(player, data): print(data) # if data == 0: # player.slider_correct += 1 # else: # player.slider_incorrect += 1 # # player.slider_attempted = player.slider_correct + player.slider_incorrect # # print('number_correct:', player.slider_correct) # print('number_incorrect:', player.slider_incorrect) # print('number_attempted:', player.slider_attempted) def js_vars(player: Player): lower1 = 101 lower2 = 11 upper1 = 500 upper2 = 99 return dict( lower1=lower1, upper1=upper1, lower2=lower2, upper2=upper2, ) def before_next_page(player: Player, timeout_happened): player.points += 300 print("Points:", player.points) class PEQ(Page): def is_displayed(player: Player): return player.push == 0 form_model = 'player' @staticmethod def get_form_fields(player): fields = [ 'important_first', 'important_second', 'easy_case', 'realistic_case', 'responsible_first', 'responsible_second', 'pressure', ] if player.Success == 1 and player.Promotion1_Success == 1: fields.extend(['sorry_success_first_blue', 'regret_success_first_blue']) elif player.Success == 1 and player.Promotion1_Success == 2: fields.extend(['sorry_success_first_purple', 'regret_success_first_purple']) elif player.Success == 0 and player.Promotion1_Failure == 1: fields.extend(['sorry_failure_first_blue', 'regret_failure_first_blue']) elif player.Success == 0 and player.Promotion1_Failure == 2: fields.extend(['sorry_failure_first_green', 'regret_failure_first_green']) if player.Success == 1 and player.other == 0 and player.Promotion2_Success == 1: fields.extend(['sorry_success_second_blue', 'regret_success_second_blue']) elif player.Success == 1 and player.other == 0 and player.Promotion2_Success == 2: fields.extend(['sorry_success_second_green', 'regret_success_second_green']) elif player.Success == 0 and player.other == 0 and player.Promotion2_Failure == 1: fields.extend(['sorry_failure_second_blue', 'regret_failure_second_blue']) elif player.Success == 0 and player.other == 0 and player.Promotion2_Failure == 2: fields.extend(['sorry_failure_second_purple', 'regret_failure_second_purple']) elif player.other == 1 and player.Promotion2_Other == 1: fields.extend(['sorry_success_second_green', 'regret_success_second_green']) elif player.other == 1 and player.Promotion2_Other == 2: fields.extend(['sorry_failure_second_purple', 'regret_failure_second_purple']) return fields class Demographics(Page): form_model = 'player' form_fields = ['age', 'gender', 'work_experience'] def before_next_page(player: Player, timeout_happened): player.pay = 5 + (math.ceil(player.points/75/ 0.25) * 0.25) class ThankYou(Page): def vars_for_template(player: Player): pay = "{:.2f}".format(player.pay) return dict( pay=pay, ) page_sequence = [Condition, Gen_Info, Study_BG, Study_BG2, First_Decision, First_Decision2, First_Decision3, CC1, First_Decision4, Results_1, Second_Decision, Second_Decision2, CC2, Second_Decision3_Success, Second_Decision3_Failure, Third_Decision, Third_Decision2, CC3, Third_Decision3_Success, Third_Decision3_Failure, Third_Decision3_Other, AlternateTask, Slider, PEQ, Demographics, ThankYou]