from otree.api import * import random import csv author = 'Lingguo XU' doc = """ Part 3: feedback preferences and WTP """ class Constants(BaseConstants): name_in_url = 'Part3' players_per_group = None num_rounds = 1 WTP_endowment = 100 ECUpercorrect = 40 with open('Part3/Feedback_100subjects.csv') as feedback_file: Feedback = list(csv.DictReader(feedback_file)) feedback_Int1 = Feedback[0]['Average_Performance'] feedback_Int2 = Feedback[1]['Average_Performance'] feedback_Int3 = Feedback[2]['Average_Performance'] feedback_Int4 = Feedback[3]['Average_Performance'] feedback_Int5 = Feedback[4]['Average_Performance'] class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): comprehension_1 = models.IntegerField() comprehension_2 = models.IntegerField() comprehension_3 = models.IntegerField() comprehension_4 = models.IntegerField(min=0, max=100, label="Please fill in a number between 0 and 100.") comprehension_5 = models.IntegerField() comprehension_6 = models.IntegerField(min=0, max=100, label="Please fill in a number between 0 and 100.") comp_attempts_1 = models.IntegerField() comp_attempts_2 = models.IntegerField() comp_attempts_3 = models.IntegerField() comp_attempts_4 = models.IntegerField() # Preference variables def make_field(): return models.IntegerField( choices=[[5, 'Rank 1-20 (top performance)'], [4, 'Rank 21-40 (above average)'], [3, 'Rank 41-60 (average performance)'], [2, 'Rank 61-80 (below average)'], [1, 'Rank 81-100 (bottom performance)'], [0, 'Not interested'], [-1, 'Not interested']], label="", initial=-1, widget=widgets.RadioSelect, ) # Subjects' preferences over five intervals Pref1 represents first preference Pref1 = make_field() Pref2 = make_field() # Check if subject choose "not interested" in any of the preference questions NotInterested = models.BooleanField(initial=False) NotInterested_hypo = models.BooleanField(initial=False) # Willingness to pay variables # def make_field_WTP(): # return models.IntegerField(initial=0, min=0, max=100, label="Please fill in a number between 0 and 100.") def make_field_WTP(): return models.IntegerField( choices=[0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100], label="Please select the highest amount of ECU you are willing to pay.") # WTPx for WTP after each preference questions, and WTPx_new for WTP adjustment in confirmation page WTP1 = make_field_WTP() WTP2 = make_field_WTP() #Variables for selecting the one WTP and implementing BDM BDM_WTP_X = models.IntegerField() # Decision on feedback giving and Part 3 payoff feedback_interval = models.IntegerField() payforfeedback = models.BooleanField() payoff_part3 = models.IntegerField() # Measuring self-efficacy efficacy_1 = models.IntegerField(min=0, max=30, label="Please fill in a number between 0 and 30.") efficacy_2 = models.IntegerField() # Measuring subjects expectation for feedback feedback_exp = models.IntegerField(min=0, max=30, label="Please fill in a number between 0 and 30.") # FUNCTIONS def creating_session(subsession): for player in subsession.get_players(): player.BDM_WTP_X = random.choice(range(0, 101, 10)) # Randomly select one number from 0-100 (step 10) as part of BDM print('set player.BDM_WTP_X to', player.BDM_WTP_X) # PAGES class Introduction(Page): def is_displayed(player): return player.participant.is_dropout == False @staticmethod def get_timeout_seconds(player): participant = player.participant if participant.is_dropout: return 1 # instant timeout, 1 second else: return player.session.config['my_page_timeout_seconds'] @staticmethod def before_next_page(player, timeout_happened): participant = player.participant if timeout_happened: participant.is_dropout = False class Instruction(Page): def is_displayed(player): return player.participant.is_dropout == False @staticmethod def get_timeout_seconds(player): participant = player.participant if participant.is_dropout: return 1 # instant timeout, 1 second else: return player.session.config['my_page_timeout_seconds'] @staticmethod def before_next_page(player, timeout_happened): participant = player.participant if timeout_happened: participant.is_dropout = True class Comprehension1(Page): form_model = 'player' form_fields = ['comprehension_1', 'comp_attempts_1'] def is_displayed(player): return player.participant.is_dropout == False @staticmethod def get_timeout_seconds(player): participant = player.participant if participant.is_dropout: return 1 # instant timeout, 1 second else: return player.session.config['my_page_timeout_seconds'] @staticmethod def before_next_page(player, timeout_happened): participant = player.participant if timeout_happened: participant.is_dropout = True class Comprehension2(Page): form_model = 'player' form_fields = ['comprehension_2', 'comp_attempts_2'] def is_displayed(player): return player.participant.is_dropout == False @staticmethod def get_timeout_seconds(player): participant = player.participant if participant.is_dropout: return 1 # instant timeout, 1 second else: return player.session.config['my_page_timeout_seconds'] @staticmethod def before_next_page(player, timeout_happened): participant = player.participant if timeout_happened: participant.is_dropout = True class Comprehension3(Page): form_model = 'player' form_fields = ['comprehension_3', 'comprehension_4', 'comp_attempts_3'] def is_displayed(player): return player.participant.is_dropout == False @staticmethod def get_timeout_seconds(player): participant = player.participant if participant.is_dropout: return 1 # instant timeout, 1 second else: return player.session.config['my_page_timeout_seconds'] @staticmethod def before_next_page(player, timeout_happened): participant = player.participant if timeout_happened: participant.is_dropout = True class Comprehension4(Page): form_model = 'player' form_fields = ['comprehension_5', 'comprehension_6', 'comp_attempts_4'] def is_displayed(player): return player.participant.is_dropout == False @staticmethod def get_timeout_seconds(player): participant = player.participant if participant.is_dropout: return 1 # instant timeout, 1 second else: return player.session.config['my_page_timeout_seconds'] @staticmethod def before_next_page(player, timeout_happened): participant = player.participant if timeout_happened: participant.is_dropout = True class Instruction_waitpage_ASU(Page): def is_displayed(player): return player.participant.is_dropout == False @staticmethod def get_timeout_seconds(player): participant = player.participant if participant.is_dropout: return 1 # instant timeout, 1 second else: return player.session.config['my_page_timeout_seconds'] @staticmethod def before_next_page(player, timeout_happened): participant = player.participant if timeout_happened: participant.is_dropout = False class Instruction_summary_ASU(Page): def is_displayed(player): return player.participant.is_dropout == False @staticmethod def get_timeout_seconds(player): participant = player.participant if participant.is_dropout: return 1 # instant timeout, 1 second else: return player.session.config['my_page_timeout_seconds'] @staticmethod def before_next_page(player, timeout_happened): participant = player.participant if timeout_happened: participant.is_dropout = False class Pref_1(Page): form_model = 'player' form_fields = ['Pref1'] def is_displayed(player): return player.participant.is_dropout == False @staticmethod def get_timeout_seconds(player): participant = player.participant if participant.is_dropout: return 1 # instant timeout, 1 second else: return player.session.config['my_page_timeout_seconds'] @staticmethod def before_next_page(player, timeout_happened): if timeout_happened: player.participant.is_dropout = True player.NotInterested = player.Pref1 == 0 # this is why the initial values of Prefx has be something other than 0 # When player select not interested, we need to decide on feedback and compute player payoff in Part 3 if player.Pref1 == 0: player.payforfeedback = False player.payoff_part3 = Constants.WTP_endowment player.participant.part3payoff = player.payoff_part3 player.feedback_interval = 0 player.participant.Pref1_survey = player.Pref1 class WTP_MPL_1(Page): form_model = 'player' form_fields = ['WTP1'] # Only display this page if subject did not select "not interested" in the last preference question @staticmethod def is_displayed(player): return player.NotInterested == 0 and player.participant.is_dropout == False @staticmethod def get_timeout_seconds(player): participant = player.participant if participant.is_dropout: return 1 # instant timeout, 1 second else: return player.session.config['my_page_timeout_seconds'] @staticmethod def before_next_page(player, timeout_happened): if timeout_happened: player.participant.is_dropout = True # Compute player payoff in Part 3: implementing BDM; if player.WTP1 >= player.BDM_WTP_X: player.payoff_part3 = Constants.WTP_endowment - player.BDM_WTP_X player.payforfeedback = True else: player.payoff_part3 = Constants.WTP_endowment player.payforfeedback = False player.participant.part3payoff = player.payoff_part3 # Get the feedback that was selected if player.payforfeedback == True: player.feedback_interval = player.Pref1 else: player.feedback_interval = 0 player.participant.WTP1_survey = player.WTP1 class Pref_2(Page): form_model = 'player' form_fields = ['Pref2'] # Only display this page if subject did not select "not interested" in the last preference question @staticmethod def is_displayed(player): return player.NotInterested == 0 and player.participant.is_dropout == False @staticmethod def get_timeout_seconds(player): participant = player.participant if participant.is_dropout: return 1 # instant timeout, 1 second else: return player.session.config['my_page_timeout_seconds'] # Save Pref1 to js, this will be used to make the Pref1 interval disappear def js_vars(player): return dict( Pref1=player.Pref1, ) @staticmethod def before_next_page(player, timeout_happened): if timeout_happened: player.participant.is_dropout = True player.NotInterested_hypo = player.Pref2 == 0 class WTP_MPL_2(Page): form_model = 'player' form_fields = ['WTP2'] # Only display this page if subject did not select "not interested" in the last preference question @staticmethod def is_displayed(player): return player.NotInterested == 0 and player.participant.is_dropout == False and player.Pref2 != 0 @staticmethod def get_timeout_seconds(player): participant = player.participant if participant.is_dropout: return 1 # instant timeout, 1 second else: return player.session.config['my_page_timeout_seconds'] def js_vars(player): return dict( Pref1=player.Pref1, Pref2=player.Pref2, ) @staticmethod def before_next_page(player, timeout_happened): if timeout_happened: player.participant.is_dropout = True class Efficacy_1(Page): form_model = 'player' form_fields = ['efficacy_1', 'efficacy_2'] def is_displayed(player): return player.participant.is_dropout == False @staticmethod def get_timeout_seconds(player): participant = player.participant if participant.is_dropout: return 1 # instant timeout, 1 second else: return player.session.config['my_page_timeout_seconds'] @staticmethod def before_next_page(player, timeout_happened): if timeout_happened: player.participant.is_dropout = True class Feedback_exp(Page): form_model = 'player' form_fields = ['feedback_exp'] # Only display this page if subject did not select "not interested" in the last preference question @staticmethod def is_displayed(player): return player.NotInterested == 0 and player.participant.is_dropout == False @staticmethod def get_timeout_seconds(player): participant = player.participant if participant.is_dropout: return 1 # instant timeout, 1 second else: return player.session.config['my_page_timeout_seconds'] @staticmethod def before_next_page(player, timeout_happened): if timeout_happened: player.participant.is_dropout = True class Feedback(Page): def is_displayed(player): return player.participant.is_dropout == False @staticmethod def get_timeout_seconds(player): participant = player.participant if participant.is_dropout: return 1 # instant timeout, 1 second else: return player.session.config['my_page_timeout_seconds'] @staticmethod def before_next_page(player, timeout_happened): if timeout_happened: player.participant.is_dropout = True class EndPage_ASU(Page): def is_displayed(player): return player.participant.is_dropout == False @staticmethod def get_timeout_seconds(player): participant = player.participant if participant.is_dropout: return 1 # instant timeout, 1 second else: return player.session.config['my_page_timeout_seconds'] @staticmethod def before_next_page(player, timeout_happened): if timeout_happened: player.participant.is_dropout = False # page_sequence = [Comprehension1, Comprehension2, Comprehension3, Comprehension4] page_sequence = [Introduction, Instruction, Comprehension1, Comprehension2, Comprehension3, Comprehension4, Instruction_waitpage_ASU, Instruction_summary_ASU, Pref_1, WTP_MPL_1, Pref_2, WTP_MPL_2, Efficacy_1, Feedback_exp, Feedback, EndPage_ASU]