import random from otree import widgets from otree.api import (BaseConstants, BaseGroup, BasePlayer, BaseSubsession, Currency as c, models) from settings import POINTS_CUSTOM_NAME author = 'Robert zur Bonsen' doc = """ """ class Constants(BaseConstants): name_in_url = 'exp' players_per_group = 2 num_rounds = 1 proposer = 'A' responder = 'B' endowment_p_first_stage_label = 'a1' endowment_p_second_stage_label = 'a2' endowment_r_first_stage_label = 'b1' endowment_r_second_stage_label = 'b2' template_instructions = 'main/Instructions.html' template_footer = 'main/Footer.html' points_label = POINTS_CUSTOM_NAME class Subsession(BaseSubsession): @property def points_per_real_world_currency(self): return c(1 / self.session.config['real_world_currency_per_point']) def creating_session(self): self.session.vars['next'] = 1 #True # Geändert class Group(BaseGroup): # Treatment endowment_first_stage = models.CurrencyField() endowment_second_stage = models.CurrencyField() endowment_other = models.CurrencyField() upper_range = models.CurrencyField() treatment = models.IntegerField() # Geändert? ...models.BooleanField() # Game #offer = models.CurrencyField(min=0) offer = models.CurrencyField() initial = models.CurrencyField()#Geändert response = models.BooleanField() timeout_happened = models.BooleanField() #treatment = models.IntegerField() # Geändert? #Contractingspace def offer_error_message(self, value): print('value is', value) if value > 160: self.initial = value return 'Cannot offer more than 160' if value < 0: self.initial = value return 'Cannot offer less than 0' #def offer_min(self): # return 0 #def offer_max(self): #return self.endowment_first_stage + self.endowment_second_stage # return 200 #Geändert def run_first_stage(self): #if self.treatment: #geändert if self.treatment == 1: #geändert self.endowment_first_stage = 0 self.endowment_second_stage = self.session.config['endowment'] self.endowment_other = 0#geändert self.upper_range = self.session.config['endowment'] elif self.treatment == 2: #geändert self.endowment_first_stage = self.session.config['endowment'] / 2 self.endowment_second_stage = self.session.config['endowment'] / 2 #geändert self.endowment_other = 0#geändert self.upper_range = self.session.config['endowment'] elif self.treatment == 3: #geändert self.endowment_first_stage = 0 self.endowment_second_stage = self.session.config['endowment'] / 2 self.endowment_other = self.session.config['endowment'] / 2#geändert self.upper_range = self.session.config['endowment'] / 2 else: self.endowment_first_stage = self.session.config['endowment'] / 2 self.endowment_second_stage = self.session.config['endowment'] / 2 # geändert self.endowment_other = 0 # geändert self.upper_range = self.session.config['endowment'] / 2 p1, p2 = self.get_players() p1.payoff = self.endowment_first_stage p2.payoff = self.endowment_other # 0 def set_payoffs(self): p1, p2 = self.get_players() if self.response: p1.payoff += self.endowment_second_stage - self.offer p2.payoff += self.offer else: p1.payoff = 0 p2.payoff = 0 @property def active(self): return all([p.active for p in self.get_players()]) QUESTIONS = { 'own_payoff': { 'label': f'How many {Constants.points_label} will you earn as bonus?', 'widget': widgets.RadioSelect }, 'stranger_payoff': { 'label': f'How many {Constants.points_label} will the stranger earn as bonus?', 'widget': widgets.RadioSelect }, 'fairoffer': { 'label': 'In your opinion, what would have been a fair offer (please enter the amount)?', 'min': 0, }, 'lowestoffer': { 'label': 'What is the lowest offer that you would have accepted?', 'min': 0, }, 'age': { 'label': 'Which category below includes your age?', 'choices': ['20 or younger', '21-40', '41-60', '61 or older', ], 'widget': widgets.RadioSelect }, 'gender': { 'label': 'What is your gender?', 'choices': ['Female', 'Male', 'Other'], 'widget': widgets.RadioSelect }, 'education': { 'label': 'What is the highest level of school you have completed or the highest degree you have received?', 'choices': ['Less than high school degree', 'High school degree or equivalent', 'College degree or equivalent', ], 'widget': widgets.RadioSelect }, 'student': { 'label': 'Are you currently enrolled in a college / university?', 'choices': ['No', 'Yes', ], 'widget': widgets.RadioSelect }, 'employment': { 'label': 'Which of the following categories best describes your employment status?', 'choices': [ 'Part-time employed', 'Full-time employed', 'Unemployed', ], 'widget': widgets.RadioSelect }, 'income': { 'label': 'How much total combined money did all members of your household earn in 2020?', 'choices': [ '$0 – $19,999', '$20,000 – $39,999', '$40,000 – $59,999', '$60,000 or more', 'no reply', ], 'widget': widgets.RadioSelect }, 'region': { 'label': 'Which region do you currently live in?', 'choices': [ 'US', 'Rest of the World', ], 'widget': widgets.RadioSelect }, 'batandball': { 'label': '''A bat and a ball cost $1.10 in total. The bat costs a dollar more than the ball. How many dollars does the ball cost?''', 'min': 0, }, 'machineswidgets': { 'label': '''If it takes 5 machines 5 minutes to make 5 widgets, how many minutes would it take 100 machines to make 100 widgets?''', 'min': 0, }, 'lilypads': { 'label': '''In a lake, there is a patch of lily pads. Every day, the patch doubles in size. If it takes 48 days for the patch to cover the entire lake, how many days would it take for the patch to cover half of the lake?''', 'min': 0, }, } class Player(BasePlayer): # Game #time_ok = models.BooleanField() timeout_happened = models.BooleanField() @property def active(self): return self.participant.vars['active'] @active.setter def active(self, value): if not value: self.payoff = c(0) self.participant.vars['active'] = value @property def role(self): if self.id_in_group == 1: return Constants.proposer else: return Constants.responder @property def stranger(self): return self.group.get_player_by_id(2 if self.id_in_group == 1 else 1) def timeout(self): self.timeout_happened = True self.group.timeout_happened = True self.active = False for p in self.group.get_players(): p.payoff = 0 # Post-Quiz q_own_payoff = models.IntegerField(**QUESTIONS['own_payoff']) def q_own_payoff_choices(self): choices = [ [1, self.payoff], [0, self.payoff + 10], [0, self.payoff + 20], ] random.shuffle(choices) return choices q_stranger_payoff = models.IntegerField(**QUESTIONS['stranger_payoff']) def q_stranger_payoff_choices(self): choices = [ [1, self.stranger.payoff], [0, self.stranger.payoff + 10], [0, self.stranger.payoff + 20], ] random.shuffle(choices) return choices # Demographics fairoffer = models.IntegerField(**QUESTIONS['fairoffer']) lowestoffer = models.IntegerField(**QUESTIONS['lowestoffer']) age = models.StringField(**QUESTIONS['age']) gender = models.StringField(**QUESTIONS['gender']) # student = models.StringField(**QUESTIONS['student']) # education = models.StringField(**QUESTIONS['education']) # income = models.StringField(**QUESTIONS['income']) region = models.StringField(**QUESTIONS['region']) batandball = models.FloatField(**QUESTIONS['batandball']) machineswidgets = models.IntegerField(**QUESTIONS['machineswidgets']) lilypads = models.IntegerField(**QUESTIONS['lilypads'])