from otree.api import * import copy doc = """ Your app description """ class C(BaseConstants): NAME_IN_URL = 'End' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 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 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]] class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): pass def group_by_arrival_time_method(subsession, waiting_players): PAs = [p for p in waiting_players] # checks if all active players are done with the main part. If yes, players can move on sum_done, sum_active = 0, 0 for id in subsession.session.vars['DoneDict']['P']: sum_done += subsession.session.vars['DoneDict']['P'][id] for id in subsession.session.vars['DoneDict']['A']: sum_done += subsession.session.vars['DoneDict']['A'][id] for id in subsession.session.vars['ActiveDict']: sum_active += subsession.session.vars['ActiveDict'][id] if sum_active == sum_done: while len(PAs) >= 1: PAs = [p for p in waiting_players] return [PAs[0]] # PAGES class ResultsWaitPage(WaitPage): group_by_arrival_time = True template_name = 'End/ResultsWaitPage.html' def vars_for_template(player: Player): return dict( french=player.participant.vars['french'], 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'], ) # for testing # paydict = {1: {'state': 1, 'lottery_nr': 1, 'rep': 2, 'choice_s_belief': 1, 'choice_s': 1, 'bonus': 1, 'belief': 17, 'number': 97, 'prize': 1, 'position_s': 0, 'state_order': [0, 1, 2], 'field_stopped': 52, 'lucky_bonus': -99}, 2: {'state': 1, 'lottery_nr': 1, 'rep': 2, 'choice_s_belief': 1, 'choice_s': 1, 'bonus': 1, 'belief': 17, 'number': 97, 'prize': 1, 'position_s': 0, 'state_order': [0, 1, 2], 'field_stopped': 52, 'lucky_bonus': 0}, 3: {'state': 2, 'lottery_nr': 4, 'rep': 1, 'choice_s_belief': 0, 'choice_s': 1, 'bonus': 1, 'belief': 14, 'number': 0, 'prize': 0, 'position_s': 0, 'state_order': [2, 0, 1], 'field_stopped': 56, 'lucky_bonus': -99}, 4: {'state': 2, 'lottery_nr': 4, 'rep': 1, 'choice_s_belief': 0, 'choice_s': 1, 'bonus': 1, 'belief': 14, 'number': 0, 'prize': 0, 'position_s': 0, 'state_order': [2, 0, 1], 'field_stopped': 56, 'lucky_bonus': 0}} class PayoffsPA(Page): def is_displayed(player: Player): return player.session.vars['part_payoff'] == 1 def vars_for_template(player: Player): role = player.participant.vars['role'] id = player.participant.id_in_session round_info = player.session.vars['PayDict'][id] position_s = round_info['position_s'] state_order = round_info['state_order'] l_nr = round_info['lottery_nr'] L_0 = C.Lotteries[l_nr]['lottery'] L_1 = C.L0_to_L1(L_0, state_order) # L_0 is lottery as defined in Constants. the outcome state is defined wrt L_0. # L_1 is th lottery as it is displayed option_a, option_b = 1, 0 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 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)) choice_s = round_info['choice_s'] # variables to determine which option is checked checked_A = '' checked_B = '' option_chosen = 'A' if choice_s == 1 and position_s == 0: option_chosen = 'B' if choice_s == 0 and position_s == 1: option_chosen = 'B' if option_chosen == 'A': checked_A = 'checked' elif option_chosen == 'B': checked_B = 'checked' # which outcome realized state_0 = round_info['state'] state_1 = state_order.index(state_0) outcome_s = L_0[1][state_0] outcome_i = L_0[2][state_0] if choice_s == 1: outcome_yielded, outcome_forgone = outcome_s, outcome_i elif choice_s == 0: outcome_yielded, outcome_forgone = outcome_i, outcome_s bonus = round_info['bonus'] stopped_from = fields_from[state_1] payoff_yielded = 0 if role == 'P': payoff_yielded = outcome_yielded add_payoff = outcome_yielded num_lucky_bonus = 0 bonus_pay = 0 if role == 'A': bonus_pay = C.max_bonus * bonus num_lucky_bonus = round_info['lucky_bonus'] add_payoff = 1000*(num_lucky_bonus + bonus) add_bonus = num_lucky_bonus * C.max_bonus player.participant.vars['add_payoff'] = add_payoff player.payoff = add_payoff + 500 b_word = 'bonuses' if num_lucky_bonus == 1: b_word = 'bonus' payoff = add_bonus + bonus_pay + payoff_yielded return dict( add_payoff=add_payoff, french=player.participant.vars['french'], role=role, round_info=round_info, # BonusDict=BonusDict, 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, choice_s=choice_s, checked_A=checked_A, checked_B=checked_B, option_chosen=option_chosen, outcome_s=outcome_s, outcome_i=outcome_i, outcome_yielded=outcome_yielded, outcome_forgone=outcome_forgone, bonus=bonus, stopped_from=stopped_from, position_s=position_s, field_stopped=round_info['field_stopped'], num_lucky_bonus=num_lucky_bonus, b_word=b_word, add_bonus=add_bonus, payoff=payoff, paydict=player.session.vars['PayDict'], ) class PayoffsOtherA(Page): def is_displayed(player: Player): return player.session.vars['part_payoff'] == 2 and player.participant.vars['role'] == 'A' def vars_for_template(player: Player): role = player.participant.vars['role'] id = player.participant.id_in_session round_info = player.session.vars['PayDict'][id] position_s = round_info['position_s'] state_order = round_info['state_order'] l_nr = round_info['lottery_nr'] L_0 = C.Lotteries[l_nr]['lottery'] L_1 = C.L0_to_L1(L_0, state_order) # L_0 is lottery as defined in Constants. the outcome state is defined wrt L_0. # L_1 is th lottery as it is displayed option_a, option_b = 1, 0 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 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)) choice_s = round_info['choice_s_belief'] # variables to determine which option is checked checked_A = '' checked_B = '' option_chosen = 'A' if choice_s == 1 and position_s == 0: option_chosen = 'B' if choice_s == 0 and position_s == 1: option_chosen = 'B' if option_chosen == 'A': checked_A = 'checked' elif option_chosen == 'B': checked_B = 'checked' # which outcome realized state_0 = round_info['state'] state_1 = state_order.index(state_0) outcome_s = L_0[1][state_0] outcome_i = L_0[2][state_0] outcome_A, outcome_B = outcome_s, outcome_i if position_s == 0: outcome_A, outcome_B = outcome_i, outcome_s if choice_s == 1: outcome_yielded, outcome_forgone = outcome_s, outcome_i elif choice_s == 0: outcome_yielded, outcome_forgone = outcome_i, outcome_s bonus = round_info['bonus'] stopped_from, stopped_to = fields_from[state_1], fields_to[state_1] # stopped_from = fields_from[state_1] payoff_yielded = 0 if role == 'P': payoff_yielded = outcome_yielded num_lucky_bonus = 0 bonus_pay = 0 if role == 'A': bonus_pay = C.max_bonus * bonus num_lucky_bonus = round_info['lucky_bonus'] add_bonus = num_lucky_bonus * C.max_bonus b_word = 'bonuses' if num_lucky_bonus == 1: b_word = 'bonus' checked_r = '' checked_nr = '' if bonus == 1: checked_r = 'checked' else: checked_nr = 'checked' payoff = add_bonus + bonus_pay + payoff_yielded add_payoff = 0 if round_info['prize'] == 1: add_payoff = 1500 player.participant.vars['add_payoff'] = add_payoff player.payoff = add_payoff + 500 return dict( add_payoff=add_payoff, outcome_A=outcome_A, outcome_B=outcome_B, treatment=player.participant.vars['treatment'], prize=round_info['prize'], guess=round_info['belief'], checked_r=checked_r, checked_nr=checked_nr, french=player.participant.vars['french'], role=role, round_info=round_info, # BonusDict=BonusDict, 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, choice_s=choice_s, checked_A=checked_A, checked_B=checked_B, option_chosen=option_chosen, outcome_s=outcome_s, outcome_i=outcome_i, outcome_yielded=outcome_yielded, outcome_forgone=outcome_forgone, bonus=bonus, stopped_from=stopped_from, stopped_to=stopped_to, position_s=position_s, field_stopped=round_info['field_stopped'], num_lucky_bonus=num_lucky_bonus, b_word=b_word, add_bonus=add_bonus, payoff=payoff, paydict=player.session.vars['PayDict'], ) class PayoffsOtherP(Page): def is_displayed(player: Player): return player.session.vars['part_payoff'] == 2 and player.participant.vars['role'] == 'P' def vars_for_template(player: Player): task_type = player.participant.vars['random_choice_2']['type'] round_info = player.participant.vars['random_choice_2']['round_info'] position_s = round_info['position_s'] state_order = round_info['state_order'] l_nr = round_info['lottery_nr'] L_0 = C.Lotteries[l_nr]['lottery'] L_1 = C.L0_to_L1(L_0, state_order) # L_0 is lottery as defined in Constants. the outcome state is defined wrt L_0. # L_1 is th lottery as it is displayed outcome_yielded, outcome_forgone = 0, 0 # to be changed later. just to avoid referencing before asignment. option_a, option_b = 1, 0 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 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)) choice_s = player.participant.vars['random_choice_2']['choice'] # variables to determine which option is checked if task_type == 'HL': choice_s = player.participant.vars['random_choice_2']['choice'] checked_A = '' checked_B = '' option_chosen = 'A' if choice_s == 1 and position_s == 0: option_chosen = 'B' if choice_s == 0 and position_s == 1: option_chosen = 'B' if option_chosen == 'A': checked_A = 'checked' elif option_chosen == 'B': checked_B = 'checked' # which outcome realized state_0 = player.participant.vars['random_choice_2']['state'] state_1 = state_order.index(state_0) outcome_s = L_0[1][state_0] outcome_i = L_0[2][state_0] if choice_s == 1: outcome_yielded, outcome_forgone = outcome_s, outcome_i elif choice_s == 0: outcome_yielded, outcome_forgone = outcome_i, outcome_s stopped_from, stopped_to = fields_from[state_1], fields_to[state_1] # stopped_from = fields_from[state_1] payoff_yielded = 0 text_a = player.participant.vars['random_choice_2']['text_a'] text_b = player.participant.vars['random_choice_2']['text_b'] checked_left = player.participant.vars['random_choice_2']['checked_left'] checked_right = player.participant.vars['random_choice_2']['checked_right'] if task_type == 'HL': option_chosen = 'A' if choice_s == 0: option_chosen = 'B' payoff_hl = player.participant.vars['random_choice_2']['payoff_hl'] add_payoff = outcome_yielded player.participant.vars['add_payoff'] = add_payoff if task_type == 'HL': add_payoff = payoff_hl player.participant.vars['add_payoff'] = add_payoff player.payoff = add_payoff + 500 return dict( add_payoff=add_payoff, payoff_b=player.participant.vars['random_choice_2']['payoff_b'], payoff_hl=payoff_hl, text_a=text_a, text_b=text_b, checked_left=checked_left, checked_right=checked_right, task_type=task_type, treatment=player.participant.vars['treatment'], french=player.participant.vars['french'], round_info=round_info, # BonusDict=BonusDict, 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, choice_s=choice_s, checked_A=checked_A, checked_B=checked_B, option_chosen=option_chosen, outcome_s=outcome_s, outcome_i=outcome_i, outcome_yielded=outcome_yielded, outcome_forgone=outcome_forgone, stopped_from=stopped_from, stopped_to=stopped_to, position_s=position_s, field_stopped=player.participant.vars['random_choice_2']['field_stopped'], paydict=player.session.vars['PayDict'], ) class End(Page): def vars_for_template(player: Player): total_payoff = player.participant.vars['add_payoff'] + 500 return dict( add_payoff=player.participant.vars['add_payoff']/100, total_payoff=total_payoff/100, french=player.participant.vars['french'], part_payoff=player.session.vars['part_payoff'], paydict=player.session.vars['PayDict'], ) page_sequence = [ResultsWaitPage, PayoffsPA, PayoffsOtherA, PayoffsOtherP, End] # page_sequence = []