from otree.api import * doc = """ Your app description """ import random import copy class Constants(BaseConstants): name_in_url = 'OwnC' players_per_group = None # Define lotteries Lotteries = dict() Lotteries[1], Lotteries[2] = dict(), dict() H = 1953 M = 1031 L = 109 d = 45 Lotteries[1] = [[20, 20, 20], [H+d, M+d, L+d], [L, H, M]] Lotteries[2] = [[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] = [[20, 20, 20], [H+d, M+d, L+d], [L, H, M]] Lotteries[4] = [[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] = [[20, 20, 20], [H+d, M+d, L+d], [L, H, M]] Lotteries[6] = [[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] = [[20, 20, 20], [H+d, M+d, L+d], [L, H, M]] Lotteries[8] = [[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] = [[20, 20, 20], [H+d, M+d, L+d], [L, H, M]] 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] ##define MCLs MC_dict = dict() # own task 1. vary safe payoff MC_dict[1], MC_dict[2], MC_dict[3] = dict(), dict(), dict() vec_A = list() vec_B = list() vec_safe, vec_high, vec_low = list(), list(), list() for i in range(350, 1450, 100): vec_A.append(str(i) + " avec 100%" ) vec_B.append("1880 avec 50% de chance et 60 avec 50% de chance") vec_safe.append(i) vec_high.append(1880) vec_low.append(60) IDs_A, IDs_B = list(), list() for i in range(1, 12): IDs_A.append("A" + str(i)) IDs_B.append("B" + str(i)) MC_dict[1]["vec_A"] = vec_A MC_dict[1]["vec_B"] = vec_B MC_dict[1]["IDs_A"] = IDs_A MC_dict[1]["IDs_B"] = IDs_B MC_dict[1]["vec_safe"] = vec_safe MC_dict[1]["vec_high"] = vec_high MC_dict[1]["vec_low"] = vec_low # own task 2. vary high payoff vec_A = list() vec_B = list() vec_safe, vec_high, vec_low = list(), list(), list() for i in range(1100, 2200, 100): vec_A.append("900 avec 100%") vec_B.append(str(i) + " avec 50% de chance et 400 avec 50% de chance") vec_safe.append(900) vec_high.append(i) vec_low.append(400) IDs_A, IDs_B = list(), list() for i in range(1, 12): IDs_A.append("A" + str(i)) IDs_B.append("B" + str(i)) MC_dict[2]["vec_A"] = vec_A MC_dict[2]["vec_B"] = vec_B MC_dict[2]["IDs_A"] = IDs_A MC_dict[2]["IDs_B"] = IDs_B MC_dict[2]["vec_safe"] = vec_safe MC_dict[2]["vec_high"] = vec_high MC_dict[2]["vec_low"] = vec_low # own task 3. vary low payoff vec_A = list() vec_B = list() vec_safe, vec_high, vec_low = list(), list(), list() for i in range(0, 770, 70): vec_A.append("1000 avec 100%") vec_B.append("1650 avec 50% de chance et " + str(i) + " avec 50% de chance") vec_safe.append(1000) vec_high.append(1650) vec_low.append(i) IDs_A, IDs_B = list(), list() for i in range(1, 12): IDs_A.append("A" + str(i)) IDs_B.append("B" + str(i)) MC_dict[3]["vec_A"] = vec_A MC_dict[3]["vec_B"] = vec_B MC_dict[3]["IDs_A"] = IDs_A MC_dict[3]["IDs_B"] = IDs_B MC_dict[3]["vec_safe"] = vec_safe MC_dict[3]["vec_high"] = vec_high MC_dict[3]["vec_low"] = vec_low #plus 1 bc of HL num_rounds = 3 for i in Lotteries: num_rounds += 1 class Subsession(BaseSubsession): pass def creating_session(subsession: Subsession): if subsession.round_number == 1: subsession.session.vars['random_choices_2'] = dict() subsession.session.vars['DoneDict_2'] = dict() subsession.session.vars['DoneDict_2']['A'] = dict() subsession.session.vars['DoneDict_2']['P'] = dict() for p in subsession.get_players(): v_position_s = list() v_state_order = list() v_state = list() v_lottery_nr = list() role = p.participant.vars['role'] subsession.session.vars['DoneDict_2'][role][p.participant.id_in_session] = 0 # p.participant.vars['random_choice_2'] = random.choice(range(1, (Constants.num_rounds+1))) # 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 L_order = list() for i in Constants.Lotteries: L_order.append(i) 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]) for i in order_lotteries: v_position_s.append(random.choice([0, 1])) states = list() for s in range(len(Constants.Lotteries[i][0])): states.append(s) random.shuffle(states) v_state_order.append(states) v_state.append(random.choice(states)) # FIRST THREE PAGES IS MCLs, then FOSD tasks. round_dict = dict() for r in [1, 2, 3]: round_dict[r] = dict() round_dict[r]['type'] = 'HL' for r in Constants.Lotteries: round_dict[r+3] = dict() round_dict[r+3]['type'] = 'FOSD' round_dict[r+3]['lottery_nr'] = order_lotteries[r - 1] round_dict[r+3]['position_s'] = v_position_s[r - 1] round_dict[r+3]['state_order'] = v_state_order[r - 1] # round_dict[r]['state'] = v_state[r - 1] p.participant.vars['round_dict_P_choice'] = round_dict # p.participant.vars['P_choice_pay'] = list() # p.participant.vars['role'] = 'P' class Group(BaseGroup): pass class Player(BasePlayer): choice_s = models.IntegerField() lottery_nr = models.IntegerField() state = models.IntegerField() position_s = models.IntegerField() state_order = models.StringField() number_a = models.IntegerField() # A_1 = models.IntegerField() # A_2 = models.IntegerField() # A_3 = models.IntegerField() # A_4 = models.IntegerField() # A_5 = models.IntegerField() # A_6 = models.IntegerField() # A_7 = models.IntegerField() # A_8 = models.IntegerField() # A_9 = models.IntegerField() # A_10 = models.IntegerField() # A_11 = models.IntegerField() A_1 = models.StringField( choices=["A", "B"], widget=widgets.RadioSelectHorizontal, label='1', ) A_2 = models.StringField( choices=["A", "B"], widget=widgets.RadioSelectHorizontal, label='2', ) A_3 = models.StringField( choices=["A", "B"], widget=widgets.RadioSelectHorizontal, label='', ) A_4 = models.StringField( choices=["A", "B"], widget=widgets.RadioSelectHorizontal, label='', ) A_5 = models.StringField( choices=["A", "B"], widget=widgets.RadioSelectHorizontal, label='', ) A_6 = models.StringField( choices=["A", "B"], widget=widgets.RadioSelectHorizontal, label='', ) A_7 = models.StringField( choices=["A", "B"], widget=widgets.RadioSelectHorizontal, label='', ) A_8 = models.StringField( choices=["A", "B"], widget=widgets.RadioSelectHorizontal, label='', ) A_9 = models.StringField( choices=["A", "B"], widget=widgets.RadioSelectHorizontal, label='', ) A_10 = models.StringField( choices=["A", "B"], widget=widgets.RadioSelectHorizontal, label='', ) A_11 = models.StringField( choices=["A", "B"], widget=widgets.RadioSelectHorizontal, label='', ) # PAGES class InstructionsP2(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 and player.participant.vars['role'] == 'P' @staticmethod def vars_for_template(player: Player): return dict( french=player.participant.vars['french'], ) class InstructionsP3(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 4 and player.participant.vars['role'] == 'P' @staticmethod def vars_for_template(player: Player): return dict( french=player.participant.vars['french'], round_dict_P_choice=player.participant.vars['round_dict_P_choice'], CMC_dict=Constants.MC_dict, ) class Instructions(Page): @staticmethod def is_displayed(player: Player): role = player.participant.vars['role'] return role == 'P' and player.round_number == 1 @staticmethod def vars_for_template(player: Player): return dict( french=player.participant.vars['french'], # to be changed ) class Choice(Page): form_model = 'player' form_fields = ['choice_s'] @staticmethod def is_displayed(player: Player): role = player.participant.vars['role'] return role == 'P' and player.round_number > 3 @staticmethod def vars_for_template(player: Player): round_info = player.participant.vars['round_dict_P_choice'][player.round_number] L_0 = Constants.Lotteries[round_info['lottery_nr']] position_s = round_info['position_s'] order = round_info['state_order'] 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]) option_a, option_b = 1, 0 if position_s == 0: L_1[1], L_1[2] = L_1[2], L_1[1] option_a, option_b = 0, 1 fields_from, fields_to = Constants.fields(L_1[0])[0], Constants.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( round_dict_P_choice= player.participant.vars['round_dict_P_choice'], position_s=position_s, 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, number='1', #treatment=player.session.vars['treatment'], french=player.participant.vars['french'], number_choice=12, choice_number=player.round_number, random_choices_2=player.participant.vars['random_choice_2'], ) @staticmethod def before_next_page(player: Player, timeout_happened): if player.participant.vars['random_choice_2']['round'] == player.round_number: state = player.participant.vars['random_choice_2']['state'] round_info = player.participant.vars['round_dict_P_choice'][player.round_number] L_0 = Constants.Lotteries[round_info['lottery_nr']] if player.choice_s == 1: payoff = L_0[1][state] else: payoff = L_0[2][state] player.participant.vars['random_choice_2']['payoff_choice'] = payoff player.participant.vars['random_choice_2']['choice'] = player.choice_s player.participant.vars['random_choice_2']['type'] = 'FOSD' player.participant.vars['random_choice_2']['round_info'] = round_info pf = [range(1, 21), range(21, 41), range(41, 61)] state_order = round_info['state_order'] field_stopped = random.choice(pf[state_order.index(state)]) player.participant.vars['random_choice_2']['field_stopped'] = field_stopped # write something in dict not to cause problems later player.participant.vars['random_choice_2']['text_a'] = "Wrong" player.participant.vars['random_choice_2']['text_b'] = "Wrong" player.participant.vars['random_choice_2']['checked_left'] = "" player.participant.vars['random_choice_2']['checked_right'] = "" player.participant.vars['random_choice_2']['payoff_hl'] = payoff player.participant.vars['random_choice_2']['payoff_b'] = -99 class HL(Page): @staticmethod def is_displayed(player: Player): role = player.participant.vars['role'] # type = player.participant.vars['round_dict_P_choice'][player.round_number]['type'] return role == 'P' and player.round_number <= 3 form_model = 'player' form_fields = ['A_1', 'A_2', 'A_3', 'A_4', 'A_5', 'A_6', 'A_7', 'A_8', 'A_9', 'A_10', 'A_11'] @staticmethod def vars_for_template(player: Player): french = player.participant.vars['french'] MC_dict = Constants.MC_dict[player.round_number] vec_A = MC_dict['vec_A'] vec_B = MC_dict['vec_B'] IDs_A = MC_dict['IDs_A'] IDs_B = MC_dict['IDs_B'] names = ['A_1', 'A_2', 'A_3', 'A_4', 'A_5', 'A_6', 'A_7', 'A_8', 'A_9', 'A_10', 'A_11'] nr = range(1, 12) if french == 0: if player.round_number == 1: text = " Note that option B is the same for all choices. " \ " Option A becomes more attractive as you move down the list of choices." elif player.round_number == 2 or player.round_number == 3: text = " Note that option A is the same for all choices. " \ " Option B becomes more attractive as you move down the list of choices." else: if player.round_number == 1: text = " Observez que l'option B est la même pour tous les choix. " \ " L'option A s'améliore au fur et à mesure que vous descendez dans la liste des choix." elif player.round_number == 2 or player.round_number == 3: text = " Observez que l'option A est la même pour tous les choix. " \ " L'option B s'améliore au fur et à mesure que vous descendez dans la liste des choix." return dict( random_choices_2=player.participant.vars['random_choice_2'], lotteries=Constants.Lotteries, # zip_table=zip(vec_A, vec_B, IDs_A, IDs_B, names, nr), # zip_table=zip(vec_A, vec_B, names, nr, form), zip_table=zip(vec_A, vec_B, HL.form_fields), round_dict_P_choice=player.participant.vars['round_dict_P_choice'], choice_number=player.round_number, french=french, num_rounds=Constants.num_rounds, number_choice=12, vec_B=vec_B, vec_A=vec_A, text=text, ) def before_next_page(player: Player, timeout_happened): # put this somewhere else, meaning the done stuff. # write into dict when players are done. principals have 5 rounds, choices between fosd and HL # if player.round_number == 5: # player.session.vars['DoneDict_2'][role][player.participant.id_in_session] = 1 # if chosen for random payoff, determine payoff and write variable for payoff feedback into dict if player.participant.vars['random_choice_2']['round'] == player.round_number: row = player.participant.vars['random_choice_2']['row'] high_outcome = player.participant.vars['random_choice_2']['high_outcome'] MC_dict = Constants.MC_dict[player.round_number] if high_outcome == 1: payoff_b = MC_dict['vec_high'][row - 1] else: payoff_b = MC_dict['vec_low'][row - 1] payoff_a = MC_dict['vec_safe'][row-1] if eval('player.A_' + str(row)) == 'A': payoff = payoff_a checked_left = "checked" checked_right = "" else: checked_left = "" checked_right = "checked" payoff = payoff_b player.participant.vars['random_choice_2']['text_a'] = MC_dict['vec_A'][row-1] player.participant.vars['random_choice_2']['text_b'] = MC_dict['vec_B'][row-1] player.participant.vars['random_choice_2']['checked_left'] = checked_left player.participant.vars['random_choice_2']['checked_right'] = checked_right player.participant.vars['random_choice_2']['payoff_hl'] = payoff player.participant.vars['random_choice_2']['choice'] = eval('player.A_' + str(row)) player.participant.vars['random_choice_2']['type'] = 'HL' player.participant.vars['random_choice_2']['payoff_b'] = payoff_b # write something in dict not to cause problems later player.participant.vars['random_choice_2']['payoff_choice'] = -99 player.participant.vars['random_choice_2']['round_info'] = player.participant.vars['round_dict_P_choice'][5] player.participant.vars['random_choice_2']['field_stopped'] = 22 page_sequence = [InstructionsP2, InstructionsP3, HL, Choice] # page_sequence = []