from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import random author = 'Thomas Graeber' doc = """ Subjective uncertainty in risk """ class Constants(BaseConstants): name_in_url = 'within_subject_risk' players_per_group = None decisions = [ # { # 'name': 'example_1', # 'y_list': [20], # 'lottery': [(70, 20), (30, 5)], # 'type': 'list', # }, # { # 'name': 'example_2', # 'y_list': [15], # 'lottery': [(60, 15), (40, 5)], # 'type': 'list', # }, { 'name': 'p_90_gains', 'y_list': [15, 20, 25], 'lottery': [(90, 'y'), (10, 0)], 'type': 'list', }, { 'name': 'p_5_gains', 'y_list': [15, 20, 25], 'lottery': [(5, 'y'), (95, 0)], 'type': 'list', }, { 'name': 'p_50_gains', 'y_list': [15, 20, 25], 'lottery': [(50, 'y'), (50, 0)], 'type': 'list', }, { 'name': 'p_1_gains', 'y_list': [15, 20, 25], 'lottery': [(1, 'y'), (99, 0)], 'type': 'list', }, { 'name': 'p_95_gains', 'y_list': [15, 20, 25], 'lottery': [(95, 'y'), (5, 0)], 'type': 'list', }, { 'name': 'p_90_losses', 'y_list': [-15, -20, -25], 'lottery': [(90, 'y'), (10, 0)], 'type': 'list', }, { 'name': 'p_5_losses', 'y_list': [-15, -20, -25], 'lottery': [(5, 'y'), (95, 0)], 'type': 'list', }, { 'name': 'p_50_losses', 'y_list': [-15, -20, -25], 'lottery': [(50, 'y'), (50, 0)], 'type': 'list', }, { 'name': 'p_95_losses', 'y_list': [-15, -20, -25], 'lottery': [(95, 'y'), (5, 0)], 'type': 'list', }, { 'name': 'p_1_losses', 'y_list': [-15, -20, -25], 'lottery': [(1, 'y'), (99, 0)], 'type': 'list', }, ] num_rounds = len(decisions) class Subsession(BaseSubsession): def creating_session(self): if self.round_number == 1: for p in self.get_players(): p.participant.vars['failed_comprehension'] = False p.participant.vars['condition_load'] = random.choice([True, False]) p.condition_load = p.participant.vars['condition_load'] p.participant.vars['lists_paying_round'] = random.randint(1, Constants.num_rounds) p.losses_first = random.choice([True, False]) # p.participant.vars['list_sequence'] = random.sample(range(Constants.num_rounds), Constants.num_rounds) # Lists in part 1 if not p.losses_first: p.participant.vars['list_sequence'] = random.sample(range(5), 5) p.participant.vars['list_sequence'].extend(random.sample(range(5, 10), 5)) else: p.participant.vars['list_sequence'] = random.sample(range(5, 10), 5) p.participant.vars['list_sequence'].extend(random.sample(range(5), 5)) for p in self.get_players(): p.set_current_task_number() if p.round_number == p.participant.vars['lists_paying_round']: p.on_paying_round = True class Group(BaseGroup): pass class Player(BasePlayer): task_number = models.IntegerField() task_identifier = models.StringField() switching_point_1 = models.FloatField() probability = models.IntegerField() condition_load = models.BooleanField() # switching_point_2 = models.FloatField() on_paying_round = models.BooleanField(initial=False) lottery_amount = models.IntegerField() endowment = models.FloatField() # Field which is 0 if always Option B, 1 if switching point, 2 if never option B indicator_never_always_switcher = models.IntegerField() switching_point = models.FloatField() lottery_identifier = models.StringField() confidence = models.FloatField() losses_first = models.BooleanField() load_sum = models.IntegerField(initial=0) load_guess = models.IntegerField(min=0, max=100, blank=False, label="Enter the sum of all red numbers that were flashed at the top while you made your choices on the previous screen:") failed_comprehension = models.BooleanField(initial=False) qn_lottery_got_wrong = models.BooleanField(initial=False) qn_list_got_wrong = models.BooleanField(initial=False) qn_confidence_got_wrong = models.BooleanField(initial=False) qn_lottery = models.IntegerField( choices=[ [0, 'It is possible that I get paid both $15 and $5, i.e., I may receive a total amount of $20 from this lottery.'], [1, 'I receive either $15 or $5 from this lottery.'], [0, 'It is possible that I receive no money from this lottery.'], ], widget=widgets.RadioSelect, blank=False, label="" ) qn_list = models.IntegerField( choices=[ [0, 'This person indicated that the lottery is worth more to them than $9.'], [0, 'This person indicated that the lottery is worth between $3 and $7 to them. '], [1, 'This person indicated that the lottery is worth between $8 and $9 to them.'], ], widget=widgets.RadioSelect, blank=False, label="" ) qn_confidence = models.FloatField( blank=False, label="" ) def set_current_task_number(self): setattr(self, 'task_number', self.participant.vars['list_sequence'][self.round_number-1]) setattr(self, 'lottery_amount', random.choice(Constants.decisions[self.task_number]['y_list'])) setattr(self, 'probability', Constants.decisions[self.task_number]['lottery'][0][0]) setattr(self, 'task_identifier', Constants.decisions[self.task_number]['name']) if self.lottery_amount > 0: setattr(self, 'endowment', 0) else: setattr(self, 'endowment', abs(self.lottery_amount)) def frange(self, start, stop, step): i = start while i < stop: if isinstance(i, int): yield i else: yield round(i, 2) i += step def right_side_amounts1(self): if self.lottery_amount > 0: lst = self.frange(0, self.lottery_amount + 1, 1) else: lst = self.frange(self.lottery_amount, 1, 1) return list(enumerate(lst, 1)) def current_lottery(self): lott = Constants.decisions[self.task_number]['lottery'] lott_new = [] for x, y in lott: if y == 'y': lott_new.append((x, self.lottery_amount)) else: lott_new.append((x, y)) return lott_new def rocl_range(self): return Constants.decisions[self.task_number]['rocl_range'] def range_bounds(self): if self.lottery_amount > 0: bounds = [0, self.lottery_amount] elif self.lottery_amount < 0: bounds = [self.lottery_amount, 0] return bounds def table_length1(self): return abs(self.lottery_amount) + 1 def set_switching_point_and_indicator(self): if self.lottery_amount > 0: if self.switching_point == 9999: self.switching_point = self.lottery_amount + 1 self.indicator_never_always_switcher = 2 elif self.switching_point == 0: self.indicator_never_always_switcher = 0 else: self.indicator_never_always_switcher = 1 elif self.lottery_amount < 0: if self.switching_point == 9999: self.switching_point = 1 self.indicator_never_always_switcher = 2 elif self.switching_point == self.lottery_amount: self.indicator_never_always_switcher = 0 else: self.indicator_never_always_switcher = 1 def set_switching_point_and_indicator_1(self): if self.switching_point_1 == 9999: self.switching_point_1 = Constants.decisions[self.task_number]['safe_range_max'] + Constants.decisions[self.task_number]['step_size'] self.indicator_never_always_switcher = 2 elif self.switching_point_1 == Constants.decisions[self.task_number]['safe_range_min']: self.indicator_never_always_switcher = 0 else: self.indicator_never_always_switcher = 1 self.switching_point = self.switching_point_1 def set_switching_point_and_indicator_2(self): if self.switching_point_2 == 9999: self.switching_point_2 = self.switching_point_1 self.switching_point = self.switching_point_2 def set_payoffs(self): random_right_side_amount = int(random.choice(self.right_side_amounts1()[1])) if random_right_side_amount >= self.switching_point: possible_payoff = c(random_right_side_amount) else: possible_payoff = c(3) if 'possible_payoffs' in self.participant.vars: self.participant.vars['possible_payoffs'].append(possible_payoff) else: self.participant.vars['possible_payoffs'] = [possible_payoff]