from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) from Multiple_Price_List.config import * import random from random import randrange # ---------------------------------------------------------------------------------------------------------------- # # *** CLASS CONSTANTS *** # # ---------------------------------------------------------------------------------------------------------------- # class Constants(BaseConstants): # ------------------------------------------------------------------------------------------------------------ # # --- oTree Settings (Don't Modify) --- # # ------------------------------------------------------------------------------------------------------------ # name_in_url = 'Ambiguity_New' players_per_group = None num_rounds = 1 # ---------------------------------------------------------------------------------------------------------------- # # --- Task-specific Settings --- # # ---------------------------------------------------------------------------------------------------------------- # # Number of choices between "lottery A" and "lottery B" # note that the number of choices determines the probabilities of high and low outcomes of lotteries "A" and "B" # for , the probability of outcome "high" is 1/X for the first choice, 2/X for the second, etc. num_choices = 16 # make sure this number is not larger than 20!!! # set enforce consistency to True to ensure that subjects cannot switch mutliple times enforce_consistency = True # Define indices index_rounds = [j for j in range(1, num_rounds + 1)] index_choices = [j for j in range(1, num_choices + 1)] # Define payoffs for option A high_a = 30 low_a = 0 # Define starting payoffs for option B high_b = 47 low_b = 0 #determine distribution of green and blue balls in Urn B green = randrange(1, 101) blue = 100 - green class Subsession(BaseSubsession): def creating_session(self): # define list with option_b choices increase = 2 option_b_hi = [] option_b_lo = [] for i in Constants.index_choices: option_hi = c(Constants.high_b - (i * increase)) option_lo = c(Constants.low_b) option_b_hi.append(option_hi) option_b_lo.append(option_lo) for p in self.get_players(): # create list corresponding to form_field variables including all choices p.participant.vars['success_color'] = 'success_color' p.participant.vars['color_choice'] = None form_fields = ['choice_' + str(k) for k in Constants.index_choices] p.participant.vars['form_fields_ambig'] = form_fields # initiate list for choices made - these will be filled with the entries from form-fields later p.participant.vars['ambig_choices_made'] = [None for j in range(1, Constants.num_choices + 1)] p.participant.vars['mpl'] = [option_b_hi, option_b_lo, form_fields,] class Group(BaseGroup): pass class Player(BasePlayer): #------------------------------------------------------------------------------------------------------------------ locals()['success_color'] = models.StringField() def set_success_color(self): if self.participant.vars['color_choice'] == 'Green': self.success_color = 'Green' else: self.success_color = 'Blue' # ------------------------------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------------------------------ # add model fields to class player for j in range(1, Constants.num_choices + 1): locals()['choice_' + str(j)] = models.StringField() del j #------------------------------------------------------------------------------------------------------------------ # determine consistency inconsistent = models.IntegerField() def set_consistency(self): n = Constants.num_choices # replace A's by 1's and B's by 0's choices_coded = [None for j in range(1, n + 1)] for j in Constants.index_choices: if self.participant.vars['ambig_choices_made'][j-1] == "A": choice = 0 choices_coded[j - 1] = choice else: choice = 1 choices_coded[j - 1] = choice # save choices self.participant.vars['ambig_choices_coded'] = choices_coded # check for multiple switching points for j in range(1, n): self.inconsistent = 1 if choices_coded[j] > choices_coded[j - 1] else 0 if self.inconsistent == 1: break # ------------------------------------------------------------------------------------------------------------------ # determine switching row switching_row = models.IntegerField(initial=0) def set_switching_row(self): # set switching point to row number of first 'A' choice self.switching_row = sum(self.participant.vars['ambig_choices_coded']) + 1 # ------------------------------------------------------------------------------------------------------------------ # set player's payoff selected = models.IntegerField() # indicates whether a player is selected for payment or not index_to_pay = models.IntegerField() option_to_pay = models.StringField() choice_to_pay = models.StringField() random_draw = models.IntegerField() green = models.IntegerField() blue = models.IntegerField() ball_color = models.StringField() def set_payoffs(self): # determine whether subject is selected for payment random_number = randrange(1, 21) if random_number == 1: self.selected = 1 else: self.selected = 0 # set choice_to_pay to participant.vars['time_choice_to_pay'] determined in creating_session random_number = randrange(1, Constants.num_choices + 1) self.choice_to_pay = 'choice_' + str(random_number) if self.selected == 1 else None self.index_to_pay = random_number if self.selected == 1 else None # find out whether option "A" or "B" was chosen for the choice to pay self.option_to_pay = getattr(self, self.choice_to_pay) if self.selected == 1 else None # determine payoff self.random_draw = randrange(0, 101) self.green = Constants.green self.blue = Constants.blue if self.selected == 1: if self.option_to_pay == 'A': if self.random_draw <= 50: self.ball_color = 'Green' if self.ball_color == self.success_color: self.payoff = c(Constants.high_a) else: self.payoff = c(Constants.low_a) else: self.ball_color = 'Blue' if self.ball_color == self.success_color: self.payoff = c(Constants.high_a) else: self.payoff = c(Constants.low_a) else: if self.random_draw <= self.green: self.ball_color = 'Green' if self.ball_color == self.success_color: self.payoff = self.participant.vars['mpl'][0][self.index_to_pay - 1] else: self.payoff = self.participant.vars['mpl'][1][self.index_to_pay - 1] else: self.ball_color = 'Blue' if self.ball_color == self.success_color: self.payoff = self.participant.vars['mpl'][0][self.index_to_pay - 1] else: self.payoff = self.participant.vars['mpl'][1][self.index_to_pay - 1] else: self.payoff = 0 self.participant.vars['payoff_ambig'] = self.payoff