#------------------------------------- # #------------------------------------- from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import random import math import openpyxl # should not use xlrd to read xlsx files. use: openpyxl and read_excel("my.xlsx",engine='openpyxl') import pandas author = 'Michael' doc = """ This is a study on investor behavior. """ #------------------------------------- # Basic inputs (parameters, distribution) #------------------------------------- class Constants(BaseConstants): name_in_url = 'PDE1' players_per_group = None num_rounds = 2 num_page = 1 # this is useless round numbers start from 1. begin_row = 1 n_of_distributions = 4 n_of_treatments = 12 num_rows = 50 # read the samples from return distributions sheet = pandas.read_excel('PDE1/r_distributions.xlsx', engine='openpyxl') #.sheet_by_index(0) sheet= sheet.dropna(axis=0, how="all", inplace=False) sheet= sheet.dropna(axis=1, how="all", inplace=False) distributions = {} for distr in range(n_of_distributions): distributions[distr] = [] for i in range(begin_row, num_rows + begin_row): distributions[distr].append([sheet.iloc[i, [2*distr]].iloc[0], sheet.iloc[i, [2*distr+1]].iloc[0]]) # Seems to work # print(distributions.keys()) # print(len(distributions)) # print(distributions) # contains all the possible permutations which are tested. i.e. in first treatment (0): in round 1 show distribution 1, round 2 show distribution 3 treat_orderings = {0:[1,2], 1:[2,1],2:[1,2], 3:[2,1], 4:[1,2], 5:[2,1], 6:[1,2], 7:[2,1], 8:[1,2], 9:[2,1], 10:[1,2], 11:[2,1]} bonus = c(10) #------------------------------------- # Allocate treatments #------------------------------------- class Subsession(BaseSubsession): def creating_session(self): # Allocate the treatment groups ---------------------------------------------------------- # grouping takes place only in the first round if self.round_number == 1: def apply_arrangement(lst, a): return [lst[i] for i in a] for p in self.get_players(): p.paid_subsection = random.randint(1,2) # Also, this would be better saved as participant. Currently saved as round 1 variable # Assign distribution combo th player This probably should be done to participant lvl. This way accessible in both rounds p.participant.vars['treatment_key'] = (p.participant.id_in_session-1) % Constants.n_of_treatments # Lists containing player's treatment distributions [round_1_dist, round_2_dist], sample oreder (row order), and pairs order (col order A = 0, B = 1) p.participant.vars['treatment_dists'] = [] p.participant.vars['sample_order'] = [] p.participant.vars['pair_order'] = [] for distr in Constants.treat_orderings[p.participant.vars['treatment_key']]: so = list(range(Constants.num_rows)); random.shuffle(so) # sample order po = [0,1]; random.shuffle(po) # pair order p.participant.vars['sample_order'].append(so) p.participant.vars['pair_order'].append(po) # apply the ordering to returns round_i_distr = [] for pair in apply_arrangement(Constants.distributions[distr-1],so): round_i_distr.append(apply_arrangement(pair,po)) p.participant.vars['treatment_dists'].append(round_i_distr) p.participant.vars['distribution_n'] = Constants.treat_orderings[p.participant.vars['treatment_key']] # Save treatment value, sampling pairs, order of sample etc. to fields in database--------------------- for p in self.get_players(): p.shown_distribution_id = p.participant.vars['distribution_n'][self.round_number-1] this_round_distr = p.participant.vars['treatment_dists'][self.round_number-1] p.shown_distribution = ' | '.join([str(pair).replace(',',' ') for pair in this_round_distr]) round_sample_order = p.participant.vars['sample_order'][self.round_number-1] p.shown_sample_order = ' '.join([str(i) for i in round_sample_order]) round_pair_order = p.participant.vars['pair_order'][self.round_number-1] p.shown_pair_order = ' '.join([str(i) for i in round_pair_order]) p.treatment_key = p.participant.vars['treatment_key'] class Group(BaseGroup): pass class Player(BasePlayer): # Treatment related --------------------------------- treatment_key = models.IntegerField() # which permutation in treat_orderings is selected shown_distribution_id = models.IntegerField() shown_distribution = models.LongStringField() shown_pair_order = models.LongStringField() shown_sample_order = models.LongStringField() # Payment related ----------------------------------- paid_subsection = models.PositiveIntegerField() # 1 or 2 (to be paid) paid_rendite1 = models.FloatField() paid_rendite2 = models.FloatField() payoff_100 = models.CurrencyField() # Other information -------------------------- browser_first = models.CharField() browser_last = models.CharField() #------------------------------------- # Tasks - Investment decision(s) #------------------------------------- # Player fills ----------------------------------- InvestmentAsset1 = models.CurrencyField( # initial=None, label='How much out of the £10\xa0000 do you invest into Asset 1?', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentAsset2 = models.CurrencyField( # initial=None, label='How much out of the £10\xa0000 do you invest into Asset 2?', min=0, max=10000, doc=""" Amount invested by this player. """ ) InvestmentEitherOr = models.CharField(initial=None, choices=['Asset 1', 'Asset 2', 'Indifferent (both assets are equally attractive)'], verbose_name='Alternatively: If you had to invest the full £10\xa0000 into either Asset 1 or Asset 2 (without the option to split the investment between the two assets), which asset would you select?', widget=widgets.RadioSelectHorizontal()) #------------------------------------- # Tasks - Beliefs about dependence #------------------------------------- BeliefsDependence_Overall = models.PositiveIntegerField( label='The returns of Asset 1 and Asset 2 move... Please select one of the categories between 1 ("most of the time in opposite directions") und 5 ("most of the time together").', choices=range(1, 6), initial=None, widget=widgets.RadioSelectHorizontal() ) BeliefsDependence_Direction1 = models.CharField(initial=None, choices=['negative', 'zero','positive'], verbose_name='If the return of Asset 1 is negative, I expect the return of Asset 2 to be...', widget=widgets.RadioSelectHorizontal() ) BeliefsDependence_Direction2 = models.CharField(initial=None, choices=['negative', 'zero','positive'], verbose_name='If the return of Asset 1 is positive, I expect the return of Asset 2 to be...', widget=widgets.RadioSelectHorizontal() ) BeliefsDependence_FreqComove1 = models.IntegerField( label='If the return of Asset 1 is negative, I expect Asset 2 to have a positive return in ... out of 100 cases.', min=0, max=100, ) BeliefsDependence_FreqComove2 = models.IntegerField( label='If the return of Asset 1 is positive, I expect Asset 2 to have a positive return in ... out of 100 cases.', min=0, max=100 ) # NOT USED # BeliefsDependence_FreqOutperf = models.IntegerField( # label='I expect the return of Asset 2 to be higher than the return of Asset 1 in ... out of 100 cases.', # min=0, max=100 # ) #------------------------------------- # Tasks - Beliefs about individual assets #------------------------------------- # NOT USED # BeliefsAssets_Mu = models.CharField(initial=None, # choices=['Asset 1', 'Asset 2','It is around the same for both assets.'], # verbose_name='Which Asset has the higher average return?', # widget=widgets.RadioSelectHorizontal() # ) # NOT USED # BeliefsDependence_Mu1 = models.FloatField( # label='I expect the return of Asset 1 to be ... (in %, e.g., 10 for 10%)' # ) # NOT USED # BeliefsDependence_Mu2 = models.FloatField( # label='I expect the return of Asset 2 to be ... (in %, e.g., 10 for 10%)' # ) # NOT USED # BeliefsAssets_PLoss = models.CharField(initial=None, # choices=['Asset 1', 'Asset 2','It is around the same for both assets.'], # verbose_name='Which Asset has the higher probability of realizing a loss (negative return)?', # widget=widgets.RadioSelectHorizontal() # ) # NOT USED # BeliefsDependence_PLoss1 = models.IntegerField( # label='I expect Asset 1 to realize a loss (negative return) in ... out of 100 cases.', # min=0, max=100 # ) # NOT USED # BeliefsDependence_PLoss2 = models.IntegerField( # label='I expect Asset 2 to realize a loss (negative return) in ... out of 100 cases.', # min=0, max=100 # ) # NOT USED # BeliefsAssets_Sigma = models.CharField(initial=None, # choices=['Asset 1', 'Asset 2','It is around the same for both assets.'], # verbose_name='Which Asset has the higher return volatility (higher fluctuation in returns)?', # widget=widgets.RadioSelectHorizontal() # ) # NOT USED # BeliefsAssets_SubjRisk1 = models.PositiveIntegerField( # label='How risky is Asset 1? Please select a category between 1 ("risk-free") and 7 ("very risky").', # choices=range(1, 8), # initial=None, # widget=widgets.RadioSelectHorizontal() # ) # NOT USED # BeliefsAssets_SubjRisk2 = models.PositiveIntegerField( # label='How risky is Asset 2? Please select a category between 1 ("risk-free") and 7 ("very risky").', # choices=range(1, 8), # initial=None, # widget=widgets.RadioSelectHorizontal() # ) #------------------------------------- # Tasks - Beliefs about portfolio return #------------------------------------- # NOT USED # BeliefsPortfolio_Wealth = models.CurrencyField( # # initial=None, # label='What level of wealth do you expect, given your investment decision (in £)?', # min=0, max=1000000 # ) BeliefsPortfolio_Mu = models.FloatField( label='I expect the return of my portfolio to be... (in %, e.g., 10 for 10%)' ) BeliefsPortfolio_PLoss = models.IntegerField( label='I expect my portfolio to realize a loss (negative return) in ... out of 100 cases', min=0, max=100 ) # NOT USED # BeliefsPortfolio_PLGain = models.IntegerField( # label='I expect my portfolio to realize a large gain (return above 20%) in ... out of 100 cases', # min=0, max=100 # ) # NOT USED # BeliefsPortfolio_PLLoss = models.IntegerField( # label='I expect my portfolio to realize a large loss (return below -10%) in ... out of 100 cases', # min=0, max=100 # ) BeliefsPortfolio_SubjRisk = models.PositiveIntegerField( label='How risky is your portfolio? Please select a category between 1 ("risk-free") and 7 ("very risky").', choices=range(1, 8), initial=None, widget=widgets.RadioSelectHorizontal() ) # NOT USED # BeliefsPortfolio_Confidence = models.PositiveIntegerField( # label='How confident are you about your investment decision? Please select a category between 1 ("not at all") and 7 ("completely confident").', # choices=range(1, 8), # initial=None, # widget=widgets.RadioSelectHorizontal()) #------------------------------------- # Tasks - Reasons for investment decision in a specific round #------------------------------------- # NOT USED ''' # http://otree.readthedocs.io/en/latest/forms.html#radio-buttons-in-tables-and-other-custom-layouts RoundSpecificReasons_Free = models.LongStringField( blank=True, label='Please describe in short why you made this investment allocation.', ) RoundSpecificReasons_Intuition = models.PositiveIntegerField( label='I made an intuitive choice, based on gut feeling.', choices=range(1, 8), initial=None, widget=widgets.RadioSelectHorizontal()) RoundSpecificReasons_AssetCompRisk = models.IntegerField( initial=None, verbose_name='Which of the following statements describes your view of the two assets?', choices=[ [1, 'Individually, Asset 1 was riskier than Asset 2'], [2, 'Individually, Asset 2 was riskier than Asset 1'], [3, 'Individually, Assets 1 and 2 were equally risky'], [4, 'I do not know'], ] ) RoundSpecificReasons_WeightAndDownsideRisk = models.IntegerField( initial=None , verbose_name='How would a change in investment weight affect the downside risks of your portfolio?' , choices=[ [1 , 'A lower investment into Asset 2 would increase my probability of loss'] , [2 , 'A higher investment into Asset 2 would increase my probability of loss'] , [3 , 'I do not know'] , ] ) RoundSpecificReasons_WeightAndUpsideChances = models.IntegerField( initial=None , verbose_name='How would a change in investment weight affect the upside chances of your portfolio?' , choices=[ [1 , 'A lower investment into Asset 2 would increase my probability of gain'] , [2 , 'A higher investment into Asset 2 would increase my probability of gain'] , [3 , 'I do not know'] , ] ) RoundSpecificReasons_2Hedges1 = models.PositiveIntegerField( label='I like the investment into Asset 2, because Asset 2 often delivers high returns, when Asset 1 delivers low returns, so that losses are offset.' , choices=range(1 , 8) , initial=None , widget=widgets.RadioSelectHorizontal()) RoundSpecificReasons_2Amplifies1 = models.PositiveIntegerField( label='I like the investment into Asset 2, because Asset 2 often delivers high returns, when Asset 1 delivers high returns, so that gains are amplified.' , choices=range(1 , 8) , initial=None , widget=widgets.RadioSelectHorizontal()) RoundSpecificReasons_RiskReturnRight = models.PositiveIntegerField( label='Overally, I think the risk-return-relation of my portfolio is just right.' , choices=range(1 , 8) , initial=None , widget=widgets.RadioSelectHorizontal()) ''' #------------------------------------- # Directly after two rounds - Stuff related to payoff #------------------------------------- # to show the realization to be used for payoff NB: Not used (?) def realize(self): return "{0:.2f}".format(self.realization) # access the number of the payoff round def pay_round_num(self): return self.in_round(1).paid_subsection paid_input1 = models.CurrencyField() paid_input2 = models.CurrencyField() # Payoff def set_payoffs(self): payoff_distribution = self.participant.vars['treatment_dists'][self.in_round(1).paid_subsection-1] # payoff_return_pair = random.sample(payoff_distribution,1) payoff_return_pair = payoff_distribution[random.randint(0,len(payoff_distribution)-1)] self.paid_rendite1 = payoff_return_pair[0] self.paid_rendite2 = payoff_return_pair[1] self.paid_input1 = self.in_round(self.in_round(1).paid_subsection).InvestmentAsset1 # How much participant invested in payoff round to asset1 self.paid_input2 = self.in_round(self.in_round(1).paid_subsection).InvestmentAsset2 # How much participant invested in payoff round to asset2 payoff = (self.paid_input1 * (1 + payoff_return_pair[0]) + self.paid_input2 * (1 + payoff_return_pair[1]))/10000 self.payoff = payoff #this to $payment port_value = self.paid_input1 * (1 + payoff_return_pair[0]) + self.paid_input2 * (1 + payoff_return_pair[1]) self.payoff_100 = port_value #----------------------------------------- # Directly after two rounds - Comparison of two rounds #----------------------------------------- # NOT USED ''' ComparisonRounds_Risk = models.IntegerField(initial=None, choices=[ [1, 'My first portfolio is riskier.'], [2, 'My two portfolios are equally risky.'], [3, 'My second portfolio is riskier.'], ], verbose_name='Which of the two portfolios you selected in your first and second round do you assess as riskier?', widget=widgets.RadioSelect()) ComparisonRounds_Return = models.IntegerField(initial=None, choices=[ [1, 'My first portfolio has a higher expected return.'], [2, 'My two portfolios have equally high expected returns.'], [3, 'My second portfolio has a higher expected return.'], ], verbose_name='Which of the two portfolios you selected in your first and second round exhibits higher expected returns?', widget=widgets.RadioSelect()) ''' #----------------------------------------- # Directly after two rounds - Reasons for investment decision independent of the particular round #----------------------------------------- # NOT USED ''' GenReasons_Mu_Consider = models.IntegerField( initial=None, verbose_name='Did you consider the average returns of Assets 1 and 2?', choices=[ [1, 'No'], [2, 'Yes'],], widget=widgets.RadioSelectHorizontal()) GenReasons_Mu_Direction = models.IntegerField( initial=None, verbose_name='You considered average returns of assets: Would you decrease or increase your investment into assets with a higher average return?', choices=[ [1, 'Decrease'], [2, 'Increase'], [3, 'I do not know'],], widget=widgets.RadioSelectHorizontal()) GenReasons_SigmaPL_Consider = models.IntegerField( initial=None, verbose_name='Did you consider the return volatily (fluctuation in returns or loss probability) of Assets 1 and 2?', choices=[ [1, 'No'], [2, 'Yes'],], widget=widgets.RadioSelectHorizontal()) GenReasons_SigmaPL_Direction = models.IntegerField( initial=None, verbose_name='You considered return volatilites (fluctuations in returns or loss probabilities) of assets: Would you decrease or increase you investment into assets with a higher return volatility (a higher fluctuation in returns or loss probability)?', choices=[ [1, 'Decrease'], [2, 'Increase'], [3, 'I do not know'],], widget=widgets.RadioSelectHorizontal()) GenReasons_Rho_Consider = models.IntegerField( initial=None, verbose_name='Did you consider the correlation between the returns of Assets 1 and 2 (e.g., whether Asset 2 tends to perform badly when Asset 1 performs badly and, vice versa, whether Asset 2 tends to perform well when Asset 1 performs well)?', choices=[ [1, 'No'], [2, 'Yes'],], widget=widgets.RadioSelectHorizontal()) GenReasons_Rho_Direction = models.IntegerField( initial=None, verbose_name='You considered the correlation: Would you decrease or increase you investment into assets with a higher correlation with your overall portfolio (i.e., Assets that go up when your portfolio goes up and down when your portfolio goes down)?', choices=[ [1, 'Decrease'], [2, 'Increase'], [3, 'I do not know'],], widget=widgets.RadioSelectHorizontal()) GenReasons_PD_Consider = models.IntegerField( initial=None, verbose_name='Did you consider the frequency of outperformance (e.g., the likelihood that the return of Asset 2 is higher than the return of Asset 1)?', choices=[ [1, 'No'], [2, 'Yes'],], widget=widgets.RadioSelectHorizontal()) GenReasons_PD_Direction = models.IntegerField( initial=None, verbose_name='You considered the frequency of outperformance: Would you decrease or increase your investment into assets with a higher frequency of outperformance?', choices=[ [1, 'Decrease'], [2, 'Increase'], [3, 'I do not know'],], widget=widgets.RadioSelectHorizontal()) ''' #----------------------------------------- # Demographics / Questionnaire - Can partially already be asked before the start of treatments (helps analyze attrition later on) #----------------------------------------- Demographics_Age = models.PositiveIntegerField( label='What is your age?', min=1, max=130 ) Demographics_Sex = models.IntegerField(initial=None, choices=[ [1, 'Male'], [2, 'Female'], ], verbose_name='Are you male or female?', widget=widgets.RadioSelectHorizontal()) Demographics_FinInterest = models.PositiveIntegerField( label='Are you interested in financial markets? Please select a category between 1 ("not at all") and 7 ("very much").', choices=range(1, 8), initial=None, widget=widgets.RadioSelectHorizontal() ) Demographics_Investor = models.IntegerField( initial=None, verbose_name='Do you own stocks or mutual funds?', choices=[ [1, 'No'], [2, 'Yes'], ] ) Demographics_FinanceProf = models.IntegerField( initial=None, verbose_name='Have you ever had a job in the financial industry?', choices=[ [1, 'No'], [2, 'Yes'], ] ) Demographics_RiskAffinity = models.PositiveIntegerField( verbose_name='Please assess your willingness to take financial risks. Select a category between 1 ("Not willing to take financial risks") and 5 ("Willing to take large risks to achieve a significant gain").', choices=range(1, 6), initial=None, widget=widgets.RadioSelectHorizontal()) Demographics_Statistics = models.PositiveIntegerField( verbose_name='How would you describe your skills in statistics? Please select a category between 1 ("Poor") and 5 ("Excellent").', choices=range(1, 6), initial=None, widget=widgets.RadioSelectHorizontal()) # NOT USED # Demographics_Impatience = models.PositiveIntegerField( # verbose_name='Are you generally rather impatient or patient? Please select a category between 0 ("Very impatient") and 10 ("Very patient").', # choices=range(0, 11), # initial=None, # widget=widgets.RadioSelectHorizontal()) # NOT USED #Demographics_NumberAffinity = models.PositiveIntegerField( # verbose_name='How do you assess the following statement (1="do not agree at all" and 6="fully agree"): I do not enjoy thinking about numerical problems.', # choices=range(1 , 7) , # initial=None , # widget=widgets.RadioSelectHorizontal()) # NOT USED # Demographics_ImportanceNumbers = models.PositiveIntegerField( # verbose_name='How do you assess the following statement (1="do not agree at all" and 6="fully agree"): I think it is important to learn about the correct interpretation of numerical information and to use numerical information to make good choices.', # choices=range(1 , 7) , # initial=None , # widget=widgets.RadioSelectHorizontal()) #----------------------------------------- # Understanding of diversification benefits #----------------------------------------- # NOT USED ''' DJ30PF_Return = models.PositiveIntegerField(initial=None, choices=[ [1, 'Higher return for Portfolio A'], [2, 'Higher return for Portfolio B'], [3, 'Same expectations'], ], verbose_name='For which portfolio do you expect a higher return?', widget=widgets.RadioSelectHorizontal()) DJ30PF_Risk = models.PositiveIntegerField(initial=None, choices=[ [1, 'Higher risk for Portfolio A'], [2, 'Higher risk for Portfolio B'], [3, 'Same risk'], ], verbose_name='For which portfolio do you expect higher risk?', widget=widgets.RadioSelectHorizontal()) ''' #----------------------------------------- # General financial literacy #----------------------------------------- # NOT USED ''' FinLit_1 = models.IntegerField( initial=None, verbose_name='The interest rate of your savings account is 1% per year and the inflation rate is 2% per year. What do you think: One year from now, will your savings be worth as much as today, more, or less than today?', choices=[ [1, 'More'], [2, 'As much as today'], [3, 'Less'], [4, 'Do not know'], [5, 'Prefer not to answer'], ] ) FinLit_2 = models.IntegerField( initial=None, verbose_name='True or false? "Bonds are usually riskier than stocks."', choices=[ [1, 'True'], [2, 'False'], [3, 'Do not know'], [4, 'Prefer not to answer'], ] ) FinLit_3 = models.IntegerField( initial=None, verbose_name='Which asset typically returns the most over a long investment horizon (for instance 10 or 20 years)?', choices=[ [1, 'Savings account'], [2, 'Stocks'], [3, 'Bonds'], [4, 'Do not know'], [5, 'Prefer not to answer'], ] ) FinLit_4 = models.IntegerField( initial=None, verbose_name='Which asset typically varies the most in value?', choices=[ [1, 'Savings account'], [2, 'Stocks'], [3, 'Bonds'], [4, 'Do not know'], [5, 'Prefer not to answer'], ] ) FinLit_5 = models.IntegerField( initial=None, verbose_name='If an investor allocates savings across multiple different assets, how does the risk of large losses change?', choices=[ [1, 'It increases'], [2, 'It decreases'], [3, 'It stays the same'], [4, 'Do not know'], [5, 'Prefer not to answer'], ] ) FinLit_6 = models.IntegerField( initial=None, verbose_name='True or false? "A mutual fund combines investments of many people, to buy a large number of different stocks."', choices=[ [1, 'True'], [2, 'False'], [3, 'Do not know'], [4, 'Prefer not to answer'], ] ) FinLit_7 = models.IntegerField( initial=None, verbose_name='True or false? "Returns of individual stocks vary less than returns of mutual funds."', choices=[ [1, 'True'], [2, 'False'], [3, 'Do not know'], [4, 'Prefer not to answer'], ] ) FinLit_8 = models.IntegerField( initial=None, verbose_name='Assume you have €100 on a savings account. The account returns 20% per year and ' 'you do not make any withdrawals (including interest payments). What is the balance ' 'of your account after five years?', choices=[ [1, 'More than €200'], [2, 'Exactly €200'], [3, 'Less than €200'], [4, 'Do not know'], [5, 'Prefer not to answer'], ] ) FinLit_9 = models.IntegerField( initial=None, verbose_name='Which of the following statements is correct?', choices=[ [1, 'After investing into a mutual fund, money cannot be withdrawn within the first year.'], [2, 'Mutual funds typically invest into multiples stocks.'], [3, 'Mutual funds guarantee a minimum payment, based on past performance.'], [4, 'None of the above statements is correct.'], [5, 'Do not know'], [6, 'Prefer not to answer'], ] ) FinLit_10 = models.IntegerField( initial=None, verbose_name='Which of the following statements is correct if someone buys a bond of firm B?', choices=[ [1, 'The investor owns part of firm B.'], [2, 'The investor has lent money to firm B.'], [3, 'The investor is liable for debts of firm B.'], [4, 'None of the above statements is correct.'], [5, 'Do not know'], [6, 'Prefer not to answer'], ] ) ''' #----------------------------------------- # Numeracy (Berlin numeracy test) #----------------------------------------- # NOT USED #----------------------------------------- # Overconfidence questions (overconfidence in performing better than others, or better than objectively true, ...) #----------------------------------------- # NOT USED #----------------------------------------- # Susceptibility to framing #----------------------------------------- # NOT USED ''' SusceptibilityFraming_1 = models.PositiveIntegerField( verbose_name='Psychologists have found that different wordings of the same message, despite unchanged content, ' 'affect the behavior of people differently. Opinions and choices of people can be manipulated ' 'with small variations in phrasing. For instance, people are more likely to buy products, which ' 'are "98% fat free" than products with "2% fat". ' 'How susceptible are you to such effects? Please describe a category between 1 ("Completely unsusceptible") and 7 ("Highly susceptible")?', choices=range(1, 8), initial=None, widget=widgets.RadioSelectHorizontal()) SusceptibilityFraming_2 = models.PositiveIntegerField( verbose_name='How susceptible are average participants of this experiment for such effects? Please select a category between 1 ("Completely unsusceptible") and 7 ("Highly susceptible")?', choices=range(1, 8), initial=None, widget=widgets.RadioSelectHorizontal()) ''' #----------------------------------------- # Final question (satisfaction, feedback...) #----------------------------------------- Satisfaction = models.PositiveIntegerField( verbose_name='How satisfied are you with your result? Plese select a category between 1 ("Very unsatisfied") and 5 ("Very satisfied")?', choices=range(1, 6), initial=None, widget=widgets.RadioSelectHorizontal()) OpenFeedback = models.LongStringField( blank=True, label='Please describe in short any feedback you might have on this experiment.', ) #----------------------------------------- # Stuff related to Prolific, mTurk, or other platform used to run the experiment #----------------------------------------- prolific_id = models.StringField( blank=True, label='Your Prolific ID') # pname = models.StringField( # blank=True, # label='Your Name',) # email = models.StringField( # blank=True, # label='Your e-mail adress',) # # clickerworker = models.LongStringField( # blank=True, # label='Please use this text field to give us feedback for your experiment. Particularly, let us know if you did not understand specific questions.',)