from locale import currency from otree.api import * from otree.api import Currency as c doc = """ Your app description """ class Constants(BaseConstants): name_in_url = 'MoralWiggleRoomDictator' players_per_group = None num_rounds = 1 compQ1Answer = c(3) compQ2Answer = c(5) compQ3Answer = c(1) compQ4Answer = c(2) compQ5Answer = c(3) class Subsession(BaseSubsession): def creating_session(self): import random for player in self.get_players(): # player.Treatment = random.choice(['Exit', 'ExitDelay', 'ExitRisk', 'ExitRiskDelay', 'ExitCharity', 'NoExit', 'NoExitCharity']) player.Treatment = random.choice(['ExitDelay']) player.Instructions = random.choice(['HighCorr','LowCorr','NoExampl']) ################################################### # GROUPS ################################################### class Group(BaseGroup): pass ################################################### # PLAYERS ################################################### class Player(BasePlayer): # Define treatment variable as a StringField Treatment = models.StringField() ReturnField = models.StringField() Risk = models.BooleanField(initial=False) Instructions = models.StringField() InstrHighCorr = models.BooleanField(initial=False) InstrLowCorr = models.BooleanField(initial=False) ## Dummy for 2 wrong answers messedUp = models.BooleanField(initial=False) ## Questions about binomial tree compQ1 = models.IntegerField( choices=[ [1,'0%'], [2,'25%'], [3,'50%'],[4,'75%'],[5,'100%'],[6,'None of the above'] ], widget=widgets.RadioSelect) compQ2 = models.IntegerField( choices=[ [1,'0%'], [2,'10%'], [3,'50%'],[4,'90%'],[5,'100%'],[6,'None of the above'] ], widget=widgets.RadioSelect) ## Questions about the volatility and other state parameters compQ3 = models.IntegerField( choices=[ [1,'Greater increases in value'], [2,'Higher swings in value'], [3,'More similar movements across two series'],[4,'Other'],[5,'Do not know'] ], widget=widgets.RadioSelect) compQ4 = models.IntegerField( choices=[ [1,'Greater increases in value'], [2,'Higher swings in value'], [3,'More similar movements across two series'],[4,'Other'],[5,'Do not know'] ], widget=widgets.RadioSelect) compQ5 = models.IntegerField( choices=[ [1,'Greater increases in value'], [2,'Higher swings in value'], [3,'More similar movements across two series'],[4,'Other'],[5,'Do not know'] ], widget=widgets.RadioSelect) compNoAttempts = models.IntegerField(initial=0) compNoAttemptsQ2 = models.IntegerField(initial=0) ########################################## ###### Order of treatments ## 1) Baseline condition #VR_B = Vola-Return order baseline condition TreatmentVR_B = models.StringField() ## 2) Unemployment condition #VR_U1 = Vola-Return order, unemployment condition 1 TreatmentVR_U1 = models.StringField() TreatmentVR_U2 = models.StringField() # U_Pos = Unemployment condition positive corr first TreatmentU_Pos = models.StringField() ## 3) Complexity condition # VR_B = Vola-Return order baseline condition complexity TreatmentVR_B_Com = models.StringField() TreatmentVR_U1_Com = models.StringField() TreatmentVR_U2_Com = models.StringField() TreatmentU_Pos_Com = models.StringField() VR_B = models.BooleanField(initial=False) VR_U1 = models.BooleanField(initial=False) VR_U2 = models.BooleanField(initial=False) U_Pos = models.BooleanField(initial=False) VR_B_Com = models.BooleanField(initial=False) VR_U1_Com = models.BooleanField(initial=False) VR_U2_Com = models.BooleanField(initial=False) U_Pos_Com = models.BooleanField(initial=False) ################################################### # INVESTMENTS - Baseline stock_b = models.CurrencyField(min=0, max=1000) bond_b = models.CurrencyField(min=0, max=1000) stock_b_hiRet = models.CurrencyField(min=0, max=1000) bond_b_hiRet = models.CurrencyField(min=0, max=1000) stock_b_hiVola = models.CurrencyField(min=0, max=1000) bond_b_hiVola = models.CurrencyField(min=0, max=1000) ################################################### # INVESTMENTS - Unemployment, positive correlation stock_Upos = models.CurrencyField(min=0, max=1000) bond_Upos = models.CurrencyField(min=0, max=1000) stock_hiRet_Upos = models.CurrencyField(min=0, max=1000) bond_hiRet_Upos = models.CurrencyField(min=0, max=1000) stock_hiVola_Upos = models.CurrencyField(min=0, max=1000) bond_hiVola_Upos = models.CurrencyField(min=0, max=1000) ################################################### # INVESTMENTS - Unemployment, negative correlation stock_Uneg = models.CurrencyField(min=0, max=1000) bond_Uneg = models.CurrencyField(min=0, max=1000) stock_hiRet_Uneg = models.CurrencyField(min=0, max=1000) bond_hiRet_Uneg = models.CurrencyField(min=0, max=1000) stock_hiVola_Uneg = models.CurrencyField(min=0, max=1000) bond_hiVola_Uneg = models.CurrencyField(min=0, max=1000) # ################################################### # # INVESTMENTS - Complexity Baseline # stock_b_Com = models.CurrencyField(min=0, max=1000) # bond_b_Com = models.CurrencyField(min=0, max=1000) # stock_b_hiRet_Com = models.CurrencyField(min=0, max=1000) # bond_b_hiRet_Com = models.CurrencyField(min=0, max=1000) # stock_b_hiVola_Com = models.CurrencyField(min=0, max=1000) # bond_b_hiVola_Com = models.CurrencyField(min=0, max=1000) # ################################################### # # INVESTMENTS - Complexity Unemployment, positive correlation # stock_Upos_Com = models.CurrencyField(min=0, max=1000) # bond_Upos_Com = models.CurrencyField(min=0, max=1000) # stock_hiRet_Upos_Com = models.CurrencyField(min=0, max=1000) # bond_hiRet_Upos_Com = models.CurrencyField(min=0, max=1000) # stock_hiVola_Upos_Com = models.CurrencyField(min=0, max=1000) # bond_hiVola_Upos_Com = models.CurrencyField(min=0, max=1000) # # ################################################### # # INVESTMENTS - Complexity Unemployment, negative correlation # stock_Uneg_Com = models.CurrencyField(min=0, max=1000) # bond_Uneg_Com = models.CurrencyField(min=0, max=1000) # stock_hiRet_Uneg_Com = models.CurrencyField(min=0, max=1000) # bond_hiRet_Uneg_Com = models.CurrencyField(min=0, max=1000) # stock_hiVola_Uneg_Com = models.CurrencyField(min=0, max=1000) # bond_hiVola_Uneg_Com = models.CurrencyField(min=0, max=1000) ################################################### # Preferences + Financial literacy ### FINANCIAL KNOWLEDGE ## My investment knowledge is good fin_know = models.IntegerField( choices=[ [0, '0 - Fully disagree'], [1, '1'], [2, '2'], [3, '3'], [4, '4'], [5, '5'], [6, '6'], [7, '7'], [8, '8'], [9, '9'], [10, '10 - Fully agree'] ], widget=widgets.RadioSelect ) ### RISK PREFERENCE # > Please tell me, in general: # how willing or unwilling you are to take risks. risk_pref = models.IntegerField( choices=[ [0, '0 - Completely unwilling to take risks'], [1, '1'], [2, '2'], [3, '3'], [4, '4'], [5, '5'], [6, '6'], [7, '7'], [8, '8'], [9, '9'], [10, '10 - Very willing to take risks'] ], widget=widgets.RadioSelect ) #### TIME PREFERENCE # > How willing are you to give up something that is beneficial for you today in order to benefit more from that in the future? time_pref = models.IntegerField( choices=[ [0, '0 - Completely unwilling to do so'], [1, '1'], [2, '2'], [3, '3'], [4, '4'], [5, '5'], [6, '6'], [7, '7'], [8, '8'], [9, '9'], [10, '7 - Very willing to do so'] ], widget=widgets.RadioSelect ) ### ALTRUISM # > How willing are you to give to good causes without expecting anything in return? altruism_pref = models.IntegerField( choices=[ [0, '0 - Completely unwilling to do so'], [1, '1'], [2, '2'], [3, '3'], [4, '4'], [5, '5'], [6, '6'], [7, '7'], [8, '8'], [9, '9'], [10, '10 - Very willing to do so'] ], widget=widgets.RadioSelect ) ### TRUST # > How well do the following statements describe you as a person? # I assume that people have only the best intentions. trust_pref = models.IntegerField( choices=[ [0, '0 - Does not describe me at all'], [1, '1'], [2, '2'], [3, '3'], [4, '4'], [5, '5'], [6, '6'], [7, '7'], [8, '8'], [9, '9'], [10, '10 - Describes me perfectly'] ], widget=widgets.RadioSelect ) ### POSITIVE RECIPROCITY # > When someone does me a favor I am willing to return it. positive_rec_pref = models.IntegerField( choices=[ [0, '0 - Does not describe me at all'], [1, '1'], [2, '2'], [3, '3'], [4, '4'], [5, '5'], [6, '6'], [7, '7'], [8, '8'], [9, '9'], [10, '10 - Describes me perfectly'] ], widget=widgets.RadioSelect ) ### NEGATIVE RECIPROCITY # > When someone does me a favor I am willing to return it. negative_rec_pref = models.IntegerField( choices=[ [0, '0 - Does not describe me at all'], [1, '1'], [2, '2'], [3, '3'], [4, '4'], [5, '5'], [6, '6'], [7, '7'], [8, '8'], [9, '9'], [10, '10 - Describes me perfectly'] ], widget=widgets.RadioSelect ) ################################################### ### DEMOGRAPHICS # Which situation applies most to you? situation = models.IntegerField( choices=[ [1, 'Single'], [2, "I have a partner, but I don't live together"], [3, 'I have a partner with whom I live'], [4, 'I am married'], [5, 'Prefer not to say'] ], widget=widgets.RadioSelect ) # How many children live in your household? children = models.IntegerField( choices=[ [0, "0"], [1, "1"], [2, "2"], [3, "3"], [4, "4 or more"] ], widget=widgets.RadioSelect ) # What is the highest education you have completed? educ = models.IntegerField( choices=[ [0, "O-level/GCSE"], [1, "A-level"], [2, "BA/Bsc."], [3, "MA/Msc."], [4, "Ph.D."], [5, "I have not completed any of the above types of training"], [6, "Prefer not to say"] ], widget=widgets.RadioSelect ) # Which of the following bands best describes your total salary per year before tax? income = models.IntegerField( choices=[ [0, "up to £10,000"], [1, "£10,000 - £18,000"], [2, "£18,001 - £25,000"], [3, "£25,001 - £33,000"], [4, "£33,001 - £45,000"], [5, "£45,001 - £60,000"], [6, "£60,001 - £65,000"], [7, "£65,001 - £85,000"], [8, "Above £85,000"], [9, "Don't know"], [10, "Prefer not to say"] ], widget=widgets.RadioSelect ) # Savings savings = models.IntegerField( choices=[ [0, "$0"], [1, "£1 - £1,000"], [2, "£1,001 - £2,500"], [3, "£2,501 - £5,000"], [4, "£5,001 - £9,000"], [5, "£9,001 - £15,000"], [6, "£15,001 - £30,000"], [7, "£30,001 - £50,000"], [8, "£50,001 - £80,000"], [9, "£80,001 - £100,000"], [10, "Above £100,001"], [11, "Don't know"], [12, "Prefer not to say"] ], widget=widgets.RadioSelect ) # Assign players to treatment groups ['Exit', 'ExitDelay', 'ExitRisk', 'ExitRiskDelay', 'ExitCharity', 'NoExit', 'NoExitCharity'] and define boolean fields to be used later on in the display of the instructions def assign_treatments(self): import random self.Treatment = random.choice( # ['Exit', 'ExitDelay', 'ExitRisk', 'ExitRiskDelay', 'ExitCharity', 'NoExit', 'NoExitCharity']) ['ExitDelay']) self.TreatmentVR_B = random.choice(['VolaRet','RetVola']) self.TreatmentVR_U1 = random.choice(['VolaRet', 'RetVola']) self.TreatmentVR_U2 = random.choice(['VolaRet', 'RetVola']) self.TreatmentU_Pos = random.choice(['PosNeg','NegPos']) self.TreatmentVR_B_Com = random.choice(['VolaRet','RetVola']) self.TreatmentVR_U1_Com = random.choice(['VolaRet', 'RetVola']) self.TreatmentVR_U2_Com = random.choice(['VolaRet', 'RetVola']) self.TreatmentU_Pos_Com = random.choice(['PosNeg','NegPos']) self.Instructions = random.choice( ['HighCorr','LowCorr','NoExampl']) if self.Treatment in ['ExitRiskDelay']: self.Risk = False if self.Instructions in ['HighCorr']: self.InstrHighCorr = True if self.Instructions in ['LowCorr']: self.InstrLowCorr = True ## Set order of decisions if self.TreatmentVR_B in ['VolaRet']: self.VR_B = True if self.TreatmentVR_U1 in ['VolaRet']: self.VR_U1 = True if self.TreatmentVR_U2 in ['VolaRet']: self.VR_U2 = True if self.TreatmentU_Pos in ['PosNeg']: self.U_Pos = True if self.TreatmentVR_B_Com in ['VolaRet']: self.VR_B_Com = True if self.TreatmentVR_U1_Com in ['VolaRet']: self.VR_U1_Com = True if self.TreatmentVR_U2_Com in ['VolaRet']: self.VR_U2_Com = True if self.TreatmentU_Pos_Com in ['PosNeg']: self.U_Pos_Com = True #Consent Consent = models.IntegerField(choices=[[1, 'I’m at least 18, understand the consent form, and agree to participate.'], [2, 'I don’t agree.']], widget=widgets.RadioSelect) ################################################### # PAGES ################################################### class Consent(Page): form_model = 'player' form_fields = ['Consent'] ## Call the assign treatment function here def before_next_page(player, timeout_happened): player.assign_treatments() def error_message(self, values): print('values is', values) if values['Consent'] == 2: return 'You can only participate in this study if you give your consent.' ################################################## ################################################## # COMPREHENSION QUESTIONS PAGE FOR SENDER class ComprehensionQ(Page): form_model = 'player' form_fields = ['compQ1', 'compQ2'] def error_message(self, values): print('values is', values) if self.compNoAttempts is None: self.compNoAttempts = 0 if self.compNoAttempts == 2: if values['compQ1'] != Constants.compQ1Answer or values['compQ2'] != Constants.compQ2Answer: self.messedUp = True if self.compNoAttempts < 2: if values['compQ1'] != Constants.compQ1Answer or values['compQ2'] != Constants.compQ2Answer: self.compNoAttempts = self.compNoAttempts + 1 return 'You have entered the wrong answer.' class ComprehensionQ_2(Page): form_model = 'player' form_fields = ['compQ3', 'compQ4', 'compQ5'] def return_message(self): self.ReturnField = " " def error_message(self, values): print('values is', values) if self.compNoAttemptsQ2 is None: self.compNoAttemptsQ2 = 0 if self.compNoAttemptsQ2 == 2: if values['compQ3'] != Constants.compQ3Answer or values['compQ4'] != Constants.compQ4Answer or values['compQ5'] != Constants.compQ5Answer: self.messedUp = True if self.compNoAttemptsQ2 < 2: if values['compQ3'] != Constants.compQ3Answer and values['compQ4'] != Constants.compQ4Answer and values['compQ5'] != Constants.compQ5Answer: self.compNoAttemptsQ2 = self.compNoAttemptsQ2 + 1 return "You answered all questions wrong." if values['compQ3'] != Constants.compQ3Answer and values['compQ4'] != Constants.compQ4Answer and values['compQ5'] == Constants.compQ5Answer: self.compNoAttemptsQ2 = self.compNoAttemptsQ2 + 1 return "You answered questions one and two wrong." if values['compQ3'] != Constants.compQ3Answer and values['compQ4'] == Constants.compQ4Answer and values[ 'compQ5'] != Constants.compQ5Answer: self.compNoAttemptsQ2 = self.compNoAttemptsQ2 + 1 return "You answered questions one and three wrong." if values['compQ3'] == Constants.compQ3Answer and values['compQ4'] != Constants.compQ4Answer and values[ 'compQ5'] != Constants.compQ5Answer: self.compNoAttemptsQ2 = self.compNoAttemptsQ2 + 1 return "You answered questions two and three wrong." if values['compQ3'] != Constants.compQ3Answer and values['compQ4'] == Constants.compQ4Answer and values[ 'compQ5'] == Constants.compQ5Answer: self.compNoAttemptsQ2 = self.compNoAttemptsQ2 + 1 return "You answered question one wrong." if values['compQ3'] == Constants.compQ3Answer and values['compQ4'] != Constants.compQ4Answer and values[ 'compQ5'] == Constants.compQ5Answer: self.compNoAttemptsQ2 = self.compNoAttemptsQ2 + 1 return "You answered question two wrong." if values['compQ3'] == Constants.compQ3Answer and values['compQ4'] == Constants.compQ4Answer and values[ 'compQ5'] != Constants.compQ5Answer: self.compNoAttemptsQ2 = self.compNoAttemptsQ2 + 1 return "You answered question three wrong." ################################################## class ComprehensionQRisk(Page): form_model = 'player' form_fields = ['compQ3Risk'] def error_message(self, values): if values['compQ3Risk'] != Constants.compQ3Answer: self.compNoAttemptsRiskQ = self.compNoAttemptsRiskQ + 1 return 'You have entered the wrong answer.' def is_displayed(self): return self.Treatment in ['ExitRisk'] ################################################### ## Information pages ################################################### # class InfoSender(Page): # def is_displayed(self): # return self.Delay==False class InfoSenderDelay(Page): def is_displayed(self): return self.Delay == True ## Page before showing participants the instructions that the receiver gets. For all treatments, except charity class InterimSender(Page): def is_displayed(self): return self.Charity==False class InfoReceiverForSender(Page): def is_displayed(self): return self.Charity==False ################################################### ## Allocation choices ################################################### ################################################### ## 1. BASELINE class DecisionScreen_b(Page): form_model = 'player' form_fields = ['stock_b','bond_b'] def error_message(self, values): print('values is', values) if values['stock_b'] + values['bond_b'] != 1000: return 'The two amounts must sum up to $1,000.' class DecisionScreen_b2(Page): form_model = 'player' form_fields = ['stock_b_hiVola', 'bond_b_hiVola'] def error_message(self, values): print('values is', values) if values['stock_b_hiVola'] + values['bond_b_hiVola'] != 1000: return 'The two amounts must sum up to $1,000.' def is_displayed(self): return self.VR_B==True class DecisionScreen_b3(Page): form_model = 'player' form_fields = ['stock_b_hiRet', 'bond_b_hiRet'] def error_message(self, values): print('values is', values) if values['stock_b_hiRet'] + values['bond_b_hiRet'] != 1000: return 'The two amounts must sum up to $1,000.' class DecisionScreen_b2_dupl(Page): form_model = 'player' form_fields = ['stock_b_hiVola', 'bond_b_hiVola'] def error_message(self, values): print('values is', values) if values['stock_b_hiVola'] + values['bond_b_hiVola'] != 1000: return 'The two amounts must sum up to $1,000.' def is_displayed(self): return self.VR_B==False ################################################### ## 2. UNEMPLOYMENT ################################################### ##### 2.1. Positive correlation class DecisionScreen_Upos(Page): form_model = 'player' form_fields = ['stock_Upos','bond_Upos'] def error_message(self, values): print('values is', values) if values['stock_Upos'] + values['bond_Upos'] != 1000: return 'The two amounts must sum up to $1,000.' def is_displayed(self): return self.U_Pos==True class DecisionScreen_Upos2(Page): form_model = 'player' form_fields = ['stock_hiVola_Upos', 'bond_hiVola_Upos'] def error_message(self, values): print('values is', values) if values['stock_hiVola_Upos'] + values['bond_hiVola_Upos'] != 1000: return 'The two amounts must sum up to $1,000.' def is_displayed(self): return self.U_Pos==True and self.VR_U1==True class DecisionScreen_Upos3(Page): form_model = 'player' form_fields = ['stock_hiRet_Upos', 'bond_hiRet_Upos'] def error_message(self, values): print('values is', values) if values['stock_hiRet_Upos'] + values['bond_hiRet_Upos'] != 1000: return 'The two amounts must sum up to $1,000.' def is_displayed(self): return self.U_Pos==True class DecisionScreen_Upos2_dupl(Page): form_model = 'player' form_fields = ['stock_hiVola_Upos', 'bond_hiVola_Upos'] def error_message(self, values): print('values is', values) if values['stock_hiVola_Upos'] + values['bond_hiVola_Upos'] != 1000: return 'The two amounts must sum up to $1,000.' def is_displayed(self): return self.U_Pos==True and self.VR_U1==False ################################################### ### 2.2. Positive correlation duplicate [for randomizing order] class DecisionScreen_Upos_dup(Page): form_model = 'player' form_fields = ['stock_Upos','bond_Upos'] def error_message(self, values): print('values is', values) if values['stock_Upos'] + values['bond_Upos'] != 1000: return 'The two amounts must sum up to $1,000.' def is_displayed(self): return self.U_Pos==False class DecisionScreen_Upos2_dup(Page): form_model = 'player' form_fields = ['stock_hiVola_Upos', 'bond_hiVola_Upos'] def error_message(self, values): print('values is', values) if values['stock_hiVola_Upos'] + values['bond_hiVola_Upos'] != 1000: return 'The two amounts must sum up to $1,000.' def is_displayed(self): return self.U_Pos==False and self.VR_U1==True class DecisionScreen_Upos3_dup(Page): form_model = 'player' form_fields = ['stock_hiRet_Upos', 'bond_hiRet_Upos'] def error_message(self, values): print('values is', values) if values['stock_hiRet_Upos'] + values['bond_hiRet_Upos'] != 1000: return 'The two amounts must sum up to $1,000.' def is_displayed(self): return self.U_Pos==False class DecisionScreen_Upos2_dupl_dup(Page): form_model = 'player' form_fields = ['stock_hiVola_Upos', 'bond_hiVola_Upos'] def error_message(self, values): print('values is', values) if values['stock_hiVola_Upos'] + values['bond_hiVola_Upos'] != 1000: return 'The two amounts must sum up to $1,000.' def is_displayed(self): return self.U_Pos==False and self.VR_U1==False ################################################### ### 2.3. Negative correlation class DecisionScreen_Uneg(Page): form_model = 'player' form_fields = ['stock_Uneg', 'bond_Uneg'] def error_message(self, values): print('values is', values) if values['stock_Uneg'] + values['bond_Uneg'] != 1000: return 'The two amounts must sum up to $1,000.' class DecisionScreen_Uneg2(Page): form_model = 'player' form_fields = ['stock_hiVola_Uneg','bond_hiVola_Uneg'] def error_message(self, values): print('values is', values) if values['stock_hiVola_Uneg'] + values['bond_hiVola_Uneg'] != 1000: return 'The two amounts must sum up to $1,000.' def is_displayed(self): return self.VR_U2==True class DecisionScreen_Uneg2_dupl(Page): form_model = 'player' form_fields = ['stock_hiVola_Uneg','bond_hiVola_Uneg'] def error_message(self, values): print('values is', values) if values['stock_hiVola_Uneg'] + values['bond_hiVola_Uneg'] != 1000: return 'The two amounts must sum up to $1,000.' def is_displayed(self): return self.VR_U2==False class DecisionScreen_Uneg3(Page): form_model = 'player' form_fields = ['stock_hiRet_Uneg', 'bond_hiRet_Uneg'] def error_message(self, values): print('values is', values) if values['stock_hiRet_Uneg'] + values['bond_hiRet_Uneg'] != 1000: return 'The two amounts must sum up to $1,000.' ################################################### ## COMPLEXITY # class DecisionScreen_b_Com(Page): # form_model = 'player' # form_fields = ['stock_b_Com','bond_b_Com', 'stock_b_hiRet_Com', 'bond_b_hiRet_Com', 'stock_b_hiVola_Com', 'bond_b_hiVola_Com'] # # def error_message(self, values): # print('values is', values) # if values['stock_b_Com'] + values['bond_b_Com'] != 1000: # return 'The two amounts must sum up to $1,000.' # if values['stock_b_hiRet_Com'] + values['bond_b_hiRet_Com'] != 1000: # return 'The two amounts must sum up to $1,000.' # if values['stock_b_hiVola_Com'] + values['bond_b_hiVola_Com'] != 1000: # return 'The two amounts must sum up to $1,000.' # # class DecisionScreen_Upos_Com(Page): # form_model = 'player' # form_fields = ['stock_Upos_Com','bond_Upos_Com', 'stock_hiRet_Upos_Com', 'bond_hiRet_Upos_Com', 'stock_hiVola_Upos_Com', 'bond_hiVola_Upos_Com'] # # def error_message(self, values): # print('values is', values) # if values['stock_Upos_Com'] + values['bond_Upos_Com'] != 1000: # return 'The two amounts must sum up to $1,000.' # if values['stock_hiRet_Upos_Com'] + values['bond_hiRet_Upos_Com'] != 1000: # return 'The two amounts must sum up to $1,000.' # if values['stock_hiVola_Upos_Com'] + values['bond_hiVola_Upos_Com'] != 1000: # return 'The two amounts must sum up to $1,000.' # # def is_displayed(self): # return self.U_Pos_Com==True # # # class DecisionScreen_Upos_dup_Com(Page): # form_model = 'player' # form_fields = ['stock_Upos_Com', 'bond_Upos_Com', 'stock_hiRet_Upos_Com', 'bond_hiRet_Upos_Com', 'stock_hiVola_Upos_Com', # 'bond_hiVola_Upos_Com'] # # def error_message(self, values): # print('values is', values) # if values['stock_Upos_Com'] + values['bond_Upos_Com'] != 1000: # return 'The two amounts must sum up to $1,000.' # if values['stock_hiRet_Upos_Com'] + values['bond_hiRet_Upos_Com'] != 1000: # return 'The two amounts must sum up to $1,000.' # if values['stock_hiVola_Upos_Com'] + values['bond_hiVola_Upos_Com'] != 1000: # return 'The two amounts must sum up to $1,000.' # # def is_displayed(self): # return self.U_Pos_Com == False # # # class DecisionScreen_Uneg_Com(Page): # form_model = 'player' # form_fields = ['stock_Uneg_Com', 'bond_Uneg_Com', 'stock_hiRet_Uneg_Com', 'bond_hiRet_Uneg_Com', 'stock_hiVola_Uneg_Com', # 'bond_hiVola_Uneg_Com'] # # def error_message(self, values): # print('values is', values) # if values['stock_Uneg_Com'] + values['bond_Uneg_Com'] != 1000: # return 'The two amounts must sum up to $1,000.' # if values['stock_hiRet_Uneg_Com'] + values['bond_hiRet_Uneg_Com'] != 1000: # return 'The two amounts must sum up to $1,000.' # if values['stock_hiVola_Uneg_Com'] + values['bond_hiVola_Uneg_Com'] != 1000: # return 'The two amounts must sum up to $1,000.' ################################################## ################################################## # PREFERENCES + FINANCIAL KNOWLEDGE QUESTIONS ? + ADD-ON DEMOGRAPHICS ? ################################################## class PreferenceQ(Page): form_model = 'player' form_fields = ['fin_know', 'risk_pref', 'time_pref', 'altruism_pref', 'trust_pref', 'positive_rec_pref', 'negative_rec_pref'] class Demographics(Page): form_model = 'player' form_fields = ['situation', 'children', 'educ', 'income', 'savings'] class ThankYou(Page): pass ################################################## # INSTRUCTIONS ################################################## class Instructions1(Page): pass class Instructions2(Page): pass class Instructions_Bond(Page): pass class Instructions3(Page): pass # class Instructions2_take2(Page): # def is_displayed(self): # return self.WannaSeeInstructions == 1 class MessedUp(Page): def is_displayed(self): return self.messedUp == True # Page sequence for delay treatment page_sequence = [ Consent, Instructions1, Instructions2, Instructions_Bond, ComprehensionQ, MessedUp, DecisionScreen_b, DecisionScreen_b2, DecisionScreen_b3, DecisionScreen_b2_dupl, DecisionScreen_Upos, DecisionScreen_Upos2, DecisionScreen_Upos3, DecisionScreen_Upos2_dupl, DecisionScreen_Uneg, DecisionScreen_Uneg2, DecisionScreen_Uneg3, DecisionScreen_Uneg2_dupl, DecisionScreen_Upos_dup, DecisionScreen_Upos2_dup, DecisionScreen_Upos3_dup, DecisionScreen_Upos2_dupl_dup, PreferenceQ, Demographics, ThankYou] # Setting with explicit correlations # page_sequence = [ Consent, Instructions1, Instructions2, Instructions3, ComprehensionQ, MessedUp, ComprehensionQ_2, MessedUp, # DecisionScreen_b, DecisionScreen_Upos, DecisionScreen_Uneg, DecisionScreen_Upos_dup, # DecisionScreen_b_Com, DecisionScreen_Upos_Com, DecisionScreen_Uneg_Com, DecisionScreen_Upos_dup_Com, # PreferenceQ, Demographics, ThankYou] # For test purposes #page_sequence = [ DecisionScreen_Upos_dup_Com, # PreferenceQ, Demographics, ThankYou]