from otree.api import * import random import time c = Currency doc = """ Risk_sharing """ # On June 19th, the role of market a and b has been switched. Thus, we should pay special attention in data # class Constants(BaseConstants): players_per_group = 2 num_rounds = 4 name_in_url = 'Risk_Sharing_fixed' prize_guess = 2 instructions_template = 'risk_sharing_fixed/intro.html' payoff_trans1 = 6 payoff_trans2 = 6 payoff_trans3 = 12 payoff_trans4 = 12 payoffH = 35 payoffL = 5 formal = 15 prob_insurance = 0.5 # ---------------------------------------------------------------------------------------------------------------- # # --- Task-specific Settings --- # # ---------------------------------------------------------------------------------------------------------------- # # number (N) of lotteries with num_lotteries = 5 # sure_payoff; "low" and "high" payoff of the initial lottery (in currency units set in settings.py) # determines the 'starting point' for all lotteries in the single choice list (safe option in i = 1) # outcomes of subsequent lotteries are defined relative to the 'initial value' by the options below sure_payoff = 6 # increments of lottery outcomes (refer to the documentation for more detailed information) # defines the (negative) increment of the low outcome over the number of choices () # similarly, defines the (positive) increment of the high outcome for the choices delta_lo = 1 delta_hi = 2 # probability of lottery outcome "high" (in percent) # refers to the likelihood of outcome denoted in percent (as Integer or Float) # i.e. implies an x%-chance to win the "high" and a (1-x)%-chance to win the "low" payoff # note that the probability in this task is constant for each of the and only outcomes change probability = 50 # additional lottery to separate risk-loving from risk-neutral preferences # if , a lottery with the same expected value but a higher st. dev. as lottery is added # note that implies that the overall number of lotteries rendered will be + 1 risk_loving = True # ---------------------------------------------------------------------------------------------------------------- # # --- Overall Settings and Appearance --- # # ---------------------------------------------------------------------------------------------------------------- # # order choices between lottery pairs randomly # if , the ordering of binary decisions is randomized for display # if , binary choices are listed in ascending order of the probability of the "high" outcome random_order = False # show instructions page # if , a separate template "Instructions.html" is rendered prior to the task # if , the task starts immediately (e.g. in case of printed instructions) instructions = True # show results page summarizing the task's outcome including payoff information # if , a separate page containing all relevant information is displayed after finishing the task # if , the template "Decision.html" will not be rendered results = True class Subsession(BaseSubsession): pass class Group(BaseGroup): random1 = models.FloatField() random2 = models.FloatField() group_random3 = models.FloatField() random_transfer = models.FloatField() class Player(BasePlayer): random_insurance = models.FloatField() lottery_choice = models.IntegerField() otherrisk = models.IntegerField() outcome_to_pay = models.StringField() outcome_lo = models.CurrencyField() outcome_hi = models.CurrencyField() prob_hi = models.FloatField() prob_lo = models.FloatField() Selectedlottery = models.CurrencyField() payoffscl = models.CurrencyField() error = models.FloatField(initial=0) random3 = models.FloatField() transfer = models.IntegerField() random_a1 = models.FloatField() random_a2 = models.FloatField() random_b1 = models.FloatField() random_b2 = models.FloatField() a1r = models.FloatField() a2r = models.FloatField() b1r = models.FloatField() b2r = models.FloatField() a1bar = models.FloatField() a2bar = models.FloatField() b1bar = models.FloatField() b2bar = models.FloatField() Belief_a1r = models.IntegerField(initial=0) Belief_a2r = models.IntegerField(initial=0) Belief_b1r = models.IntegerField(initial=0) Belief_b2r = models.IntegerField(initial=0) rrandom_a1 = models.FloatField() rrandom_a2 = models.FloatField() rrandom_b1 = models.FloatField() rrandom_b2 = models.FloatField() ra1r = models.FloatField() ra2r = models.FloatField() rb1r = models.FloatField() rb2r = models.FloatField() ra1bar = models.FloatField() ra2bar = models.FloatField() rb1bar = models.FloatField() rb2bar = models.FloatField() rBelief_a1r = models.IntegerField(initial=0) rBelief_a2r = models.IntegerField(initial=0) rBelief_b1r = models.IntegerField(initial=0) rBelief_b2r = models.IntegerField(initial=0) rBelief_a1 = models.IntegerField(max=100, min=0) rBelief_a2 = models.IntegerField(max=100, min=0) rBelief_b1 = models.IntegerField(max=100, min=0) rBelief_b2 = models.IntegerField(max=100, min=0) rRealized_insurance = models.FloatField() Share_a = models.FloatField( choices=[[100, '分摊'], [0, '拒绝']], widget=widgets.RadioSelect, label="我选择:", initial=-1, ) Other_Share_a = models.FloatField(initial=-1) Other_Share_b = models.FloatField(initial=-1) Share_b = models.FloatField( choices=[[100, '分摊'], [0, '拒绝']], widget=widgets.RadioSelect, label="我选择:", ) Realized_insurance = models.FloatField(initial=-1) Belief_a1 = models.IntegerField(max=100, min=0) Belief_a2 = models.IntegerField(initial = -1) Belief_b1 = models.IntegerField(max=100, min=0) Belief_b2 = models.IntegerField(initial = -1) payoff1 = models.FloatField(initial=0) payoff1a = models.FloatField(initial=0) Other_payoff1a = models.FloatField(initial=0) payoff1b = models.FloatField(initial=0) Other_payoff1b = models.FloatField(initial=0) payoff_rr = models.FloatField(initial=0) payoff_dis = models.CurrencyField(initial=0) finish_a = models.FloatField() random_round = models.FloatField() random_round2 = models.FloatField() formal_decision = models.FloatField( choices=[[1, '是'], [0, '否']], widget=widgets.RadioSelectHorizontal, label="请选择是否购买保险", ) formal_decisiona = models.FloatField() is_winnera = models.FloatField(initial=-1) is_winnerb = models.FloatField(initial=-1) success_sharea = models.FloatField(initial=-1) success_shareb = models.FloatField(initial=-1) Selected_lottery = models.FloatField() more_risk_averse = models.FloatField() test_tries = models.FloatField(initial=0) question1 = models.FloatField( ) question2 = models.FloatField( ) question3 = models.FloatField( ) question4 = models.FloatField( ) question5 = models.FloatField( ) question5correct = models.FloatField(initial=0) question6 = models.FloatField( ) question6correct = models.FloatField(initial=0) payoff_question = models.FloatField(initial=0) #####cognitive reflection task############ Crt_Bat = models.FloatField( label=''' Q1. 一个球拍和一个球总共卖1.10元,球拍比球多卖1.00元,请问球的价格是多少元?''', ) Crt_Widget = models.FloatField( label=''' Q2. 如果5个机器耗时5分钟制作了5个装饰品,请问100个机器制作100个装饰品要耗时多久?''', ) Crt_Lake = models.FloatField( label=''' Q3. 湖面上有一片睡莲,它们每天以两倍的数量增加着。如果睡莲铺满整个湖面需要48天,那么它覆盖湖面的一半区域需要几天?''', ) Know = models.StringField( choices=['是', '否'], label=''' Q4. 您是否曾经看到过或者回答过上述问题?''', widget=widgets.RadioSelect() ) ##### Regret questions ####################### Regret_1 = models.IntegerField( label=''' Q5. 每当我做选择时,我都会好奇如果我的选择不同会发生什么(1代表''完全不同意'',5代表''完全同意'')''', choices=[1, 2, 3, 4, 5], widget=widgets.RadioSelectHorizontal ) Regret_2 = models.IntegerField( label=''' Q6. 每当我做选择时,我都会试图了解其他选择的结果(1代表''完全不同意'',5代表''完全同意'')''', choices=[1, 2, 3, 4, 5], widget=widgets.RadioSelectHorizontal ) Regret_3 = models.IntegerField( label=''' Q7. 即使我做的决定有很好的结果,如果我发现其他选择会有更好的结果,我仍然会感觉有些挫败(1代表''完全不同意'',5代表''完全同意'')''', choices=[1, 2, 3, 4, 5], widget=widgets.RadioSelectHorizontal ) Regret_4 = models.IntegerField( label=''' Q8. 当我回想我现在的生活状况时,我经常会考量我已经错过的机会(1代表''完全不同意'',5代表''完全同意'')''', choices=[1, 2, 3, 4, 5], widget=widgets.RadioSelectHorizontal ) Regret_5 = models.IntegerField( label=''' Q9. 我一旦决定了前面的路怎么走,就不会再回头看(1代表''完全不同意'',5代表''完全同意'')''', choices=[1, 2, 3, 4, 5], widget=widgets.RadioSelectHorizontal ) ##### Risk questions ############################# Q_risk = models.IntegerField( label=''' Q1. 请评价自己:您是愿意冒险的人还是试图规避风险的人(0代表''完全不愿意冒险'',10代表''非常愿意冒险'')''', choices=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], widget=widgets.RadioSelectHorizontal ) ##### Regret questions in the loss and gain domain ####################### Regret_G = models.IntegerField( label=''' Q11. 您选择不投资该项目。与此同时,该投资项目的价值翻了一番多。这意味着如果您之前投资了该项目,您本可以获得巨大的收益。在这种情况下,今天的您会(1代表着“非常后悔没有参与投资”,5代表着“完全不后悔”) ''', choices=[1, 2, 3, 4, 5], widget=widgets.RadioSelectHorizontal ) Regret_L = models.IntegerField( label=''' Q12. 现在请思考另一种情况。您在该项目中投资了大量的资金,与此同时,市场不景气,该投资项目的价值缩水一半。在这种情况下,今天的您会(1代表着“非常后悔参与投资”,5代表着“完全不后悔”) ''', choices=[1, 2, 3, 4, 5], widget=widgets.RadioSelectHorizontal ) ##### Numeracy questions############### N_1 = models.FloatField( label='''Q8. 假设您投掷一枚公平的硬币1000次,您认为有多少次这枚硬币会反面朝上?''' , ) N_2 = models.FloatField( label= '''Q9. 中国的小型彩票有1%的概率会中奖10元。请您猜测如果有1000个人每人买一张彩票,会有多少人能获得10元的奖金?''' , ) # old question # N_3 = models.FloatField( # label= # '''Q15. 在另一种彩票中,有千分之一的概率能中奖一辆轿车。请问平均多少张彩票能中奖一辆轿车?''', # # ) N_3 = models.FloatField( label='''Q10. 森林里有20%的蘑菇是红色,50%是棕色,30%是白色。红蘑菇有毒的可能性为20%,而非红色蘑菇有毒的可能性为5%。请问森林中有毒蘑菇是红色的概率是多少?''', ) N_4 = models.FloatField( label='''Q11. 小镇上的1000人中有500人是合唱团成员。500名合唱团成员中有100名是男性,500名不是合唱团的居民中有300名是男性。请问随机抽取一名男性是合唱团成员的概率有多大?请用小数的形式表示''', ) N_5 = models.FloatField( label='''Q12. 假设我们投掷一枚五边形的骰子50次,平均而言,在这50次的投掷中,有多少次五边形骰子会显示为奇数(1、3、5)?''', ) # N_5b =models.FloatField( # label='''Q16. Imagine we are throwing a loaded die (6 sides). The probability that the die shows a 6 is twice as # high as the probability of each of the other numbers. On average, out of these 70 throws how many times would # the die show the number 6?''', # ) ###### Demographic questions ########### Age = models.IntegerField( label='Q8. 请问您的年龄是?', min=15, max=40) gender = models.StringField( choices=['男性', '女性'], label='Q9. 请问您的性别是?', widget=widgets.RadioSelect) Nation = models.StringField( label='Q10. 请问您的国籍是?' ) Major = models.StringField( choices=['会计', '经济', '金融', '工商管理(除会计、经济、金融的其他商科专业)' , '教育', '工程学', '医疗卫生', '社会科学或历史学', '数学,计算机或物理学', '生物学', '人文科学', '公共事务管理或社会服务类', '心理学', '其他(如果您不是学生,请选择“其他”并说明您的职业)' ], label='Q11. 请问您的专业是?', widget=widgets.RadioSelect) Major_other = models.StringField(blank=True, label='如果选择“其他”,请具体说明:' ) Education = models.StringField( choices=['本科', '硕士', '博士', '以上均不适用' ], label='Q12. 请问您的学历层次是?', widget=widgets.RadioSelect) HH_income = models.StringField( choices=['少于10,000元', '10,000-15,000元', '15,000-20,000元', '20,000-30,000元', '30,000-40,000元', '40,000元以上' ], label='Q13. 请问您的总家庭月收入是?', widget=widgets.RadioSelect) Work = models.IntegerField( choices=[[1, '是'], [0, '否']], label='Q14. 请问您有带薪工作吗?', widget=widgets.RadioSelect) Pre_experiment = models.IntegerField( choices=[[1, '是'], [0, '否']], label='Q15. 请问您之前参加过其他的经济学实验吗?', widget=widgets.RadioSelect) #######reci###### Belief_Reci = models.IntegerField( choices=[1, 2, 3, 4, 5], label='Q2:如果想将来得到别人的帮助我应该先找机会帮助他。', widget=widgets.RadioSelectHorizontal ) Positive_Reci = models.IntegerField( choices=[1, 2, 3, 4, 5], label='Q3:我愿意给与曾经帮助过我的人一定的回报。', widget=widgets.RadioSelectHorizontal ) Negative_Reci = models.IntegerField( choices=[1, 2, 3, 4, 5], label='Q4:如果我受到了别人的不公正待遇,我会找机会进行报复。', widget=widgets.RadioSelectHorizontal ) Belief_Reci2 = models.IntegerField( choices=[1, 2, 3, 4, 5], label='Q5:如果我对别人不公正,别人将会找机会报复我。', widget=widgets.RadioSelectHorizontal ) Positive_Reci2 = models.IntegerField( choices=[1, 2, 3, 4, 5], label='Q6:如果别人帮助我获得了成功,我愿意将我的所得分享一部分给他。', widget=widgets.RadioSelectHorizontal ) Negative_Reci2 = models.IntegerField( choices=[1, 2, 3, 4, 5], label='Q7:如果我受到了别人的不公正待遇,我以后会拒绝给予他帮助。', widget=widgets.RadioSelectHorizontal ) # Functions def creating_session(subsession): subsession.group_randomly(fixed_id_in_group=True) for p in subsession.get_players(): p.random_insurance = random.random() if p.random_insurance <= Constants.prob_insurance: p.formal_decision = 1 if p.random_insurance > Constants.prob_insurance: p.formal_decision = 0 n = Constants.num_lotteries # create list of lottery indices # -------------------------------------------------------------------------------------------------------- indices = [j for j in range(1, n + 1)] # create list of low and high outcomes (matched by index) # -------------------------------------------------------------------------------------------------------- outcomes_lo = [c(Constants.sure_payoff - Constants.delta_lo * j) for j in range(0, n)] outcomes_hi = [c(Constants.sure_payoff + Constants.delta_hi * j) for j in range(0, n)] choice_num = [j + 1 for j in range(0, n)] prob_lo = [c(Constants.probability) for j in range(0, n)] prob_hi = [c(Constants.sure_payoff) for j in range(0, n)] # append indices and outcomes by "risk loving" lottery if # -------------------------------------------------------------------------------------------------------- if Constants.risk_loving: indices.append(n + 1) outcomes_lo.append(c(outcomes_lo[-1] - Constants.delta_hi)) outcomes_hi.append(c(outcomes_hi[-1] + Constants.delta_hi)) # create list of lotteries # -------------------------------------------------------------------------------------------------------- p.participant.vars['scl_lotteries'] = list( zip(indices, outcomes_lo, outcomes_hi) ) # randomize order of lotteries if # -------------------------------------------------------------------------------------------------------- if Constants.random_order: random.shuffle( p.participant.vars['scl_lotteries'] ) def intro(group: Group): p1 = group.get_player_by_id(1) p2 = group.get_player_by_id(2) group.group_random3 = random.random() p1.random3 = group.group_random3 p2.random3 = group.group_random3 p1.otherrisk = p2.in_round(1).lottery_choice p2.otherrisk = p1.in_round(1).lottery_choice group.random_transfer = random.random() for p in group.get_players(): if group.random_transfer < 0.25: p.transfer = Constants.payoff_trans1 if 0.25 <= group.random_transfer < 0.5: p.transfer = Constants.payoff_trans2 if 0.5 <= group.random_transfer < 0.75: p.transfer = Constants.payoff_trans3 if 0.75 < group.random_transfer: p.transfer = Constants.payoff_trans4 def formal_decision(group: Group): p1 = group.get_player_by_id(1) p2 = group.get_player_by_id(2) p1.formal_decisiona = p1.formal_decision p2.formal_decisiona = -p1.formal_decision p1.Selected_lottery = float(abs(16 - p1.participant.payoff) / 4 + 1) p2.Selected_lottery = float(abs(16 - p2.participant.payoff) / 4 + 1) def set_payoffs(group: Group): group.random1 = random.random() group.random2 = random.random() p1 = group.get_player_by_id(1) p2 = group.get_player_by_id(2) p1.Other_Share_a = p2.Share_a p2.Other_Share_a = p1.Share_a p1.Other_Share_b = p2.Share_b p2.Other_Share_b = p1.Share_b p1.Realized_insurance = p1.formal_decision p2.Realized_insurance = p1.formal_decision if p1.formal_decision == 1: if group.random1 >= 0.5: p1.is_winnera = 1 p2.is_winnera = 0 if p1.Share_a != 100 or p2.Share_a != 100: p1.payoff1a = Constants.payoffH - Constants.formal p2.payoff1a = Constants.payoffL if group.random1 < 0.5: p1.is_winnera = 0 p2.is_winnera = 1 if p1.Share_a != 100 or p2.Share_a != 100: p2.payoff1a = Constants.payoffH p1.payoff1a = Constants.payoffL + Constants.formal if group.random2 >= 0.5: p1.is_winnerb = 1 p2.is_winnerb = 0 if p1.Share_b == 100 and p2.Share_b == 100: p1.payoff1b = Constants.payoffH - p1.transfer p2.payoff1b = p2.transfer + Constants.payoffL if p1.Share_b != 100 or p2.Share_b != 100: p1.payoff1b = Constants.payoffH p2.payoff1b = Constants.payoffL if group.random2 < 0.5: p1.is_winnerb = 0 p2.is_winnerb = 1 if p1.Share_b == 100 and p2.Share_b == 100: p2.payoff1b = Constants.payoffH - p2.transfer p1.payoff1b = p1.transfer + Constants.payoffL if p1.Share_b != 100 or p2.Share_b != 100: p2.payoff1b = Constants.payoffH p1.payoff1b = Constants.payoffL if p1.formal_decision == 0: if group.random1 >= 0.5: p1.is_winnera = 1 p2.is_winnera = 0 if p1.Share_a == 100 and p2.Share_a == 100: p1.payoff1a = Constants.payoffH - p1.transfer p2.payoff1a = p2.transfer + Constants.payoffL if p1.Share_a != 100 or p2.Share_a != 100: p1.payoff1a = Constants.payoffH p2.payoff1a = Constants.payoffL if group.random1 < 0.5: p1.is_winnera = 0 p2.is_winnera = 1 if p1.Share_a == 100 and p2.Share_a == 100: p2.payoff1a = Constants.payoffH - p2.transfer p1.payoff1a = p1.transfer + Constants.payoffL if p1.Share_a != 100 or p2.Share_a != 100: p2.payoff1a = Constants.payoffH p1.payoff1a = Constants.payoffL if group.random2 >= 0.5: p1.is_winnerb = 1 p2.is_winnerb = 0 if p1.Share_b == 100 and p2.Share_b == 100: p1.payoff1b = Constants.payoffH - p1.transfer p2.payoff1b = p2.transfer + Constants.payoffL if p1.Share_b != 100 or p2.Share_b != 100: p1.payoff1b = Constants.payoffH p2.payoff1b = Constants.payoffL if group.random2 < 0.5: p1.is_winnerb = 0 p2.is_winnerb = 1 if p1.Share_b == 100 and p2.Share_b == 100: p2.payoff1b = Constants.payoffH - p2.transfer p1.payoff1b = p1.transfer + Constants.payoffL if p1.Share_b != 100 or p2.Share_b != 100: p2.payoff1b = Constants.payoffH p1.payoff1b = Constants.payoffL for p in group.get_players(): if p.round_number == 1: p.random_round = round(random.random() * Constants.num_rounds, 0) p.random_round2 = round(random.random() * Constants.num_rounds / 2, 0) + Constants.num_rounds / 2 if p.random_round == 0: p.random_round = 1 if p.random_round2 == Constants.num_rounds/2: p.random_round2 = Constants.num_rounds/2+1 else: p.random_round = p.in_round(1).random_round p.random_round2 = p.in_round(1).random_round2 if p.round_number <= p.random_round: p.payoff_rr = p.payoff1a + p.payoff1b if p1.Share_a == 100 and p2.Share_a == 100: p.success_sharea = 1 if p1.Share_b == 100 and p2.Share_b == 100: p.success_shareb = 1 else: p.payoff_rr = p.in_round(p.random_round).payoff_rr if p.round_number == 1: if p.question5 == 30: p.question5correct = 1 if p.question6 == 10: p.question6correct = 1 if p1.round_number >= Constants.num_rounds / 2 + 1: p1.b1r = p2.Share_b p2.b1r = p1.Share_b p1.b2r = p2.Belief_b1 p2.b2r = p1.Belief_b1 if p1.formal_decision != 1: p1.a1r = p2.Share_a p2.a1r = p1.Share_a p1.a2r = p2.Belief_a1 p2.a2r = p1.Belief_a1 for p in group.get_players(): p.random_b1 = 100 * round(random.random(), 1) p.random_b2 = 100 * round(random.random(), 1) p.b1bar = 100 - ((p.Belief_b1 - 1)*10 - p.b1r)**2/100 p.b2bar = 100 - ((p.Belief_b2 - 1)*10 - (p.b2r-1)*10)**2/100 if p.b1bar >= p.random_b1 : p.Belief_b1r = Constants.prize_guess if p.Belief_b2 == p.b2r : p.Belief_b2r = Constants.prize_guess if p.Realized_insurance != 1: p.random_a1 = 100 * round(random.random(), 1) p.random_a2 = 100 * round(random.random(), 1) p.a1bar = 100 - ((p.Belief_a1 - 1) * 10 - p.a1r) ** 2 / 100 p.a2bar = 100 - ((p.Belief_a2 - 1) * 10 - (p.a2r-1)*10) ** 2 / 100 if p.a1bar >= p.random_a1: p.Belief_a1r = Constants.prize_guess if p.Belief_a2 == p.a2r: p.Belief_a2r = Constants.prize_guess for p in group.get_players(): if p.round_number >= Constants.num_rounds / 2 + 1: p.payoff_question = p.Belief_b1r if p.round_number > p.random_round2 : p.payoff_question = p.in_round(p.random_round2).payoff_question if p.round_number == Constants.num_rounds: p.rRealized_insurance = p.in_round(p.random_round2).Realized_insurance p.rBelief_b1 = (p.in_round(p.random_round2).Belief_b1-1)*10 p.rb1r = (p.in_round(p.random_round2).b1r) p.rb1bar = p.in_round(p.random_round2).b1bar p.rrandom_b1 = p.in_round(p.random_round2).random_b1 p.rBelief_b1r = p.in_round(p.random_round2).Belief_b1r p.rBelief_b2 = (p.in_round(p.random_round2).Belief_b2-1)*10 p.rb2r = (p.in_round(p.random_round2).b2r-1)*10 p.rb2bar = p.in_round(p.random_round2).b2bar p.rrandom_b2 = p.in_round(p.random_round2).random_b2 p.rBelief_b2r = p.in_round(p.random_round2).Belief_b2r if p.in_round(p.random_round2).Realized_insurance != 1 : p.rBelief_a1 = (p.in_round(p.random_round2).Belief_a1-1)*10 p.ra1r = (p.in_round(p.random_round2).a1r) p.ra1bar = p.in_round(p.random_round2).a1bar p.rrandom_a1 = p.in_round(p.random_round2).random_a1 p.rBelief_a1r = p.in_round(p.random_round2).Belief_a1r p.rBelief_a2 = (p.in_round(p.random_round2).Belief_a2-1)*10 p.ra2r = (p.in_round(p.random_round2).a2r-1)*10 p.ra2bar = p.in_round(p.random_round2).a2bar p.rrandom_a2 = p.in_round(p.random_round2).random_a2 p.rBelief_a2r = p.in_round(p.random_round2).Belief_a2r p1.Other_payoff1a = p2.payoff1a p2.Other_payoff1a = p1.payoff1a p1.Other_payoff1b = p2.payoff1b p2.Other_payoff1b = p1.payoff1b def set_payoff_scl(subsession: Subsession): n = Constants.num_lotteries # create list of lottery indices # -------------------------------------------------------------------------------------------------------- indices = [j for j in range(1, n + 1)] # create list of low and high outcomes (matched by index) # -------------------------------------------------------------------------------------------------------- outcomes_lo = [c(Constants.sure_payoff - Constants.delta_lo * j) for j in range(0, n)] outcomes_hi = [c(Constants.sure_payoff + Constants.delta_hi * j) for j in range(0, n)] prob_lo = [c(Constants.probability) for j in range(0, n)] prob_hi = [c(Constants.sure_payoff) for j in range(0, n)] for player in subsession.get_players(): if player.round_number == Constants.num_rounds: player.participant.vars['scl_lotteries'] = list( zip(indices, outcomes_lo, outcomes_hi) ) p = Constants.probability rnd = random.randint(1, 100) player.outcome_to_pay = "high" if rnd <= p else "low" # select lottery choice out of list of lotteries # ------------------------------------------------------------------------------------------------------------ lottery_selected = [i for i in player.participant.vars['scl_lotteries'] if i[0] == player.in_round(1).lottery_choice] lottery_selected = lottery_selected[0] # store payoffs of chosen lottery in the model # ------------------------------------------------------------------------------------------------------------ player.outcome_lo = lottery_selected[1] player.outcome_hi = lottery_selected[2] # set player's payoff # ------------------------------------------------------------------------------------------------------------ if player.outcome_to_pay == "high": player.payoffscl = player.outcome_hi else: player.payoffscl = player.outcome_lo player.payoff_dis = player.payoff_rr + player.payoffscl + player.payoff_question # PAGES class Instructions(Page): # variables for template # ---------------------------------------------------------------------------------------------------------------- def vars_for_template(self): num_lotteries = Constants.num_lotteries + 1 if Constants.risk_loving else Constants.num_lotteries return { 'n': num_lotteries, 'prob_hi': "{0:.1f}".format(Constants.probability) + "%", 'prob_lo': "{0:.1f}".format(100 - Constants.probability) + "%" } def is_displayed(player): return player.round_number == Constants.num_rounds class Intro(Page): @staticmethod def is_displayed(player): return player.round_number == 1 def vars_for_template(player): return dict( payoffH=Constants.payoffH, num_rounds=Constants.num_rounds, ) class Waitforintro(WaitPage): after_all_players_arrive = intro body_text = "请耐心等待实验继续" class Decision1(Page): # form model # ---------------------------------------------------------------------------------------------------------------- form_model = 'player' # form fields # ---------------------------------------------------------------------------------------------------------------- form_fields = ['lottery_choice'] # variables for template # ---------------------------------------------------------------------------------------------------------------- def vars_for_template(self): return { 'n': Constants.num_lotteries, 'lotteries': self.participant.vars['scl_lotteries'], 'prob_hi': "{0:.1f}".format(Constants.probability) + "%", 'prob_lo': "{0:.1f}".format(100 - Constants.probability) + "%" } def is_displayed(player): return player.round_number == 1 class Quiz(Page): form_model = 'player' form_fields = ['question1', 'question2', 'question3', 'question4', 'question5', 'question6'] def is_displayed(player): return player.round_number == 1 def error_message(self, values): all_correct = values['question1'] + values['question2'] + values['question3'] + values['question4'] + + values[ 'question6'] + values['question5'] if all_correct != 44: self.test_tries = self.test_tries + 1 self.error = 1 self.question1 = values['question1'] self.question2 = values['question2'] self.question3 = values['question3'] self.question4 = values['question4'] self.question5 = values['question5'] self.question6 = values['question6'] return "您给出的答案至少有一个不正确。请您认真阅读下方提示并确定理解任务。" class Quizcheck(Page): @staticmethod def is_displayed(player): return player.round_number == 1 class Feedback(Page): # variables for template # ---------------------------------------------------------------------------------------------------------------- def vars_for_template(self): return { 'lotteries': self.participant.vars['scl_lotteries'], 'prob_hi': "{0:.1f}".format(Constants.probability) + "%", 'prob_lo': "{0:.1f}".format(100 - Constants.probability) + "%" } class Formal_decision(Page): @staticmethod def is_displayed(player): return player.id_in_group == 1 def vars_for_template(player): return dict( payoffin=Constants.payoffH - Constants.formal, payoffH1=Constants.payoffH, payoffH2=Constants.payoffH, payoffL1=Constants.payoffL, payoffL2=Constants.payoffL, payoffHT1=Constants.payoffH - player.transfer, payoffHT2=Constants.payoffH, payoffLT1=player.transfer+Constants.payoffL, payoffLT2=Constants.payoffL, ) class Waitforformal(WaitPage): after_all_players_arrive = formal_decision body_text = "请耐心等待实验继续" class SharingDecisionA_insurance(Page): form_model = 'player' form_fields = ['Share_b'] @staticmethod def is_displayed(player: Player): return player.formal_decisiona != 0 def vars_for_template(player): if player.id_in_group == 1: return dict( payoffH1=Constants.payoffH - Constants.formal, payoffH2=Constants.payoffH, payoffL1=Constants.formal, payoffL2=Constants.payoffL, payoffHT1=Constants.payoffH - player.transfer, payoffHT2=Constants.payoffH, payoffLT1=player.transfer+Constants.payoffL, payoffLT2=Constants.payoffL, insurancedecision="您已购买了保险" ) if player.id_in_group == 2: return dict( payoffH1=Constants.payoffH - Constants.formal, payoffH2=Constants.payoffH, payoffL1=Constants.formal, payoffL2=Constants.payoffL, payoffHT1=Constants.payoffH - player.transfer, payoffHT2=Constants.payoffH, payoffLT1=player.transfer + Constants.payoffL, payoffLT2=Constants.payoffL, insurancedecision="对方已购买了保险" ) class SharingDecisionA_no_insurance(Page): form_model = 'player' form_fields = ['Share_a', 'Share_b'] @staticmethod def is_displayed(player: Player): return player.formal_decisiona == 0 def vars_for_template(player): if player.id_in_group == 1: return dict( payoffH1=Constants.payoffH, payoffH2=Constants.payoffH, payoffL1=Constants.payoffL, payoffL2=Constants.payoffL, payoffHT1=Constants.payoffH - player.transfer, payoffHT2=Constants.payoffH - player.transfer, payoffLT1=player.transfer+Constants.payoffL, payoffLT2=player.transfer+Constants.payoffL, insurancedecision="您没有购买保险" ) if player.id_in_group == 2: return dict( payoffH1=Constants.payoffH, payoffH2=Constants.payoffH, payoffL1=Constants.payoffL, payoffL2=Constants.payoffL, payoffHT1=Constants.payoffH - player.transfer, payoffHT2=Constants.payoffH - player.transfer, payoffLT1=player.transfer+Constants.payoffL, payoffLT2=player.transfer+Constants.payoffL, insurancedecision="对方没有购买保险" ) class Belief_no_insurance(Page): form_model = 'player' form_fields = ['Belief_a1', 'Belief_a2', 'Belief_b1', 'Belief_b2'] @staticmethod def is_displayed(player): return player.round_number > 0.5 * Constants.num_rounds and player.formal_decisiona == 0 def error_message(self, values): if values['Belief_b1'] <= 0 or values['Belief_b2'] <= 0 or values['Belief_a1'] <= 0 or values['Belief_a2'] <= 0: return "您至少还有一个问题没有回答。" class Belief_insurance(Page): form_model = 'player' form_fields = ['Belief_b1', 'Belief_b2'] @staticmethod def is_displayed(player): return player.round_number > 0.5 * Constants.num_rounds and player.formal_decisiona != 0 def error_message(self, values): if values['Belief_b1'] <= 0 or values['Belief_b2'] <= 0: return "您至少还有一个问题没有回答。" class ResultsWaitPage3(WaitPage): after_all_players_arrive = set_payoffs body_text = "请耐心等待实验继续。" class Results(Page): @staticmethod def is_displayed(player): return player.round_number == Constants.num_rounds def vars_for_template(player: Player): return dict(total_earnings=int(player.payoff_dis), random_round1 = int(player.random_round), random_round2 = int(player.random_round2), p_question = int(player.payoff_question), p_scl = int(player.payoffscl), p_rr = int(player.payoff_rr), c_lottery = int(player.in_round(1).lottery_choice)) class End(Page): @staticmethod def is_displayed(player): return player.round_number == Constants.num_rounds def vars_for_template(player: Player): return dict(total_earnings=player.payoff_dis, id=player.id_in_subsession, random_round=player.random_round) class Demographics(Page): form_model = 'player' form_fields = ['Age', 'gender', 'Nation', 'Major', 'Major_other', 'Education', 'HH_income', 'Work','Pre_experiment'] @staticmethod def is_displayed(player): return player.round_number == Constants.num_rounds class Risk(Page): form_model = 'player' form_fields = ['Q_risk'] @staticmethod def is_displayed(player): return player.round_number == Constants.num_rounds class Cognitive(Page): form_model = 'player' form_fields = ['Crt_Bat', 'Crt_Widget', 'Crt_Lake', 'Know'] @staticmethod def is_displayed(player): return player.round_number == Constants.num_rounds class Regret_Loss_Gain(Page): form_model = 'player' form_fields = ['Regret_G', 'Regret_L'] @staticmethod def is_displayed(player): return player.round_number == Constants.num_rounds class Reci(Page): form_model = 'player' form_fields = ['Belief_Reci', 'Positive_Reci', 'Negative_Reci', 'Belief_Reci2', 'Positive_Reci2', 'Negative_Reci2'] @staticmethod def is_displayed(player): return player.round_number == Constants.num_rounds class Regret(Page): form_model = 'player' form_fields = ['Regret_1', 'Regret_2', 'Regret_3', 'Regret_4', 'Regret_5'] @staticmethod def is_displayed(player): return player.round_number == Constants.num_rounds class Start(Page): @staticmethod def is_displayed(player): return player.round_number == Constants.num_rounds class End(Page): @staticmethod def is_displayed(player): return player.round_number == Constants.num_rounds class Numeracy(Page): form_model = 'player' form_fields = ['N_1', 'N_2', 'N_3', 'N_4', 'N_5'] @staticmethod def is_displayed(player): return player.round_number == Constants.num_rounds class Before_Feedback(Page): @staticmethod def is_displayed(player): return player.round_number == 1 class Before_Belief(Page): @staticmethod def is_displayed(player): return player.round_number == Constants.num_rounds / 2 + 1 class Whiteinsurance2(Page): @staticmethod def is_displayed(player): return player.id_in_group == 2 and player.round_number == 1 class Whiteinsurance1(Page): @staticmethod def is_displayed(player): return player.id_in_group == 1 and player.round_number == 1 class Whiteinsurance3(Page): @staticmethod def is_displayed(player): return player.id_in_group == 2 and player.round_number > 1 class Rematch(Page): pass class Waitforall(WaitPage): wait_for_all_groups = True after_all_players_arrive = set_payoff_scl body_text = "请等待系统进行重新匹配。" page_sequence = [Decision1, Intro, Quiz, Waitforintro, Whiteinsurance1, Whiteinsurance2, Whiteinsurance3,Feedback, Formal_decision, Waitforformal, SharingDecisionA_no_insurance, SharingDecisionA_insurance, Before_Belief, Belief_insurance, Belief_no_insurance, ResultsWaitPage3, Rematch, Waitforall,Start, Risk, Reci, Demographics, Results, End ]