from otree.api import * import json doc = """ Your app description """ class C(BaseConstants): NAME_IN_URL = 'S1' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 x = [[1,2]] platforms = [['platforms_tb', '淘宝'], ['platforms_jd', '京东'], ['platforms_pdd','拼多多'], ['platforms_ks','快手电商'], ['platforms_dy', '抖音电商']] payments = [['payments_alipay', '支付宝'], ['payments_wechat', '微信支付'], ['payments_yunpay', '云闪付']] # Page orders demo_order = ['inChina', 'age', 'education', 'income', 'single', 'shop_freq', 'shop_amount_week','multi_account', 'set_limit'] shop_att_order= ['shop_feel', 'ideal_shop', 'ideal_change'] ideal_change_platforms = ['ideal_change_tb', 'ideal_change_jd', 'ideal_change_pdd', 'ideal_change_ks', 'ideal_change_dy', 'ideal_change_other'] class Subsession(BaseSubsession): pass class Group(BaseGroup): pass # Functions def swb(label): return models.IntegerField(label=label, choices=[-3, -2, -1, 0, 1, 2, 3], widget=widgets.RadioSelect) def addiction(label): return models.IntegerField(label=label, choices=[-2, -1, 0, 1, 2], widget=widgets.RadioSelect) def mpl(label): return models.IntegerField(label=label, choices=[0, 1], widget=widgets.RadioSelect) class Player(BasePlayer): # Page: Welcome is_mobile = models.BooleanField(label="您目前是否在使用手机或者平板浏览该页面?") phone = models.StringField( label = "为了方便您后续参与我们的实验, 我们需要知道您的手机号是多少" ) # Page: Consent # Intro: consents consent1 = models.BooleanField( label = "您是否同意参与我们的研究?", ) consent2 = models.BooleanField( label = "这项研究需要确保数据的高质量。您是否已经认真阅读了上述说明,并承诺会认真回答研究中的每个问题?", ) # Page: Demographics # Intro: demographics inChina = models.BooleanField( label = "您当前是否长期定居在中国?", ) age = models.IntegerField( label = "您的年龄是几岁", min = 18, max = 100, ) education = models.IntegerField( label = "请选择您的最高学历", choices = [ [1, "小学及以下"], [2, "初中"], [3, "普高/中专/技校/职高"], [4, "大专"], [5, "本科"], [6, "硕士"], [7, "博士"], ], widget = widgets.RadioSelectHorizontal, ) income = models.IntegerField( label = "过去一年您的总收入是多少?请选择您的总收入所在的区间(单位:元)\n 请注意:总收入仅包括工作收入(薪水、奖金、其他报酬以及您自己企业的收入)", choices = [ [1, "4万以下"], [2, "4-8万"], [3, "8-12万"], [4, "12-16万"], [5, "16-20万"], [6, "20-40万"], [7, "40万以上"], ], widget=widgets.RadioSelectHorizontal, ) single = models.BooleanField( label = "您当前是自己单人居住,还是和其他家庭成员一起居住?", choices=[ [1, "自己单人居住"], [2, "和其他家庭成员一起居住"], ], widget=widgets.RadioSelect, ) shop_freq = models.IntegerField( label = "根据您过去的网购经历,您网购的频率为", choices=[ [1, "几乎从不"], [2, "每个月一到三次"], [3, "每周一到三次"], [4, "不会每天网购, 但每周多于三次"], [5, "每天一到三次"], [6, "每天多于三次"], ] ) shop_amount_week = models.IntegerField( label = "根据您过去的网购经历,您网购的每周消费总额为", choices=[ [1, "低于50元"], [2, "50-100元"], [3, "100-200元"], [4, "200-300元"], [5, "300-500元"], [6, "500元以上"], ] ) multi_account = models.BooleanField( label = "有些人可能会有多个账号用于购物,在您目前正在使用的电商平台中,您是否在淘宝/天猫/京东/拼多多/抖音电商/快手电商中的某个平台拥有多个账号?", choices=[ [True, "是的,我在其中一个平台上有不止一个账号可以登录"], [False, "不是,我在所有平台上都只有唯一的账户可以登录"], ] ) set_limit = models.BooleanField( label = "您目前是否有给自己的网上购物设定预算的习惯?\n 设定预算是指,您会为自己设定一段时间内网上购物的最大金额,并通过某种方法限制自己不超出该金额。", ) # platforms used platforms_tb = models.BooleanField(blank=True, initial=False) platforms_jd = models.BooleanField(blank=True, initial=False) platforms_pdd = models.BooleanField(blank=True, initial=False) platforms_ks = models.BooleanField(blank=True, initial=False) platforms_dy = models.BooleanField(blank=True, initial=False) platforms_other = models.StringField( blank=True, label = "如果有其他平台,请说明", default="", ) # payment methods payments_alipay = models.BooleanField(blank=True) payments_wechat = models.BooleanField(blank=True) payments_yunpay = models.BooleanField(blank=True) payments_other = models.StringField( blank=True, label = "如果有其他支付方式,请说明", ) # Page: Shop_attitudes2 # Intro: shopping attitudes shop_feel = models.IntegerField( label = '有些消费者认为他们网上购物太多,在理想情况下应当减少网购。另一些消费者对网购花费感到满意,或者认为理想情况下想要网购更多。您对过去一周的网上购物感觉如何?', choices=[ [1, '我在网上购物的花费太多'], [0, '我在网上购物的花费适量'], [-1, '我在网上购物的花费太少'], ], widget=widgets.RadioSelect ) ideal_shop = models.IntegerField( label = '结合过去一周的网上购物金额,您认为在理想情况下,您倾向于减少还是增加在网购上的开支?', choices=[ [1, '增加'], [0, '不变'], [-1, '减少'], ], widget=widgets.RadioSelect ) ideal_change = models.IntegerField( label = '相比于您过去一周的网上购物金额,您认为在理想情况下自己会改变多少在网购上的开支(请输入百分比)', ) # ideal change for each platform, table question ideal_change_tb = models.IntegerField(label= '淘宝/天猫', choices=[1, 2, 3, 4, 5, 6, 7], widget=widgets.RadioSelect, initial= -1) ideal_change_jd = models.IntegerField(label= '京东', choices=[1, 2, 3, 4, 5, 6, 7], widget=widgets.RadioSelect, initial= -1) ideal_change_pdd = models.IntegerField(label= '拼多多', choices=[1, 2, 3, 4, 5, 6, 7], widget=widgets.RadioSelect, initial= -1) ideal_change_ks = models.IntegerField(label= '快手电商', choices=[1, 2, 3, 4, 5, 6, 7], widget=widgets.RadioSelect, initial= -1) ideal_change_dy = models.IntegerField(label= '抖音电商', choices=[1, 2, 3, 4, 5, 6, 7,], widget=widgets.RadioSelect, initial= -1) ideal_change_other = models.IntegerField(label= '其他所有平台', choices=[1, 2, 3, 4, 5, 6, 7], widget=widgets.RadioSelect, initial= -1) used_platforms = models.StringField(label = "store the used platforms list in json") # Page: Shop_attitudes3 # Intro: other metrics shop_on_phone = models.IntegerField( label = '当您在以下电商平台:淘宝/天猫,京东,拼多多,快手电商,以及抖音电商进行购物的时候,您有多大比例是在手机上购物,而不是在其他地方(平板/电脑)完成的?', min = 0, max = 100, ) want_limit = models.IntegerField( label = '有些人会给自己设置网购的预算:如果他们发现自己的网购消费达到一定数额,将会被提醒。您对设置这样的网购预算有多大兴趣?\n 请选择1-7来表示兴趣程度,数字越大表示兴趣越大', choices = [1, 2, 3, 4, 5, 6, 7], widget = widgets.RadioSelectHorizontal ) life_better = models.IntegerField( label = '在过去的一周里,您认为网购平台的使用在多大程度上让您的生活变得更好或更糟?(-5=让我的生活更糟,+5=让我的生活更好)', choices= [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5], widget=widgets.RadioSelectHorizontal, ) # Page: SWB # Intro: scale 1 to 7 swb1 = swb("我是一个快乐的人") swb2 = swb("我对我的生活很满意") swb3 = swb("我感到焦虑") swb4 = swb("我感到沮丧") swb5 = swb("我可以专注于我正在做的事情") swb6 = swb("我很容易分心") swb7 = swb("我睡眠很好") # Page: Addiction # Intro: scale -2 to +2 addiction1 = addiction("我总是在想网上购物") addiction2 = addiction("我经常思考如何腾出更多的时间或金钱花在网购上") addiction3 = addiction("网购对我的生活很重要") addiction4 = addiction("我越来越倾向于网购") addiction5 = addiction("我感觉到我必须越来越多地在网购才能获得和以前一样的满足感") addiction6 = addiction("我最近经常在计划之外网购") addiction7 = addiction("当我心情不好时,网购可以让我心情愉快") addiction8 = addiction("我网购是为了减少内疚、焦虑、无助、孤独和/或抑郁的感觉") addiction9 = addiction("网购可以帮助我暂时忘记个人问题") addiction10 = addiction("当我因某些原因不能网购时,我会感到沮丧或困惑") addiction11 = addiction("如果因为某些原因我不能在想网购的时间网购,我会变得情绪不好或暴躁") addiction12 = addiction("当试图网上购物但不能时,我会感到不安或沮丧") addiction13 = addiction("我曾尝试减少或停止网上购物,但失败了") addiction14 = addiction("别人告诉我要减少网购,但是我没听他们的") addiction15 = addiction("如果我在一段时间内通过设置预算减少了网购量,但之后取消预算后,还会重新开始,结果会像以前网购一样多") addiction16 = addiction("因为网购,我对兴趣爱好、休闲活动、日常活动(例如,学校和工作)或锻炼的重视程度减少了") addiction17 = addiction("本选项请选择很少") addiction18 = addiction("我因为网购而忽略了爱人、家人和朋友") addiction19 = addiction("我为了进行网购减少了与父母和朋友的相处时间") addiction20 = addiction("我在网上购物太多,导致了经济问题") addiction21 = addiction("我非常担心网购的问题,以至于有时让我失眠") addiction22 = addiction("我在网上购物太多,以至于降低了我的幸福感") # Page: MPL # Intro: mpl1 = mpl("本期1元,研究完成后13元") mpl2 = mpl("本期1元,研究完成后12元") mpl3 = mpl("本期1元,研究完成后11元") mpl4 = mpl("本期1元,研究完成后10元") mpl5 = mpl("本期1元,研究完成后9元") mpl6 = mpl("本期1元,研究完成后8元") mpl7 = mpl("本期1元,研究完成后7元") MPLs = models.StringField() MPL_bonus = models.IntegerField(labels = "bonus of selected row") # Page: Intro_tasks # determine which tutorial to show system = models.StringField( label = "我们的软件支持Windows系统和Mac OS(苹果笔记本),请问您的电脑是哪一种系统?", choices=["Windows", "Mac"], widget=widgets.RadioSelect ) # Page: Tutorial_test finished = models.BooleanField( label = "您是否已经尝试完成了所有流程?如果您在后续的研究中数据上传遇到问题,这可能会影响到您的报酬支付。", widget=widgets.RadioSelect ) # Page: Feedback feedback = models.LongStringField ( label="您在刚才的问题回答中有哪些疑问?疑问可以包括问题的描述,对于操作的流程,以及查看教程中您遇到的问题。请您用简短的文字告诉我们您发现的问题和提出的建议" ) # PAGES class Welcome(Page): form_model = 'player' form_fields = ['is_mobile'] def error_message(player: Player, values): if values['is_mobile']: return "请使用电脑端浏览器进行此实验!" class Instruction(Page): pass class Consent(Page): form_fields = ['consent1', 'consent2'] form_model = 'player' @staticmethod def before_next_page(player: Player, timeout_happened): print(player.consent1) class Exit1(Page): @staticmethod def is_displayed(player: Player): displayed = False # Exit page if: # player consent1==False or consent2==False if player.consent1==False or player.consent2==False: displayed = True print(f"==>> displayed: {displayed}") return displayed class Exit2(Page): @staticmethod def is_displayed(player: Player): displayed = False # Exit page if: # inChina==False or multi_account==True or set_limit==True if player.inChina==False or player.multi_account==True or player.set_limit==True: displayed = True print(f"==>> displayed: {displayed}") return displayed class Demographics(Page): form_fields = ['inChina', 'age', 'education', 'income', 'single', 'shop_freq', 'shop_amount_week', 'multi_account', 'set_limit', 'platforms_tb', 'platforms_jd', 'platforms_pdd', 'platforms_ks', 'platforms_dy', 'platforms_other', 'payments_alipay', 'payments_wechat', 'payments_yunpay', 'payments_other'] form_model = 'player' class Shop_attitudes(Page): form_fields = ['shop_feel', 'ideal_shop', 'ideal_change'] form_model = 'player' @staticmethod def before_next_page(player: Player, timeout_happened): used_platforms = [ player.platforms_tb, player.platforms_jd, player.platforms_pdd, player.platforms_ks, player.platforms_dy, player.platforms_other ] print(f"==>> used_platforms: {used_platforms}") all_platforms = ['ideal_change_tb', 'ideal_change_jd', 'ideal_change_pdd', 'ideal_change_ks', 'ideal_change_dy', 'ideal_change_other'] updated_platforms = [] for i in range(len(all_platforms)): if used_platforms[i] is True: updated_platforms.append(all_platforms[i]) if used_platforms[5] != "": updated_platforms.append('ideal_change_other') # update C.ideal_change_platforms player.used_platforms = json.dumps(updated_platforms) print(f"==>> updated_platforms: {updated_platforms}") class Shop_attitudes2(Page): form_model = 'player' @staticmethod def get_form_fields(player: Player): return json.loads(player.used_platforms) class Shop_attitudes3(Page): form_fields = ['shop_on_phone', 'want_limit', 'life_better'] form_model = 'player' class SWB(Page): form_fields = ['swb1', 'swb2', 'swb3', 'swb4', 'swb5', 'swb6', 'swb7'] form_model = 'player' class Addiction(Page): form_fields = ['addiction1', 'addiction2', 'addiction3', 'addiction4', 'addiction5', 'addiction6', 'addiction7', 'addiction8', 'addiction9', 'addiction10', 'addiction11', 'addiction12', 'addiction13', 'addiction14', 'addiction15', 'addiction16', 'addiction17', 'addiction18', 'addiction19', 'addiction20', 'addiction21', 'addiction22'] form_model = 'player' class MPL(Page): form_fields = ['mpl1', 'mpl2', 'mpl3', 'mpl4', 'mpl5', 'mpl6', 'mpl7'] form_model = 'player' @staticmethod def before_next_page(player: Player, timeout_happened): MPLs = [player.mpl1, player.mpl2, player.mpl3, player.mpl4, player.mpl5, player.mpl6, player.mpl7] player.MPLs = json.dumps(MPLs) class MPL_results(Page): @staticmethod def vars_for_template(player: Player): import random mpl_choices = json.loads(player.MPLs) bonus = [7, 8, 9, 10, 11, 12, 13] index = random.randint(1, 7) choice = mpl_choices[index-1] if choice == 0: choice_txt = f"本期1元, 研究完成后{bonus[index-1]}元" else: choice_txt = f"一次支付报酬8元" return dict(choice_txt = choice_txt) class Intro_tasks(Page): pass class Intro_scraper(Page): form_fields = ['system'] form_model = 'player' class Tutorial_win(Page): @staticmethod def is_displayed(player: Player): return player.system == "Windows" class Tutorial_mac(Page): @staticmethod def is_displayed(player: Player): return player.system == "Mac" class Tutorial_test(Page): form_fields = ['finished'] form_model = 'player' class Upload(Page): pass class Screenshot(Page): pass class Feedback(Page): form_fields = ['feedback'] form_model = 'player' class Thanks(Page): pass page_sequence = [Welcome, Instruction, Consent, Exit1, Demographics, Exit2, Shop_attitudes, Shop_attitudes2, Shop_attitudes3, SWB, Addiction, MPL, MPL_results, Intro_tasks, Intro_scraper, Tutorial_win, Tutorial_mac, Tutorial_test, Upload, Screenshot, Upload, Feedback, Thanks]