from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range, ) import random import itertools author = 'Zeyu Qiu' doc = """ Your app description """ class Constants(BaseConstants): name_in_url = 'WeScale_PG_new' players_per_group = 2 num_rounds = 1 # """Amount allocated to each player""" multiplier = 0.75 pounds = 0.05 fixed = 1.10 def set_scale_choices_list(length): choices_list = [] for i in range(length): choices_list.append((i + 1, str(i + 1))) return choices_list def make_scale_field(label_string, length): return models.IntegerField( choices=set_scale_choices_list(length), widget=widgets.RadioSelectHorizontal, label=label_string # blank=True ) class Subsession(BaseSubsession): def creating_session(self): # treatments for p in self.get_groups(): if p.id_in_subsession: pressures = itertools.cycle([1, 0]) for player in self.get_groups(): player.code_treatment = next(pressures) if p.code_treatment == 1: p.treatment = "equal" else: p.treatment = "unequal" #for p in self.get_groups(): #if p.id_in_subsession: #treatment_rand = random.random() #if treatment_rand > 0.5: #p.treatment = "equal" #else: #p.treatment = "unequal" # treatment in player section for p in self.get_players(): p.treatment = p.group.treatment # roles and endowment for p in self.get_players(): if p.treatment: t_rand = random.random() if p.treatment == "unequal": if t_rand > 0.5: if p.id_in_group == 1: p.your_type = "high" else: p.your_type = "low" else: if p.id_in_group == 2: p.your_type = "low" else: p.your_type = "high" else: p.your_type = "neutral" for p in self.get_players(): if p.your_type == "low": p.my_endowment = 10 p.other_endowment = 30 elif p.your_type == "high": p.my_endowment = 30 p.other_endowment = 10 else: p.my_endowment = 20 p.other_endowment = 20 # prolific ID for p in self.get_players(): p.Prolific_ID = p.participant.label class Group(BaseGroup): treatment = models.StringField() code_treatment = models.IntegerField() total_contribution = models.IntegerField() individual_share = models.FloatField() total_contribution_estimate = models.IntegerField() total_payoff = models.FloatField() def set_payoffs(self): self.total_contribution = sum([p.contribution for p in self.get_players()]) self.total_contribution_estimate = sum([p.contribution_estimate for p in self.get_players()]) self.individual_share = ( self.total_contribution * Constants.multiplier ) # / Constants.players_per_group for p in self.get_players(): p.my_payoff = (p.my_endowment - p.contribution) + self.individual_share for p in self.get_players(): p.other_contribution = self.total_contribution - p.contribution for p in self.get_players(): p.other_contribution_estimate = self.total_contribution_estimate - p.contribution_estimate for p in self.get_players(): if p.contribution_estimate == p.other_contribution: p.estimate_pay = 10 else: p.estimate_pay = 0 self.total_payoff = sum([p.my_payoff for p in self.get_players()]) for p in self.get_players(): p.other_payoff = self.total_payoff - p.my_payoff p.bonus_earnings = ((p.my_payoff + p.estimate_pay) * Constants.pounds) p.fixed_earnings = Constants.fixed p.final_earnings = p.fixed_earnings + p.bonus_earnings #p.my_payoff = p.payoff class Player(BasePlayer): Prolific_ID = models.StringField( label="Prolific ID", ) your_type = models.StringField() my_endowment = models.IntegerField() other_endowment = models.IntegerField() treatment = models.StringField() ################################################ contribution = models.IntegerField( label="Please now enter your contribution decision:", min= 0, ) def contribution_error_message(self, value): contribution_answer_equal = self.my_endowment if value > contribution_answer_equal: error_message = "You cannot contribute more than the number of tokens you have been allocated. " \ "Please try again." return error_message ################################################ contribution_estimate = models.IntegerField( label="How many tokens do you estimate that the other group member you are matched with has contributed?", min=0, ) def contribution_estimate_error_message(self, value): contribution_estimate_answer_equal = self.other_endowment if value > contribution_estimate_answer_equal: error_message = "Your estimate cannot exceed the number of tokens the other group member has been " \ "allocated. Please try again." return error_message ################################################ other_contribution = models.IntegerField() other_contribution_estimate = models.IntegerField() other_payoff = models.FloatField() bonus_earnings = models.CurrencyField() fixed_earnings = models.CurrencyField() final_earnings = models.CurrencyField() my_payoff = models.FloatField() estimate_pay = models.FloatField() ################################################ control_question = models.StringField( choices=[ ['1', 'I agree to take part. Take me to the study.'], ['2', 'I do not agree to take part in this study. Take me back to Prolific.'], ], label="Do you agree to participate in this study?", widget=widgets.RadioSelect ) def control_question_error_message(self, value): correct_answer = '1' if value != correct_answer: error_message = "If you do not agree to take part in this study, please close your browser tab." return error_message ################################################ question1 = models.IntegerField( label="", min=0, ) def question1_error_message(self, value): correct_equal_q1 = 20 correct_low_unequal_q1 = 10 correct_high_unequal_q1 = 30 if self.your_type == 'neutral' and value != correct_equal_q1: error_equal_q1 = "correct answer: (20 - 0) + 0.75 x 0 = 20 points" return error_equal_q1 elif self.your_type == 'low' and value != correct_low_unequal_q1: error_low_unequal_q1 = "correct answer: (10 - 0) + 0.75 x 0 = 10 points" return error_low_unequal_q1 elif self.your_type == 'high' and value != correct_high_unequal_q1: error_high_unequal_q1 = "correct answer: (30 - 0) + 0.75 x 0 = 30 points" return error_high_unequal_q1 ################################################ question2 = models.IntegerField( label="", min=0, ) def question2_error_message(self, value): correct_equal_q2 = 21 correct_low_unequal_q2 = 11 correct_high_unequal_q2 = 31 if self.your_type == 'neutral' and value != correct_equal_q2: error_equal_q2 = "correct answer: (20 - 8) + 0.75 x 12 = 21 points" return error_equal_q2 elif self.your_type == 'low' and value != correct_low_unequal_q2: error_low_unequal_q2 = "correct answer: (10 - 8) + 0.75 x 12 = 11 points" return error_low_unequal_q2 elif self.your_type == 'high' and value != correct_high_unequal_q2: error_high_unequal_q2 = "correct answer: (30 - 8) + 0.75 x 12 = 31 points" return error_high_unequal_q2 ################################################ onescale_before = models.StringField( choices=[['1', 'A'], ['2', 'B'], ['3', 'C'], ['4', 'D'], ['5', 'E'], ['6', 'F'], ['7', 'G'], ], label="", widget=widgets.RadioSelectHorizontal ) wescale_before = models.StringField( choices=[['1', ''], ['2', ''], ['3', ''], ['4', ''], ['5', ''], ['6', ''], ['7', ''], ], label="", widget=widgets.RadioSelectHorizontal ) onescale_after = models.StringField( choices=[['1', 'A'], ['2', 'B'], ['3', 'C'], ['4', 'D'], ['5', 'E'], ['6', 'F'], ['7', 'G'], ], label="", widget=widgets.RadioSelectHorizontal ) wescale_after = models.StringField( choices=[['1', ''], ['2', ''], ['3', ''], ['4', ''], ['5', ''], ['6', ''], ['7', ''], ], label="", widget=widgets.RadioSelectHorizontal ) gender = models.StringField( choices=[ ['1', 'Male'], ['2', 'Female'], ['3', 'Other'], ], label="1. What is your gender?", widget=widgets.RadioSelect ) other_gender_belief = models.StringField( choices=[ ['1', 'Male'], ['2', 'Female'], ['3', 'Other'], ], label="2. What do you think was the gender of the other group member you were matched with?", widget=widgets.RadioSelect ) age = models.IntegerField( label="3. What is your age?", min = 0, max = 120 ) #def hight_error_message(self, value): #if value == : #error_message = "Your other group member cannot contribution more than their endowment. " #return error_message language = models.StringField( choices=[ ['1', 'Yes'], ['2', 'No'], ], label="4. Is English your first language?", widget=widgets.RadioSelect ) max_income = models.StringField( choices=[ ['1', 'Very important'], ['2', 'Important'], ['3', 'Indifferent'], ['4', 'Not important'], ['5', 'Not important at all'], ], label="5. How important was for you to maximise your own income during the experiment?", widget=widgets.RadioSelect ) trust = models.StringField( choices=[ ['1', 'Most people can be trusted'], ['2', 'You need to be very careful in dealing with people'], ], label="6. Generally speaking, would you say that most people can be trusted or that you need to be very " "careful in dealing with people?", widget=widgets.RadioSelect ) risk = models.StringField( choices=[ ['1', ''], ['2', ''], ['3', ''], ['4', ''], ['5', ''], ['6', ''], ['7', ''], ['8', ''], ['9', ''], ['10', ''], ], label="", widget=widgets.RadioSelectHorizontal ) instructions = models.StringField( choices=[ ['1', 'Very difficult'], ['2', 'Difficult'], ['3', 'Neutral'], ['4', 'Easy'], ['5', 'Very easy'], ], label="8. How did you find the instructions?", widget=widgets.RadioSelect ) ################################################ fair_contribute = models.IntegerField( label="", min=0, ) def fair_contribute_error_message(self, value): contribution_estimate_answer_equal = self.my_endowment if value > contribution_estimate_answer_equal: error_message = "You cannot contribute more than the number of tokens you have been allocated." return error_message ################################################ other_fair_contribute = models.IntegerField( label="", min=0, ) def other_fair_contribute_error_message(self, value): contribution_estimate_answer_equal = self.other_endowment if value > contribution_estimate_answer_equal: error_message = "The other group member cannot contribute more than the number of tokens they have been " \ "allocated." return error_message ################################################ econ_exp = models.IntegerField( label="11. How many economics experiments have you participated in before this one? ", ) feedback = models.StringField( blank=True, label="12. Do you have any other comments or feedback regarding this experiment?", ) ################################################