from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import random import itertools from otree_tools.widgets import AdvancedSliderWidget #from captcha.fields import ReCaptchaField #from captcha.widgets import ReCaptchaV2Checkbox author = 'Elisa Macchi' doc = """ Experiment - Sender Version """ class Constants(BaseConstants): name_in_url = 'exp_sender' players_per_group = None num_rounds = 1 min_time = 15 max_time = 20 intro_template = 'exp_sender/instructions.html' instructions_template_r1 = 'exp_sender/instructions_s.html' instructions_template_r2 = 'exp_sender/instructions_s_dating.html' # Statics sil_pic = 'black_men.png' participation_fee = c(5000) endowment = c(1000) bonus = c(1000) minbonus = c(0) maxbonus = c(9000) totbonus = c(10000) halfbonus = c(5000) thank_you_bonus = c(1000) penalty = c(100) # comprehension questions correct answers correct_answers = {'uq1': 3, 'uq2': 1, 'uq3': 3 } correct_answers_d = {'uq1_d': 3, 'uq2_d': 2} # treatment information = ['symmetric', 'asymmetric'] class Subsession(BaseSubsession): def creating_session(self): info = itertools.cycle(Constants.information) for p in self.get_players(): p.information = next(info) class Group(BaseGroup): pass class Player(BasePlayer): def set_payoffs(self): p = self p.random_bonus_1 = random.choice([5000, 7000, 10000]) p.random_bonus_2 = random.choice([5000, 7000, 10000]) if p.signal_credit == 1: p.signal_cost_credit = abs(p.unit_update_credit_age * Constants.penalty) elif p.signal_credit == 2: # weight p.signal_cost_credit = abs(p.unit_update_credit_weight * Constants.penalty) elif p.signal_credit == 3: # height p.signal_cost_credit = abs(p.unit_update_credit_height * Constants.penalty) else: p.signal_cost_credit = 0 if p.signal_dating == 1: p.signal_cost_dating = abs(p.unit_update_dating_age * Constants.penalty) elif p.signal_dating == 2: # weight p.signal_cost_dating = abs(p.unit_update_dating_weight * Constants.penalty) elif p.signal_dating == 3: # height p.signal_cost_dating = abs(p.unit_update_dating_height * Constants.penalty) else: p.signal_cost_dating = 0 print(p.signal_cost_credit) p.earnings_credit = Constants.endowment - p.signal_cost_credit p.earnings_dating = Constants.endowment - p.signal_cost_dating p.participant.vars["payoff_round1"] = p.earnings_credit + p.random_bonus_1 p.participant.vars["payoff_round2"] = p.earnings_dating + p.random_bonus_2 p.round_that_counts = random.choice([1, 2]) if p.qualified is False: p.payoff = Constants.thank_you_bonus else: if p.round_that_counts == 1: p.payoff = p.participant.vars["payoff_round1"] else: p.payoff = p.participant.vars["payoff_round2"] # Captcha # captcha = ReCaptchaField(widget=ReCaptchaV2Checkbox) # Treatment: information = models.StringField() # Demographics: year_of_birth = models.IntegerField(choices=range(1930, 2018, 1), label='''In which year were you born?''') age = models.IntegerField() gender = models.IntegerField(choices=[[1, 'Male'], [0, 'Female'], [2, 'Other']], label='''Are you:''' ) income = models.CurrencyField( label='''What is your monthly personal income in USh? Please, provide your best approximation.''', choices=currency_range(c(0), c(50000000), c(20000)) ) hhincome = models.CurrencyField( label=''' What is your monthly household income in USh? Please, provide your best guess.''', choices=currency_range(c(0), c(100000000), c(50000)) ) marital_status = models.IntegerField(choices=[[1, 'Single'], [2, 'Married'], [3, 'Living as married'], [4, 'Separated'], [5, 'Divorced'], [6, 'Widowed']], widget=widgets.RadioSelectHorizontal, label=''' Are you:''' ) children = models.IntegerField(choices=range(0, 16, 1), label=''' How many children do you have? Please, only count those you support financially.''' ) education = models.IntegerField(choices=[[1, 'Primary school'], [2, 'Secondary school'], [3, 'Technical/Vocational training'], [4, 'Some College'], [5, 'Bachelor Degree'], [6, 'Masters Degree'], [7, 'PhD, MD, or other Doctorate'], [8, 'None of the above']], widget=widgets.RadioSelect, label=''' What is the highest level of education you have completed?''' ) height = models.IntegerField(choices=range(130, 216, 1), label=''' What is your height in cm? Please, provide your best guess.''') weight = models.IntegerField(choices=range(30, 300, 1), label=''' What is your weight in kg? Please, provide your best guess.''') race = models.IntegerField(choices=[[1, 'African'], [2, 'Indian'], [3, 'Asian'], [4, 'White'], [5, 'Mixed']], label='''What is your race?''') health = models.IntegerField(choices=[[1, 'Poor '], [2, 'Fair'], [3, 'Good'], [4, 'Very good'] ], widget=widgets.RadioSelectHorizontal, label='''In general, you would say that your health is''') # ask about NCDs? country = models.StringField(label='''What is your country of residence?''') zip = models.StringField(label='''In which district do you live?''') westernized = models.BooleanField(label='''Do you ever watch western TV or read western magazines? ''') loan = models.IntegerField(choices=[[0, 'No, never.'], [1, 'Yes, only from banks.'], [2, 'Yes, only from informal money lenders.'], [3, 'Yes, both from banks and from money lenders.'] ], widget=widgets.RadioSelect, label='''Have you ever borrowed money or received a loan from a non-family member?''') loan_hypothetical = models.IntegerField(choices=[ [0, 'A bank.'], [1, 'An informal money lender.'], ], widget=widgets.RadioSelect, label='''If you needed to borrow 5 million Ush and could not ask to family/friends, would you rather go to:''') loan_hypothetical_why = models.LongStringField( label='''Why would you prefer that?''') # Screening qualified = models.BooleanField() # Comprehension Questions cp_error = models.BooleanField() # error cp_error_d = models.BooleanField() # error error1 = models.BooleanField() # first error error2 = models.BooleanField() error1d = models.BooleanField() # second error error2d = models.BooleanField() # second error flagged = models.BooleanField() # if you make 3 mistakes flagged_d = models.BooleanField() # if you make 3 mistakes uq1 = models.IntegerField( choices=[[1, 'It is never worthwhile to change a characteristic.'], [3, 'It can be worthwhile to change a characteristics if it makes you appear like a good ' 'borrower to the eyes of the Lender.'], ], widget=widgets.RadioSelect, label="In this game:") uq1_d = models.IntegerField( choices=[[1, 'It is never worthwhile it to change your characteristic.'], [3, 'It can be worthwhile to change a characteristics if it makes you appear' ' MORE successful at finding a partner ' 'to the eyes of the Receiver.'], ], widget=widgets.RadioSelect, label="In this game:") uq2 = models.IntegerField( choices=[[1, 'Choose the characteristics that make you appear a good borrower.'], [3, 'Be genuine about your characteristics.'], ], widget=widgets.RadioSelect, label="To increase your earnings in this game, do you think you have to:") uq2_d = models.IntegerField( choices=[[1, 'That the Receiver thinks you are married.'], [2, 'That the Receiver thinks that you are attractive to the other sex ' 'and very successful at finding a partner.'], ], widget=widgets.RadioSelect, label="A high dating rating means:") uq3 = models.IntegerField( choices=[[2, 'You can change either your age or your weight or your height for FREE.'], [3, 'You can change either your age or your weight or your height for SMALL FEE.'], ], widget=widgets.RadioSelect, label="In each round:") # Choices signal_credit = models.IntegerField(choices = [[0, 'No: do not change.'], [1, 'Yes: change your AGE'], [2, 'Yes: change your WEIGHT'], [3, 'Yes: change your HEIGHT']], widget=widgets.RadioSelect, label=""" Do you want to change an information? Please, select one. """, blank=True) signal_dating = models.IntegerField(choices=[[0, 'No: do not change.'], [1, 'Yes: change your AGE'], [2, 'Yes: change your WEIGHT'], [3, 'Yes: change your HEIGHT']], widget=widgets.RadioSelect, label=""" Do you want to change a characteristic? Please, select one. """, blank=True) # unit_update_credit_age = models.IntegerField(widget=widgets.Slider(attrs={'step': 1}), # blank=True, # min = -10, # max = 10) # # unit_update_credit_weight = models.IntegerField(widget=widgets.Slider(attrs={'step': 1}), # blank=True, # min=-10, # max=10) # # unit_update_credit_height = models.IntegerField(widget=widgets.Slider(attrs={'step': 1}), # blank=True, # min=-10, # max=10) # # unit_update_dating_age = models.IntegerField(widget=widgets.Slider(attrs={'step': 1}), # blank=True, # min=-10, # max=10) # # unit_update_dating_weight = models.IntegerField(widget=widgets.Slider(attrs={'step': 1}), # blank=True, # min=-10, # max=10) # # unit_update_dating_height = models.IntegerField(widget=widgets.Slider(attrs={'step': 1}), # blank=True, # min=-10, # max=10) unit_update_credit_age = models.IntegerField(widget=AdvancedSliderWidget(attrs={'step': 1, 'tick_interval': 5, 'suffix': 'y', 'min': -10, 'max': 10}), blank=True) unit_update_credit_weight = models.IntegerField(widget=AdvancedSliderWidget(attrs={'step': 1, 'tick_interval': 5, 'suffix': 'kg', 'min': -10, 'max': 10}), blank=True) unit_update_credit_height = models.IntegerField(widget=AdvancedSliderWidget(attrs={'step': 1, 'tick_interval': 5, 'suffix': 'cm', 'min': -10, 'max': 10}), blank=True) unit_update_dating_age = models.IntegerField(widget=AdvancedSliderWidget(attrs={'step': 1, 'tick_interval': 5, 'suffix': 'y', 'min': -10, 'max': 10})) unit_update_dating_weight = models.IntegerField(widget=AdvancedSliderWidget(attrs={'step': 1, 'tick_interval': 5, 'suffix': 'kg', 'min': -10, 'max': 10}), blank=True) unit_update_dating_height = models.IntegerField(widget=AdvancedSliderWidget(attrs={'step': 1, 'tick_interval': 5, 'suffix': 'cm', 'min': -10, 'max': 10}), blank=True) update_credit_age = models.IntegerField() update_credit_weight = models.IntegerField() update_credit_height = models.IntegerField() update_dating_age = models.IntegerField() update_dating_weight = models.IntegerField() update_dating_height = models.IntegerField() update_error = models.BooleanField() # error # Treatments player_number = models.IntegerField() issues = models.LongStringField(label="", blank=True) comments = models.LongStringField(label="", blank=True) # Results round_that_counts = models.IntegerField() signal_cost_credit = models.CurrencyField() signal_cost_dating = models.CurrencyField() random_bonus_1 = models.CurrencyField() random_bonus_2 = models.CurrencyField() earnings_credit = models.CurrencyField() earnings_dating = models.CurrencyField() # Phone Number phone_number = models.StringField() phone_error = models.BooleanField() payment_method = models.IntegerField(choices=[[0, "Mobile Money"], [1, "Air time"]], widget=widgets.RadioSelect)