from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import random import csv author = 'Your name here' doc = """ Your app description """ class Constants(BaseConstants): name_in_url = 'LA_Effort_Treatments' players_per_group = None min_tasks = 0 max_tasks = 100 with open('LA_Effort/wage_list.csv') as wage_file: wages = list(csv.DictReader(wage_file)) with open('LA_Effort/fixed_list.csv') as fixed_file: fixed = list(csv.DictReader(fixed_file)) num_rounds = len(fixed) num_pt1_rounds = len(wages) num_decisions = num_rounds + num_pt1_rounds class Subsession(BaseSubsession): def before_session_starts(self): if self.round_number == 1: for p in self.get_players(): randomized_fixed = random.sample(Constants.fixed, len(Constants.fixed)) p.participant.vars['fixed'] = randomized_fixed for p in self.get_players(): fixed_data = p.current_fixed() p.fixed_id = int(fixed_data['id']) p.fixed_pay = float(fixed_data['fixed_pay']) p.piece_pay = float(fixed_data['piece_pay']) class Group(BaseGroup): pass class Player(BasePlayer): fixed_id = models.IntegerField() fixed_pay= models.FloatField() piece_pay = models.FloatField() decision_that_counts = models.StringField() def current_fixed(self): return self.participant.vars['fixed'][self.round_number - 1] tasks_1 = models.PositiveIntegerField(initial=0, min=Constants.min_tasks, max=Constants.max_tasks, widget=widgets.SliderInput(), verbose_name='') checkslider1 = models.IntegerField(blank=True) # This puts task choices into a list for use by the next function def ListifyTasks_Treat(self): return [p.tasks_1 for p in self.in_all_rounds()] def ListifyFixed(self): return [p.fixed_pay for p in self.in_all_rounds()] def ListifyPiece(self): return [p.piece_pay for p in self.in_all_rounds()] # This does the individual task number and donation amount randomization def TaskRandomization(self): if self.participant.vars['task_rounds']['Det']==1: temp_tasks_list = [self.participant.vars['det_tasks_chosen'], self.participant.vars['stoch_tasks_chosen'], self.ListifyTasks_Treat()] tasks_list = [item for sublist in temp_tasks_list for item in sublist] low_wage_list_temp = [self.participant.vars['det_rate_l'], self.participant.vars['stoch_rate_l']] low_wage_list = [item for sublist in low_wage_list_temp for item in sublist] hi_wage_list_temp = [self.participant.vars['det_rate_h'], self.participant.vars['stoch_rate_h']] hi_wage_list = [item for sublist in hi_wage_list_temp for item in sublist] elif self.participant.vars['task_rounds']['Det']==2: temp_tasks_list = [self.participant.vars['stoch_tasks_chosen'], self.participant.vars['det_tasks_chosen'], self.ListifyTasks_Treat()] tasks_list = [item for sublist in temp_tasks_list for item in sublist] low_wage_list_temp = [self.participant.vars['stoch_rate_l'], self.participant.vars['det_rate_l']] low_wage_list = [item for sublist in low_wage_list_temp for item in sublist] hi_wage_list_temp = [self.participant.vars['stoch_rate_h'], self.participant.vars['det_rate_h']] hi_wage_list = [item for sublist in hi_wage_list_temp for item in sublist] fixed_rate_list = self.ListifyFixed() piece_rate_list = self.ListifyPiece() tasks_rand = tasks_list[self.participant.vars['paying_round']] coin_flip = random.randint(1, 2) self.participant.vars['tasks_chosen'] = tasks_rand self.participant.vars['wage_final'] = 0 self.participant.vars['wage_potential_l'] = 0 self.participant.vars['wage_potential_h'] = 0 self.participant.vars['fixed_chosen'] = 0 # if the paying round is between 1 and 18 if (self.participant.vars['paying_round'] < Constants.num_pt1_rounds): # set the potential wages before choosing one of them self.participant.vars['wage_potential_l'] = low_wage_list[self.participant.vars['paying_round']] self.participant.vars['wage_potential_h'] = hi_wage_list[self.participant.vars['paying_round']] # if the coin flip is 1 (or it's 2 but the wage is not stochastic), give low if (coin_flip < 2 or hi_wage_list[self.participant.vars['paying_round']] == 0): self.participant.vars['wage_final'] = low_wage_list[self.participant.vars['paying_round']] # if the coin flip is 2, give the high rate else: self.participant.vars['wage_final'] = hi_wage_list[self.participant.vars['paying_round']] # if the round is 19, pay from that decision based on the coin elif ((self.participant.vars['paying_round']) == Constants.num_pt1_rounds): # set the potential wages in this case as well self.participant.vars['wage_potential_l'] = piece_rate_list[0] self.participant.vars['wage_potential_h'] = fixed_rate_list[0] self.participant.vars['fixed_chosen'] = 1 if (coin_flip < 2): self.participant.vars['wage_final'] = piece_rate_list[0] else: self.participant.vars['wage_final'] = fixed_rate_list[0] # if the payment round is round 30, then pay from the second fixed choice else: # set the potential wages in this case as well self.participant.vars['wage_potential_l'] = piece_rate_list[1] self.participant.vars['wage_potential_h'] = fixed_rate_list[1] self.participant.vars['fixed_chosen'] = 1 if (coin_flip < 2): self.participant.vars['wage_final'] = piece_rate_list[1] else: self.participant.vars['wage_final'] = fixed_rate_list[1] def getPayoff(self): self.participant.payoff = self.participant.vars['wage_final'] * self.participant.vars['tasks_chosen'] def checkslider1_error_message(self, value): if not value: return 'Please move the slider for Slider 1 before submitting.' def checkslider2_error_message(self, value): if not value: return 'Please move the slider for Slider 2 before submitting.'