from otree.api import * import random import time doc = """ Your app description """ class C(BaseConstants): NAME_IN_URL = 'strategymethod' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 r_min = 0 N_size = 4 # this is the sample size P_yellow = [0.60, 0.40] # yellow and green box respectively p_yellow_Yellow = int(P_yellow[0]*100) p_yellow_Green = int(P_yellow[1]*100) P_Yellow_Box = 0.90 P_Yellow_Other = 0.20 prob_y = int(P_yellow[0] * 100) prob_g = int(P_yellow[1] * 100) class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): rand_box = models.FloatField() round_yellow_n = models.IntegerField() round_green_n = models.IntegerField() report = models.IntegerField(min=0, max=100) report_other = models.IntegerField(min=0, max=100) round_payoff = models.IntegerField(initial=0) payoff_final = models.CurrencyField(initial=0) # Questions to check understanding n_balls = models.IntegerField( label='How many balls does each box have?', min=0, max=100) p1_g_Y = models.IntegerField( label='What is the probability that one green marble is drawn ' 'if the box is Yellow? ' 'Answer in percentage points.', min=0, max=100) seq_length = models.IntegerField( label='How many marbles will be drawn from the box at the end of the section?', min=0, max=100) replacement = models.BooleanField( label='When generating a sample, is each marble returned to the Box after each draw?', choices=[ [False, 'No'], [True, 'Yes'], ] ) hidden_box = models.BooleanField( label='Will you know the probability each Box is selected for you?', choices=[ [False, 'No'], [True, 'Yes'], ] ) hidden_box_other = models.BooleanField( label='Will you know the probability each Box is selected for Participant 2?', choices=[ [False, 'No'], [True, 'Yes'], ] ) ## Count the number of wrong answers wrong_answer_n_balls = models.IntegerField(initial=0) wrong_answer_p1_g_Y = models.IntegerField(initial=0) wrong_answer_seq_length = models.IntegerField(initial=0) wrong_answer_replacement = models.IntegerField(initial=0) wrong_answer_hidden_box = models.IntegerField(initial=0) wrong_answer_hidden_box_other = models.IntegerField(initial=0) ## time time_wait = models.IntegerField() time_instructions = models.IntegerField() time_test = models.IntegerField() time_payment = models.IntegerField() time_end_instructions = models.IntegerField() # FUNCTIONS def n_balls_error_message(player, value): print('value is', value) if value < player.session.config['n_marbles']: player.wrong_answer_n_balls += 1 return 'There are more balls in the box.' if value > player.session.config['n_marbles']: player.wrong_answer_n_balls += 1 return 'There are less balls in the box.' def p1_g_Y_error_message(player, value): print('value is', value) if value < (100-C.p_yellow_Yellow): player.wrong_answer_p1_g_Y += 1 return 'The probability is larger.' if value > (100-C.p_yellow_Yellow): player.wrong_answer_p1_g_Y += 1 return 'The probability is smaller.' def seq_length_error_message(player, value): print('value is', value) if value < C.N_size: player.wrong_answer_seq_length += 1 return 'There will be more balls drawn.' if value > C.N_size: player.wrong_answer_seq_length += 1 return 'There will be less balls drawn.' def replacement_error_message(player, value): print('value is', value) if value != True: player.wrong_answer_replacement += 1 return 'The marble is returned to the original Box.' def hidden_box_error_message(player, value): print('value is', value) if value != True: player.wrong_answer_hidden_box += 1 return 'You will know the probability the Yellow box will be selected for you.' def hidden_box_other_error_message(player, value): print('value is', value) if value != True: player.wrong_answer_hidden_box_other += 1 return 'You will know the probability the Yellow box will be selected for you and Participant 2.' # PAGES class Wait_Instructions(Page): @staticmethod def before_next_page(player: Player, timeout_happened): player.time_wait = int(time.time()) class General(Page): pass class BoxesMarblesSequences(Page): form_model = 'player' @staticmethod def before_next_page(player: Player, timeout_happened): player.rand_box = random.choices(C.P_yellow, k=1, weights=[C.P_Yellow_Box, 1 - C.P_Yellow_Box])[0] marble_sample = random.choices([0, 1], k=C.N_size, weights=[1 - player.rand_box, player.rand_box]) yellow_n = sum(marble_sample) player.round_yellow_n = yellow_n player.round_green_n = C.N_size - yellow_n class Sequences(Page): form_model = 'player' @staticmethod def js_vars(player): # this function generates the sequence of marbles to be pass to JS rand_seq = [1] * player.round_yellow_n + [0] * player.round_green_n # random.shuffle(rand_seq) # This code is if the sequence shown is random return dict( marble_sample=rand_seq, N=C.N_size ) @staticmethod def before_next_page(player: Player, timeout_happened): player.time_instructions = int(time.time()) class TestGral(Page): form_model = 'player' form_fields = [ 'n_balls', 'p1_g_Y', 'seq_length', 'replacement', 'hidden_box', 'hidden_box_other', ] @staticmethod def before_next_page(player: Player, timeout_happened): player.time_test = int(time.time()) class PaymentInfo(Page): @staticmethod def before_next_page(player: Player, timeout_happened): player.time_payment = int(time.time()) class Summary(Page): @staticmethod def before_next_page(player: Player, timeout_happened): player.time_end_instructions = int(time.time()) page_sequence = [ Wait_Instructions, General, BoxesMarblesSequences, Sequences, TestGral, PaymentInfo, ]