from otree.api import * import random import csv doc = """ baseline """ class Constants(BaseConstants): name_in_url = 'pooling_baseline' players_per_group = None part_0_length=2 #consent part_1_length=4 #instructions round 1 part_1_length_r2=1 #instructions round 2 part_2_length=1 #quiz part_2_length_r2=1 #quiz round 2 part_3_length=1 #game part_3_length_r2=1 #game round 2 part_4_length=13 #post-experiment num_rounds = part_0_length+part_1_length+part_1_length_r2+part_2_length+part_2_length_r2+part_3_length+part_3_length_r2+part_4_length+3 with open('Experimental Parameters_pooling.csv') as exp_params_pooling: exp_params_pooling= list(csv.DictReader(exp_params_pooling)) with open('Experimental Parameters_discrete.csv') as exp_params_discrete: exp_params_discrete= list(csv.DictReader(exp_params_discrete)) class Subsession(BaseSubsession): pass def creating_session(subsession: Subsession): if subsession.round_number==1: for p in subsession.get_players(): p.participant.rounds=[1, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100] p.participant.pooling_first=subsession.session.config['pooling_first'] p.participant.quiz_n_correct=0 p.participant.strike=0 p.participant.quiz_your_answers=[100]*3 p.participant.correct_answers=[0, 0, 0] p.participant.correctly_answered=[0]*3 #pooling parameters p.participant.exp_params_pooling_values=[] for name in Constants.exp_params_pooling.copy()[0].keys(): p.participant.exp_params_pooling_values.append([int(float(x[name])*100) for x in Constants.exp_params_pooling.copy()]) p.participant.exp_params_pooling_payoff=p.participant.exp_params_pooling_values[0][::-1] p.participant.exp_params_pooling_costs=p.participant.exp_params_pooling_values[1:] p.participant.exp_params_pooling_costs=[elem[::-1] for elem in p.participant.exp_params_pooling_costs] # descrete parameteres p.participant.exp_params_discrete_values=[] for name in Constants.exp_params_discrete.copy()[0].keys(): p.participant.exp_params_discrete_values.append([int(float(x[name])*100) for x in Constants.exp_params_discrete.copy()]) p.participant.exp_params_discrete_payoff=p.participant.exp_params_discrete_values[0][::-1] p.participant.exp_params_discrete_costs=p.participant.exp_params_discrete_values[1:] p.participant.exp_params_discrete_costs=[elem[::-1] for elem in p.participant.exp_params_discrete_costs] #use this to select cost round randomly p.participant.cost_round=random.choice(list(range(0, len(p.participant.exp_params_discrete_costs)))) #use this to select cost round randomly from particular list #p.participant.cost_round=random.choice([3, 9]) p.participant.risk=[1+i/100 for i in list(range(25, 75, 5))] random.shuffle(p.participant.risk) p.participant.payoff_part=random.choice([1, 2]) if p.participant.payoff_part==1: p.participant.payoff_round=random.choice([1, 2]) p.participant.head_or_tail=random.choice([1, 2]) else: p.participant.payoff_round=random.choice(list(range(1, 11))) p.participant.head_or_tail=random.choice([1, 2]) p.participant.temp_payoff=0 class Group(BaseGroup): pass class Player(BasePlayer): prolific_id=models.StringField() cost_round=models.IntegerField() n_correct=models.IntegerField() quiz_1=models.IntegerField(widget=widgets.RadioSelect) quiz_2=models.IntegerField(widget=widgets.RadioSelect) quiz_3=models.IntegerField(widget=widgets.RadioSelect) risk_option=models.FloatField() risk_1=models.IntegerField(widget=widgets.RadioSelect) effort=models.IntegerField(widget=widgets.RadioSelect, choices=[ [0, 'College A'], [1, 'College B'], [2, 'College C'], [3, 'College D'], [4, 'College E'], [5, 'College F'], [6, 'College G'], [7, 'College H'], [8, 'College I'], [9, 'College J'], ]) reasoning=models.LongStringField() q_age=models.IntegerField(min=1, max=120) q_gender=models.IntegerField(widget=widgets.RadioSelect, choices=[ [1, "Male"], [2, "Female"], [3, "Other"]]) q_6_confusing=models.FloatField(blank=True) q_7_feedback=models.LongStringField(blank=True) def risk_1_choices(player): choices=[ [0, 'Fixed amount of $'+str(player.participant.risk[0])], [1, 'Receiving $1 or $2 with equal chance of each.'], ] return choices def quiz_1_choices(player): if player.participant.pooling_first==0: if player.participant.rounds[2]==1: pooling=0 else: pooling=1 else: if player.participant.rounds[2]==1: pooling=1 else: pooling=0 if pooling == 0: choices=[ [1, 'College A'], [2, 'College B'], [3, 'College C'], [4, 'College D'], [5, 'College E'], [6, 'College F'], [7, 'College G'], [0, 'College H'], [8, 'College I'], [9, 'College J'], ] elif pooling == 1: choices=[ [1, 'College A'], [2, 'College B'], [3, 'College C'], [4, 'College D'], [5, 'College E'], [0, 'College F'], [6, 'College G'], [7, 'College H'], [8, 'College I'], [9, 'College J'], ] #random.shuffle(choices) return choices def quiz_2_choices(player): if player.participant.pooling_first==0: if player.participant.rounds[2]==1: pooling=0 else: pooling=1 else: if player.participant.rounds[2]==1: pooling=1 else: pooling=0 if pooling == 0: choices=[ [1, '0'], [2, '1'], [3, '5'], [4, '8'], [5, '30'], [6, '40'], [0, '50'], [7, '65'], [8, '85'], [9, '99'], ] elif pooling == 1: choices=[ [1, '0'], [2, '30'], [3, '40'], [0, '50'], [4, '65'], [5, '85'], [6, '99'], ] #random.shuffle(choices) return choices def quiz_3_choices(player): if player.participant.pooling_first==0: if player.participant.rounds[2]==1: pooling=0 else: pooling=1 else: if player.participant.rounds[2]==1: pooling=1 else: pooling=0 if pooling == 0: choices=[ [0, '109'], [1, '110'], [2, '9'], [3, '10'] ] elif pooling == 1: choices=[ [0, '115'], [1, '100'], [2, '15'], [3, '0'] ] #random.shuffle(choices) return choices # PAGES class P0_consent(Page): @staticmethod def is_displayed(player): return [player.participant.rounds[0]<=Constants.part_0_length][0] form_model="player" @staticmethod def get_form_fields(player): if player.participant.rounds[0]==1: return ['prolific_id'] @staticmethod def vars_for_template(player): r_num=player.participant.rounds[0] return{ 'r_num': r_num, 'payoff': player.participant.exp_params_pooling_payoff, 'costs': player.participant.exp_params_pooling_costs, 'cost_round': player.participant.cost_round, 'payoff_d': player.participant.exp_params_discrete_payoff, 'costs_d': player.participant.exp_params_discrete_costs, 'payoff_p': player.participant.payoff_part, 'payoff_r': player.participant.payoff_round, } @staticmethod def before_next_page(player, timeout_happened): if player.participant.rounds[0]==1: player.cost_round=player.participant.cost_round if player.participant.rounds[0]==Constants.part_0_length: player.participant.rounds[1]=1 player.participant.rounds[0]+=1 class P1_inst(Page): @staticmethod def is_displayed(player): return [player.participant.rounds[1]<=Constants.part_1_length or player.participant.rounds[4]<=Constants.part_1_length_r2][0] @staticmethod def vars_for_template(player): pooling_first=player.participant.pooling_first r_num=player.participant.rounds[1] if player.participant.pooling_first==0: if player.participant.rounds[1]<=Constants.part_1_length: payoff_vec=[90, 80, 60, 55, 42, 30, 28, 17, 10, 5] cost=[99, 85, 65, 50, 40, 30, 8, 5, 1, 0] else: payoff_vec=[90, 80, 60, 55, 42, 30, 15, 15, 15, 15] cost=[99, 85, 65, 50, 40, 30, 0, 0, 0, 0] else: if player.participant.rounds[1]<=Constants.part_1_length: payoff_vec=[90, 80, 60, 55, 42, 30, 15, 15, 15, 15] cost=[99, 85, 65, 50, 40, 30, 0, 0, 0, 0] else: payoff_vec=[90, 80, 60, 55, 42, 30, 28, 17, 10, 5] cost=[99, 85, 65, 50, 40, 30, 8, 5, 1, 0] return{ 'r_num': r_num, 'strike': player.participant.strike, 'inst_num': r_num-1, 'payoff_vec' : payoff_vec, 'cost' : cost, 'pooling_first' : pooling_first, } @staticmethod def before_next_page(player, timeout_happened): if player.participant.rounds[1]==Constants.part_1_length: player.participant.rounds[2]=1 player.participant.rounds[1]+=1 if player.participant.rounds[4]==Constants.part_1_length_r2: player.participant.rounds[5]=1 player.participant.rounds[4]+=1 class P2_quiz(Page): @staticmethod def is_displayed(player): return [player.participant.rounds[2]<=Constants.part_2_length or player.participant.rounds[5]<=Constants.part_2_length_r2][0] form_model="player" form_fields=['quiz_1', 'quiz_2', 'quiz_3'] @staticmethod def vars_for_template(player): if player.participant.pooling_first==0: if player.participant.rounds[2]==1: r_num=1 payoff_vec=[90, 80, 60, 55, 42, 30, 28, 17, 10, 5] cost=[99, 85, 65, 50, 40, 30, 8, 5, 1, 0] else: r_num=2 payoff_vec=[90, 80, 60, 55, 42, 30, 15, 15, 15, 15] cost=[99, 85, 65, 50, 40, 30, 0, 0, 0, 0] else: if player.participant.rounds[2]==1: r_num=2 payoff_vec=[90, 80, 60, 55, 42, 30, 15, 15, 15, 15] cost=[99, 85, 65, 50, 40, 30, 0, 0, 0, 0] else: r_num=1 payoff_vec=[90, 80, 60, 55, 42, 30, 28, 17, 10, 5] cost=[99, 85, 65, 50, 40, 30, 8, 5, 1, 0] return{ 'r_num': r_num, 'corr':player.participant.quiz_n_correct, 'r1': player.participant.rounds[2], 'r2':player.participant.rounds[5], 'payoff_vec' : payoff_vec, 'cost' : cost, } @staticmethod def before_next_page(player, timeout_happened): player.participant.quiz_your_answers[0]=player.quiz_1 player.participant.quiz_your_answers[1]=player.quiz_2 player.participant.quiz_your_answers[2]=player.quiz_3 player.participant.correctly_answered=[player.participant.quiz_your_answers[i]==player.participant.correct_answers[i] for i in range(0, len(player.participant.correct_answers))] player.participant.quiz_n_correct=sum(player.participant.correctly_answered) player.n_correct=player.participant.quiz_n_correct class P2_quiz_feedback_detailed(Page): @staticmethod def is_displayed(player): return [player.participant.rounds[2]==Constants.part_2_length or player.participant.rounds[5]==Constants.part_2_length_r2][0] @staticmethod def vars_for_template(player): if player.participant.pooling_first==0: if player.participant.rounds[2]==1: r_num=1 payoff_vec=[90, 80, 60, 55, 42, 30, 28, 17, 10, 5] cost=[99, 85, 65, 50, 40, 30, 8, 5, 1, 0] else: r_num=2 payoff_vec=[90, 80, 60, 55, 42, 30, 15, 15, 15, 15] cost=[99, 85, 65, 50, 40, 30, 0, 0, 0, 0] else: if player.participant.rounds[2]==1: r_num=2 payoff_vec=[90, 80, 60, 55, 42, 30, 15, 15, 15, 15] cost=[99, 85, 65, 50, 40, 30, 0, 0, 0, 0] else: r_num=1 payoff_vec=[90, 80, 60, 55, 42, 30, 28, 17, 10, 5] cost=[99, 85, 65, 50, 40, 30, 8, 5, 1, 0] if r_num == 1: choices_1=[ [1, 'College A'], [2, 'College B'], [3, 'College C'], [4, 'College D'], [5, 'College E'], [6, 'College F'], [7, 'College G'], [0, 'College H'], [8, 'College I'], [9, 'College J'], ] elif r_num == 2: choices_1=[ [1, 'College A'], [2, 'College B'], [3, 'College C'], [4, 'College D'], [5, 'College E'], [0, 'College F'], [6, 'College G'], [7, 'College H'], [8, 'College I'], [9, 'College J'], ] #random.shuffle(choices_1) if r_num == 1: choices_2=[ [1, '0'], [2, '1'], [3, '5'], [4, '8'], [5, '30'], [6, '40'], [0, '50'], [7, '65'], [8, '85'], [9, '99'], ] elif r_num == 2: choices_2=[ [1, '0'], [2, '30'], [3, '40'], [0, '50'], [4, '65'], [5, '85'], [6, '99'], ] #random.shuffle(choices_2) if r_num == 1: choices_3=[ [0, '109'], [1, '110'], [2, '9'], [3, '10'] ] elif r_num == 2: choices_3=[ [0, '115'], [1, '100'], [2, '15'], [3, '0'] ] #random.shuffle(choices_3) return{ 'correct': player.participant.quiz_n_correct, 'strike': player.participant.strike, 'correctly_answered': player.participant.correctly_answered, 'your_answers': player.participant.quiz_your_answers, 'correct_answers': player.participant.correct_answers, 'choices_1': choices_1, 'choices_2': choices_2, 'choices_3': choices_3, 'r_num': r_num, 'payoff_vec' : payoff_vec, 'cost' : cost, } @staticmethod def before_next_page(player, timeout_happened): if player.participant.rounds[2]==Constants.part_2_length: if player.participant.quiz_n_correct==3: player.participant.rounds[3]=1 player.participant.rounds[2]+=1 player.participant.strike=0 else: if player.participant.strike==0: player.participant.rounds[1]=2 player.participant.rounds[2]=100 player.participant.quiz_n_correct=0 player.participant.strike=1 else: player.participant.rounds[2]=100 elif player.participant.rounds[5]==Constants.part_2_length_r2: if player.participant.quiz_n_correct==3: player.participant.rounds[6]=1 player.participant.rounds[5]+=1 else: if player.participant.strike==0: player.participant.rounds[4]=1 player.participant.rounds[5]=100 player.participant.quiz_n_correct=0 player.participant.strike=1 else: player.participant.rounds[5]=100 class P3_game(Page): @staticmethod def is_displayed(player): return [player.participant.rounds[3]<=Constants.part_3_length or player.participant.rounds[6]<=Constants.part_3_length_r2][0] form_model="player" form_fields=['effort'] @staticmethod def vars_for_template(player): if player.participant.rounds[3]<=Constants.part_3_length: round_number=1 elif player.participant.rounds[6]<=Constants.part_3_length_r2: round_number=2 if player.participant.pooling_first==0: if player.participant.rounds[3]==1: r_num=1 payoff_vec=player.participant.exp_params_discrete_payoff cost=player.participant.exp_params_discrete_costs[player.participant.cost_round] else: r_num=2 payoff_vec=player.participant.exp_params_pooling_payoff cost=player.participant.exp_params_pooling_costs[player.participant.cost_round] else: if player.participant.rounds[3]==1: r_num=2 payoff_vec=player.participant.exp_params_pooling_payoff cost=player.participant.exp_params_pooling_costs[player.participant.cost_round] else: r_num=1 payoff_vec=player.participant.exp_params_discrete_payoff cost=player.participant.exp_params_discrete_costs[player.participant.cost_round] net_payoff=[100-b+a for a, b in zip(payoff_vec, cost)] valid_investment=[100-b for b in cost] return{ 'r_num' : r_num, 'payoff_vec' : payoff_vec, 'cost' : cost, 'net_payoff' : net_payoff, 'round_number': round_number, 'valid_investment': valid_investment, } def before_next_page(player, timeout_happened): if player.participant.payoff_part==1: if player.participant.pooling_first==0: if player.participant.rounds[3]==1: r_num=1 payoff_vec=player.participant.exp_params_discrete_payoff cost=player.participant.exp_params_discrete_costs[player.participant.cost_round] else: r_num=2 payoff_vec=player.participant.exp_params_pooling_payoff cost=player.participant.exp_params_pooling_costs[player.participant.cost_round] else: if player.participant.rounds[3]==1: r_num=2 payoff_vec=player.participant.exp_params_pooling_payoff cost=player.participant.exp_params_pooling_costs[player.participant.cost_round] else: r_num=1 payoff_vec=player.participant.exp_params_discrete_payoff cost=player.participant.exp_params_discrete_costs[player.participant.cost_round] net_payoff=[100-b+a for a, b in zip(payoff_vec, cost)] if player.participant.payoff_round==r_num: player.participant.temp_payoff=net_payoff[player.effort]/100*2 class P3_game_feedback(Page): @staticmethod def is_displayed(player): return [player.participant.rounds[3]<=Constants.part_3_length or player.participant.rounds[6]<=Constants.part_3_length_r2][0] @staticmethod def vars_for_template(player): if player.participant.pooling_first==0: if player.participant.rounds[3]==1: r_num=1 payoff_vec=player.participant.exp_params_discrete_payoff cost=player.participant.exp_params_discrete_costs[player.participant.cost_round] else: r_num=2 payoff_vec=player.participant.exp_params_pooling_payoff cost=player.participant.exp_params_pooling_costs[player.participant.cost_round] else: if player.participant.rounds[3]==1: r_num=2 payoff_vec=player.participant.exp_params_pooling_payoff cost=player.participant.exp_params_pooling_costs[player.participant.cost_round] else: r_num=1 payoff_vec=player.participant.exp_params_discrete_payoff cost=player.participant.exp_params_discrete_costs[player.participant.cost_round] if player.participant.rounds[3]==1: round_number=1 else: round_number=2 net_payoff=[100 - b + a for a, b in zip(payoff_vec, cost)] return{ 'r_num': r_num, 'payoff': player.participant.temp_payoff, 'round_number': round_number, 'payoff_vec' : payoff_vec, 'cost' : cost, 'round_payoff' : net_payoff[player.effort], 'round_school': ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K'][player.effort] } @staticmethod def before_next_page(player, timeout_happened): if player.participant.rounds[3]==Constants.part_3_length: player.participant.rounds[4]=1 player.participant.rounds[3]+=1 if player.participant.rounds[6]==Constants.part_3_length_r2: player.participant.rounds[7]=1 player.participant.rounds[6]+=1 class P4_post(Page): @staticmethod def is_displayed(player): return [player.participant.rounds[7]<=Constants.part_4_length][0] form_model="player" @staticmethod def get_form_fields(player): if player.participant.rounds[7]>=2 and player.participant.rounds[7]=2 and player.participant.rounds[7]=2 and player.participant.rounds[7]