from otree.api import * doc = """ Your app description """ class C(BaseConstants): NAME_IN_URL = 'IncentivizedBeliefs' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): #treatment variable myTreatment = models.IntegerField() #0 = environmental, 1 = racial #socio-demographics gender = models.IntegerField(choices=[[99, 'none of the above'], [1, 'Man'], [0, 'Woman']]) age = models.IntegerField(min=12, max=100) education = models.IntegerField( choices=[[0, 'less than high school degree'], [1, 'high school degree or equivalent'], [2, 'some college'], [3, '2-year college degree'], [4, 'bachelor/4-year college degree'], [5, 'some graduate school'], [6, 'graduate degree (e.g. JD/MD/MA/PhD))']]) #race (needs to be implemented as bools per value because multiple options may apply for the same person) white = models.BooleanField(blank=True) black = models.BooleanField(blank=True) hispanic = models.BooleanField(blank=True) asian = models.BooleanField(blank=True) native = models.BooleanField(blank=True) otherRace = models.BooleanField(blank=True) whiteOrder = models.IntegerField() blackOrder = models.IntegerField() hispanicOrder = models.IntegerField() asianOrder = models.IntegerField() nativeOrder = models.IntegerField() income = models.IntegerField( choices=[[0, 'Less than $10,000'], [1, '$10,000 to $19,999'], [2, '$20,000 to $29,999'], [3, '$30,000 to $39,999'], [4, '$40,000 to $49,999'], [5, '5$0,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 $109,999'], [11, '$110,000 to $119,999'], [12, '$120,000 to $129,999'], [13, '$130,000 to $139,999'], [14, '$140,000 to $149,999'], [15, 'More than $150,000']]) #political measures partisanship = models.FloatField() checksliderPartisanship = models.FloatField(initial=-1, blank=True) didVoteLastElection = models.IntegerField(choices=[[0, 'No'], [1, 'Yes'], [-1, 'I was not allowed to vote'], [-2, 'I do not want to answer']]) perceivedPolarization = models.FloatField() checksliderPerceivedPolarization = models.FloatField(initial=-1, blank=True) perceivedPolarizationCC = models.FloatField() checksliderPerceivedPolarizationCC = models.FloatField(initial=-1, blank=True) #self-report measures unincentivized1 = models.FloatField() #treatment 0 = declineSpecies; treatment1 = unincentivized2 = models.FloatField() #treatment 0 = increaseTemp; treatment1 = unincentivized3 = models.FloatField() #treatment 0 = humanClimateChange; treatment1 = unincentivized4 = models.FloatField() #treatment 0 = increaseHurricanes; treatment1 = unincentivized5 = models.FloatField() #treatment 0 = increaseWildfires; treatment1 = checkslider1 = models.FloatField(initial = -1, blank = True) checkslider2 = models.FloatField(initial = -1, blank = True) checkslider3 = models.FloatField(initial = -1, blank = True) checkslider4 = models.FloatField(initial = -1, blank = True) checkslider5 = models.FloatField(initial = -1, blank = True) directPartyPreference = models.IntegerField(choices=[[0, 'Democrats'], [1, 'Republicans']]) #incentivized measures estimateTest = models.FloatField() checksliderTest = models.FloatField(initial = -9999, blank = True) estimateTemperatureDiff = models.FloatField() checksliderTemperatureDiff = models.FloatField(initial = -9999, blank = True) estimateTemperatureDiffAbs = models.FloatField() errorMyGuess = models.FloatField(initial = -9999, blank = True) bonusMyGuess = models.FloatField() madeMyGuess = models.IntegerField(initial = 0) estimateOthersEstimate = models.FloatField() checksliderOthersEstimate = models.FloatField(initial = -9999, blank = True) estimateOthersEstimateAbs = models.FloatField() errorOtherGuess = models.FloatField(initial = -9999, blank = True) bonusOtherGuess = models.FloatField() #final questions usedHelp = models.IntegerField(choices=[[0, 'No'], [1, 'Yes']]) checksliderTrustInData = models.FloatField(initial = -1, blank = True) trustInData = models.FloatField() comments = models.StringField(blank = True) ########################################## PAGES ########################################## class welcome(Page): @staticmethod def before_next_page(player, timeout_happened): import random # assignign treatment factors player.myTreatment = random.randint(0,1) #0 = Climate change ; 1 = Racial questions #making sure race options appear in random order orderRace = list(range(1,6)) random.shuffle(orderRace) player.whiteOrder = orderRace[0] player.blackOrder = orderRace[1] player.hispanicOrder = orderRace[2] player.asianOrder = orderRace[3] player.nativeOrder = orderRace[4] class preQuestion(Page): form_model = 'player' form_fields = [ 'education', 'gender', 'age', 'income', 'white', 'black', 'hispanic', 'asian', 'native', 'otherRace', 'partisanship', 'didVoteLastElection', 'perceivedPolarization', 'perceivedPolarizationCC', 'checksliderPerceivedPolarization', 'checksliderPartisanship', 'checksliderPerceivedPolarizationCC', 'directPartyPreference'] @staticmethod def error_message(player,values): if player.checksliderPartisanship < 0: return 'It seems you did not move the slider under question 7, which is needed to continue. If your response for that question is supposed to be in the center, please move the slider a little and then move it back to the center, so it is clear that you actively chose the center.' if player.checksliderPerceivedPolarization < 0: return 'It seems you did not move the slider under question 8, which is needed to continue. If your response for that question is supposed to be in the center, please move the slider a little and then move it back to the center, so it is clear that you actively chose the center.' if player.checksliderPerceivedPolarizationCC < 0: return 'It seems you did not move the slider under question 9, which is needed to continue. If your response for that question is supposed to be in the center, please move the slider a little and then move it back to the center, so it is clear that you actively chose the center.' @staticmethod def live_method(player, data): t = data['slider'] thisValue = float(data['v']) if t == 1: player.partisanship = thisValue player.checksliderPartisanship = thisValue if t == 2: player.perceivedPolarization = thisValue player.checksliderPerceivedPolarization = thisValue if t == 3: player.perceivedPolarizationCC = thisValue player.checksliderPerceivedPolarizationCC = thisValue @staticmethod def js_vars(player): return dict( partisanship = player.field_maybe_none('partisanship'), perceivedPolarization = player.field_maybe_none('perceivedPolarization'), perceivedPolarizationCC = player.field_maybe_none('perceivedPolarizationCC') ) class unincentivizedBeliefs(Page): form_model = 'player' form_fields = ['unincentivized1','unincentivized2','unincentivized3','unincentivized4','unincentivized5', 'checkslider1','checkslider2','checkslider3','checkslider4','checkslider5'] @staticmethod def error_message(player,values): if player.checkslider1 < 0: return 'It seems you did not move the slider under question 1, which is needed to continue. If your response for that question is supposed to be in the center, please move the slider a little and then move it back to the center, so it is clear that you actively chose the center.' if player.checkslider2 < 0: return 'It seems you did not move the slider under question 2, which is needed to continue. If your response for that question is supposed to be in the center, please move the slider a little and then move it back to the center, so it is clear that you actively chose the center.' if player.checkslider3 < 0: return 'It seems you did not move the slider under question 3, which is needed to continue. If your response for that question is supposed to be in the center, please move the slider a little and then move it back to the center, so it is clear that you actively chose the center.' if player.checkslider4 < 0: return 'It seems you did not move the slider under question 4, which is needed to continue. If your response for that question is supposed to be in the center, please move the slider a little and then move it back to the center, so it is clear that you actively chose the center.' if player.checkslider5 < 0: return 'It seems you did not move the slider under question 5, which is needed to continue. If your response for that question is supposed to be in the center, please move the slider a little and then move it back to the center, so it is clear that you actively chose the center.' @staticmethod def live_method(player, data): t = data['slider'] thisValue = float(data['v']) if t == 1: player.unincentivized1 = thisValue player.checkslider1 = thisValue if t == 2: player.unincentivized2 = thisValue player.checkslider2 = thisValue if t == 3: player.unincentivized3 = thisValue player.checkslider3 = thisValue if t == 4: player.unincentivized4 = thisValue player.checkslider4 = thisValue if t == 5: player.unincentivized5 = thisValue player.checkslider5 = thisValue @staticmethod def js_vars(player): return dict( unincentivized1=player.field_maybe_none('unincentivized1'), unincentivized2=player.field_maybe_none('unincentivized2'), unincentivized3=player.field_maybe_none('unincentivized3'), unincentivized4=player.field_maybe_none('unincentivized4'), unincentivized5=player.field_maybe_none('unincentivized5'), ) class announceTimePressure(Page): timeout_seconds = 300 class presentTest(Page): timeout_seconds = 80 class estimateTest(Page): timeout_seconds = 80 form_model = 'player' form_fields = ['estimateTest','checksliderTest'] @staticmethod def error_message(player,values): if player.checksliderTest < -1000: return 'Please move the slider to indicate your response. If your response for that question is supposed to be in the center, please move the slider a little and then move it back to the center, so it is clear that you actively chose the center.' @staticmethod def live_method(player, data): t = data['slider'] thisValue = float(data['v']) if t == 1: player.estimateTest = thisValue player.checksliderTest = thisValue class getReady4RealTask(Page): form_model = 'player' form_fields = ['trustInData','checksliderTrustInData'] @staticmethod def error_message(player,values): if player.checksliderTrustInData < 0: return 'Please move the slider to indicate your response. If your response for that question is supposed to be in the center, please move the slider a little and then move it back to the center, so it is clear that you actively chose the center.' @staticmethod def live_method(player, data): t = data['slider'] thisValue = float(data['v']) if t == 1: player.trustInData = thisValue player.checksliderTrustInData = thisValue class presentTempDiff(Page): timeout_seconds = 120 class estimateTempDiff(Page): timeout_seconds = 50 form_model = 'player' form_fields = ['estimateTemperatureDiff', 'checksliderTemperatureDiff'] @staticmethod def error_message(player,values): if player.checksliderTemperatureDiff < -1000: return 'It seems you did not move the slider, which is needed to continue. If your response for that question is supposed to be in the center, please move the slider a little and then move it back to the center, so it is clear that you actively chose the center.' @staticmethod def live_method(player, data): t = data['slider'] thisValue = float(data['v']) if t == 1: player.estimateTemperatureDiff = thisValue player.checksliderTemperatureDiff = thisValue player.madeMyGuess = 1 @staticmethod def before_next_page(player, timeout_happened): if player.myTreatment == 0: player.errorMyGuess = abs(2.22 - player.estimateTemperatureDiff) if player.myTreatment == 1: player.errorMyGuess = abs(3.115 - player.estimateTemperatureDiff) player.estimateTemperatureDiffAbs = abs(player.estimateTemperatureDiff) player.bonusMyGuess = 2.0 - player.errorMyGuess if player.bonusMyGuess < 0.0: player.bonusMyGuess = 0.0 player.payoff = player.payoff + player.bonusMyGuess class presentEstimateOthers(Page): pass class estimateOthers(Page): form_model = 'player' form_fields = ['estimateOthersEstimate', 'checksliderOthersEstimate'] @staticmethod def error_message(player,values): if player.checksliderOthersEstimate < -1000: return 'It seems you did not move the slider, which is needed to continue. If your response for that question is supposed to be in the center, please move the slider a little and then move it back to the center, so it is clear that you actively chose the center.' @staticmethod def live_method(player, data): t = data['slider'] thisValue = float(data['v']) if t == 1: player.estimateOthersEstimate = thisValue player.checksliderOthersEstimate = thisValue @staticmethod def before_next_page(player, timeout_happened): if player.myTreatment == 0: player.errorOtherGuess = abs(4.1 - player.estimateOthersEstimate) if player.myTreatment == 1: player.errorOtherGuess = abs(1.1 - player.estimateOthersEstimate) player.estimateOthersEstimateAbs = abs(player.estimateOthersEstimate) player.bonusOtherGuess = 2.0 - player.errorOtherGuess if player.bonusOtherGuess < 0.0: player.bonusOtherGuess = 0.0 player.payoff = player.payoff + player.bonusOtherGuess class postQuestion(Page): form_model = 'player' form_fields = ['usedHelp', 'comments'] page_sequence = [welcome, preQuestion, unincentivizedBeliefs, announceTimePressure, presentTest, estimateTest, getReady4RealTask, presentTempDiff, estimateTempDiff, presentEstimateOthers, estimateOthers, postQuestion ]