from otree.api import * c = cu doc = '' class C(BaseConstants): NAME_IN_URL = 'experiment_t1_e2' PLAYERS_PER_GROUP = None NUM_ROUNDS = 30 MY_CONSTANT = 0 LEFT_ARM_PRIZE = 20 RIGHT_ARM_PRIZE = 50 class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): choice = models.StringField() is_winner = models.BooleanField() payoff_this_round = models.CurrencyField(initial=0) is_optimal = models.BooleanField() attention_passed = models.BooleanField() bandit_earnings = models.IntegerField() cum_payoff = models.CurrencyField() decision_rt = models.FloatField() p2_q1_rules = models.IntegerField(choices=[[1, '1'], [2, '2'], [3, '3'], [4, '4'], [5, '5'], [6, '6'], [7, '7']], label='1. I understood the rules of this task.', widget=widgets.RadioSelectHorizontal) p2_q2_tickets = models.IntegerField(choices=[[1, '1'], [2, '2'], [3, '3'], [4, '4'], [5, '5'], [6, '6'], [7, '7']], label='2. I understood how points in this task translated into lottery tickets.', widget=widgets.RadioSelectHorizontal) p2_q4_engaging = models.IntegerField(choices=[[1, '1'], [2, '2'], [3, '3'], [4, '4'], [5, '5'], [6, '6'], [7, '7']], label='3. I found this task engaging.', widget=widgets.RadioSelectHorizontal) p2_q6_focused = models.IntegerField(choices=[[1, '1'], [2, '2'], [3, '3'], [4, '4'], [5, '5'], [6, '6'], [7, '7']], label='4. I was able to stay focused during this task.', widget=widgets.RadioSelectHorizontal) p2_q7_repetitive = models.IntegerField(choices=[[1, '1'], [2, '2'], [3, '3'], [4, '4'], [5, '5'], [6, '6'], [7, '7']], label='5. This task felt repetitive.', widget=widgets.RadioSelectHorizontal) p2_q9_identify_best = models.IntegerField(choices=[[1, '1'], [2, '2'], [3, '3'], [4, '4'], [5, '5'], [6, '6'], [7, '7']], label='6. I actively tried to identify which option performed best.', widget=widgets.RadioSelectHorizontal) cq1 = models.StringField(choices=[['no lottery tickets', 'no lottery tickets'], ['1 lottery ticket', '1 lottery ticket'], ['5 lottery tickets', '5 lottery tickets'], ['I am not sure', 'I am not sure']], label='1. In Phase 2, each point earned gives you:', widget=widgets.RadioSelect) cq2 = models.StringField(choices=[['fixed', 'fixed'], ['changing every round', 'changing every round'], ['chosen by the participant', 'chosen by the participant'], ['I am not sure', 'I am not sure']], label='2. Within Phase 2, the probabilities associated with the options are:', widget=widgets.RadioSelect) cq3 = models.StringField(choices=[['The same as in Phase 1', 'The same as in Phase 1'], ['Different from Phase 1', 'Different from Phase 1'], ['Chosen by the participant', 'Chosen by the participant'], ['I am not sure', 'I am not sure']], label='3. In Phase 2, the option reward patterns are:', widget=widgets.RadioSelect) cq_fails = models.IntegerField(initial=0) video_game_freq = models.StringField() game_familiarity = models.IntegerField() exp_familiarity = models.IntegerField() age = models.IntegerField() gender = models.StringField() study_level = models.StringField() field_of_study = models.StringField(blank=True) coursework = models.StringField() prev_econ_exp = models.StringField() tech_issues = models.LongStringField(blank=True) enter_draw = models.StringField() email = models.StringField(blank=True) p2_belief_alpha = models.IntegerField(max=100, min=0) p2_belief_beta = models.IntegerField(max=100, min=0) p2_belief_gamma = models.IntegerField(max=100, min=0) comments = models.LongStringField(blank=True) monthly_budget = models.StringField(blank=True) class Introduction(Page): form_model = 'player' form_fields = ['cq_fails'] @staticmethod def is_displayed(player: Player): return player.participant.vars.get('group') == 'Group 2' and player.round_number == 1 class Decision(Page): form_model = 'player' form_fields = ['choice', 'decision_rt'] @staticmethod def is_displayed(player: Player): return player.participant.vars.get('group') == 'Group 2' @staticmethod def vars_for_template(player: Player): if 'treatment' not in player.participant.vars: if player.id_in_group % 2 == 1: player.participant.vars['treatment'] = 'A' else: player.participant.vars['treatment'] = 'B' last_earned = None if player.round_number > 1: prev_player = player.in_round(player.round_number - 1) if prev_player.bandit_earnings is not None: last_earned = prev_player.bandit_earnings return { 'last_earned': last_earned } @staticmethod def before_next_page(player: Player, timeout_happened): import random if player.choice is not None: p_left, prize_left = 0.5, 22 p_mid, prize_mid = 0.35, 28 p_right, prize_right = 0.65, 15 #choice and prize if player.choice == 'left': prob = p_left actual_prize = prize_left elif player.choice == 'mid': prob = p_mid actual_prize = prize_mid else: # 'right' prob = p_right actual_prize = prize_right # cal opt choice ev_left = p_left * prize_left ev_mid = p_mid * prize_mid ev_right = p_right * prize_right max_ev = max(ev_left, ev_mid, ev_right) if player.choice == 'left' and ev_left == max_ev: player.is_optimal = True elif player.choice == 'mid' and ev_mid == max_ev: player.is_optimal = True elif player.choice == 'right' and ev_right == max_ev: player.is_optimal = True else: player.is_optimal = False # bandit if random.random() < prob: player.is_winner = True player.payoff = actual_prize player.bandit_earnings = actual_prize else: player.is_winner = False player.payoff = 0 player.bandit_earnings = 0 # payoff if player.round_number == 1: player.cum_payoff = player.payoff else: prev_cum = player.in_round(player.round_number - 1).cum_payoff player.cum_payoff = (prev_cum if prev_cum else 0) + player.payoff if player.round_number == 30: player.participant.vars['task2_total_bank'] = int(player.cum_payoff) class Results(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): return player.participant.vars.get('group') == 'Group 2' and player.round_number == C.NUM_ROUNDS @staticmethod def vars_for_template(player: Player): all_players = player.in_all_rounds() total_wins = sum([1 for p in all_players if p.is_winner == True]) total_earned = int(player.cum_payoff) return { 'total_wins': total_wins, 'total_earned': total_earned, } class Questionnaire(Page): form_model = 'player' form_fields = ['video_game_freq', 'age', 'gender', 'study_level', 'field_of_study', 'coursework', 'prev_econ_exp', 'tech_issues', 'p2_q1_rules', 'p2_q2_tickets', 'p2_q4_engaging', 'p2_q6_focused', 'p2_q7_repetitive', 'p2_q9_identify_best', 'monthly_budget', 'p2_belief_alpha', 'p2_belief_beta', 'p2_belief_gamma', 'comments'] @staticmethod def is_displayed(player: Player): return player.participant.vars.get('group') == 'Group 2' and player.round_number == C.NUM_ROUNDS page_sequence = [Introduction, Decision, Results, Questionnaire]