from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import csv import random, numpy as np from django_countries.fields import CountryField author = 'Your name here' doc = """ A quiz app that reads its questions from a spreadsheet (see quiz.csv in this directory). There is 1 question per page; the number of pages in the game is determined by the number of questions in the CSV. See the comment below about how to randomize the order of pages. """ class Constants(BaseConstants): name_in_url = 'Stanford_Economics' players_per_group = None stakes = c(1000) num_rounds = 1 class Subsession(BaseSubsession): def creating_session(self): for p in self.get_players(): if random.random() > .5: p.payment_type = 'cross_over' else: p.payment_type = 'iq_test' class Group(BaseGroup): pass class Player(BasePlayer): payment_type = models.StringField() signal_1_repeat_Control = models.IntegerField( blank=True, choices=[ [1, 'Your score is in the top half of performances'], [2, 'Your score is in the bottom half of performances'], ], widget=widgets.RadioSelectHorizontal ) signal_2_repeat_Control = models.IntegerField( blank=True, choices=[ [1, 'Your score is in the top half of performances'], [2, 'Your score is in the bottom half of performances'], ], widget=widgets.RadioSelectHorizontal ) signal_3_repeat_Control = models.IntegerField( blank=True, choices=[ [1, 'Your score is in the top half of performances'], [2, 'Your score is in the bottom half of performances'], ], widget=widgets.RadioSelectHorizontal ) signal_4_repeat_Control = models.IntegerField( blank=True, choices=[ [1, 'Your score is in the top half of performances'], [2, 'Your score is in the bottom half of performances'], ], widget=widgets.RadioSelectHorizontal ) signal_1_repeat_SG = models.IntegerField( blank=True, choices=[ [1, 'You are a good team'], [2, 'You are a bad team'], ], widget=widgets.RadioSelectHorizontal ) signal_2_repeat_SG = models.IntegerField( blank=True, choices=[ [1, 'You are a good team'], [2, 'You are a bad team'], ], widget=widgets.RadioSelectHorizontal ) signal_3_repeat_SG = models.IntegerField( blank=True, choices=[ [1, 'You are a good team'], [2, 'You are a bad team'], ], widget=widgets.RadioSelectHorizontal ) signal_4_repeat_SG = models.IntegerField( blank=True, choices=[ [1, 'You are a good team'], [2, 'You are a bad team'], ], widget=widgets.RadioSelectHorizontal ) type = models.StringField() joint_type = models.StringField() signal_1 = models.IntegerField() signal_2 = models.IntegerField() signal_3 = models.IntegerField() signal_4 = models.IntegerField() o_signal_1 = models.StringField() o_signal_2 = models.StringField() o_signal_3 = models.StringField() p_0 = models.StringField() p_1 = models.StringField() p_2 = models.StringField() p_3 = models.StringField() Y_0 = models.IntegerField() Y_1 = models.IntegerField() Y_2 = models.IntegerField() Y_3 = models.IntegerField() U1x = models.IntegerField( widget=widgets.Slider(attrs={'step': '1.00'}), label = ''' What is the probability of the coin coming up heads?''' ) U1 = models.IntegerField( choices=[ [1, 'Heads is more likely'], [2, 'Tails is more likely'], [3, 'Heads and tails are equally likely'], ], widget=widgets.RadioSelect ) U2x = models.IntegerField( widget=widgets.Slider(attrs={'step': '1.00'}), ) U2 = models.IntegerField( choices=[ [1, 'Heads is more likely'], [2, 'Tails is more likely'], [3, 'Heads and tails are equally likely'], ], widget=widgets.RadioSelect ) U3x = models.IntegerField( widget=widgets.Slider(attrs={'step': '1.00'}), label = ''' What is the probability that the coin came up heads?''' ) U3 = models.IntegerField( choices=[ [1, 'Heads is more likely'], [2, 'Tails is more likely'], [3, 'Heads and tails are equally likely'], ], widget=widgets.RadioSelect ) feedback_part_1 = models.LongStringField(blank=True) feedback_part_2 = models.LongStringField(blank=True) Belief_0 = models.IntegerField( widget=widgets.Slider(attrs={'step': '1.00'}) ) Belief_1 = models.IntegerField( widget=widgets.Slider(attrs={'step': '1.00'}) ) Belief_2 = models.IntegerField( widget=widgets.Slider(attrs={'step': '1.00'}) ) Belief_3 = models.IntegerField( widget=widgets.Slider(attrs={'step': '1.00'}) ) Belief_4 = models.IntegerField( widget=widgets.Slider(attrs={'step': '1.00'}) ) score = models.IntegerField() def current_question(self): return self.session.vars['questions'][self.round_number - 1] def set_type(self): if self.participant.vars['score'] >= self.session.config['score_for_top_half']: self.type = 'winner' else: self.type = 'loser' if self.participant.vars['treatment'] == 'Control': self.joint_type = self.type elif self.participant.vars['treatment'] == 'RobotSG': if (self.type == 'winner' and random.random() > .25) or (self.type == 'loser' and random.random() > .75): self.joint_type = 'winner' else: self.joint_type = 'loser' elif self.participant.vars['treatment'] == 'HumanSG': # For simplicity, we use a random number as opposed to another subject's score. This is equivalent. if (self.type == 'winner' and random.random() > .25) or (self.type == 'loser' and random.random() > .75): self.joint_type = 'winner' else: self.joint_type = 'loser' def set_payoff(self): if self.participant.vars['passed_screening'] is True: choice = random.randint(0, 4) y = np.random.rand(2, 5) b = np.divide([self.Belief_0, self.Belief_1, self.Belief_2, self.Belief_3, self.Belief_4], 100) x = (np.maximum(((y[0] > b) * (y[1] < y[0])), ((y[0] < b) * (self.type == 'winner')))) x = x[choice] self.payoff = x*c(self.session.config['payment_belief_elicitation']) + c(max(self.participant.vars['score'], 0)*self.session.config['payment_per_point']) + c(self.session.config['base_payment']) else: self.payoff = c(self.session.config['payment_fail_screening']) def set_signal(self): s = self.session.config['signal_strength'] if self.joint_type == 'winner': self.signal_1 = (random.random() < s) self.signal_2 = (random.random() < s) self.signal_3 = (random.random() < s) self.signal_4 = (random.random() < s) elif self.joint_type == 'loser': self.signal_1 = (random.random() < 1-s) self.signal_2 = (random.random() < 1-s) self.signal_3 = (random.random() < 1-s) self.signal_4 = (random.random() < 1-s) self.participant.vars['signals'] = [self.signal_1, self.signal_2, self.signal_3, self.signal_4] C1 = models.IntegerField( blank=True, label=''' What is the probability that you win the prize?''', choices=[ [1, '90%'], [2, '75%'], [3, '40%'], [4, '10%'], ], widget=widgets.RadioSelectHorizontal ) C2 = models.IntegerField( blank=True, label=''' Would you have had a higher chance of winning by reporting Bob 40 instead of Bob 75 as the robot most similar to you?''', choices=[ [1, 'Higher chance reporting Bob 40'], [2, 'Higher chance reporting Bob 75'], [3, 'The same'], ], widget=widgets.RadioSelect ) C1_num_wrong = models.IntegerField(initial=0 ) C2_num_wrong = models.IntegerField(initial=0 ) instr_1 = models.IntegerField(initial=0 ) instr_2 = models.IntegerField(initial=0 ) def C1_error_message(self, value): print('value is', value) if value !=1: self.C1_num_wrong += 1 return 'Your answer to Q1 is Incorrect. Because you stated that you believe to be most like Bob 75 and Bob 90 is better than Bob 75, your score will be replaced with the score of Bob 90. Bob 90 has a 90% chance of scoring in the top half.' def C2_error_message(self, value): print('value is', value) if value != 2: self.C2_num_wrong += 1 return 'Your answer to Q2 is Incorrect. Because you stated that you believe to be most like Bob 75 and Bob 50 is worse than Bob 75, your score will not be replaced and you have a 75% chance of receiving the money. If you would have reported that you believe to be most like Bob 40, then your score would be replaced with the score of Bob 50 as Bob 50 is better than Bob 40. However, Bob 50 only has a 50% chance of scoring in the top half.' UQ1 = models.IntegerField( blank=True, choices=[ [1, 'You will be shown multiple reports from judges at the same time'], [2, 'You will be shown multiple reports from judges one after the other'], ], widget=widgets.RadioSelect ) UQ1_num_wrong = models.IntegerField(initial=0 ) UQ2 = models.IntegerField( blank=True, choices=[ [1, '1'], [2, '2'], [3, '3'], [4, '4'], [5, '5'], ], ) UQ2_num_wrong = models.IntegerField(initial=0 ) UQ3 = models.IntegerField( blank=True, choices=[ [1, '1'], [2, '2'], [3, '3'], [4, '4'], [5, '5'], ], ) UQ3_num_wrong = models.IntegerField(initial=0 ) UQ4Control = models.IntegerField( blank=True, choices=[ [1, 'Your score is in the top half of performances'], [2, 'Your score is in the bottom half of performances'], ], widget=widgets.RadioSelect ) UQ4SG = models.IntegerField( blank=True, choices=[ [1, 'You are a good team'], [2, 'You are a bad team'], ], widget=widgets.RadioSelect ) UQ4_num_wrong = models.IntegerField(initial=0 ) UQ5Control = models.IntegerField( blank=True, choices=[ [1, 'Your score is in the top half of performances'], [2, 'Your score is in the bottom half of performances'], ], widget=widgets.RadioSelect ) UQ5SG = models.IntegerField( blank=True, choices=[ [1, 'You are a good team'], [2, 'You are a bad team'], ], widget=widgets.RadioSelect ) UQ5_num_wrong = models.IntegerField(initial=0 ) UQ6 = models.IntegerField( blank=True, choices=[ [1, 'Yes'], [2, 'No'], ], widget=widgets.RadioSelect ) def UQ1_error_message(self, value): print('value is', value) if value !=2: self.UQ1_num_wrong += 1 return 'Your answer to Q1 is Incorrect. We will randomly choose one report from the three judges and show it to you. We will then ask you again about how likely it is you scored in the top half of performances. We repeat these two steps, randomly choosing a report a report and asking you about your performance, for another three times (so you see 4 reports).' def UQ2_error_message(self, value): print('value is', value) if value !=3: self.UQ2_num_wrong += 1 return 'Your answer to Q2 is Incorrect. There are three judges: one super mean judge, one super nice judge and one realistic judge.' def UQ3_error_message(self, value): print('value is', value) if value !=4: self.UQ3_num_wrong += 1 return 'Your answer to Q3 is incorrect. We will randomly choose one report from the three judges and show it to you. We will then ask you again about how likely it is you scored in the top half of performances. We repeat these two steps, randomly choosing a report a report and asking you about your performance, for another three times (so you see 4 reports).' def UQ4Control_error_message(self, value): print('value is', value) if self.participant.vars['treatment'] == 'Control': if value !=2: self.UQ4_num_wrong += 1 return 'Your answer to Q4 is incorrect. The report of the super mean judge will always say that your score is in the bottom half.' def UQ4SG_error_message(self, value): print('value is', value) if self.participant.vars['treatment'] != 'Control': if value !=2: self.UQ4_num_wrong += 1 return 'Your answer to Q4 is incorrect. The report of the super mean judge will always say that you are a bad team.' def UQ5Control_error_message(self, value): print('value is', value) if self.participant.vars['treatment'] == 'Control': if value !=1: self.UQ5_num_wrong += 1 return 'Your answer to Q5 is incorrect. The report of the realistic judge will say the truth.' def UQ5SG_error_message(self, value): print('value is', value) if self.participant.vars['treatment'] != 'Control': if value !=1: self.UQ5_num_wrong += 1 return 'Your answer to Q5 is incorrect. The report of the realistic judge will say the truth.' def UQ6_error_message(self, value): print('value is', value) if value !=1: self.UQ6_num_wrong += 1 return 'Your answer to Q6 is incorrect. It could be the case that the report of the super nice judge is always randomly chosen.' UQ6_num_wrong = models.IntegerField(initial=0 ) Message1_num_wrong = models.IntegerField(initial=0 ) Message2_num_wrong = models.IntegerField(initial=0 ) Message3_num_wrong = models.IntegerField(initial=0 ) Message4_num_wrong = models.IntegerField(initial=0 ) gender = models.PositiveIntegerField(label='Gender: To which gender identity do you most identify?', choices=[[0, 'Female'], [1, 'Male'], [2, 'Transgender Female'], [3, 'Transgender Male'], [4, 'Gender Variant/Non-Conforming'], [5, 'Not Listed'], [6, 'Prefer Not to Answer']], widget=widgets.RadioSelect) ethnic = models.PositiveIntegerField(label='Ethnicity: You consider yourself to be?', choices=[[0, 'White'], [2, 'Asian'], [3, 'Black'], [4, 'Other']], widget=widgets.RadioSelect) ethnic2 = models.PositiveIntegerField(label='Hispanic: You consider yourself to be Hispanic?', choices=[[0, 'No'], [1, 'Yes']], widget=widgets.RadioSelect) mumbirthplace = CountryField(blank_label='(select country)') dadbirthplace = CountryField(blank_label='(select country)') mumocc = models.PositiveIntegerField(label="What is or was your mother's occupation?", widget=widgets.RadioSelect, choices=[[0, 'Professional/ Managerial'], [1, 'Sales/ Retail'], [2, 'Clerical/ Administrative'], [3, 'Services'], [4, 'Manual Work'], [5, 'No Occupation/ Home-maker'], [6, 'Other']]) dadocc = models.PositiveIntegerField(label="What is or was your father's occupation?", widget=widgets.RadioSelect, choices=[[0, 'Professional/ Managerial'], [1, 'Sales/ Retail'], [2, 'Clerical/ Administrative'], [3, 'Services'], [4, 'Manual Work'], [5, 'No Occupation/ Home-maker'], [6, 'Other']]) householdincome = models.PositiveIntegerField( label='To the best of your knowledge, what was the total household income of your parental household when you grew up?', widget=widgets.RadioSelect, choices=[[0, 'Less than $10,000'], [1, 'Between $10,000 and $29,999'], [2, '$20,000 to $49,999'], [3, '$50,000 to $69,999'], [4, '$70,000 to $99,999'], [5, '$100,000 to $129,999'], [6, '$130,000 to $199,999'], [7, '$200,000 or more'], [8, 'I do not know']]) age = models.PositiveIntegerField(label='What is your current age in years?', min=18, max=100) percentMTurk = models.PositiveIntegerField(label='What percentage of your income comes from MTurk work?', min=0, max=100) education = models.PositiveIntegerField(label='What is your highest level of completed education?', choices=[[1, 'Some High School'], [2, 'High School Diploma/ GED'], [3, "Some College/Associate's Degree"], [4, "Bachelor Degree"], [5, "Graduate Degree"]], widget=widgets.RadioSelect) marital = models.PositiveIntegerField(label='What is your marital status?', choices=[[0, 'Single, Never Married'], [1, 'Married or domestic partnership'], [2, 'Widowed/Divorced/Separated']], widget=widgets.RadioSelect) income = models.PositiveIntegerField(widget=widgets.RadioSelect, choices=[[0, 'Less than $10,000'], [1, 'Between $10,000 and $19,999'], [2, '$20,000 to $29,999'], [3, '$30,000 to $39,999'], [4, '$40,000 to $49,999'], [5, '$50,000 to $59,999'], [6, '$60,000 to $69,999'], [7, '$70,000 to $79,999'], [8, '$80,000 to $89,999'], [9, '$90,000 to $99,999'], [10, '$100,000 to $149,999'], [11, 'More than $149,999'], ], label="What is your household's total combined income during the past 12 months? This includes money from jobs, net income from business, farm or rent, pensions, dividends, interest, Social Security payments and any other monetary income.") occup = models.PositiveIntegerField(widget=widgets.RadioSelect, choices=[[0, 'Professional/ Managerial'], [1, 'Sales/ Retail'], [2, 'Clerical/ Administrative'], [3, 'Services'], [4, 'Manual Work'], [5, 'Student'], [6, 'I have no work outside of MTurk']], label='What occupation type most accurately describes your work outside of MTurk?') state = models.PositiveIntegerField( choices=[[0, 'Not USA'], [1, 'Alabama'], [2, 'Alaska'], [3, 'Arizona'], [4, 'Arkansas'], [5, 'California'], [6, 'Colorado'], [7, 'Connecticut'], [8, 'Delaware'], [9, 'Florida'], [10, 'Georgia'], [11, 'Hawaii'], [12, 'Idaho'], [13, 'Illinois'], [14, 'Indiana'], [15, 'Iowa'], [16, 'Kansas'], [17, 'Kentucky'], [18, 'Louisiana'], [19, 'Maine'], [20, 'Maryland'], [21, 'Massachusetts'], [22, 'Michigan'], [23, 'Minnesota'], [24, 'Mississippi'], [25, 'Missouri'], [26, 'Montana'], [27, 'Nebraska'], [28, 'Nevada'], [29, 'New Hampshire'], [30, 'New Jersey'], [31, 'New Mexico'], [32, 'New York'], [33, 'North Carolina'], [34, 'North Dakota'], [35, 'Ohio'], [36, 'Oklahoma'], [37, 'Oregon'], [38, 'Pennsylvania'], [39, 'Rhode Island'], [40, 'South Carolina'], [41, 'South Dakota'], [42, 'Tennessee'], [43, 'Texas'], [44, 'Utah'], [45, 'Vermont'], [46, 'Virginia'], [47, 'Washington'], [48, 'West Virginia'], [49, 'Wisconsin'], [50, 'Wyoming']], label='Which state do you live in?') message_number = models.IntegerField(initial=0) def message_counter(self): self.message_number += 1