import time import string import random from otree import settings from otree.api import * #SESSION class C(BaseConstants): NAME_IN_URL = 'sg_post' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 #SUBSESSION class Subsession(BaseSubsession): pass #GROUP class Group(BaseGroup): pass #PLAYER class Player(BasePlayer): understood = models.IntegerField( choices=[[1, 'Yes'], [0, 'No']], widget=widgets.RadioSelect, blank=True ) difficult = models.IntegerField( choices=[[0, 'Very Easy'], [1, 'Easy'], [2, 'Neither Easy nor Hard'], [3, 'Hard'], [4, 'Very Hard']], widget=widgets.RadioSelect, blank=True ) how_decision = models.IntegerField( choices=[[0, 'Picked an alternative without thinking much about it'], [1, 'Thought a little bit about it'], [2, 'Tried to make a very thoughtful choice']], widget=widgets.RadioSelect, blank=True ) best = models.IntegerField( choices=[[0, 'Not at all'],[1, 'Slightly'],[2, 'Somewhat'],[3, 'Mostly'],[4, 'Completely']], widget=widgets.RadioSelect, blank=True ) certainty = models.IntegerField( choices=[[0, 'Not at all'],[1, 'Slightly'],[2, 'Somewhat'],[3, 'Mostly'],[4, 'Completely']], widget=widgets.RadioSelect, blank=True ) initial_att = models.IntegerField( label='I paid attention to this', choices=[[0, 'Strongly Disagree'],[1, 'Disagree'],[2, 'Neither Agree nor Disagree'],[3, 'Agree'],[4, 'Strongly Agree']], widget=widgets.RadioSelect, blank=True ) initial_care = models.IntegerField( label='This was important for me when I decided how to split the money', choices=[[0, 'Strongly Disagree'],[1, 'Disagree'],[2, 'Neither Agree nor Disagree'],[3, 'Agree'],[4, 'Strongly Agree']], widget=widgets.RadioSelect, blank=True ) final_att = models.IntegerField( label='I paid attention to this', choices=[[0, 'Strongly Disagree'],[1, 'Disagree'],[2, 'Neither Agree nor Disagree'],[3, 'Agree'],[4, 'Strongly Agree']], widget=widgets.RadioSelect, blank=True ) final_care = models.IntegerField( label='This was important for me when I decided how to split the money', choices=[[0, 'Strongly Disagree'],[1, 'Disagree'],[2, 'Neither Agree nor Disagree'],[3, 'Agree'],[4, 'Strongly Agree']], widget=widgets.RadioSelect, blank=True ) effort_att = models.IntegerField( label='I paid attention to this', choices=[[0, 'Strongly Disagree'],[1, 'Disagree'],[2, 'Neither Agree nor Disagree'],[3, 'Agree'],[4, 'Strongly Agree']], widget=widgets.RadioSelect, blank=True ) effort_care = models.IntegerField( label='This was important for me when I decided how to split the money', choices=[[0, 'Strongly Disagree'],[1, 'Disagree'],[2, 'Neither Agree nor Disagree'],[3, 'Agree'],[4, 'Strongly Agree']], widget=widgets.RadioSelect, blank=True ) luck_att = models.IntegerField( label='I paid attention to this', choices=[[0, 'Strongly Disagree'],[1, 'Disagree'],[2, 'Neither Agree nor Disagree'],[3, 'Agree'],[4, 'Strongly Agree']], widget=widgets.RadioSelect, blank=True ) luck_care = models.IntegerField( label='This was important for me when I decided how to split the money', choices=[[0, 'Strongly Disagree'],[1, 'Disagree'],[2, 'Neither Agree nor Disagree'],[3, 'Agree'],[4, 'Strongly Agree']], widget=widgets.RadioSelect, blank=True ) accurate = models.IntegerField( choices=[[0, 'Strongly Disagree'],[1, 'Disagree'],[2, 'Neither Agree nor Disagree'],[3, 'Agree'],[4, 'Strongly Agree']], widget=widgets.RadioSelect, blank=True ) write0 = models.LongStringField() write1 = models.LongStringField() short_attempts = models.IntegerField(initial=0) time_survey0 = models.FloatField(label='Time: Survey0') #FUNCTIONS def compute_math(player): participant = player.participant ## compute player payoff result= sum(participant.math_list) participant.math_score= result participant.math_money= participant.math_score*.50 def select_recall(player: Player): participant = player.participant if participant.treatment == 'T0': #Lottery participant.cognitiveload_control = 1 if random.random() <= 0.4 else 0 else: #Cognitive Load correct = participant.cognitiveload_list length = len(correct) group_of_items = list(range(length)) participant.cognitiveload_random = random.choice(group_of_items) def compute_bonus(player): participant = player.participant if participant.treatment == 'T0': result= participant.cognitiveload_control else: correct = participant.cognitiveload_list result= correct[participant.cognitiveload_random] participant.cognitiveload_score=result participant.cognitiveload_money=participant.cognitiveload_score*10 math_result = sum(participant.math_list) participant.math_score=math_result participant.math_money=participant.math_score*0.10 def set_payoff(player): participant = player.participant raven_money=participant.bonus_money cognitiveload_money=participant.cognitiveload_money math_money=participant.math_money total_bonus=raven_money+cognitiveload_money+math_money player.payoff=10+total_bonus participant.payoff=10+total_bonus def understood_error_message(player, value): if value not in [0, 1]: return 'You have to select one of the options.' def difficult_error_message(player, value): if value not in [0, 1, 2, 3, 4]: return 'You have to select one of the options.' def how_decision_error_message(player, value): if value not in [0, 1, 2,]: return 'You have to select one of the options.' def best_error_message(player, value): if value not in [0, 1, 2, 3, 4]: return 'You have to select one of the options.' def certainty_error_message(player, value): if value not in [0, 1, 2, 3, 4]: return 'You have to select one of the options.' def accurate_error_message(player, value): if value not in [0, 1, 2, 3, 4]: return 'You have to select one of the options.' def initial_att_error_message(player, value): if value not in [0, 1, 2, 3, 4]: return 'You have to select one of the options.' def initial_care_error_message(player, value): if value not in [0, 1, 2, 3, 4]: return 'You have to select one of the options.' def final_att_error_message(player, value): if value not in [0, 1, 2, 3, 4]: return 'You have to select one of the options.' def final_care_error_message(player, value): if value not in [0, 1, 2, 3, 4]: return 'You have to select one of the options.' def effort_att_error_message(player, value): if value not in [0, 1, 2, 3, 4]: return 'You have to select one of the options.' def effort_care_error_message(player, value): if value not in [0, 1, 2, 3, 4]: return 'You have to select one of the options.' def luck_att_error_message(player, value): if value not in [0, 1, 2, 3, 4]: return 'You have to select one of the options.' def luck_care_error_message(player, value): if value not in [0, 1, 2, 3, 4]: return 'You have to select one of the options.' # PAGES class Intro(Page): form_model = 'player' @staticmethod def vars_for_template(player): compute_math(player) select_recall(player) compute_bonus(player) set_payoff(player) @staticmethod def before_next_page(player, timeout_happened): player.time_survey0 = round(time.time(),3) class Survey0(Page): form_model = 'player' form_fields = ['write0','write1'] @staticmethod def vars_for_template(player): participant = player.participant #AUXILIARY: Generate column names letters = list(string.ascii_uppercase) names = [] for i in range(25): if i < len(letters)/2: names.append(letters[(i * 2) + 1]) # B, D, F, ..., Z else: prefix = "A" + letters[(i - len(letters)) * 2 + 1] # AA, AC, AE, ... names.append(prefix) # DEFAULT tasks_list = participant.tasks_list effort_list = [participant.alloc_effort0, participant.alloc_effort1, participant.alloc_effort2, participant.alloc_effort3, participant.alloc_effort4, participant.alloc_effort5, participant.alloc_effort6] luck_list = [participant.alloc_luck0, participant.alloc_luck1, participant.alloc_luck2, participant.alloc_luck3, participant.alloc_luck4, participant.alloc_luck5] effort_count = 0 luck_count = 0 allocations = {} for i in range(len(tasks_list)): task = tasks_list[i] name = f"alloc_{names[i]}" if task in {0,1,2,3,4}: allocations[name] = effort_list[min(effort_count, 7)] effort_count += 1 elif task in {5,6,7,8,9}: allocations[name] = luck_list[min(luck_count, 6)] luck_count += 1 else: allocations[name] = -1 # NODEFAULT nodefault_list = participant.nodefault_list for j in range(len(nodefault_list)): task = nodefault_list[j] i = j + len(tasks_list) name = f"alloc_{names[i]}" if task in {10}: allocations[name] = participant.nodefault_effort elif task in {11}: allocations[name] = participant.nodefault_luck else: allocations[name] = -1 # PERFORMANCE performance_list = participant.performance_list decision_list = [participant.performance0, participant.performance1, participant.performance2, participant.performance3, participant.performance4, participant.performance5, participant.performance6, participant.performance7, participant.performance8, participant.performance9] performance_count = 0 for h in range(len(performance_list)): task = performance_list[h] i = h + len(tasks_list) + len(nodefault_list) name = f"alloc_{names[i]}" allocations[name] = decision_list[performance_count] performance_count += 1 # PERFORMANCE TASKS COMPLETED for i, val in enumerate(performance_list): task_num = 15 + i a_val = val - 20 globals()[f'task{task_num}'] = a_val # COMPLEMENTARY ALLOCATIONS for i in range(len(allocations)): key = list(allocations.keys())[i] # alloc_B, alloc_D, alloc_F, ... base_key = key[:-1] # Remove the last character to get the "base" (e.g., alloc_A) complement_key = f"{base_key}{chr(ord(key[-1]) - 1)}" # Get the complementary key (e.g., alloc_A -> alloc_B) allocations[complement_key] = 6 - allocations[key] for key, value in allocations.items(): if value == -1 or value == 7: allocations[key] = "-" for key, value in allocations.items(): if isinstance(value, (int, float)): # Check if the value is a number allocations[key] = str(value) + " USD" return dict(alloc_A=allocations["alloc_A"],alloc_B=allocations["alloc_B"],alloc_C=allocations["alloc_C"],alloc_D=allocations["alloc_D"],alloc_E=allocations["alloc_E"],alloc_F=allocations["alloc_F"],alloc_G=allocations["alloc_G"],alloc_H=allocations["alloc_H"],alloc_I=allocations["alloc_I"],alloc_J=allocations["alloc_J"],alloc_K=allocations["alloc_K"],alloc_L=allocations["alloc_L"],alloc_M=allocations["alloc_M"],alloc_N=allocations["alloc_N"],alloc_O=allocations["alloc_O"],alloc_P=allocations["alloc_P"],alloc_Q=allocations["alloc_Q"],alloc_R=allocations["alloc_R"],alloc_S=allocations["alloc_S"],alloc_T=allocations["alloc_T"],alloc_U=allocations["alloc_U"],alloc_V=allocations["alloc_V"],alloc_W=allocations["alloc_W"],alloc_X=allocations["alloc_X"],alloc_Y=allocations["alloc_Y"],alloc_Z=allocations["alloc_Z"],alloc_AA=allocations["alloc_AA"],alloc_AB=allocations["alloc_AB"],alloc_AC=allocations["alloc_AC"],alloc_AD=allocations["alloc_AD"],alloc_AE=allocations["alloc_AE"],alloc_AF=allocations["alloc_AF"],alloc_AG=allocations["alloc_AG"],alloc_AH=allocations["alloc_AH"],alloc_AI=allocations["alloc_AI"],alloc_AJ=allocations["alloc_AJ"],alloc_AK=allocations["alloc_AK"],alloc_AL=allocations["alloc_AL"],alloc_AM=allocations["alloc_AM"],alloc_AN=allocations["alloc_AN"],alloc_AO=allocations["alloc_AO"],alloc_AP=allocations["alloc_AP"],alloc_AQ=allocations["alloc_AQ"],alloc_AR=allocations["alloc_AR"],alloc_AS=allocations["alloc_AS"],alloc_AT=allocations["alloc_AT"],alloc_AU=allocations["alloc_AU"],alloc_AV=allocations["alloc_AV"],alloc_AW=allocations["alloc_AW"],alloc_AX=allocations["alloc_AX"], task0=tasks_list[0],task1=tasks_list[1],task2=tasks_list[2],task3=tasks_list[3],task4=tasks_list[4],task5=tasks_list[5],task6=tasks_list[6],task7=tasks_list[7],task8=tasks_list[8],task9=tasks_list[9],task10=tasks_list[10],task11=tasks_list[11],task12=tasks_list[12],task13=nodefault_list[0],task14=nodefault_list[1], task15=task15,task16=task16,task17=task17,task18=task18,task19=task19,task20=task20,task21=task21,task22=task22,task23=task23,task24=task24) @staticmethod def error_message(player: Player, values): write = values.get('write1') if write is None or len(write) < 100: player.short_attempts += 1 return dict(write1='Please write a longer response (at least 100 characters).') class Survey1(Page): form_model = 'player' form_fields = ['understood'] class Survey2(Page): form_model = 'player' form_fields = ['difficult','how_decision','best','certainty'] class Survey3(Page): form_model = 'player' form_fields = ['initial_att','initial_care','final_att','final_care','effort_att','effort_care','luck_att','luck_care'] page_sequence = [Intro,Survey0,Survey1,Survey2,Survey3]