from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import random from random import randrange author = ' Sunduz Divle ' doc = """ Multiple price list task measuring the demand for autonomy as proposed by Ertac et al. (2019), Journal of Economic Psychology. Codes are modifed from 'Felix Holzmeister's mpl codes. """ class Constants(BaseConstants): lottery_a_hi = "Benim cevaplarım eşleştiğim kişi için de geçerli olsun. " lottery_b_hi = "Herkesin kendi cevabının geçerli olması için " lottery_a_lo = "Benim cevaplarımın eşleştiğim kişi için de geçerli olması için " lottery_b_lo = "Herkesin kendi cevabı geçerli olsun. " num_choices = 5 endowment = c(8) # include 'certain' choice (** only applies if **) # if , the binary choice with probability of the outcome "high" being equal to 1 is included # if , the list only contains ( - 1) binary decision pairs # note, however, that the probability of outcome "high" is set by , not ( - 1), though # i.e., if , the last choice implies a probability of (X - 1)/X (given ) certain_choice = True # ---------------------------------------------------------------------------------------------------------------- # # --- Overall Settings and Appearance --- # # ---------------------------------------------------------------------------------------------------------------- # # show each lottery pair on a separate page # if , each single binary choice between lottery "A" and "B" is shown on a separate page # if , all choices are displayed in a table on one page one_choice_per_page = True # order choices between lottery pairs randomly # if , the ordering of binary decisions is randomized for display # if , binary choices are listed in ascending order of the probability of the "high" outcome random_order = False # enforce consistency, i.e. only allow for a single switching point # if , all options "A" above a selected option "A" are automatically selected # similarly, all options "B" below a selected option "B" are automatically checked, implying consistent choices # note that is only implemented if and enforce_consistency = False # depict probabilities as percentage numbers # if , the probability of outcome "high" will be displayed as percentage number # if , the probabilities will be displayed as fractions, i.e. "1/X", "2/X", etc. percentage = False # show small pie charts for each lottery # if , a pie chart depicting the probabilities of outcomes is rendered next to each lottery # if , no graphical representation of probabilities is displayed small_pies = False # display lotteries in terms of large pie charts # if , lotteries are depicted as pie charts; if lotteries are list items # note that only affects the task's appearance if large_pies = False # show progress bar # if and , a progress bar is rendered # if , no information with respect to the advance within the task is displayed # the progress bar graphically depicts the advance within the task in terms of how many decision have been made # further, information in terms of "page x out of " (with x denoting the current choice) is provided progress_bar = True # show instructions page # if , a separate template "Instructions.html" is rendered prior to the task # if , the task starts immediately (e.g. in case of printed instructions) instructions = True # show results page summarizing the task's outcome including payoff information # if , a separate page containing all relevant information is displayed after finishing the task # if , the template "Decision.html" will not be rendered results = False # ---------------------------------------------------------------------------------------------------------------- # # --- oTree Settings (Don't Modify) --- # # ---------------------------------------------------------------------------------------------------------------- # name_in_url = 'mpl_responsbility' players_per_group = 2 if one_choice_per_page: if certain_choice: num_rounds = num_choices else: num_rounds = num_choices - 1 else: num_rounds = 1 class Subsession(BaseSubsession): def creating_session(self): if self.round_number == 1: n = Constants.num_choices for p in self.get_players(): # create list of lottery indices # ---------------------------------------------------------------------------------------------------- indices = [j for j in range(1, n)] indices.append(n) if Constants.certain_choice else None # create list of compensations # ---------------------------------------------------------------------------------------------------- if Constants.percentage: neg_payments = [ "bana verilen 5 TL'den" + "{0:.2f}".format( k ) + " TL vermeyi kabul ederim. " for k in indices ] pos_payments = [ "bana verilen 5 TL'den " + "{0:.2f}".format(k) + " TL vermeyi kabul ederim. " for k in indices ] else: neg_payments = [ "bana verilen 5 TL'den " + str(k) + " TL vermeyi kabul ederim. " for k in indices ] pos_payments = [ "bana verilen 5 TL'den " + str(k) + " TL vermeyi kabul ederim. " for k in indices ] compensations_n = neg_payments compensations_p = pos_payments # create list corresponding to form_field variables including all choices # ---------------------------------------------------------------------------------------------------- form_fields = ['choice_' + str(k) for k in indices] # create list of choices # ---------------------------------------------------------------------------------------------------- p.participant.vars['mplr_choices_n'] = list( zip(indices, form_fields, compensations_n) ) p.participant.vars['mplr_choices_p'] = list( zip(indices, form_fields, compensations_p) ) # randomly determine index/choice of binary decision to pay # ---------------------------------------------------------------------------------------------------- p.participant.vars['mplr_index_to_pay'] = random.choice(indices) p.participant.vars['mplr_choice_to_pay'] = 'choice_' + str(p.participant.vars['mplr_index_to_pay']) # randomize order of lotteries if # ---------------------------------------------------------------------------------------------------- if Constants.random_order: random.shuffle(p.participant.vars['mplr_choices_n']) # initiate list for choices made # ---------------------------------------------------------------------------------------------------- p.participant.vars['mplr_choices_made'] = [None for j in range(1, n + 1)] # generate random switching point for PlayerBot in tests.py # -------------------------------------------------------------------------------------------------------- for participant in self.session.get_participants(): participant.vars['mplr_switching_point'] = random.randint(1, n) class Group(BaseGroup): def set_payments(self): players = self.get_players() player_implemented = self.get_player_by_id(1) player_not_implemented = self.get_player_by_id(2) if player_implemented.option_to_pay == 'A': if player_implemented.first_resp_choice == 0 or player_implemented.second_resp_choice == 0: player_implemented.additional_payoff = 5- player_implemented.participant.vars['mplr_index_to_pay'] player_implemented.payoff_mplr = player_implemented.participant.vars['payoff_rat_ind'] + player_implemented.additional_payoff player_not_implemented.payoff_mplr = player_not_implemented.participant.vars['payoff_others_rat_ind'] + 5 else: player_implemented.payoff_mplr = player_implemented.participant.vars['payoff_rat_ind'] + 5 player_not_implemented.payoff_mplr = player_not_implemented.participant.vars['payoff_others_rat_ind'] + 5 else: if player_implemented.first_resp_choice == 0 or player_implemented.second_resp_choice == 0: player_implemented.payoff_mplr = player_implemented.participant.vars['payoff_rat_ind'] + 5 player_not_implemented.payoff_mplr = player_not_implemented.participant.vars['payoff_rat_ind'] + 5 else: player_implemented.additional_payoff = 5- player_implemented.participant.vars['mplr_index_to_pay'] player_implemented.payoff_mplr = player_implemented.participant.vars['payoff_rat_ind'] + player_implemented.additional_payoff player_not_implemented.payoff_mplr = player_not_implemented.participant.vars['payoff_rat_ind'] + 5 for p in players: p.participant.vars['payoff_mplr'] = p.payoff_mplr print("Player:", p.id_in_group, "payoff mpl_responsibility", p.payoff_mplr) class Player(BasePlayer): payoff_mplr = models.IntegerField() additional_payoff = models.IntegerField(initial=0) first_resp_choice = models.IntegerField(label='7. Kazancınızın nasıl hesaplanmasını istersiniz?', choices=[ [0, "A: Benim cevaplarım eşleştiğim kişi için de geçerli olsun. "], [1, "B: Herkesin kendi cevabı geçerli olsun."], [2, "C: Fark etmez"], ], widget = widgets.RadioSelectHorizontal ) second_resp_choice = models.IntegerField(label='Kazancınızın nasıl hesaplanmasını istersiniz?', choices=[ [0, "A: Benim cevaplarım eşleştiğim kişi için de geçerli olsun. "], [1, "B: Herkesin kendi cevabının geçerli olması için bana verilen 5 TL'den 1 TL veririm."], ], widget = widgets.RadioSelectHorizontal ) if Constants.certain_choice: for j in range(1, Constants.num_choices + 1): locals()['choice_' + str(j)] = models.StringField() del j else: for j in range(1, Constants.num_choices): locals()['choice_' + str(j)] = models.StringField() del j random_draw = models.IntegerField() choice_to_pay = models.StringField() option_to_pay = models.StringField() inconsistent = models.IntegerField() switching_row = models.IntegerField() # set player's payoff def set_payoffs(self): # random draw to determine whether to pay the "high" or "low" outcome of the randomly picked lottery # ------------------------------------------------------------------------------------------------------------ self.random_draw = randrange(1, len(self.participant.vars['mplr_choices_n'])) # set to participant.var['choice_to_pay'] determined creating_session # ------------------------------------------------------------------------------------------------------------ self.choice_to_pay = self.participant.vars['mplr_choice_to_pay'] # elicit whether lottery "A" or "B" was chosen for the respective choice # ------------------------------------------------------------------------------------------------------------ self.option_to_pay = getattr(self, self.choice_to_pay) def set_consistency(self): n = Constants.num_choices if self.participant.vars['choice_negr'] == 0: # replace A's by 1's and B's by 0's self.participant.vars['mplr_choices_made'] = [ 1 if j == 'A' else 0 for j in self.participant.vars['mplr_choices_made'] ] else: # replace B's by 1's and A's by 0's self.participant.vars['mplr_choices_made'] = [ 1 if j == 'B' else 0 for j in self.participant.vars['mplr_choices_made'] ] # check for multiple switching behavior for j in range(1, n): choices = self.participant.vars['mplr_choices_made'] self.inconsistent = 1 if choices[j] > choices[j - 1] else 0 if self.inconsistent == 1: break # determine switching row # :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: def set_switching_row(self): # set switching point to row number of first 'B' choice if self.inconsistent == 0: self.switching_row = sum(self.participant.vars['mplr_choices_made']) print( 'Player: mpl_resp wtp:', self.switching_row)