from otree.api import * c = cu doc = '' class C(BaseConstants): NAME_IN_URL = 'experiment_t1_e1' 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() 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) 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) 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) 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) 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) 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 this study, 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 a task, the probabilities associated with the options are:', widget=widgets.RadioSelect) cq3 = models.StringField(choices=[['a higher chance of winning the prize draw', 'a higher chance of winning the prize draw'], ['a lower chance of winning the prize draw', 'a lower chance of winning the prize draw'], ['no difference in the chance of winning', 'no difference in the chance of winning'], ['I am not sure', 'I am not sure']], label='3. Earning more lottery tickets means:', widget=widgets.RadioSelect) cq_fails = models.IntegerField(initial=0) p1_belief_alpha = models.IntegerField(max=100, min=0) p1_belief_beta = models.IntegerField(max=100, min=0) p1_belief_gamma = models.IntegerField(max=100, min=0) class Introduction(Page): form_model = 'player' form_fields = ['cq_fails'] @staticmethod def is_displayed(player: Player): return player.participant.vars.get('group') == 'Group 1' 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 1' @staticmethod def vars_for_template(player: Player): 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.8, 10 p_mid, prize_mid = 0.5, 16 p_right, prize_right = 0.4, 20 #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['task1_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 1' 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 = ['q1_rules', 'q2_tickets', 'q4_engaging', 'q6_focused', 'q7_repetitive', 'q9_identify_best', 'p1_belief_alpha', 'p1_belief_beta', 'p1_belief_gamma'] @staticmethod def is_displayed(player: Player): return player.participant.vars.get('group') == 'Group 1' and player.round_number == C.NUM_ROUNDS page_sequence = [Introduction, Decision, Results, Questionnaire]