from statistics import correlation from click import option from otree.api import * doc = """ Your app description """ import random, itertools, copy def BuildLottery(pos_a, state_order, Ah, Al, Bh, Bl, correlation, pi=0): # change correlation structure lot0 = [[50, 50], [Ah + pi, Al + pi], [Bh, Bl]] if correlation == "negative": lot0 = [[50, 50], [Ah+ pi, Al+ pi], [Bl, Bh]] # change state_order if correlation == "negative": lot0 = [[50, 50], [Al+ pi, Ah+ pi], [Bh, Bl]] # change state_order outcomes_a, outcomes_b = [], [] for s in state_order: outcomes_a.append(lot0[1][s]) outcomes_b.append(lot0[2][s]) if pos_a == 0: lot1 = [lot0[0], outcomes_b, outcomes_a] else: lot1 = [lot0[0], outcomes_a, outcomes_b] return lot1 def probas(pp, N): probas = list() for i in pp: probas.append(int(round((i/N)*100, 0))) return probas def fields(pp): fields_to, fields_from = list(), list() a, b = 1, 0 for i in pp: fields_from.append(a) a = a + i b = b + i fields_to.append(b) return [fields_from, fields_to] class C(BaseConstants): NAME_IN_URL = 'main' PLAYERS_PER_GROUP = None Lotteries = dict() Lotteries['main'], Lotteries['practice'] = dict(), dict() Ah, Al, Bh, Bl = 99, 55, 88, 44 Lotteries['practice'][99] = {'Ah': Ah, 'Al': Al, 'Bh': Bh, 'Bl': Bl} Ah, Al, Bh, Bl = 280, 80, 270, 70 Lotteries['main'][1] = {'Ah': Ah, 'Al': Al, 'Bh': Bh, 'Bl': Bl} Ah, Al, Bh, Bl = 280, 80, 220, 20 Lotteries['main'][2] = {'Ah': Ah, 'Al': Al, 'Bh': Bh, 'Bl': Bl} Ah, Al, Bh, Bl = 220, 120, 210, 110 Lotteries['main'][3] = {'Ah': Ah, 'Al': Al, 'Bh': Bh, 'Bl': Bl} Ah, Al, Bh, Bl = 280, 180, 210, 110 Lotteries['main'][4] = {'Ah': Ah, 'Al': Al, 'Bh': Bh, 'Bl': Bl} # Ah, Al, Bh, Bl = 260, 20, 180, 100 # Lotteries['main'][5] = {'Ah': Ah, 'Al': Al, 'Bh': Bh, 'Bl': Bl} # Ah, Al, Bh, Bl = 280, 30, 140, 120 # Lotteries['main'][6] = {'Ah': Ah, 'Al': Al, 'Bh': Bh, 'Bl': Bl} # Ah, Al, Bh, Bl = 290, 50, 110, 100 # Lotteries['main'][7] = {'Ah': Ah, 'Al': Al, 'Bh': Bh, 'Bl': Bl} # Ah, Al, Bh, Bl = 130, 130, 130, 130 Lotteries['main'][5] = {'Ah': Ah, 'Al': Al, 'Bh': Bh, 'Bl': Bl} N_main = len(Lotteries['main'])*3 - 1 num_relevant = N_main num_rep_learn = 4 NUM_ROUNDS = 3*len(Lotteries['main']) + num_rep_learn + 1 - 1 coarse_lower_bound = 0 coarse_upper_bound = 300 coarse_step_size = 30 fine_step_size = 3 target_value = 110 def creating_session(subsession): if subsession.round_number == 1: for p in subsession.get_players(): v_type, v_pos_a, v_state_order, v_lot, v_state, v_blockround, v_total, v_pos_neg = [], [], [], [], [], [], [], [] # practice rounds realized_states = [0, 1, 0 ,1] random.shuffle(realized_states) pos_a_practice = random.choice([0, 1]) pos_neg_practice = random.choice([0, 1]) state_order_practice = random.choice([[0, 1], [1, 0]]) for j in range(C.num_rep_learn): v_type.append('practice') v_pos_a.append(pos_a_practice) v_pos_a.append(pos_neg_practice) v_state_order.append(state_order_practice) v_lot.append(99) v_state.append(realized_states[j]) v_blockround.append(j+1) v_total.append(C.num_rep_learn) count = 1 order_dict = dict() for l in range(1, len(C.Lotteries['main'])): order_dict[count] = {'nr': l, 'negative': 0, 'positive': 0} count += 1 order_dict[count] = {'nr': l, 'negative': 10, 'positive': 0} count += 1 order_dict[count] = {'nr': l, 'negative': 0, 'positive': 10} count += 1 order_dict[count] = {'nr': len(C.Lotteries['main']), 'negative': 10, 'positive': 0} count += 1 order_dict[count] = {'nr': len(C.Lotteries['main']), 'negative': 0, 'positive': 30} count += 1 #main tasks # v_order = list(range(1, len(C.Lotteries['main']))) # random.shuffle(v_order) # v_order.append(len(C.Lotteries['main'])) v_order = list(range(1, len(order_dict)+ 1 )) random.shuffle(v_order) order_dict[99] = {'nr': 99, 'negative': 0, 'positive': 0} for j in range(1, len(order_dict) ): v_type.append('main') v_pos_a.append(random.choice([0,1])) v_pos_neg.append(random.choice([0, 1])) v_state_order.append(random.choice([[0, 1], [1, 0]])) v_lot.append(v_order[j-1]) v_state.append(random.choice([0, 1])) v_blockround.append(j) v_total.append(C.num_relevant ) relevant_round = [] RoundDict = dict() for r in range(1, C.NUM_ROUNDS): RoundDict[r] = dict() RoundDict[r]['position_a'] = v_pos_a[r - 1] RoundDict[r]['position_neg'] = v_pos_a[r - 1] state_order = v_state_order[r - 1] RoundDict[r]['state_order'] = state_order key = v_lot[r - 1] RoundDict[r]['lottery_nr'] = order_dict[key]['nr'] RoundDict[r]['type'] = v_type[r - 1] if v_type[r - 1] == 'practice': RoundDict[r]['feedback'] = 1 else: RoundDict[r]['feedback'] = 0 RoundDict[r]['type'] = v_type[r - 1] if v_type[r - 1] == 'main': relevant_round.append(r) RoundDict[r]['blockround'] = v_blockround[r - 1] RoundDict[r]['total_block'] = v_total[r - 1] RoundDict[r]['pi_pos'] = order_dict[key]['positive'] RoundDict[r]['pi_neg'] = order_dict[key]['negative'] if v_type[r - 1] == 'practice': pars = C.Lotteries[v_type[r - 1]][key] else: pars = C.Lotteries[v_type[r - 1]][order_dict[key]['nr']] for corr in ["negative", "positive"]: RoundDict[r][corr] = dict() lot = BuildLottery(pos_a=v_pos_a[r - 1], state_order=v_state_order[r - 1], Ah=pars['Ah'], Al=pars['Al'], Bh=pars['Bh'], Bl=pars['Bl'], correlation=corr, pi=order_dict[key][corr]) RoundDict[r][corr]['lottery'] = lot # draw random outcome etc state0 = v_state[r - 1] RoundDict[r][corr]['state'] = state0 state1 = state_order.index(state0) fields_from, fields_to = fields(lot[0])[0], fields(lot[0])[1] field_from, field_to = fields_from[state1], fields_to[state1] population = list() weights = list() for i in range(field_from + 1, field_to + 1): population.append(i) weights.append(1 / (field_to - field_from + 1)) RoundDict[r][corr]['realized_field'] = random.choices( population=population, weights=weights )[0] # this is the outcome of A and B, wrt to the L0 RoundDict[r][corr]['outcome_a'] = lot[1][state1] RoundDict[r][corr]['outcome_b'] = lot[2][state1] if v_pos_a[r - 1] == 0: RoundDict[r][corr]['outcome_a'] = lot[2][state1] RoundDict[r][corr]['outcome_b'] = lot[1][state1] RoundDict[r][corr]['make_choice'] = 1 relevant = random.choice(relevant_round) RoundDict[C.NUM_ROUNDS] = copy.deepcopy(RoundDict[relevant]) RoundDict[C.NUM_ROUNDS]['make_choice'] = 0 p.participant.vars['relevant'] = relevant p.participant.vars['RoundDict'] = RoundDict # test vars p.participant.vars['test_tries'] = 0 p.participant.vars['test_1'] = 0 p.participant.vars['test_2'] = 0 p.participant.vars['test_3'] = 0 p.participant.vars['test_4'] = 0 p.participant.vars['saved_eval'] = None class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): test_1 = models.IntegerField(blank=True) test_2 = models.IntegerField(blank=True) test_3 = models.IntegerField(blank=True) test_4 = models.IntegerField(blank=True) test_tries = models.IntegerField() evaluation_passed = models.IntegerField(initial=0, blank=True) menu = models.StringField() pi_pos = models.IntegerField() pi_neg = models.IntegerField() lottery_nr = models.IntegerField() pos_a = models.IntegerField() pos_neg = models.IntegerField() state_order = models.StringField() correlation = models.StringField choice = models.StringField(blank=True) ce_value = models.FloatField(blank=True) type = models.StringField() realized = models.StringField() attention = models.IntegerField() age = models.IntegerField( label="Age", min=16, max=120, ) gender = models.StringField( label="Gender", choices=[ "Female", "Male", "Non-binary / third gender", "Prefer not to say", ], widget=widgets.RadioSelect, ) education = models.StringField( label="Highest completed education", choices=[ "Less than high school", "High school / secondary school", "Vocational training / apprenticeship", "Some college / university (no degree yet)", "Bachelor’s degree", "Master’s degree", "PhD / doctorate", "Other", ], ) country = models.StringField( label="Country of residence", blank=False, ) employment = models.StringField( label="Employment status", choices=[ "Student", "Employed full-time", "Employed part-time", "Self-employed", "Unemployed", "Retired", "Other", ], ) income = models.StringField( label="Household income (optional)", blank=False, choices=[ "Prefer not to say", "Under £1,000 per month", "£1,000–£1,999 per month", "£2,000–£2,999 per month", "£3,000–£3,999 per month", "£4,000–£4,999 per month", "£5,000–£6,999 per month", "£7,000+ per month", ], ) Crt_barrel = models.IntegerField( label='', # In a lake, there is a patch of lily pads. Every day, the patch doubles in size. If it takes 48 days for the patch to cover the entire lake, how many days would it take for the patch to cover half of the lake?''', ) Crt_student = models.IntegerField( label='', # In a lake, there is a patch of lily pads. Every day, the patch doubles in size. If it takes 48 days for the patch to cover the entire lake, how many days would it take for the patch to cover half of the lake?''', ) Crt_pig = models.IntegerField( label='', # In a lake, there is a patch of lily pads. Every day, the patch doubles in size. If it takes 48 days for the patch to cover the entire lake, how many days would it take for the patch to cover half of the lake?''', ) Crt_simon = models.IntegerField( label='', widget=widgets.RadioSelect, choices= [ [0, "a atteint le seuil de rentabilité en bourse"], [1, "a gagné de l'argent"], [-1, "a perdu de l'argent"], ] ) Know2 = models.IntegerField( widget=widgets.RadioSelect, choices=[ [1, "Oui"], [0, "Non"], ], label='', # Have you ever seen or answered the previous set of questions?''', # widget=widgets.RadioSelect() ) # PAGES class Choice(Page): form_model = 'player' form_fields = ['choice'] def is_displayed(player): return player.round_number != C.NUM_ROUNDS # def error_message(player, value): # round_info = player.participant.vars['RoundDict'][player.round_number] # print ("hello") # if value['choice'] is None: # return 'Please make a choice.' def vars_for_template(player): round_info = player.participant.vars['RoundDict'][player.round_number] L_1 = round_info['negative']['lottery'] L_2 = round_info['positive']['lottery'] left_value, right_value = "negative", "positive" if round_info['position_neg'] == 0: L_2 = round_info['negative']['lottery'] L_1 = round_info['positive']['lottery'] left_value, right_value = "positive", "negative" position_a = round_info['position_a'] option_a, option_b = 0, 1 a_value, b_value = 'B', 'A' if position_a == 1: option_a, option_b = 1, 0 b_value, a_value = 'B', 'A' fields_from, fields_to = fields(L_1[0])[0], fields(L_1[0])[1] pp, oo_1_1, oo_2_1 = L_1[0], L_1[1], L_1[2] pp, oo_1_2, oo_2_2 = L_2[0], L_2[1], L_2[2] pp = probas(pp, sum(L_1[0])) wheels_1 = ['wheels_yellow_1.png', 'wheels_yellow_2.png'] wheels_2 = ['wheels_orange_1.png', 'wheels_orange_2.png'] player.pos_a = round_info['position_a'] # player.state_order = str([oo_1, oo_2]) player.lottery_nr = round_info['lottery_nr'] player.type = round_info['type'] menu = round_info['menu'] display_left = 0 if round_info['position_neg'] == 1 and menu == "negative": display_left = 1 if round_info['position_neg'] == 0 and menu == "positive": display_left = 1 option_1, option_2 = "A", "B" if display_left == 0: option_1, option_2 = "C", "D" return dict( option_1=option_1, option_2=option_2, display_left=display_left, fields=zip(fields_from, fields_to, pp), fields_from=fields_from, fields_to=fields_to, option_a=option_a, option_b=option_b, position_a=position_a, L_1=L_1, round_number=player.round_number, rows_1=zip(fields_from, fields_to, pp, oo_1_1, oo_2_1, wheels_1), rows_2=zip(fields_from, fields_to, pp, oo_1_2, oo_2_2, wheels_2), feedback=round_info['feedback'], num_choice=player.round_number, total_block=round_info['total_block'], num_rep_learn=1, blockround=round_info['blockround'], pos_a=round_info['position_a'], a_value=a_value, b_value=b_value, round_info=round_info, disabled_b='', table_width=60, ) def before_next_page(player, timeout_happened): player.participant.vars['RoundDict'][player.round_number]['choice'] = player.choice if player.participant.vars['relevant'] == player.round_number: player.participant.vars['RoundDict'][C.NUM_ROUNDS] = copy.deepcopy(player.participant.vars['RoundDict'][player.round_number]) player.participant.vars['RoundDict'][C.NUM_ROUNDS]['feedback'] = 1 class Menu(Page): form_model = 'player' form_fields = ['menu'] def is_displayed(player): round_info = player.participant.vars['RoundDict'][player.round_number] return player.round_number != C.NUM_ROUNDS def vars_for_template(player): round_info = player.participant.vars['RoundDict'][player.round_number] L_1 = round_info['negative']['lottery'] L_2 = round_info['positive']['lottery'] left_value, right_value = "negative", "positive" if round_info['position_neg'] == 0: L_2 = round_info['negative']['lottery'] L_1 = round_info['positive']['lottery'] left_value, right_value = "positive", "negative" position_a = round_info['position_a'] option_a, option_b = 0, 1 a_value, b_value = 'B', 'A' if position_a == 1: option_a, option_b = 1, 0 b_value, a_value = 'B', 'A' fields_from, fields_to = fields(L_1[0])[0], fields(L_1[0])[1] pp, oo_1_1, oo_2_1 = L_1[0], L_1[1], L_1[2] pp, oo_1_2, oo_2_2 = L_2[0], L_2[1], L_2[2] pp = probas(pp, sum(L_1[0])) wheels_1 = ['wheels_yellow_1.png', 'wheels_yellow_2.png'] wheels_2 = ['wheels_orange_1.png', 'wheels_orange_2.png'] player.pos_a = round_info['position_a'] player.pos_neg = round_info['position_neg'] player.lottery_nr = round_info['lottery_nr'] player.type = round_info['type'] player.pi_pos = round_info['pi_pos'] player.pi_neg = round_info['pi_neg'] player.state_order = str([oo_1_1, oo_2_1, oo_1_2, oo_2_2]) disabled_a_1, disabled_b_1 = 'disabled', 'disabled' disabled_a_2, disabled_b_2 = 'disabled', 'disabled' # for screenshots # oo_1 = [750, 750, 10, 10] # oo_2 = [220, 220, 570, 570] # oo_1 = [260, 260, 260, 260] # oo_2 = [40, 40, 40, 40] return dict( left_value=left_value, right_value=right_value, fields=zip(fields_from, fields_to, pp), fields_from=fields_from, fields_to=fields_to, option_a=option_a, option_b=option_b, position_a=position_a, L_1=L_1, round_number=player.round_number, rows_1=zip(fields_from, fields_to, pp, oo_1_1, oo_2_1, wheels_1), rows_2=zip(fields_from, fields_to, pp, oo_1_2, oo_2_2, wheels_2), feedback=round_info['feedback'], num_choice=player.round_number, total_block=round_info['total_block'], num_rep_learn=1, blockround=round_info['blockround'], pos_a=round_info['position_a'], a_value=a_value, b_value=b_value, round_info=round_info, disabled_a_1=disabled_a_1, disabled_b_1=disabled_b_1, disabled_a_2=disabled_a_2, disabled_b_2=disabled_b_2, table_width=80, ) def before_next_page(player, timeout_happened): player.participant.vars['RoundDict'][player.round_number]['menu'] = player.menu class Feedback(Page): def is_displayed(player): round_info = player.participant.vars['RoundDict'][player.round_number] return round_info['feedback'] == 1 def vars_for_template(player): round_info = player.participant.vars['RoundDict'][player.round_number] menu = round_info['menu'] L_1 = round_info['negative']['lottery'] L_2 = round_info['positive']['lottery'] left_value, right_value = "negative", "positive" if round_info['position_neg'] == 0: L_2 = round_info['negative']['lottery'] L_1 = round_info['positive']['lottery'] left_value, right_value = "positive", "negative" position_a = round_info['position_a'] option_a, option_b = 0, 1 a_value, b_value = 'B', 'A' if position_a == 1: option_a, option_b = 1, 0 b_value, a_value = 'B', 'A' fields_from, fields_to = fields(L_1[0])[0], fields(L_1[0])[1] pp, oo_1_1, oo_2_1 = L_1[0], L_1[1], L_1[2] pp, oo_1_2, oo_2_2 = L_2[0], L_2[1], L_2[2] pp = probas(pp, sum(L_1[0])) wheels_1 = ['wheels_yellow_1.png', 'wheels_yellow_2.png'] wheels_2 = ['wheels_orange_1.png', 'wheels_orange_2.png'] color_wheel = 'yellow' menu = round_info['menu'] display_left = 0 if round_info['position_neg'] == 1 and menu == "negative": display_left = 1 if round_info['position_neg'] == 0 and menu == "positive": display_left = 1 color_1, color_2 = "green", "purple" rows = zip(fields_from, fields_to, pp, oo_1_1, oo_2_1, wheels_1) option_1, option_2 = "A", "B" if display_left == 0: color_wheel = 'orange' option_1, option_2 = "C", "D" color_1, color_2 = "blue", "darkred" rows = zip(fields_from, fields_to, pp, oo_1_2, oo_2_2, wheels_2) # # for hack realized_field = round_info[menu]['realized_field'] if position_a == 1: payoff_A = round_info[menu]['outcome_a'] payoff_B = round_info[menu]['outcome_b'] if position_a == 0: payoff_B = round_info[menu]['outcome_a'] payoff_A = round_info[menu]['outcome_b'] player.realized = str([payoff_A, payoff_B]) choiceA = 0 P_choice = round_info['choice'] if P_choice == 'A': choiceA = 1 if position_a == choiceA: implemented_option = ' Option A' checked_A = 'checked' checked_B = '' if position_a != choiceA: implemented_option = ' Option B' checked_B = 'checked' checked_A = '' choice = round_info['choice'] chosen_option = ' Option A' if choice == "A" and position_a == 0: chosen_option = ' Option B' if choice == "B" and position_a == 1: chosen_option = ' Option B' if choice == "B"and position_a == 0: chosen_option = ' Option A' if display_left == 0: if position_a == choiceA: implemented_option = ' Option C' checked_A = 'checked' checked_B = '' if position_a != choiceA: implemented_option = ' Option D' checked_B = 'checked' checked_A = '' choice = round_info['choice'] chosen_option = ' Option C' if choice == "A" and position_a == 0: chosen_option = ' Option D' if choice == "B" and position_a == 1: chosen_option = ' Option D' if choice == "B" and position_a == 0: chosen_option = ' Option C' menu = round_info['menu'] payoff = 0 if player.round_number == C.NUM_ROUNDS: if P_choice == 'A': player.participant.vars['RoundDict'][C.NUM_ROUNDS]['payoff'] = round_info[menu]['outcome_a'] if P_choice == 'B': player.participant.vars['RoundDict'][C.NUM_ROUNDS]['payoff'] = round_info[menu]['outcome_b'] player.payoff = player.participant.vars['RoundDict'][C.NUM_ROUNDS]['payoff'] payoff = player.participant.vars['RoundDict'][C.NUM_ROUNDS]['payoff'] return dict( color_wheel=color_wheel, color_1=color_1, color_2=color_2, option_1=option_1, option_2=option_2, round_info=round_info, payoff=payoff, L_1=L_1, pp=pp, fields=zip(fields_from, fields_to, pp), fields_from=fields_from, fields_to=fields_to, chosen_option=chosen_option, realized_field=realized_field, checked_A=checked_A, checked_B=checked_B, payoff_A=payoff_A, payoff_B=payoff_B, round_number=player.round_number, rows=rows, ) class CE(Page): form_model = 'player' form_fields = ['ce_value'] def is_displayed(player): round_info = player.participant.vars['RoundDict'][player.round_number] if player.round_number == C.NUM_ROUNDS: return False if player.round_number != C.NUM_ROUNDS: return round_info['type'] == 'main' def vars_for_template(player): round_info = player.participant.vars['RoundDict'][player.round_number] L_1 = round_info['lottery'] position_a = round_info['position_a'] option_a, option_b = 0, 1 a_value, b_value = 'B', 'A' if position_a == 1: option_a, option_b = 1, 0 b_value, a_value = 'B', 'A' fields_from, fields_to = fields(L_1[0])[0], fields(L_1[0])[1] pp, oo_1, oo_2 = L_1[0], L_1[1], L_1[2] pp = probas(pp, sum(L_1[0])) wheels = ['wheels1v5.png', 'wheels2v5.png', 'wheels3v5.png', 'wheels4v5.png'] if len(oo_2) < 4: wheels = ['wheels50_1.png', 'wheels50_2.png'] player.pos_a = round_info['position_a'] player.state_order = str([oo_1, oo_2]) player.lottery_nr = round_info['lottery_nr'] player.type = round_info['type'] # for screenshots # oo_1 = [750, 750, 10, 10] # oo_2 = [220, 220, 570, 570] # oo_1 = [260, 260, 260, 260] # oo_2 = [40, 40, 40, 40] return dict( oo_1=oo_1, oo_2=oo_2, fields=zip(fields_from, fields_to, pp), fields_from=fields_from, fields_to=fields_to, option_a=option_a, option_b=option_b, position_a=position_a, L_1=L_1, round_number=player.round_number, rows=zip(fields_from, fields_to, pp, oo_1, oo_2, wheels), feedback=round_info['feedback'], num_choice=player.round_number, total_block=round_info['total_block'], num_rep_learn=1, blockround=round_info['blockround'], pos_a=round_info['position_a'], a_value=a_value, b_value=b_value, round_info=round_info, ) @staticmethod def js_vars(player: Player): return dict( coarse_lower_bound=C.coarse_lower_bound, coarse_upper_bound=C.coarse_upper_bound, coarse_step_size=C.coarse_step_size, fine_step_size=C.fine_step_size, ) def before_next_page(player, timeout_happened): player.participant.vars['RoundDict'][player.round_number]['CE'] = player.ce_value if player.participant.vars['relevant'] == player.round_number: player.participant.vars['RoundDict'][C.NUM_ROUNDS] = copy.deepcopy(player.participant.vars['RoundDict'][player.round_number]) grid = list(range(C.coarse_lower_bound, C.coarse_upper_bound + 1, C.fine_step_size)) random_value = random.choice(grid) player.participant.vars['RoundDict'][C.NUM_ROUNDS]['random_value'] = random_value if player.ce_value >= random_value: player.participant.vars['RoundDict'][C.NUM_ROUNDS]['make_choice'] = 1 player.participant.vars['RoundDict'][C.NUM_ROUNDS]['feedback'] = 1 else: player.participant.vars['RoundDict'][C.NUM_ROUNDS]['make_choice'] = 0 player.participant.vars['RoundDict'][C.NUM_ROUNDS]['feedback'] = 0 class Attention(Page): form_model = 'player' form_fields = ['attention'] def is_displayed(player): round_info = player.participant.vars['RoundDict'][player.round_number] if player.round_number == C.NUM_ROUNDS: return False if round_info['blockround'] == C.N_main: return True def vars_for_template(player): round_info = player.participant.vars['RoundDict'][player.round_number] L_1 = round_info['lottery'] position_a = round_info['position_a'] option_a, option_b = 0, 1 a_value, b_value = 'B', 'A' if position_a == 1: option_a, option_b = 1, 0 b_value, a_value = 'B', 'A' fields_from, fields_to = fields(L_1[0])[0], fields(L_1[0])[1] pp, oo_1, oo_2 = L_1[0], ["ML", "JZ"], ["SD", "FR"] pp = probas(pp, sum(L_1[0])) wheels = ['wheels1v5.png', 'wheels2v5.png', 'wheels3v5.png', 'wheels4v5.png'] if len(oo_2) < 4: wheels = ['wheels50_1.png', 'wheels50_2.png'] # for screenshots # oo_1 = [750, 750, 10, 10] # oo_2 = [220, 220, 570, 570] # oo_1 = [260, 260, 260, 260] # oo_2 = [40, 40, 40, 40] return dict( oo_1=oo_1, oo_2=oo_2, fields=zip(fields_from, fields_to, pp), fields_from=fields_from, fields_to=fields_to, option_a=option_a, option_b=option_b, position_a=position_a, L_1=L_1, round_number=player.round_number, rows=zip(fields_from, fields_to, pp, oo_1, oo_2, wheels), feedback=round_info['feedback'], num_choice=player.round_number, total_block=round_info['total_block'], num_rep_learn=1, blockround=round_info['blockround'], pos_a=round_info['position_a'], a_value=a_value, b_value=b_value, round_info=round_info, ) @staticmethod def js_vars(player: Player): return dict( coarse_lower_bound=C.coarse_lower_bound, coarse_upper_bound=C.coarse_upper_bound, coarse_step_size=C.coarse_step_size, fine_step_size=C.fine_step_size, ) class onlyCE(Page): form_model = 'player' form_fields = ['ce_value'] @staticmethod def js_vars(player: Player): return dict( coarse_lower_bound=C.coarse_lower_bound, coarse_upper_bound=C.coarse_upper_bound, coarse_step_size=C.coarse_step_size, fine_step_size=C.fine_step_size, ) class Instructions(Page): form_model = 'player' form_fields = ['test_1', 'test_2', 'test_3', 'test_4', 'evaluation_passed', 'ce_value'] def is_displayed(player): return player.round_number == 1 def error_message(player, value): if player.round_number != 1: return None if player.test_tries >= 2: return None if value['evaluation_passed'] == 1: player.participant.vars['saved_eval'] = value['ce_value'] else: player.participant.vars['saved_eval'] = None if value['evaluation_passed'] != 1: player.participant.vars['test_1'] = value['test_1'] player.participant.vars['test_2'] = value['test_2'] player.participant.vars['test_3'] = value['test_3'] player.participant.vars['test_4'] = value['test_4'] return 'You can proceed only after submitting a correct evaluation.' if value['test_1'] is None or value['test_2'] is None or value['test_3'] is None or value['test_4'] is None: player.participant.vars['errorX'] = 1 return 'Please answer all comprehension questions.' # to kick out people answering wrong more than 3 times add to conditions "and player.test_tries == 2" else: bb = value['test_1'] + value['test_2'] + value['test_3'] + value['test_4'] if bb != 4: player.participant.vars['test_tries'] = player.participant.vars['test_tries'] + 1 player.test_tries = player.participant.vars['test_tries'] player.participant.vars['test_1'] = value['test_1'] player.participant.vars['test_2'] = value['test_2'] player.participant.vars['test_3'] = value['test_3'] player.participant.vars['test_4'] = value['test_4'] return "You answered at least one of the questions incorrectly. Please read the hints below and make sure you " \ "understand the task well." def vars_for_template(player): pp = (50, 50) oo_1 = (40, 60) oo_2 = (70, 150) fields_from, fields_to = fields(pp)[0], fields(pp)[1] wheels = ['wheels50_1.png', 'wheels50_2.png'] pp_2 = (50, 50) oo_1_2 = (150, 30) oo_2_2 = (50, 90) fields_from_2, fields_to_2 = fields(pp_2)[0], fields(pp_2)[1] error = 0 if player.participant.vars['test_tries'] > 0: error = 1 if 'errorX' in player.participant.vars: error = 1 player.test_tries = player.participant.vars['test_tries'] q2_pa_1, q2_pb_1 = oo_1_2[0], oo_2_2[0] q2_pa_2, q2_pb_2 = oo_1_2[1], oo_2_2[1] round_info = player.participant.vars['RoundDict'][player.round_number] type = round_info['type'] pp_c = (50, 50) oo_c_1 = (200, 40) oo_c_2 = (70, 80) oo_c_2_1 = oo_1_2 oo_c_2_2 = oo_2_2 return dict( explain=zip(fields_from, fields_to, pp, oo_1, oo_2), explain2=zip(fields_from_2, fields_to_2, pp_2, oo_1_2, oo_2_2), explain_c=zip(fields_from, fields_to, pp_c, oo_c_1, oo_c_2), explain_c2=zip(fields_from, fields_to, pp_c, oo_c_2_1, oo_c_2_2), N_fields=sum(pp), rows=zip(fields_from, fields_to, pp, oo_1, oo_2, wheels), rows2=zip(fields_from, fields_to, pp, oo_1, oo_2, wheels), rows4=zip(fields_from_2, fields_to_2, pp_2, oo_1_2, oo_2_2, wheels), rows_c_1=zip(fields_from, fields_to, pp_c, oo_c_1, oo_c_2, wheels), rows_c_2=zip(fields_from, fields_to, pp_c, oo_c_2_1, oo_c_2_2, wheels), rows5=zip(fields_from, fields_to, pp, oo_1, oo_2, wheels), proba_A=50, proba_B=50, proba_A_2=50, test_1=player.participant.vars['test_1'], test_2=player.participant.vars['test_2'], test_3=player.participant.vars['test_3'], test_4=player.participant.vars['test_4'], error=error, type=type, round_info=round_info, total_block=player.participant.vars['RoundDict'][player.round_number+4]['total_block'], a_value="disabled", b_value="disabled", ) @staticmethod def js_vars(player: Player): return dict( coarse_lower_bound=C.coarse_lower_bound, coarse_upper_bound=C.coarse_upper_bound, coarse_step_size=C.coarse_step_size, fine_step_size=C.fine_step_size, target_value=C.target_value, round_number=player.round_number, saved_eval=player.participant.vars['saved_eval'], ) class InstructionsCE(Page): form_model = 'player' form_fields = ['test_4', 'evaluation_passed', 'ce_value'] def is_displayed(player): return player.round_number == 1 def error_message(player, value): if player.round_number != 1: return None if player.test_tries >= 2: return None if value['evaluation_passed'] == 1: player.participant.vars['saved_eval'] = value['ce_value'] else: player.participant.vars['saved_eval'] = None if value['evaluation_passed'] != 1: player.participant.vars['test_4'] = value['test_4'] return 'You can proceed only after submitting a correct evaluation.' if value['test_4'] is None: player.participant.vars['errorX'] = 1 return 'Please answer all comprehension questions.' # to kick out people answering wrong more than 3 times add to conditions "and player.test_tries == 2" else: bb = value['test_4'] if bb != 1: player.participant.vars['test_tries'] = player.participant.vars['test_tries'] + 1 player.test_tries = player.participant.vars['test_tries'] player.participant.vars['test_4'] = value['test_4'] return "You answered at least one of the questions incorrectly. Please read the hints below and make sure you " \ "understand the task well." def vars_for_template(player): pp = (50, 50) oo_1 = (40, 60) oo_2 = (70, 150) fields_from, fields_to = fields(pp)[0], fields(pp)[1] wheels = ['wheels50_1.png', 'wheels50_2.png'] pp_2 = (50, 50) oo_1_2 = (150, 30) oo_2_2 = (50, 90) fields_from_2, fields_to_2 = fields(pp_2)[0], fields(pp_2)[1] error = 0 if 'errorX' in player.participant.vars: if player.participant.vars['errorX'] > 0: error = 1 player.test_tries = player.participant.vars['test_tries'] q2_pa_1, q2_pb_1 = oo_1_2[0], oo_2_2[0] q2_pa_2, q2_pb_2 = oo_1_2[1], oo_2_2[1] round_info = player.participant.vars['RoundDict'][player.round_number] type = round_info['type'] pp_c = (50, 50) oo_c_1 = (200, 40) oo_c_2 = (70, 80) oo_c_2_1 = oo_1_2 oo_c_2_2 = oo_2_2 return dict( explain=zip(fields_from, fields_to, pp, oo_1, oo_2), explain2=zip(fields_from_2, fields_to_2, pp_2, oo_1_2, oo_2_2), explain_c=zip(fields_from, fields_to, pp_c, oo_c_1, oo_c_2), explain_c2=zip(fields_from, fields_to, pp_c, oo_c_2_1, oo_c_2_2), N_fields=sum(pp), rows=zip(fields_from, fields_to, pp, oo_1, oo_2, wheels), rows2=zip(fields_from, fields_to, pp, oo_1, oo_2, wheels), rows4=zip(fields_from_2, fields_to_2, pp_2, oo_1_2, oo_2_2, wheels), rows_c_1=zip(fields_from, fields_to, pp_c, oo_c_1, oo_c_2, wheels), rows_c_2=zip(fields_from, fields_to, pp_c, oo_c_2_1, oo_c_2_2, wheels), rows5=zip(fields_from, fields_to, pp, oo_1, oo_2, wheels), proba_A=50, proba_B=50, proba_A_2=50, test_1=player.participant.vars['test_1'], test_2=player.participant.vars['test_2'], test_3=player.participant.vars['test_3'], test_4=player.participant.vars['test_4'], error=error, type=type, round_info=round_info, total_block=player.participant.vars['RoundDict'][player.round_number+4]['total_block'], a_value="disabled", b_value="disabled", ) @staticmethod def js_vars(player: Player): return dict( coarse_lower_bound=C.coarse_lower_bound, coarse_upper_bound=C.coarse_upper_bound, coarse_step_size=C.coarse_step_size, fine_step_size=C.fine_step_size, target_value=C.target_value, round_number=player.round_number, saved_eval=player.participant.vars['saved_eval'], ) class InstructionsChoice(Page): form_model = 'player' form_fields = ['test_1', 'test_2', 'test_3'] def is_displayed(player): return player.round_number == 1 def error_message(player, value): if player.round_number != 1: return None if player.test_tries >= 2: return None if value['test_1'] is None or value['test_2'] is None or value['test_3'] is None: player.participant.vars['errorX'] = 1 return 'Please answer all comprehension questions.' # to kick out people answering wrong more than 3 times add to conditions "and player.test_tries == 2" else: bb = value['test_1'] + value['test_2'] + value['test_3'] if bb != 3: player.participant.vars['test_tries'] = player.participant.vars['test_tries'] + 1 player.test_tries = player.participant.vars['test_tries'] player.participant.vars['test_1'] = value['test_1'] player.participant.vars['test_2'] = value['test_2'] player.participant.vars['test_3'] = value['test_3'] return "You answered at least one of the questions incorrectly. Please read the hints below and make sure you " \ "understand the task well." def vars_for_template(player): pp = (50, 50) oo_1 = (40, 60) oo_2 = (70, 150) fields_from, fields_to = fields(pp)[0], fields(pp)[1] wheels = ['wheels_yellow_1.png', 'wheels_yellow_2.png'] pp_2 = (50, 50) oo_1_2 = (150, 30) oo_2_2 = (50, 90) fields_from_2, fields_to_2 = fields(pp_2)[0], fields(pp_2)[1] error = 0 if player.participant.vars['test_tries'] > 0: error = 1 if 'errorX' in player.participant.vars: error = 1 player.test_tries = player.participant.vars['test_tries'] q2_pa_1, q2_pb_1 = oo_1_2[0], oo_2_2[0] q2_pa_2, q2_pb_2 = oo_1_2[1], oo_2_2[1] round_info = player.participant.vars['RoundDict'][player.round_number] type = round_info['type'] pp_c = (50, 50) oo_c_1 = (200, 40) oo_c_2 = (70, 80) oo_c_2_1 = oo_1_2 oo_c_2_2 = oo_2_2 return dict( explain=zip(fields_from, fields_to, pp, oo_1, oo_2), explain2=zip(fields_from_2, fields_to_2, pp_2, oo_1_2, oo_2_2), explain_c=zip(fields_from, fields_to, pp_c, oo_c_1, oo_c_2), explain_c2=zip(fields_from, fields_to, pp_c, oo_c_2_1, oo_c_2_2), N_fields=sum(pp), rows=zip(fields_from, fields_to, pp, oo_1, oo_2, wheels), rows2=zip(fields_from, fields_to, pp, oo_1, oo_2, wheels), rows4=zip(fields_from_2, fields_to_2, pp_2, oo_1_2, oo_2_2, wheels), rows_c_1=zip(fields_from, fields_to, pp_c, oo_c_1, oo_c_2, wheels), rows_c_2=zip(fields_from, fields_to, pp_c, oo_c_2_1, oo_c_2_2, wheels), rows5=zip(fields_from, fields_to, pp, oo_1, oo_2, wheels), proba_A=50, proba_B=50, proba_A_2=50, test_1=player.participant.vars['test_1'], test_2=player.participant.vars['test_2'], test_3=player.participant.vars['test_3'], test_4=player.participant.vars['test_4'], error=error, type=type, round_info=round_info, total_block=player.participant.vars['RoundDict'][player.round_number+4]['total_block'], a_value="disabled", b_value="disabled", ) def before_next_page(player, timeout_happened): player.participant.vars['errorX'] = 0 class InstructionsMenu(Page): form_model = 'player' form_fields = ['test_4'] def is_displayed(player): if player.round_number==1: if player.field_maybe_none("test_tries") >= 2: return False else: return True def error_message(player, value): if player.round_number != 1: return None if player.test_tries >= 2: return None if value['test_4'] is None: player.participant.vars['errorX'] = 1 return 'Please answer all comprehension questions.' # to kick out people answering wrong more than 3 times add to conditions "and player.test_tries == 2" bb = value['test_4'] if bb != 1: player.participant.vars['test_tries'] = player.participant.vars['test_tries'] + 1 player.test_tries = player.participant.vars['test_tries'] player.participant.vars['errorX'] = 1 player.participant.vars['test_4'] = value['test_4'] return "You answered at least one of the questions incorrectly. Please read the hints below and make sure you " \ "understand the task well." def vars_for_template(player): pp = (50, 50) oo_1 = (40, 60) oo_2 = (70, 150) fields_from, fields_to = fields(pp)[0], fields(pp)[1] wheels_1 = ['wheels_yellow_1.png', 'wheels_yellow_2.png'] wheels_2 = ['wheels_orange_1.png', 'wheels_orange_2.png'] pp_2 = (50, 50) oo_1_2 = (150, 30) oo_2_2 = (50, 90) fields_from_2, fields_to_2 = fields(pp_2)[0], fields(pp_2)[1] error = 0 if 'errorX' in player.participant.vars: if player.participant.vars['errorX'] > 0: error = 1 player.test_tries = player.participant.vars['test_tries'] return dict( table_width=80, N_fields=sum(pp), rows_1=zip(fields_from, fields_to, pp, oo_1, oo_2, wheels_1), rows_2=zip(fields_from, fields_to, pp, oo_1_2, oo_2_2, wheels_2), left_value="negative", right_value="positive", test_4=player.participant.vars['test_4'], error=error, ) class instructions_empty(Page): def is_displayed(player): return player.round_number == 1 class NewBlock(Page): def is_displayed(player): if player.round_number != 1 and player.round_number != C.NUM_ROUNDS: round_info = player.participant.vars['RoundDict'][player.round_number] return round_info['type'] == 'practice' and player.participant.vars['RoundDict'][player.round_number-1]['type'] == 'main' else: return False class PayoffRelevant(Page): def is_displayed(player): if player.round_number != 1 and player.round_number != C.NUM_ROUNDS: round_info = player.participant.vars['RoundDict'][player.round_number] return round_info['type'] == 'main' and player.participant.vars['RoundDict'][player.round_number-1]['type'] == 'practice' else: return False def vars_for_template(player): image= "progress_choice.png" return dict( image=image, N_blocks=2, N_practive=4, ) class kicked(Page): def is_displayed(player: Player): if player.round_number == 1 and player.field_maybe_none("test_tries") is not None: return player.test_tries >= 2 else: return False class StartTask(Page): def is_displayed(player): return player.round_number == 1 def vars_for_template(player): return dict( image="progress_practice.png", N_blocks=2, N_practive=4, ) class Transition2(Page): timeout_seconds = 0.5 @staticmethod def is_displayed(player): round_info = player.participant.vars['RoundDict'][player.round_number] if player.round_number == C.NUM_ROUNDS: return False else: return round_info['type'] == 'main' and player.participant.vars['RoundDict'][player.round_number + 1]['type'] != 'practice' and player.round_number != C.NUM_ROUNDS-1 @staticmethod def vars_for_template(player): return dict( message="Next evaluation task starting..." ) class Transition(Page): @staticmethod def is_displayed(player): if player.round_number >= C.NUM_ROUNDS: return False round_dict = player.participant.vars['RoundDict'] current_type = round_dict[player.round_number]['type'] next_type = round_dict[player.round_number + 1]['type'] return current_type == 'main' and next_type != 'practice' @staticmethod def vars_for_template(player): return dict( message="Next evaluation task starting..." ) class Demographics(Page): form_model = "player" form_fields = [ "age", "gender", "education", "country", "employment", "income", ] def is_displayed(player): return player.round_number == C.NUM_ROUNDS class Cognitive2(Page): form_model = 'player' form_fields = ['Crt_barrel', 'Crt_student', 'Crt_pig', 'Crt_simon', 'Know2'] def is_displayed(player): return player.round_number == C.NUM_ROUNDS class Introduction(Page): def is_displayed(player: Player): return player.round_number == 1 class End(Page): def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS class StartSurvey(Page): def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS page_sequence = [StartSurvey, Cognitive2, Demographics, Introduction, InstructionsChoice, InstructionsMenu, kicked, StartTask, PayoffRelevant, Menu, Choice, Feedback, End]