from otree.api import * import copy, random, itertools doc = """ Your app description """ class C(BaseConstants): NAME_IN_URL = 'main' PLAYERS_PER_GROUP = None 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] def L0_to_L1(L_0, state_order): L_1 = list() for i in range(len(L_0)): L_1.append(list()) for i in state_order: L_1[0].append(L_0[0][i]) L_1[1].append(L_0[1][i]) L_1[2].append(L_0[2][i]) return L_1 name_in_url = 'NOB' players_per_group = None max_bonus = 1000 Lotteries = dict() Lotteries[1], Lotteries[2] = dict(), dict() H = 1953 M = 1031 L = 109 d = 45 Lotteries[1]['lottery'] = [[20, 20, 20], [H+d, M+d, L+d], [L, H, M]] Lotteries[2]['lottery'] = [[20, 20, 20], [H+d, M+d, L+d], [M, L, H]] Lotteries[3], Lotteries[4] = dict(), dict() H = 1953 M = 1031 L = 109 d = 110 Lotteries[3]['lottery'] = [[20, 20, 20], [H+d, M+d, L+d], [L, H, M]] Lotteries[4]['lottery'] = [[20, 20, 20], [H+d, M+d, L+d], [M, L, H]] Lotteries[5], Lotteries[6] = dict(), dict() H = 1403 M = 688 L = 103 d = 359 Lotteries[5]['lottery'] = [[20, 20, 20], [H+d, M+d, L+d], [L, H, M]] Lotteries[6]['lottery'] = [[20, 20, 20], [H+d, M+d, L+d], [M, L, H]] Lotteries[7], Lotteries[8] = dict(), dict() H = 1403 M = 688 L = 103 d = 523 Lotteries[7]['lottery'] = [[20, 20, 20], [H+d, M+d, L+d], [L, H, M]] Lotteries[8]['lottery'] = [[20, 20, 20], [H+d, M+d, L+d], [M, L, H]] Lotteries[9] = dict() H = 1480 M = 750 L = 50 d = 699 Lotteries[9]['lottery'] = [[20, 20, 20], [H+d, M+d, L+d], [L, H, M]] # number of repetitions for agents # for testing to be changed num_rep = 8 participation_fee = 500 num_lot = len(Lotteries) # number of bonus decisions for Ps in OB treatment. The, number of screens for As. num_rounds is max of the two num_rounds_p_OB = num_lot*3 num_rounds_p_NOB = num_lot num_rounds_a_OB = num_lot*(2+3) num_rounds_a_NOB = num_lot*(2+1) num_rounds = max(num_rounds_a_OB, num_rounds_p_OB) NUM_ROUNDS = num_rounds # determines total number of states num_states = 0 num_lotteries = 0 L_order = list() for i in Lotteries: num_states = len(Lotteries[i]['lottery'][0]) + num_states num_lotteries = num_lotteries + 1 L_order.append(i) num_participants = 24 class Subsession(BaseSubsession): pass def creating_session(subsession): if subsession.round_number == 1: #trying to figure out erroe subsession.session.vars['pairs_vec'] = list() subsession.session.vars['executed'] = 0 subsession.session.vars['part_payoff'] = random.choices(population=[1, 2], weights=[0.8, 0.2])[0] # subsession.session.vars['lucky_bonus'] = dict() # dict tracking who of the participants are active and finished main part. count_Ps tracks number of Ps who #passed through wait page subsession.session.vars['ActiveDict'] = dict() subsession.session.vars['DoneDict'] = dict() for r in ['P', 'A']: subsession.session.vars['DoneDict'][r] = dict() subsession.session.vars['count_Ps'] = 0 # vars for wait page subsession.session.vars['countP'] = 0 subsession.session.vars['test_run'] = 0 ## vars to be used below subsession.session.vars['Lotteries'] = copy.deepcopy(C.Lotteries) subsession.session.vars['BonusDict'] = dict() subsession.session.vars['BeliefDict'] = dict() subsession.session.vars['ChoiceDict'] = dict() subsession.session.vars['PayDict'] = dict() subsession.session.vars['DisplayDict'] = dict() ## for attention check. Used in pages. When is attention check displayed? # for p in subsession.get_players(): # p.participant.vars['check_number'] = 1 subsession.session.vars['num_lotteries'] = C.num_lotteries tt = [subsession.session.config['treatment'], subsession.session.config['treatment']] # random.shuffle(tt) treatments = itertools.cycle(tt) roles = itertools.cycle(['P', 'A']) count_P = 1 for p in subsession.get_players(): p.participant.label = 'P' + str(p.participant.id_in_session) p.participant.vars['add_payoff'] = 0 subsession.session.vars['PayDict'][p.participant.id_in_session] = dict() # # role = next(roles) role = p.participant.vars['role'] = role p.session.vars['ActiveDict'][p.participant.id_in_session] = 0 p.session.vars['DoneDict'][role][p.participant.id_in_session] = 0 # p.participant.vars['lucky_bonus'] = 0 # #change this such that every other participant is P # # if count_P <= C.num_participants*0.5: # if role == 'P': # p.participant.vars['role'] = 'P' # count_P += 1 # subsession.session.vars['PayDict'][p.participant.id_in_session] = dict() # # for testing: # if subsession.session.vars['test_run'] == 1: # subsession.session.vars['BonusDict'][p.participant.id_in_session] = {1: {0: [1, 0], 1: [1, 0], 2: [1, 0], 3: [1, 0]}, # 2: {0: [1, 0], 1: [1, 0], 2: [1, 0], 3: [1, 0]}, # 3: {0: [1, 0], 1: [1, 0], 2: [1, 0]}, # 4: {0: [1, 0], 1: [1, 0], 2: [1, 0]}} # else: # #change needed here. Problem: only for later numbers. # p.participant.vars['role'] = 'A' # count_P += 1 # for i in subsession.session.vars['PayDict']: # subsession.session.vars['PayDict'][i][p.participant.id_in_session] = dict() # for ii in range(1, C.num_participants+1, 2): # subsession.session.vars['PayDict'][ii] = dict() # for jj in range(2, C.num_participants+2, 2): # subsession.session.vars['PayDict'][ii][jj] = dict() #check if that works. seems to work. Next:simplify above and test # # for integration with prolific (oTree HR) # p.participant.vars['finished'] = False # print(p.participant.id_in_session) treatment = next(treatments) p.participant.vars['treatment'] = treatment subsession.session.vars['num_rep'] = C.num_rep # to be changed, for testing p.participant.vars['french'] = 1 if p.participant.id_in_session > 5: p.participant.vars['french'] = 1 # Assigns some participants to role of A, some to P ######################################################################################################################## #################### Common variables ################################################################################### ######################################################################################################################## # variables for comprehension tests p.participant.vars['test_tries'] = 0 p.participant.vars['test_1'] = 0 p.participant.vars['test_2'] = 0 p.participant.vars['test_3'] = 0 if treatment == 'OB': if role == 'P': p.participant.vars['last_page'] = C.num_rounds_p_OB else: p.participant.vars['last_page'] = C.num_rounds_a_OB else: if role == 'P': p.participant.vars['last_page'] = C.num_rounds_p_NOB else: p.participant.vars['last_page'] = C.num_rounds_a_NOB ######################################################################################################################## #################### Agent variables ################################################################################### ######################################################################################################################## L_order = C.L_order # randomizes order of lotteries such that same lotteries do not appear one after the other # assumes that lotteries are always followed by their counterpart with different correlation v_l = list() order_lotteries = list() for i in range(0, len(L_order), 2): if len(L_order)-i >= 2: v_l.append(L_order[i:i + 2]) else: v_l.append(L_order[len(L_order)-1]) random.shuffle(v_l) for i in range(len(v_l)): if type(v_l[i]) == list: random.shuffle(v_l[i]) for c in [0, 1]: for j in range(len(v_l)): if type(v_l[j]) == list: order_lotteries.append(v_l[j][c]) else: if c == 0: order_lotteries.append(v_l[j]) # determine order of states and position_s for each lottery display_l = dict() count = 1 for i in order_lotteries: state_order = list() for s in range(len(C.Lotteries[i]['lottery'][0])): state_order.append(s) random.shuffle(state_order) display_l[i] = dict() display_l[i]['state_order'] = state_order display_l[i]['position_s'] = random.choice([0, 1]) display_l[i]['task_num'] = count count += 1 ############ # define the round_dict # the first rounds in which people state beliefs and then make a choice v_page = list() v_lottery_nr = list() v_position_s = list() v_state_order = list() # determines random outcomes of lotteries when agents make choices v_state_0 = list() # which round is feedback for? v_feedback_for = list() # number of rep for choice v_rep_num = list() # when do agents have to wait for all Ps to be done? v_num_scenario = list() # number of lottery task in order seen by participant # first round choices for i in order_lotteries: v_page.append('C') v_lottery_nr.append(i) v_rep_num.append(1) v_state_0.append(-99) v_num_scenario.append(-99) # then, beliefs and choices there if treatment == 'OB': for i in order_lotteries: for time in [0, 1, 2]: v_page.append('B') v_lottery_nr.append(i) v_rep_num.append(1) v_state_0.append(display_l[i]['state_order'][time]) v_num_scenario.append(time+1) v_page.append('C') v_lottery_nr.append(i) v_rep_num.append(2) v_state_0.append(-99) v_num_scenario.append(-99) if treatment == 'NOB': for i in order_lotteries: v_page.append('B') v_lottery_nr.append(i) v_rep_num.append(1) v_state_0.append(0) v_num_scenario.append(-99) v_page.append('C') v_lottery_nr.append(i) v_rep_num.append(2) v_state_0.append(-99) v_num_scenario.append(-99) round_dict = dict() for r in range(1, C.num_rounds + 1): round_dict[r] = dict() if treatment == 'NOB' and r > C.num_rounds_a_NOB: round_dict[r]['page'] = 'NoShow' else: round_dict[r]['page'] = v_page[r - 1] round_dict[r]['lottery_nr'] = v_lottery_nr[r - 1] round_dict[r]['rep_num'] = v_rep_num[r - 1] round_dict[r]['state_0'] = v_state_0[r - 1] round_dict[r]['num_scenario'] = v_num_scenario[r - 1] lottery_nr = v_lottery_nr[r - 1] round_dict[r]['position_s'] = display_l[lottery_nr]['position_s'] round_dict[r]['state_order'] = display_l[lottery_nr]['state_order'] round_dict[r]['task_num'] = display_l[lottery_nr]['task_num'] # # # # if v_page[r - 1] == 'C': # round_dict[r]['state_0'] = random.choice(display_l[lottery_nr]['state_order']) # # put field stopped into round dict # L_0 = C.Lotteries[lottery_nr]['lottery'] # state_order = display_l[lottery_nr]['state_order'] # L_1 = C.L0_to_L1(L_0, state_order) # # # feedback variables that are payoff relevant # state_0 = round_dict[r]['state_0'] # fields_from, fields_to = C.fields(L_1[0])[0], C.fields(L_1[0])[1] # state_1 = state_order.index(state_0) # field_from, field_to = fields_from[state_1], fields_to[state_1] # 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)) # field_stopped = random.choices( # population=population, # weights=weights # )[0] # round_dict[r]['field_stopped'] = field_stopped # else: # round_dict[r]['state_0'] = -99 # round_dict[r]['field_stopped'] = 0 # # round_dict[r]['display'] = 1 # if r > C.num_rounds_a: # round_dict[r] = dict() # round_dict[r]['display'] = 0 # round_dict[r]['wait'] = -99 # round_dict[r]['page'] = -99 # round_dict[r]['feedback'] = -99 # round_dict[r]['lottery_nr'] = -99 p.participant.vars['round_dict'] = round_dict p.participant.vars['A_num_rounds'] = r # print(round_dict) ######################################################################################################################## ######################################################################################################## ######################################################################################################################## # Principal variables ### variables for bonus decisions #numbers of total bonus deicions in OB and NOB if treatment == 'OB': p.participant.vars['bonus_num_rounds'] = C.num_rounds_p_OB else: p.participant.vars['bonus_num_rounds'] = C.num_lotteries Lotteries = copy.deepcopy(C.Lotteries) #creates random order of outcomes, and random order of states. lottery_order = list() lottery_order_NOB = list() for i in Lotteries: state_order = list() ran_out = list() lottery_order_NOB.append(i) for j in range(len(Lotteries[i]['lottery'][0])): lottery_order.append(i) ran_out.append(j) ran_state = list() s_a = list() for k in range(len(Lotteries[i]['lottery'][0])): ran_state.append(k) s_a.append(random.choice([0, 1])) random.shuffle(ran_state) state_order.append(ran_state) Lotteries[i]['state_order'] = state_order Lotteries[i]['outcomes'] = ran_out Lotteries[i]['position_s'] = s_a # create list with two sublists to write bonus payments into Lotteries[i]['bonus_payments'] = list() Lotteries[i]['bonus_payments'].append(list()) Lotteries[i]['bonus_payments'].append(list()) random.shuffle(ran_out) # random order of lotteries random.shuffle(lottery_order) random.shuffle(lottery_order_NOB) p.participant.vars['Lotteries'] = Lotteries # display is vector that tells when page is displayed display = list() if treatment == 'OB': for i in range(C.num_rounds_p_OB): display.append(1) for i in range(max(C.num_rounds - C.num_rounds_p_OB, 0)): display.append(0) lottery_order.append(-99) p.participant.vars['Lottery_order'] = lottery_order else: for i in range(len(lottery_order_NOB)): display.append(1) for i in range(C.num_rounds - len(lottery_order_NOB)): lottery_order_NOB.append(-99) display.append(0) p.participant.vars['Lottery_order'] = lottery_order_NOB p.participant.vars['display'] = display p.participant.vars['BonusDict'] = dict() for i in Lotteries: p.participant.vars['BonusDict'][i] = dict() for j in range(len(Lotteries[i]['lottery'][0])): p.participant.vars['BonusDict'][i][j] = list() p.participant.vars['BeliefDict'] = dict() for i in Lotteries: p.participant.vars['BeliefDict'][i] = dict() for j in range(len(Lotteries[i]['lottery'][0])): p.participant.vars['BeliefDict'][i][j] = list() p.participant.vars['ChoiceDict'] = dict() for rep in [1, 2]: p.participant.vars['ChoiceDict'][rep] = dict() for i in Lotteries: p.participant.vars['ChoiceDict'][rep][i] = dict() for j in range(len(Lotteries[i]['lottery'][0])): p.participant.vars['ChoiceDict'][rep][i][j] = list() p.participant.vars['DisplayDict'] = dict() for i in Lotteries: p.participant.vars['DisplayDict'][i] = dict() for j in range(len(Lotteries[i]['lottery'][0])): p.participant.vars['DisplayDict'][i][j] = list() ### define draw for part II if role == 'P': p.participant.vars['random_choice_2'] = dict() # p.participant.vars['random_choice_2']['round'] = random.choices( # population=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], # weights=[11/42, 11/42, 11/42, 1/42, 1/42, 1/42, 1/42, 1/42, 1/42, 1/42, 1/42, 1/42] # )[0] # to be changed p.participant.vars['random_choice_2']['round'] = random.choices( population=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], weights=[11/42, 11/42, 11/42, 1/42, 1/42, 1/42, 1/42, 1/42, 1/42, 1/42, 1/42, 1/42] )[0] p.participant.vars['random_choice_2']['row'] = random.choices( [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])[0] p.participant.vars['random_choice_2']['high_outcome'] = random.choices( [0, 1])[0] p.participant.vars['random_choice_2']['state'] = random.choices( [0, 1, 2])[0] class Group(BaseGroup): pass class Player(BasePlayer): bonus_s = models.IntegerField( choices=[1, 0], ) bonus_i = models.IntegerField( choices=[1, 0], ) page = models.StringField() state_order = models.StringField() position_s = models.IntegerField() state_0 = models.IntegerField() outcome_s = models.IntegerField() outcome_i = models.IntegerField() attention_1 = models.IntegerField() attention_2 = models.IntegerField() occurrence = models.IntegerField() lottery_nr = models.IntegerField() lotteries_dict = models.LongStringField() treatment = models.StringField() role_player = models.StringField(label=''' Please choose the treatment. "A" stands for Agents, "P" for Principal.''', choices=['A', 'P'],) test_1 = models.IntegerField() test_2 = models.IntegerField() test_3 = models.IntegerField() test_tries = models.IntegerField() french = models.IntegerField( label='''Do you speak French?''', choices=[[1, 'Yes'], [0, 'No']], widget=widgets.RadioSelectHorizontal ) consent = models.IntegerField( label='''I have read and consent to the above''', choices=[[1, 'Yes, continue with the survey'], [0, 'No, exit the survey']], widget=widgets.RadioSelectHorizontal ) P_id = models.StringField( label='''Please enter your Prolific ID. Please make sure it is correct. Otherwise we will not be able to pay to you.''', ) #################################################################################################################### # additional vars for agent choices choice_s = models.IntegerField() belief_s = models.IntegerField(min=0, max=100, label="") belief_i = models.IntegerField(min=0, max=100, label="") bonus_received = models.IntegerField() # PAGES class Consent(Page): form_model = 'player' form_fields = ['consent'] def is_displayed(player: Player): return player.round_number == 1 def before_next_page(player: Player, timeout_happened): player.participant.vars['consent'] = player.consent class StartExperiment(Page): def is_displayed(player: Player): return player.round_number == 1 def vars_for_template(player: Player): return dict( id=player.participant.id_in_session, tt=player.participant.vars, tttt=player.session.vars, ) class Introduction(Page): def is_displayed(player: Player): return player.round_number == 1 def vars_for_template(player: Player): return dict( french=player.participant.vars['french'], ) class Summary(Page): def is_displayed(player: Player): return player.round_number == 1 def before_next_page(player: Player, timeout_happened): role = player.participant.vars['role'] player.session.vars['ActiveDict'][player.participant.id_in_session] = 1 def vars_for_template(player: Player): return dict( french=player.participant.vars['french'], ) class Instructions(Page): form_model = 'player' form_fields = ['test_1', 'test_2', 'test_3'] def is_displayed(player: Player): return player.round_number == 1 def error_message(player, value): french = player.participant.vars['french'] bb = value['test_1'] + value['test_2'] + value['test_3'] # to kick out people answering wrong more than 3 times add to conditions "and player.test_tries == 2" 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'] if french == 1: return "Vous avez mal répondu à au moins une des questions. Veuillez lire les conseils ci-dessous et" \ " assurez-vous de bien comprendre la tâche." else: return "You answered at least one of the questions wrong. Please read the hints below and make sure you " \ "understand the task well." def vars_for_template(player: Player): player.test_tries = player.participant.vars['test_tries'] french = player.participant.vars['french'] pp_0 = (20, 20, 20) pp = (33.3, 33.3, 33.3) oo_1 = (400, 600, 2000) oo_2 = (700, 1500, 800) fields_from, fields_to = C.fields(pp_0)[0], C.fields(pp_0)[1] stopped_from, stopped_to = fields_from[0], fields_to[0] ex_A, ex_B = oo_1[0], oo_2[0] ff_2 = (20, 20, 20) pp_2 = (33.3, 33.3, 33.3) oo_1_2 = (200, 300, 1500) oo_2_2 = (700, 600, 500) fields_from_2, fields_to_2 = C.fields(ff_2)[0], C.fields(ff_2)[1] error = 0 if player.participant.vars['test_tries'] > 0: error = 1 role = player.participant.vars['role'] if role == 'A': b_player = 'you (the blue player)' o_player = 'the orange player' b_players = 'you (the blue players)' o_players = 'the orange players' else: b_player = 'the blue player' o_player = 'you (the orange player)' b_players = 'the blue players' o_players = 'you (the orange players)' # write role and treatment into vars player.role_player = player.participant.vars['role'] player.treatment = player.participant.vars['treatment'] return dict( b_player=b_player, o_player=o_player, b_players=b_players, o_players=o_players, french=player.participant.vars['french'], pp=pp, oo_1=oo_1, oo_2=oo_2, oo_1_highlight=zip(oo_1, fields_from), oo_2_highlight=zip(oo_2, fields_from), ooo_1_highlight=zip(oo_1, fields_from), ooo_2_highlight=zip(oo_2, fields_from), fields=zip(fields_from, fields_to, pp), fields11=zip(fields_from, fields_to, pp), fields111=zip(fields_from, fields_to, pp), explain=zip(fields_from, fields_to, pp, oo_1, oo_2), pp_2=pp_2, oo_1_2=oo_1_2, oo_2_2=oo_2_2, fields22=zip(fields_from_2, fields_to_2, pp_2), error=error, test_1=player.participant.vars['test_1'], test_2=player.participant.vars['test_2'], test_3=player.participant.vars['test_3'], treatment=player.participant.vars['treatment'], ex_A=ex_A, ex_B=ex_B, role=role, stopped_from=stopped_from, num_scenarios=player.participant.vars['bonus_num_rounds'], num_left=C.num_rep-1, ) class StartTask(Page): def is_displayed(player: Player): return player.round_number == 1 def vars_for_template(player: Player): return dict( french=player.participant.vars['french'], role=player.participant.vars['role'], ) class BonusDecision(Page): form_model = 'player' form_fields = ['bonus_s', 'bonus_i'] def is_displayed(player: Player): return player.participant.vars['display'][player.round_number - 1] == 1 and player.participant.vars['role'] == 'P' def vars_for_template(player: Player): french = player.participant.vars['french'] L = player.participant.vars['Lottery_order'][player.round_number-1] occurrence = player.participant.vars['Lottery_order'][:player.round_number].count(L)-1 L_0 = player.participant.vars['Lotteries'][L]['lottery'] order = player.participant.vars['Lotteries'][L]['state_order'][occurrence] state = player.participant.vars['Lotteries'][L]['outcomes'][occurrence] position_s = player.participant.vars['Lotteries'][L]['position_s'][occurrence] outcome_s, outcome_i = L_0[1][state], L_0[2][state] treatment = player.participant.vars['treatment'] outcome_A, outcome_B = outcome_s, outcome_i n_a, n_b = "bonus_s", "bonus_i" L_1 = list() for i in range(len(L_0)): L_1.append(list()) for j in order: L_1[i].append(L_0[i][j]) if position_s == 0: L_1[1], L_1[2] = L_1[2], L_1[1] outcome_A, outcome_B = outcome_i, outcome_s n_a, n_b = "bonus_i", "bonus_s" fields_from, fields_to = C.fields(L_1[0])[0], C.fields(L_1[0])[1] stopped_from, stopped_to = fields_from[order.index(state)], fields_to[order.index(state)] if treatment == 'NOB': stopped_from = -99 # this makes sure no field is highlighted in nNOB oo_1, oo_2 = L_1[1], L_1[2] sum_fields = sum(L_1[0]) pp = list() for i in range(len(oo_1)): pp.append(round((L_1[0][i]/sum_fields)*100, 1)) # write stuff into models player.lottery_nr = L player.occurrence = occurrence+1 player.state_order = str([oo_1, oo_2]) player.state_0 = state player.position_s = position_s player.outcome_s = outcome_s player.outcome_i = outcome_i player.treatment = player.participant.vars['treatment'] return dict( display=player.participant.vars['display'], round_dict=player.participant.vars['round_dict'], french=french, state=state, BonusDict=player.participant.vars['BonusDict'], fields=zip(fields_from, fields_to, pp), oo_1=zip(oo_1, fields_from), oo_2=zip(oo_2, fields_from), lotteries=player.participant.vars['Lotteries'], order=order, position_s=position_s, outcome_s=outcome_s, outcome_i=outcome_i, outcome_A=outcome_A, outcome_B=outcome_B, fields_from=fields_from, fields_to=fields_to, stopped_from=stopped_from, stopped_to=stopped_to, lottery_order=player.participant.vars['Lottery_order'], occurrence=occurrence, dict=player.participant.vars['Lotteries'], treatment=treatment, bonus_num_rounds=player.participant.vars['bonus_num_rounds'], role=player.participant.vars['role'], n_a=n_a, n_b=n_b, ) #commented out so experiment can be shared def before_next_page(player: Player, timeout_happened): player.session.vars['ActiveDict'][player.participant.id_in_session] = 1 if player.round_number == player.participant.vars['bonus_num_rounds']: player.session.vars['DoneDict']['P'][player.participant.id_in_session] = 1 id = player.participant.id_in_session # L is the index of the lottery in the dict Lotteries L = player.participant.vars['Lottery_order'][player.round_number - 1] # How many times has the subject seen the same lottery (starts at 0) occurrence = player.participant.vars['Lottery_order'][:player.round_number].count(L) - 1 # L_0 is the lottery as defined in Constants, that is without changing the order of states L_0 = player.participant.vars['Lotteries'][L]['lottery'] # State is the index of the state that occurs. Defined wrt to the order in L_0 state = player.participant.vars['Lotteries'][L]['outcomes'][occurrence] # outcomes of the inferior and the superior option in the given scenario outcome_s, outcome_i = L_0[1][state], L_0[2][state] state_order = player.participant.vars['Lotteries'][L]['state_order'][occurrence] pos_s = player.participant.vars['Lotteries'][L]['position_s'][occurrence] # write bonuses in BonusDict. for OB, this is specific to state. For NOB, I just write same bonus for every state if player.participant.vars['treatment'] == 'OB': player.participant.vars['BonusDict'][L][state].append(player.bonus_s) player.participant.vars['BonusDict'][L][state].append(player.bonus_i) player.participant.vars['DisplayDict'][L][state] = [pos_s, state_order] else: for i in range(len(L_0[0])): player.participant.vars['BonusDict'][L][i].append(player.bonus_s) player.participant.vars['BonusDict'][L][i].append(player.bonus_i) player.participant.vars['DisplayDict'][L][i] = [pos_s, state_order] # write BonusDict in session.vars, with id if player.round_number == player.participant.vars['last_page']: player.session.vars['BonusDict'][player.participant.id_in_session] = player.participant.vars['BonusDict'] player.session.vars['DisplayDict'][player.participant.id_in_session] = player.participant.vars[ 'DisplayDict'] role = player.participant.vars['role'] player.session.vars['DoneDict'][role][player.participant.id_in_session] = 1 sum_done, sum_active = 0, 0 for id in player.session.vars['DoneDict']['P']: sum_done += player.session.vars['DoneDict']['P'][id] for id in player.session.vars['DoneDict']['A']: sum_done += player.session.vars['DoneDict']['A'][id] for id in player.session.vars['ActiveDict']: sum_active += player.session.vars['ActiveDict'][id] if sum_active == sum_done: # determine payoff # first randomly match principals and agents. This is used both for part I and II. lucky_bonus = dict() v_ps, v_as = [], [] for id in player.session.vars['DoneDict']['P']: if player.session.vars['DoneDict']['P'][id] == 1: v_ps.append(id) for id in player.session.vars['DoneDict']['A']: if player.session.vars['DoneDict']['A'][id] == 1: v_as.append(id) lucky_bonus[id] = 0 random.shuffle(v_as) for id_p in v_ps: state = random.choice([0, 1, 2]) lottery_nr = random.choice([1, 2, 3, 4, 5, 6, 7, 8, 9]) rep = random.choice([1, 2]) match = v_as[v_ps.index(id_p)] choice_belief = random.choice([0, 1]) choice = player.session.vars['ChoiceDict'][match][rep][lottery_nr][state] pos_choice = 1 if choice == 1: pos_choice = 0 bonus = player.session.vars['BonusDict'][id_p][lottery_nr][state][pos_choice] if bonus == 0: others = [] for a in v_as: if a != match: others.append(a) lucky_bonus[random.choice(others)] += 1 pos_choice_b = 1 if choice_belief == 1: pos_choice_b = 0 belief = player.session.vars['BeliefDict'][match][lottery_nr][state][pos_choice_b] number = random.choice(range(0, 101)) if belief < number: prize = player.session.vars['BonusDict'][id_p][lottery_nr][state][0] else: p = number / 100 prize = random.choices(population=[0, 1], weights=[(1 - p), p])[0] pf = [range(1, 21), range(21, 41), range(41, 61)] state_order = player.session.vars['DisplayDict'][match][lottery_nr][state][1] field_stopped = random.choice(pf[state_order.index(state)]) position_s = player.session.vars['DisplayDict'][match][lottery_nr][state][0] for ii in [id_p, match]: player.session.vars['PayDict'][ii]['state'] = state player.session.vars['PayDict'][ii]['lottery_nr'] = lottery_nr player.session.vars['PayDict'][ii]['rep'] = rep player.session.vars['PayDict'][ii]['choice_s_belief'] = choice_belief player.session.vars['PayDict'][ii]['choice_s'] = choice player.session.vars['PayDict'][ii]['bonus'] = bonus player.session.vars['PayDict'][ii]['belief'] = belief player.session.vars['PayDict'][ii]['number'] = number player.session.vars['PayDict'][ii]['prize'] = prize player.session.vars['PayDict'][ii]['position_s'] = position_s player.session.vars['PayDict'][ii]['state_order'] = state_order player.session.vars['PayDict'][ii]['field_stopped'] = field_stopped for id in v_as: player.session.vars['PayDict'][id]['lucky_bonus'] = lucky_bonus[id] for id in v_ps: player.session.vars['PayDict'][id]['lucky_bonus'] = -99 class LotteryChoice(Page): form_model = 'player' form_fields = ['choice_s'] def is_displayed(player: Player): # display = player.participant.vars['round_dict'][player.round_number]['display'] role = player.participant.vars['role'] page = player.participant.vars['round_dict'][player.round_number]['page'] return role == 'A' and page == 'C' def vars_for_template(player: Player): french = player.participant.vars['french'] round_info = player.participant.vars['round_dict'][player.round_number] L_0 = player.session.vars['Lotteries'][round_info['lottery_nr']]['lottery'] position_s = round_info['position_s'] state_order = round_info['state_order'] L_1 = C.L0_to_L1(L_0, state_order) # L_0 is lottery as defined in C. the outcome state is defined wrt L_0. # L_1 is th lottery as it is displayed option_a, option_b = 1, 0 belief_a, belief_b = "belief_s", "belief_i" if position_s == 0: L_1[1], L_1[2] = copy.deepcopy(L_1[2]), copy.deepcopy(L_1[1]) option_a, option_b = 0, 1 belief_a, belief_b = "belief_i", "belief_s" fields_from, fields_to = C.fields(L_1[0])[0], C.fields(L_1[0])[1] p, oo_1, oo_2 = L_1[0], L_1[1], L_1[2] pp = list() for i in range(len(p)): pp.append(round(p[i]*(10/6), 1)) # write stuff into player.models player.lottery_nr = round_info['lottery_nr'] player.position_s = position_s player.state_order = str([oo_1, oo_2]) return dict( ChoiceDict=player.participant.vars['ChoiceDict'], session_lot=player.session.vars['Lotteries'], french=player.participant.vars['french'], fields=zip(fields_from, fields_to, pp), oo_1=zip(oo_1, fields_from), oo_2=zip(oo_2, fields_from), option_a=option_a, option_b=option_b, treatment=player.participant.vars['treatment'], num_choices=player.session.vars['num_lotteries'], task_num=round_info['task_num'], rep_num=round_info['rep_num'], L_0=L_0, L_1=L_1, round_dict=player.participant.vars['round_dict'], belief_a=belief_a, belief_b=belief_b, PayDict=player.session.vars['PayDict'], luck_bonus=player.session.vars['lucky_bonus'], ) def before_next_page(player: Player, timeout_happened): player.participant.vars['round_dict'][player.round_number]['choice_s'] = player.choice_s round_info = player.participant.vars['round_dict'][player.round_number] rep = round_info['rep_num'] L_nr = round_info['lottery_nr'] pos_s = round_info['position_s'] state_order = round_info['state_order'] state = round_info['state_0'] treatment = player.participant.vars['treatment'] for s in [0, 1, 2]: player.participant.vars['ChoiceDict'][rep][L_nr][s] = player.choice_s player.participant.vars['DisplayDict'][L_nr][s] = [pos_s, state_order] # if player is on last round, set done to 1 in DoneDict. Then write choices and beliefs into session.vars # Then check if all active players are done. if yes, payoffs are determined. if player.round_number == player.participant.vars['last_page']: player.session.vars['ChoiceDict'][player.participant.id_in_session] = player.participant.vars['ChoiceDict'] player.session.vars['BeliefDict'][player.participant.id_in_session] = player.participant.vars['BeliefDict'] player.session.vars['DisplayDict'][player.participant.id_in_session] = player.participant.vars['DisplayDict'] role = player.participant.vars['role'] player.session.vars['DoneDict'][role][player.participant.id_in_session] = 1 sum_done, sum_active = 0, 0 for id in player.session.vars['DoneDict']['P']: sum_done += player.session.vars['DoneDict']['P'][id] for id in player.session.vars['DoneDict']['A']: sum_done += player.session.vars['DoneDict']['A'][id] for id in player.session.vars['ActiveDict']: sum_active += player.session.vars['ActiveDict'][id] if sum_active == sum_done: # determine payoff # first randomly match principals and agents. This is used both for part I and II. lucky_bonus = dict() v_ps, v_as = [], [] for id in player.session.vars['DoneDict']['P']: if player.session.vars['DoneDict']['P'][id] == 1: v_ps.append(id) for id in player.session.vars['DoneDict']['A']: if player.session.vars['DoneDict']['A'][id] == 1: v_as.append(id) lucky_bonus[id] = 0 random.shuffle(v_as) for id_p in v_ps: state = random.choice([0, 1, 2]) lottery_nr = random.choice([1, 2, 3, 4, 5, 6, 7, 8, 9]) rep = random.choice([1, 2]) match = v_as[v_ps.index(id_p)] choice_belief = random.choice([0, 1]) choice = player.session.vars['ChoiceDict'][match][rep][lottery_nr][state] pos_choice = 1 if choice == 1: pos_choice = 0 bonus = player.session.vars['BonusDict'][id_p][lottery_nr][state][pos_choice] if bonus == 0: others = [] for a in v_as: if a != match: others.append(a) lucky_bonus[random.choice(others)] += 1 pos_choice_b = 1 if choice_belief == 1: pos_choice_b = 0 belief = player.session.vars['BeliefDict'][match][lottery_nr][state][pos_choice_b] number = random.choice(range(0, 101)) if belief < number: prize = player.session.vars['BonusDict'][id_p][lottery_nr][state][0] else: p = number/100 prize = random.choices(population=[0, 1], weights=[(1-p), p])[0] pf = [range(1, 21), range(21, 41), range(41, 61)] state_order = player.session.vars['DisplayDict'][match][lottery_nr][state][1] field_stopped = random.choice(pf[state_order.index(state)]) position_s = player.session.vars['DisplayDict'][match][lottery_nr][state][0] for ii in [id_p, match]: player.session.vars['PayDict'][ii]['state'] = state player.session.vars['PayDict'][ii]['lottery_nr'] = lottery_nr player.session.vars['PayDict'][ii]['rep'] = rep player.session.vars['PayDict'][ii]['choice_s_belief'] = choice_belief player.session.vars['PayDict'][ii]['choice_s'] = choice player.session.vars['PayDict'][ii]['bonus'] = bonus player.session.vars['PayDict'][ii]['belief'] = belief player.session.vars['PayDict'][ii]['number'] = number player.session.vars['PayDict'][ii]['prize'] = prize player.session.vars['PayDict'][ii]['position_s'] = position_s player.session.vars['PayDict'][ii]['state_order'] = state_order player.session.vars['PayDict'][ii]['field_stopped'] = field_stopped for id in v_as: player.session.vars['PayDict'][id]['lucky_bonus'] = lucky_bonus[id] for id in v_ps: player.session.vars['PayDict'][id]['lucky_bonus'] = -99 class Instructions_beliefs(Page): def is_displayed(player: Player): return player.participant.vars['role'] == 'A' and player.round_number == 10 def vars_for_template(player: Player): pp_0 = (20, 20, 20) pp = (33.3, 33.3, 33.3) oo_1 = (400, 600, 2000) oo_2 = (700, 1500, 800) fields_from, fields_to = C.fields(pp_0)[0], C.fields(pp_0)[1] stopped_from, stopped_to = fields_from[0], fields_to[0] treatment = player.participant.vars['treatment'] n_scenario = 9 if treatment == 'OB': n_scenario = 27 return dict( n_scenario=n_scenario, french=player.participant.vars["french"], fields=zip(fields_from, fields_to, pp), outcome_A=700, outcome_B=400, oo_1=zip(oo_1, fields_from), oo_2=zip(oo_2, fields_from), stopped_from=stopped_from, stopped_to=stopped_to, treatment=treatment, ) class Belief(Page): form_model = 'player' form_fields = ['belief_s', 'belief_i'] def is_displayed(player: Player): page = player.participant.vars['round_dict'][player.round_number]['page'] return page == 'B' and player.participant.vars['role'] == 'A' def vars_for_template(player: Player): french = player.participant.vars['french'] round_info = player.participant.vars['round_dict'][player.round_number] L_0 = player.session.vars['Lotteries'][round_info['lottery_nr']]['lottery'] position_s = round_info['position_s'] order = round_info['state_order'] state = round_info['state_0'] occurrence = round_info['rep_num'] outcome_s, outcome_i = L_0[1][state], L_0[2][state] treatment = player.participant.vars['treatment'] outcome_A, outcome_B = outcome_s, outcome_i belief_a, belief_b = "belief_s", "belief_i" L_1 = list() for i in range(len(L_0)): L_1.append(list()) for j in order: L_1[i].append(L_0[i][j]) if position_s == 0: L_1[1], L_1[2] = L_1[2], L_1[1] outcome_A, outcome_B = outcome_i, outcome_s belief_a, belief_b = "belief_i", "belief_s" fields_from, fields_to = C.fields(L_1[0])[0], C.fields(L_1[0])[1] stopped_from, stopped_to = fields_from[order.index(state)], fields_to[order.index(state)] if treatment == 'NOB': stopped_from = -99 # this makes sure no field is highlighted in nNOB oo_1, oo_2 = L_1[1], L_1[2] sum_fields = sum(L_1[0]) pp = list() for i in range(len(oo_1)): pp.append(round((L_1[0][i]/sum_fields)*100, 1)) #Example # oo_1 = (400, 600, 2000) # oo_2 = (700, 1500, 800) # outcome_A, outcome_B = 400, 700 # write stuff into models player.lottery_nr = round_info['lottery_nr'] player.occurrence = occurrence+1 player.state_order = str([oo_1, oo_2]) player.state_0 = state player.position_s = position_s player.outcome_s = outcome_s player.outcome_i = outcome_i player.treatment = player.participant.vars['treatment'] return dict( n_scenario=round_info['num_scenario'], n_task=round_info['task_num'], lottery_order=player.participant.vars['Lottery_order'], round_dict=player.participant.vars['round_dict'], french=french, state=state, BeliefDict=player.participant.vars['BeliefDict'], fields=zip(fields_from, fields_to, pp), oo_1=zip(oo_1, fields_from), oo_2=zip(oo_2, fields_from), lotteries=player.participant.vars['Lotteries'], order=order, position_s=position_s, outcome_s=outcome_s, outcome_i=outcome_i, outcome_A=outcome_A, outcome_B=outcome_B, fields_from=fields_from, fields_to=fields_to, stopped_from=stopped_from, stopped_to=stopped_to, occurrence=occurrence, dict=player.participant.vars['Lotteries'], treatment=treatment, display=player.participant.vars['display'], bonus_num_rounds=player.participant.vars['bonus_num_rounds'], role=player.participant.vars['role'], belief_a=belief_a, belief_b=belief_b, ) def before_next_page(player: Player, timeout_happened): id = player.participant.id_in_session # L is the index of the lottery in the dict Lotteries round_info = player.participant.vars['round_dict'][player.round_number] L = round_info['lottery_nr'] # # How many times has the subject seen the same lottery (starts at 0) # occurrence = player.participant.vars['Lottery_order'][:player.round_number].count(L) - 1 # # L_0 is the lottery as defined in Constants, that is without changing the order of states L_0 = player.participant.vars['Lotteries'][L]['lottery'] # # State is the index of the state that occurs. Defined wrt to the order in L_0 state = round_info['state_0'] # # outcomes of the inferior and the superior option in the given scenario # outcome_s, outcome_i = L_0[1][state], L_0[2][state] # # # # write beleifs into BeliefDict. for OB, this is specific to state. For NOB, I just write same bonus for every state if player.participant.vars['treatment'] == 'OB': player.participant.vars['BeliefDict'][L][state].append(player.belief_s) player.participant.vars['BeliefDict'][L][state].append(player.belief_i) else: for i in range(len(L_0[0])): player.participant.vars['BeliefDict'][L][i].append(player.belief_s) player.participant.vars['BeliefDict'][L][i].append(player.belief_i) # # write BonusDict in session.vars, with id if player.participant.vars['role'] == 'A': player.session.vars['BeliefDict'][id] = player.participant.vars['BeliefDict'] def js_vars(player: Player): round_info = player.participant.vars['round_dict'][player.round_number] L_0 = player.session.vars['Lotteries'][round_info['lottery_nr']]['lottery'] position_s = round_info['position_s'] order = round_info['state_order'] state = round_info['state_0'] occurrence = round_info['rep_num'] outcome_s, outcome_i = L_0[1][state], L_0[2][state] treatment = player.participant.vars['treatment'] outcome_A, outcome_B = outcome_s, outcome_i belief_a, belief_b = "belief_s", "belief_i" L_1 = list() for i in range(len(L_0)): L_1.append(list()) for j in order: L_1[i].append(L_0[i][j]) if position_s == 0: L_1[1], L_1[2] = L_1[2], L_1[1] outcome_A, outcome_B = outcome_i, outcome_s belief_a, belief_b = "belief_i", "belief_s" return dict( belief_a=belief_a, belief_b=belief_b, ) class test(Page): def is_displayed(player: Player): return player.round_number == player.participant.vars['last_page'] def vars_for_template(player: Player): return dict( BonusDict=player.session.vars['BonusDict'], BeliefDict=player.session.vars['BeliefDict'], ChoiceDict=player.session.vars['ChoiceDict'], PayDict=player.session.vars['PayDict'], DisplayDict=player.session.vars['DisplayDict'], ) class NoConsent(Page): def is_displayed(player: Player): return player.participant.vars['consent'] == 0 page_sequence = [Consent, NoConsent, Introduction, Summary, Instructions, StartTask, Instructions_beliefs, LotteryChoice, Belief, BonusDecision] # page_sequence = [ Instructions_beliefs, LotteryChoice, Belief, BonusDecision] # page_sequence = []