from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range, ) from random import randint author = 'Your name here' doc = """ Your app description """ class Constants(BaseConstants): name_in_url = 'online_study' players_per_group = None num_rounds = 20 exchange_rate = 0.1 initial_earning = 40 ## round when the player have been selected to get paid round_selected = randint(1, num_rounds) expert_q1a = 2 expert_q2a = 2 expert_q3a_t0 = 1 expert_q3a_t1 = 2 expert_q4a = 2 class Subsession(BaseSubsession): def creating_session(self): import itertools for p in self.get_players(): rand_n = randint(1, 100) if rand_n <= 50: p.activeness = 0 else: p.activeness = 1 rand_n2 = randint(1, 100) if rand_n2 <= 50: p.problem = 0 else: p.problem = 1 p.problem_letter = "A"*(p.problem == 0) + "B"*(p.problem == 1) if self.round_number == 1: treatment_loop = itertools.cycle([0, 0, 1, 1]) altruism_loop = itertools.cycle([0, 1]) for player in self.get_players(): player.participant.vars['QC_Fail'] = 2 ## define QC_fail being 2 if it is the beginning of the game. player.treatment = next(treatment_loop) player.participant.vars['treatment'] = player.treatment player.expert_altruism = next(altruism_loop) player.participant.vars['altruism'] = player.expert_altruism else: for player in self.get_players(): player.expert_altruism = player.participant.vars['altruism'] player.treatment = player.participant.vars['treatment'] class Group(BaseGroup): pass class Player(BasePlayer): # Treatment: 0 = observable; 1 = concealed treatment = models.IntegerField() final_payment = models.FloatField(initial=0.0, min=0) problem = models.IntegerField(choices=[[0, "A"], [1, "B"]]) problem_letter = models.StringField() # private_signal = models.IntegerField() # private_signal_letter = models.StringField(blank=True) diagnosis_letter = models.StringField(blank=True) recommend_soln_letter = models.StringField(blank=True) treatment_final = models.IntegerField() treatment_final_letter = models.StringField() # expert's choice of precision precision_choice = models.FloatField( choices = [ [0.5, "50%"], [0.6, "60%"], [0.7, "70%"], [0.8, "80%"], [0.9, "90%"], [1, "100%"], ], widget = widgets.RadioSelectHorizontal, blank = True ) diagnostic_result = models.IntegerField() diagnostic_cost = models.IntegerField() # Expert's altruism level expert_altruism = models.FloatField() # altruism_contract = models.IntegerField() altruism_payoff = models.IntegerField() # actual income from gamma*U^p payment = models.IntegerField() payment_temp = models.IntegerField() # Whether active or passive activeness = models.IntegerField() # Quality check indicators qual_check = models.IntegerField() # Control questions expert_q1 = models.IntegerField( choices = [ [1, '20%'], [2, '80%'] ], widget=widgets.RadioSelectHorizontal, label="") def expert_q1_error_message(self, value): if value != Constants.expert_q1a: return 'Your answer is not correct. Please answer it again.' expert_q2 = models.IntegerField( choices = [ [1,'0 token'], [2, '9 tokens'], [3, '25 tokens'] ], widget=widgets.RadioSelectHorizontal, label='') def expert_q2_error_message(self, value): if value != Constants.expert_q2a: return 'Your answer is not correct. Please answer it again.' expert_q3 = models.IntegerField( choices=[ [1, 'My diagnostic accuracy is observable to the client'], [2, 'My diagnostic accuracy not observable to the client'], ], widget=widgets.RadioSelect, label = "" ) def expert_q3_error_message(self, value): if self.treatment == 0: if value != Constants.expert_q3a_t0: return 'Your answer is not correct. Please answer it again.' if self.treatment == 1: if value != Constants.expert_q3a_t1: return 'Your answer is not correct. Please answer it again.' expert_q4 = models.IntegerField( choices=[ [1, 'This client will always follow my recommendation of solution'], [2, 'This client may or may not follow my recommendation of solution'], ], widget=widgets.RadioSelect, label="" ) def expert_q4_error_message(self, value): if value != Constants.expert_q4a: return 'Your answer is not correct. Please answer it again.'