from otree.api import * class C(BaseConstants): NAME_IN_URL = 'pilot' PLAYERS_PER_GROUP = None NUM_ROUNDS = 100 # Total rounds NUM_CLS = 2 # Number of class used NUM_CLS_ROUNDS = int(NUM_ROUNDS / NUM_CLS) TIMEOUT_S = 60 # Maximum time used for each image NUM_ROUNDS_PAY = 1 # Number of rounds paid BREAK_ROUND = 10 # Number of rounds before going to break NUM_TREAT_GP = 2 # Number of control and treatment groups TIMEOUT = 'TRUE' #TRUE if timeout, else no timeout BONUS_LIST = [0, 1, 5, 10, 20] INSTRUCTIONS_TEMPLATE1 = 'pilot/instructions1.html' INSTRUCTIONS_TEMPLATE2 = 'pilot/instructions2.html' INSTRUCTIONS_TEMPLATE3 = 'pilot/instructions3.html' BSR = 'pilot/BSR.html' #PRIOR = 0.5 PRIOR_LIST = [0.5] # prob of category1 between 0 and 1 [0.5, 0.8] #PRIOR_DISPLAY = PRIOR*100 PAYOFF = 5 PARTICIPATION_FEE = 5 class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): Authorization = models.CharField( choices=['Yes, I would like to participate in this study, I am a resident of the United States, and I am 18 or older', 'No, I cannot participate'], widget=widgets.RadioSelect) math = models.CharField(#label = '100/2=', #choices=['20', # '30', # '50'], #widget=widgets.RadioSelect ) atten = models.CharField(#label = '2+5+3=', #choices=['10', # '12', # '14'], #widget=widgets.RadioSelect ) quiz = models.FloatField( min=0, max=100, label = "" ) prob = models.FloatField( min=0, max=100, label = "" #label="What is the probability that this picture is a DOG (rather than a cat)? Please pick a number from 0 to 100:", ) check_slider_main = models.IntegerField( min=0, max=100, label = "" ) prob_expost = models.FloatField( min=0, max=100, label = "" #label="What is the probability that this picture is a DOG (rather than a cat)? Please pick a number from 0 to 100:", ) check_slider_expost = models.IntegerField( min=0, max=100, label = "" ) prac1 = models.FloatField( min=0, max=100, label = "" ) check_slider_one = models.IntegerField( min=0, max=100, label = "" ) prac2 = models.FloatField( min=0, max=100, label = "" ) check_slider_two = models.IntegerField( min=0, max=100, label = "" ) prac3 = models.FloatField( min=0, max=100, label = "" ) check_slider_three = models.IntegerField( min=0, max=100, label = "" ) prac4 = models.FloatField( min=0, max=100, label = "" ) check_slider_four = models.IntegerField( min=0, max=100, label = "" ) fatigue = models.StringField(blank=True, label = "When did you start to feel fatigue? (e.g. Session 2 Round 24)") instruction = models.StringField(blank=True, label = "Is the instruction clear enough to you? If not, why do you think it is not clear?") ever_work_pict = models.CharField(blank=True) #ever_work_pict = models.StringField(blank=True, label = "Do you have any other comments about the experiment? Any feedback is welcome.") #random_pict = [models.IntegerField(min=0,max=9,label = str(i)) for i in range(C.NUM_ROUNDS)] other_comment = models.StringField(blank=True, label = "Do you have any other comments about the experiment? Any feedback is welcome.") button_clicks = models.IntegerField(initial=0) timer = models.IntegerField(initial=0) class Machine(ExtraModel): filename = models.StringField() machine_prob = models.FloatField() def prob_error_message(player, value): if value > 100: return 'Number must be between 0 and 100.' # FUNCTIONS def creating_session(subsession): def createList(r1, r2): return [item for item in range(r1, r2+1)] if subsession.round_number == 1: import random for player in subsession.get_players(): participant = player.participant #participant.AI_inst1 = random.choice([0,1]) participant.prior = random.choice(C.PRIOR_LIST) # 'treat_gp' determines which treatment groups subjects are assigned # treat_gp = 1 implies control (no algorithm score) # treat_gp = 2 implies concurrent algorithm score # treat_gp = 3 implies ex-post algorithm score participant.treat_gp = random.choice(createList(1, C.NUM_TREAT_GP)) # 'paying_rounds' is a list of numbers determining which rounds to be paid, from 0 to 99 participant.paying_rounds = random.sample(range(C.NUM_ROUNDS), C.NUM_ROUNDS_PAY) #should this be subject specific? # 'random_pic_num' represents which pictures to show to subjects, this is subject specific participant.random_pic_num = random.sample(range(72), C.NUM_CLS_ROUNDS) participant.random_pic_num2 = random.sample(range(72), C.NUM_CLS_ROUNDS) participant.random_pic_num3 = random.sample(range(72), C.NUM_CLS_ROUNDS) # 'random_class' represents a list of number drawn from a uniform distribution determine cat or dog, this is subject specific participant.random_class = [random.uniform(0, 1) for _ in range(C.NUM_ROUNDS)] participant.bonus_list1 = random.sample(C.BONUS_LIST, k=(int(C.NUM_ROUNDS/C.BREAK_ROUND/C.NUM_CLS))) participant.bonus_list2 = random.sample(C.BONUS_LIST, k=(int(C.NUM_ROUNDS/C.BREAK_ROUND/C.NUM_CLS))) dummy = [25] #participant.bonus_list = participant.bonus_list.extend(dummy) for i in range(C.NUM_ROUNDS): if participant.random_class[i] < participant.prior: participant.random_class[i] = 0 #category1 else: participant.random_class[i] = 1 #category2 def set_payoffs(player: Player): import random subsession = player.subsession session = player.session participant = player.participant participant.payoff_list = [None] * C.NUM_ROUNDS_PAY participant.bsq_prob_list = [None] * C.NUM_ROUNDS_PAY prob_list = [random.uniform(0, 1) for _ in range(C.NUM_ROUNDS_PAY)] for i in range(C.NUM_ROUNDS_PAY): if participant.random_class[participant.paying_rounds[i]] == 0: participant.bsq_prob_list[i] = 1 - (1 - player.in_round(participant.paying_rounds[i]+1).prob / 100)**2 else: participant.bsq_prob_list[i] = 1 - (player.in_round(participant.paying_rounds[i]+1).prob / 100) **2 for i in range(C.NUM_ROUNDS_PAY): from random import choices potential_payment = [0, C.PAYOFF] weights = [1 - participant.bsq_prob_list[i], participant.bsq_prob_list[i]] participant.payoff_list[i] = random.choices(potential_payment, weights)[0] if player.in_round(participant.paying_rounds[i]+1).prob < 0: # if the person either put something does not make sense, or not enough time, their payoff for the round must be equal to 0. participant.payoff_list[i] = 0 #player.payoff = sum(participant.payoff_list) # participant.payoff_list[i] = player.in_round(participant.paying_rounds[i]+1).prob # for player in subsession.get_players(): # import random # participant = player.participant # participant.payoff_list = [None] * C.NUM_ROUNDS_PAY # for i in range(C.NUM_ROUNDS_PAY): # prev_player = player.in_round(participant.paying_rounds[i]+1) # participant.payoff_list[i] = player.in_round(1).prob # for i in range(C.NUM_ROUNDS_PAY): # participant.payoff_list[i] = player.prob # participant.total_payoff = sum(participant.payoff_list) # PAGES class Consent(Page): form_model = 'player' form_fields = ['Authorization'] @staticmethod def is_displayed(player: Player): return player.round_number == 1 class Consentout(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): return (player.round_number == 1) & (player.in_round(1).Authorization == 'No, I cannot participate') def js_vars(player): return dict( consentlink= player.subsession.session.config['consentlink'] ) class Consentfinal(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): return (player.round_number == 1) & (player.in_round(1).Authorization == 'No, I cannot participate') def js_vars(player): return dict( consentlink= player.subsession.session.config['consentlink'] ) class Attention(Page): form_model = 'player' form_fields = ['math', 'atten'] @staticmethod def is_displayed(player: Player): return player.round_number == 1 class Attentionout(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): return (player.round_number == 1)&((player.in_round(1).math != '50') | (player.in_round(1).atten != '14')) def js_vars(player): return dict( attentionlink= player.subsession.session.config['attentionlink'] ) class Attentionfinal(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): return (player.round_number == 1)&((player.in_round(1).math != '50') | (player.in_round(1).atten != '14')) def js_vars(player): return dict( attentionlink= player.subsession.session.config['attentionlink'] ) class Welcome(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 class Introduction1(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 #@staticmethod #def before_next_page(player, timeout_happened): # player.prolific_id = player.participant.label class Introduction2(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 class Introduction3(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 class Treatment1(Page): @staticmethod def is_displayed(player: Player): participant = player.participant treatment = participant.treat_gp return player.round_number == 1 and treatment == 2 #def vars_for_template(player): # participant = player.participant # AI_inst1 = participant.AI_inst1 # return dict( # AI_inst1=AI_inst1) class Treatment2(Page): @staticmethod def is_displayed(player: Player): participant = player.participant treatment = participant.treat_gp return player.round_number == 1 and treatment == 3 class Quiz(Page): form_model = 'player' form_fields = ['quiz'] @staticmethod def is_displayed(player: Player): participant = player.participant treatment = participant.treat_gp return player.round_number == 1 and treatment > 1 #and participant.AI_inst1 == 1 def error_message(player, value): if value['quiz'] != 79: return 'The answer is not correct. Please think about it again.' class Main(Page): form_model = 'player' form_fields = ['prob', 'check_slider_main'] if C.TIMEOUT == 'TRUE': timeout_seconds = C.TIMEOUT_S @staticmethod def prob_error_message(player, value): if values['prob'] < 0 | values['prob'] > 100: return 'Number must be between 0 and 100.' @staticmethod def vars_for_template(player): import pathlib import math participant = player.participant block_paid = math.ceil(player.round_number /C.BREAK_ROUND) - 1 # -1 because to match python numbering if player.round_number <= C.NUM_CLS_ROUNDS: a = player.round_number Category1="a DOG" category1="a dog" ctegory1 = "dog" Ctegory1="DOG" Category2="a CAT" category2 = "a cat" ctegory2 = "cat" Ctegory2="CAT" treatment = participant.treat_gp image = player.participant.random_pic_num[player.round_number - 1] amount_paid = participant.bonus_list1[block_paid] if player.participant.random_class[player.round_number - 1] == 0: image_path='pilot/dog/dog{}.png'.format(image) rows = read_csv('pilot/machine_results/dog.csv', Machine) else: image_path='pilot/cat/cat{}.png'.format(image) rows = read_csv('pilot/machine_results/cat.csv', Machine) #image_path='sample/dog/dog{}.png'.format(image) #image_path='sample/figure{}.png'.format(player.participant.random_pict) elif C.NUM_CLS_ROUNDS < player.round_number & player.round_number <= 2 * C.NUM_CLS_ROUNDS : a = player.round_number - C.NUM_CLS_ROUNDS Category1="a TRUCK" category1="a truck" ctegory1 = "truck" Ctegory1="TRUCK" Category2="a CAR" category2 = "a car" ctegory2 = "car" Ctegory2="CAR" treatment = participant.treat_gp image = player.participant.random_pic_num2[player.round_number - 1 - C.NUM_CLS_ROUNDS] block_paid = block_paid - int(C.NUM_ROUNDS/C.BREAK_ROUND/C.NUM_CLS) amount_paid = participant.bonus_list2[block_paid] if player.participant.random_class[player.round_number - 1] == 0: image_path='pilot/truck/truck{}.png'.format(image) rows = read_csv('pilot/machine_results/truck.csv', Machine) else: image_path='pilot/car/car{}.png'.format(image) rows = read_csv('pilot/machine_results/car.csv', Machine) #image_path='sample/dog/dog{}.png'.format(image) #image_path='sample/figure{}.png'.format(player.participant.random_pict) else: image = player.participant.random_pic_num3[player.round_number - 1 - 2 * C.NUM_CLS_ROUNDS] a = player.round_number - 2 * C.NUM_CLS_ROUNDS Category1="a BIRD" category1="a bird" ctegory1 = "bird" Category2="an AIRPLANE" category2 = "an airplane" ctegory2 = "airplane" treatment = participant.treat_gp if player.participant.random_class[player.round_number - 1] == 0: image_path='pilot/bird/bird{}.png'.format(image) rows = read_csv('pilot/machine_results/bird.csv', Machine) else: image_path='pilot/airplane/airplane{}.png'.format(image) rows = read_csv('pilot/machine_results/airplane.csv', Machine) #image_path='sample/dog/dog{}.png'.format(image) #image_path='sample/figure{}.png'.format(player.participant.random_pict) dict1 = dict( # image = player.random_pict[player.round_number - 1] #image_path='../sample/figure/figure{}.png'.format(image) image_path=image_path, #image_path = pathlib.Path().resolve() round_number=a, Category1=Category1, category1 = category1, ctegory1=ctegory1, Ctegory1=Ctegory1, Category2=Category2, category2=category2, ctegory2=ctegory2, Ctegory2=Ctegory2, treatment=treatment, amount_paid = amount_paid ) dict2 = rows[image] dict2 = dict(machine_prob = int(dict2["machine_prob"])) def Merge(dict1, dict2): #res = dict1 | dict2 #only for Python 3.9 or more res = {**dict1,**dict2} return res dict3 = Merge(dict1, dict2) return dict3 @staticmethod def before_next_page(player: Player, timeout_happened): if timeout_happened: player.prob = -0.0000000001 if player.round_number == C.NUM_ROUNDS: set_payoffs(player) #class ResultsWaitPage(WaitPage): # after_all_players_arrive = set_payoffs class Expost(Page): form_model = 'player' form_fields = ['prob_expost', 'check_slider_expost'] if C.TIMEOUT == 'TRUE': timeout_seconds = C.TIMEOUT_S def is_displayed(player: Player): participant = player.participant treatment = participant.treat_gp return treatment == 3 @staticmethod def prob_error_message(player, value): if values['prob_expost'] < 0 | values['prob_expost'] > 100: return 'Number must be between 0 and 100.' @staticmethod def vars_for_template(player): import pathlib participant = player.participant if player.round_number <= C.NUM_CLS_ROUNDS: a = player.round_number Category1="a DOG" category1="a dog" ctegory1 = "dog" Ctegory1="DOG" Category2="a CAT" category2 = "a cat" ctegory2 = "cat" Ctegory2="CAT" treatment = participant.treat_gp image = player.participant.random_pic_num[player.round_number - 1] if player.participant.random_class[player.round_number - 1] == 0: image_path='pilot/dog/dog{}.png'.format(image) rows = read_csv('pilot/machine_results/dog.csv', Machine) else: image_path='pilot/cat/cat{}.png'.format(image) rows = read_csv('pilot/machine_results/cat.csv', Machine) #image_path='sample/dog/dog{}.png'.format(image) #image_path='sample/figure{}.png'.format(player.participant.random_pict) elif C.NUM_CLS_ROUNDS < player.round_number & player.round_number <= 2 * C.NUM_CLS_ROUNDS : a = player.round_number - C.NUM_CLS_ROUNDS Category1="a TRUCK" category1="a truck" ctegory1 = "truck" Ctegory1="TRUCK" Category2="a CAR" category2 = "a car" ctegory2 = "car" Ctegory2="CAR" treatment = participant.treat_gp image = player.participant.random_pic_num2[player.round_number - 1 - C.NUM_CLS_ROUNDS] if player.participant.random_class[player.round_number - 1] == 0: image_path='pilot/truck/truck{}.png'.format(image) rows = read_csv('pilot/machine_results/truck.csv', Machine) else: image_path='pilot/car/car{}.png'.format(image) rows = read_csv('pilot/machine_results/car.csv', Machine) #image_path='sample/dog/dog{}.png'.format(image) #image_path='sample/figure{}.png'.format(player.participant.random_pict) else: image = player.participant.random_pic_num3[player.round_number - 1 - 2 * C.NUM_CLS_ROUNDS] a = player.round_number - 2 * C.NUM_CLS_ROUNDS Category1="a BIRD" category1="a bird" ctegory1 = "bird" Category2="an AIRPLANE" category2 = "an airplane" ctegory2 = "airplane" treatment = participant.treat_gp if player.participant.random_class[player.round_number - 1] == 0: image_path='pilot/bird/bird{}.png'.format(image) rows = read_csv('pilot/machine_results/bird.csv', Machine) else: image_path='pilot/airplane/airplane{}.png'.format(image) rows = read_csv('pilot/machine_results/airplane.csv', Machine) #image_path='sample/dog/dog{}.png'.format(image) #image_path='sample/figure{}.png'.format(player.participant.random_pict) dict1 = dict( # image = player.random_pict[player.round_number - 1] #image_path='../sample/figure/figure{}.png'.format(image) image_path=image_path, #image_path = pathlib.Path().resolve() round_number=a, Category1=Category1, category1 = category1, ctegory1=ctegory1, Ctegory1=Ctegory1, Category2=Category2, category2=category2, ctegory2=ctegory2, Ctegory2=Ctegory2, treatment=treatment ) dict2 = rows[image] dict2 = dict(machine_prob = int(dict2["machine_prob"])) def Merge(dict1, dict2): #res = dict1 | dict2 #only for Python 3.9 or more res = {**dict1,**dict2} return res dict3 = Merge(dict1, dict2) return dict3 @staticmethod def before_next_page(player: Player, timeout_happened): if timeout_happened: player.prob = -0.0000000001 if player.round_number == C.NUM_ROUNDS: set_payoffs(player) class Interval(Page): timeout_seconds = 0.5 def is_displayed(player: Player): return player.round_number % C.BREAK_ROUND != 1 @staticmethod def vars_for_template(player): participant = player.participant if player.round_number <= C.NUM_CLS_ROUNDS: a = player.round_number elif C.NUM_CLS_ROUNDS < player.round_number & player.round_number <= 2 * C.NUM_CLS_ROUNDS : a = player.round_number - C.NUM_CLS_ROUNDS else: a = player.round_number - 2 * C.NUM_CLS_ROUNDS return dict( round_number=a ) class Interval_expost(Page): timeout_seconds = 0.5 @staticmethod def vars_for_template(player): participant = player.participant if player.round_number <= C.NUM_CLS_ROUNDS: a = player.round_number elif C.NUM_CLS_ROUNDS < player.round_number & player.round_number <= 2 * C.NUM_CLS_ROUNDS : a = player.round_number - C.NUM_CLS_ROUNDS else: a = player.round_number - 2 * C.NUM_CLS_ROUNDS return dict( round_number=a ) class Interval1(Page): timeout_seconds = 0.5 def is_displayed(player: Player): return player.round_number % C.NUM_CLS_ROUNDS == 1 class Interval2(Page): timeout_seconds = 0.5 def is_displayed(player: Player): return player.round_number % C.NUM_CLS_ROUNDS == 1 class Interval3(Page): timeout_seconds = 0.5 def is_displayed(player: Player): return player.round_number % C.NUM_CLS_ROUNDS == 1 class Start(Page): @staticmethod def is_displayed(player: Player): return player.round_number % C.NUM_CLS_ROUNDS == 1 def vars_for_template(player): participant = player.participant prior = int(participant.prior*100) prior_other = 100 - prior if player.round_number <= C.NUM_CLS_ROUNDS: part = 1 category1 = "a dog" category2 = "a cat" ctegory1 = "dog" ctegory2 = "cat" elif C.NUM_CLS_ROUNDS < player.round_number & player.round_number <= 2 * C.NUM_CLS_ROUNDS : part = 2 category1 = "a truck" category2 = "a car" ctegory1 = "truck" ctegory2 = "car" else: part = 3 category1 = "a bird" category2 = "an airplane" ctegory1 = "bird" ctegory2 = "airplane" return dict( part=part, category1=category1, category2=category2, ctegory1=ctegory1, ctegory2=ctegory2, prior=prior, prior_other=prior_other) class Prior(Page): @staticmethod def is_displayed(player: Player): return player.round_number % C.NUM_CLS_ROUNDS == 1 def vars_for_template(player): participant = player.participant prior = int(participant.prior*100) prior_other = 100 - prior if player.round_number <= C.NUM_CLS_ROUNDS: part = 1 category1 = "a dog" category2 = "a cat" ctegory1 = "dog" ctegory2 = "cat" elif C.NUM_CLS_ROUNDS < player.round_number & player.round_number <= 2 * C.NUM_CLS_ROUNDS : part = 2 category1 = "a truck" category2 = "a car" ctegory1 = "truck" ctegory2 = "car" else: part = 3 category1 = "a bird" category2 = "an airplane" ctegory1 = "bird" ctegory2 = "airplane" return dict( part=part, category1=category1, category2=category2, ctegory1=ctegory1, ctegory2=ctegory2, prior=prior, prior_other = prior_other) class Practice1(Page): form_model = 'player' form_fields = ['prac1', 'check_slider_one'] if C.TIMEOUT == 'TRUE': timeout_seconds = C.TIMEOUT_S @staticmethod def is_displayed(player: Player): return player.round_number % C.NUM_CLS_ROUNDS == 1 def vars_for_template(player): participant = player.participant treatment = participant.treat_gp import pathlib if player.round_number <= C.NUM_CLS_ROUNDS: part = 1 Category1 = "a DOG" category1="a dog" ctegory1 = "dog" Ctegory1="DOG" Category2 = "a CAT" category2 = "a cat" Ctegory2="CAT" image_path='pilot/dog/dog73.png' rows = read_csv('pilot/machine_results/dog.csv', Machine) elif C.NUM_CLS_ROUNDS < player.round_number & player.round_number <= 2 * C.NUM_CLS_ROUNDS : part = 2 Category1 = "a TRUCK" category1="a truck" ctegory1 = "truck" Ctegory1="TRUCK" Category2 = "a CAR" category2 = "a car" Ctegory2="CAR" image_path='pilot/truck/truck73.png' rows = read_csv('pilot/machine_results/truck.csv', Machine) else: part = 3 Category1 = "a BIRD" category1="a bird" ctegory1 = "bird" Ctegory1="BIRD" Category2 = "an AIRPLANE" category2 = "an airplane" Ctegory2="AIRPLANE" image_path='pilot/bird/bird73.png' rows = read_csv('pilot/machine_results/bird.csv', Machine) dict1 = dict( part=part, Category1=Category1, category1=category1, ctegory1=ctegory1, Ctegory1 = Ctegory1, Category2=Category2, category2=category2, Ctegory2 = Ctegory2, image_path=image_path, treatment=treatment) dict2 = rows[73] dict2 = dict(machine_prob = int(dict2["machine_prob"])) def Merge(dict1, dict2): res = {**dict1,**dict2} #res = dict1 | dict2 return res dict3 = Merge(dict1, dict2) return dict3 class Practice2(Page): form_model = 'player' form_fields = ['prac2', 'check_slider_two'] if C.TIMEOUT == 'TRUE': timeout_seconds = C.TIMEOUT_S @staticmethod def is_displayed(player: Player): return player.round_number % C.NUM_CLS_ROUNDS == 1 def vars_for_template(player): participant = player.participant treatment = participant.treat_gp import pathlib if player.round_number <= C.NUM_CLS_ROUNDS: part = 1 Category1 = "a DOG" category1="a dog" ctegory1 = "dog" Ctegory1="DOG" Category2 = "a CAT" category2 = "a cat" Ctegory2="CAT" image_path='pilot/cat/cat73.png' rows = read_csv('pilot/machine_results/cat.csv', Machine) elif C.NUM_CLS_ROUNDS < player.round_number & player.round_number <= 2 * C.NUM_CLS_ROUNDS : part = 2 Category1 = "a TRUCK" category1="a truck" ctegory1 = "truck" Ctegory1="TRUCK" Category2 = "a CAR" category2 = "a car" Ctegory2="CAR" image_path='pilot/car/car73.png' rows = read_csv('pilot/machine_results/car.csv', Machine) else: part = 3 Category1 = "a BIRD" category1="a bird" ctegory1 = "bird" Ctegory1="BIRD" Category2 = "an AIRPLANE" category2 = "an airplane" Ctegory2="AIRPLANE" image_path='pilot/airplane/airplane73.png' rows = read_csv('pilot/machine_results/airplane.csv', Machine) dict1 = dict( part=part, Category1=Category1, category1=category1, ctegory1=ctegory1, Ctegory1 = Ctegory1, Category2=Category2, category2=category2, Ctegory2 = Ctegory2, image_path=image_path, treatment=treatment) dict2 = rows[73] dict2 = dict(machine_prob = int(dict2["machine_prob"])) def Merge(dict1, dict2): #res = dict1 | dict2 res = {**dict1,**dict2} return res dict3 = Merge(dict1, dict2) return dict3 class Practice3(Page): form_model = 'player' form_fields = ['prac3', 'check_slider_three'] if C.TIMEOUT == 'TRUE': timeout_seconds = C.TIMEOUT_S @staticmethod def is_displayed(player: Player): return player.round_number % C.NUM_CLS_ROUNDS == 1 def vars_for_template(player): participant = player.participant treatment = participant.treat_gp import pathlib if player.round_number <= C.NUM_CLS_ROUNDS: part = 1 Category1 = "a DOG" category1="a dog" ctegory1 = "dog" Ctegory1="DOG" Category2 = "a CAT" category2 = "a cat" Ctegory2="CAT" image_path='pilot/dog/dog74.png' rows = read_csv('pilot/machine_results/dog.csv', Machine) elif C.NUM_CLS_ROUNDS < player.round_number & player.round_number <= 2 * C.NUM_CLS_ROUNDS : part = 2 Category1 = "a TRUCK" category1="a truck" ctegory1 = "truck" Ctegory1="TRUCK" Category2 = "a CAR" category2 = "a car" Ctegory2="CAR" image_path='pilot/truck/truck74.png' rows = read_csv('pilot/machine_results/truck.csv', Machine) else: part = 3 Category1 = "a BIRD" category1="a bird" ctegory1 = "bird" Ctegory1="BIRD" Category2 = "an AIRPLANE" category2 = "an airplane" Ctegory2="AIRPLANE" image_path='pilot/bird/bird74.png' rows = read_csv('pilot/machine_results/bird.csv', Machine) dict1 = dict( part=part, Category1=Category1, category1=category1, ctegory1=ctegory1, Ctegory1 = Ctegory1, Category2=Category2, category2=category2, Ctegory2 = Ctegory2, image_path=image_path, treatment=treatment) dict2 = rows[74] dict2 = dict(machine_prob = int(dict2["machine_prob"])) def Merge(dict1, dict2): #res = dict1 | dict2 res = {**dict1,**dict2} return res dict3 = Merge(dict1, dict2) return dict3 class Practice4(Page): form_model = 'player' form_fields = ['prac4', 'check_slider_four'] if C.TIMEOUT == 'TRUE': timeout_seconds = C.TIMEOUT_S @staticmethod def is_displayed(player: Player): return player.round_number % C.NUM_CLS_ROUNDS == 1 def vars_for_template(player): participant = player.participant treatment = participant.treat_gp import pathlib if player.round_number <= C.NUM_CLS_ROUNDS: part = 1 Category1 = "a DOG" category1="a dog" ctegory1 = "dog" Ctegory1="DOG" Category2 = "a CAT" category2 = "a cat" Ctegory2="CAT" image_path='pilot/cat/cat74.png' rows = read_csv('pilot/machine_results/cat.csv', Machine) elif C.NUM_CLS_ROUNDS < player.round_number & player.round_number <= 2 * C.NUM_CLS_ROUNDS : part = 2 Category1 = "a TRUCK" category1="a truck" ctegory1 = "truck" Ctegory1="TRUCK" Category2 = "a CAR" category2 = "a car" Ctegory2="CAR" image_path='pilot/car/car74.png' rows = read_csv('pilot/machine_results/car.csv', Machine) else: part = 3 Category1 = "a BIRD" category1="a bird" ctegory1 = "bird" Ctegory1="BIRD" Category2 = "an AIRPLANE" category2 = "an airplane" Ctegory2="AIRPLANE" image_path='pilot/airplane/airplane74.png' rows = read_csv('pilot/machine_results/airplane.csv', Machine) dict1 = dict( part=part, Category1=Category1, category1=category1, ctegory1=ctegory1, Ctegory1 = Ctegory1, Category2=Category2, category2=category2, Ctegory2 = Ctegory2, image_path=image_path, treatment=treatment) dict2 = rows[74] dict2 = dict(machine_prob = int(dict2["machine_prob"])) def Merge(dict1, dict2): #res = dict1 | dict2 res = {**dict1,**dict2} return res dict3 = Merge(dict1, dict2) return dict3 class Middle(Page): @staticmethod def is_displayed(player: Player): return player.round_number % C.NUM_CLS_ROUNDS == 1 def vars_for_template(player): participant = player.participant if player.round_number <= C.NUM_CLS_ROUNDS: part = 1 category1 = "a dog" category2 = "a cat" bonus = participant.bonus_list1[0] elif C.NUM_CLS_ROUNDS < player.round_number & player.round_number <= 2 * C.NUM_CLS_ROUNDS : part = 2 category1 = "a truck" category2 = "a car" bonus = participant.bonus_list2[0] else: part = 3 category1 = "a bird" category2 = "an airplane" bonus = participant.bonus_list[2*int(C.NUM_CLS_ROUNDS/C.BREAK_ROUND)] return dict( part=part, category1=category1, category2=category2, bonus = bonus) class Break(Page): @staticmethod def is_displayed(player: Player): return (player.round_number % C.NUM_CLS_ROUNDS != 1) & (player.round_number %C.BREAK_ROUND == 0) def vars_for_template(player): participant = player.participant if player.round_number <= C.NUM_CLS_ROUNDS: a = player.round_number part = 1 category1 = "a dog" category2 = "a cat" if player.round_number < C.NUM_CLS_ROUNDS: bonus = participant.bonus_list1[int(player.round_number / C.BREAK_ROUND)] else: bonus = 100 elif C.NUM_CLS_ROUNDS < player.round_number & player.round_number <= 2 * C.NUM_CLS_ROUNDS : a = player.round_number - C.NUM_CLS_ROUNDS part = 2 category1 = "a truck" category2 = "a car" if player.round_number == C.NUM_ROUNDS: bonus = 100 else: bonus = participant.bonus_list2[int(player.round_number / C.BREAK_ROUND)-int(C.NUM_ROUNDS/C.BREAK_ROUND/C.NUM_CLS)] else: a = player.round_number - 2 * C.NUM_CLS_ROUNDS part = 3 category1 = "a bird" category2 = "an airplane" return dict( part=part, category1=category1, category2=category2, a=a, bonus = bonus) class End(Page): @staticmethod def is_displayed(player: Player): return player.round_number % C.NUM_CLS_ROUNDS == 0 def vars_for_template(player): if player.round_number <= C.NUM_CLS_ROUNDS: part = 1 category1 = "a dog" category2 = "a cat" elif C.NUM_CLS_ROUNDS < player.round_number & player.round_number <= 2 * C.NUM_CLS_ROUNDS : part = 2 category1 = "a truck" category2 = "a car" else: part = 3 category1 = "a bird" category2 = "an airplane" return dict( part=part, category1=category1, category2=category2) class Survey(Page): form_model = 'player' form_fields = ['fatigue', 'instruction', 'ever_work_pict', 'other_comment'] def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS class Result(Page): def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS @staticmethod def live_method(player: Player, data): if data == 'clicked-button': player.button_clicks += 1 def vars_for_template(player: Player): import math participant = player.participant player_input = player.in_round(participant.paying_rounds[0]+1).prob player_input_other = 100 - player_input round_paid = participant.paying_rounds[0]+1 block_paid = math.ceil(round_paid/C.BREAK_ROUND) - 1 # -1 because to match python numbering #amount_paid = participant.bonus_list[block_paid] if (participant.paying_rounds[0]+1)%C.NUM_CLS_ROUNDS == 0: round_num = C.NUM_CLS_ROUNDS else: round_num = (participant.paying_rounds[0]+1)%C.NUM_CLS_ROUNDS part_num = math.ceil((participant.paying_rounds[0]+1)/C.NUM_CLS_ROUNDS) if part_num == 1: image = participant.random_pic_num[round_num-1] amount_paid = participant.bonus_list1[block_paid] if participant.random_class[participant.paying_rounds[0]] == 0: image_path='pilot/dog/dog{}.png'.format(image) answer = "a dog" category1 = "a dog" category2 = "a cat" else: image_path='pilot/cat/cat{}.png'.format(image) answer = "a cat" category1 = "a dog" category2 = "a cat" elif part_num ==2: image = participant.random_pic_num2[round_num-1] block_paid = block_paid - int(C.NUM_ROUNDS/C.BREAK_ROUND/C.NUM_CLS) amount_paid = participant.bonus_list2[block_paid] if participant.random_class[participant.paying_rounds[0]] == 0: image_path='pilot/truck/truck{}.png'.format(image) answer = "a truck" category1 = "a truck" category2 = "a car" else: image_path='pilot/car/car{}.png'.format(image) answer = "a car" category1 = "a truck" category2 = "a car" else: image = participant.random_pic_num3[round_num-1] if participant.random_class[participant.paying_rounds[0]] == 0: image_path='pilot/bird/bird{}.png'.format(image) answer = "a bird" category1 = "a bird" category2 = "an airplane" else: image_path='pilot/airplane/airplane{}.png'.format(image) answer = "an airplane" category1 = "a bird" category2 = "an airplane" return dict(set_payoff = sum(participant.payoff_list), prob = round(participant.bsq_prob_list[0]*100,2), player_input=player_input, player_input_other=player_input_other, total=sum(participant.payoff_list) + C.PARTICIPATION_FEE, #total=participant.payoff_plus_participation_fee, round_num=round_num, part_num = part_num, image_path=image_path, category1 = category1, category2 = category2, answer=answer, amount_paid = amount_paid ) class Timerprac(Page): def vars_for_template(player: Player): import math participant = player.participant player_input = player.in_round(participant.paying_rounds[0]+1).prob player_input_other = 100 - player_input round_paid = participant.paying_rounds[0]+1 block_paid = math.ceil(round_paid/C.BREAK_ROUND) - 1 # -1 because to match python numbering if round_paid <= C.NUM_CLS_ROUNDS: amount_paid = participant.bonus_list1[block_paid] else: block_paid = block_paid - int(C.NUM_ROUNDS/C.BREAK_ROUND/C.NUM_CLS) amount_paid = participant.bonus_list2[block_paid] return dict( amount_paid = amount_paid ) def is_displayed(player: Player): if player.round_number == C.NUM_ROUNDS: participant = player.participant player_input = player.in_round(participant.paying_rounds[0]+1).prob return (player.round_number == C.NUM_ROUNDS) & (player_input >= 0) else: return player.round_number == C.NUM_ROUNDS class Timer(Page): form_model = 'player' form_fields = ['timer'] def is_displayed(player: Player): if player.round_number == C.NUM_ROUNDS: participant = player.participant player_input = player.in_round(participant.paying_rounds[0]+1).prob return (player.round_number == C.NUM_ROUNDS) & (player_input >= 0) else: return player.round_number == C.NUM_ROUNDS @staticmethod def before_next_page(player: Player, timeout_happened): import math last2digit = player.timer%100 participant = player.participant prob = round(participant.bsq_prob_list[0]*100,2) round_paid = participant.paying_rounds[0]+1 block_paid = math.ceil(round_paid/C.BREAK_ROUND) - 1 #amount_paid = participant.bonus_list[block_paid] if round_paid <= C.NUM_CLS_ROUNDS: amount_paid = participant.bonus_list1[block_paid] else: block_paid = block_paid - int(C.NUM_ROUNDS/C.BREAK_ROUND/C.NUM_CLS) amount_paid = participant.bonus_list2[block_paid] if last2digit < prob: player.payoff = amount_paid else: player.payoff = 0 #def before_next_page(player: Player, timeout_happened): # last2digit = player.timer%100 # participant = player.participant # prob = round(participant.bsq_prob_list[0]*100,2) # if last2digit < prob: # player.payoff == C.PAYOFF + C.PARTICIPATION_FEE # else: # player.payoff == C.PARTICIPATION_FEE class Final(Page): def is_displayed(player: Player): if player.round_number == C.NUM_ROUNDS: participant = player.participant player_input = player.in_round(participant.paying_rounds[0]+1).prob return (player.round_number == C.NUM_ROUNDS) & (player_input >= 0) else: return player.round_number == C.NUM_ROUNDS def vars_for_template(player: Player): last2digit = player.timer%100 participant = player.participant prob = round(participant.bsq_prob_list[0]*100,2) total = participant.payoff return dict( last2digit=last2digit, prob = prob, total = total) class Thankyou(Page): def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS @staticmethod def js_vars(player): return dict( completionlink= player.subsession.session.config['completionlink'] ) page_sequence = [Consent, Consentout, Consentfinal, Attention, Attentionout, Attentionfinal, Welcome, Introduction1, Introduction3, Treatment1, Treatment2, Quiz, Start, Practice1, Interval1, Practice2, Interval2, Practice3, Interval3, Practice4, Middle, Prior, Interval, Main, #Interval_expost, Expost, Break, End, Survey, Result, Timerprac, Timer, Final, Thankyou]