from otree.api import * # Import risk params from input.riskParams import expParts ## MARK: Only keep this! from random import randint import numpy as np import matplotlib as plt from matplotlib import cm import json # Save dict as string doc = """ Your app description """ # MARK: Change study number here to make pages visible thisStudyId = "priceList_new" # Function to make feedback field def make_field(label): return models.LongStringField( blank=True, label=label, ) class Constants(BaseConstants): name_in_url = 'mpl_n' players_per_group = None num_rounds = 1 class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): # Select fixed amount randomStudy = models.StringField() # Save name of randomly selected study study = models.IntegerField() # Safe info about instruction choices choice_Instructions = models.IntegerField() # Save shell selected during instructions outcome_Instructions = models.StringField() # Save risk outcome during instructions multiSwitch_Instructions = models.IntegerField( initial=0 ) switches_Instructions = models.LongStringField() # Select color to determine type envelopeSelect=models.IntegerField() # Save key variable choice_Study2 = models.IntegerField() # Save inconsistent switches multiSwitch = models.IntegerField( initial=0 ) inconsistentSwitches = models.LongStringField() # Internal Feedback feedback_colorSelect = make_field("Feedback commentary:") feedback_generalTask = make_field("Feedback commentary:") feedback_option1 = make_field("Feedback commentary:") feedback_option2 = make_field("Feedback commentary:") feedback_attentionQuestion = make_field("Feedback commentary:") feedback_compQuestion = make_field("Feedback commentary:") feedback_attentionScreen = make_field("Feedback commentary:") feedback_task = make_field("Feedback commentary:") feedback_exitPage = make_field("Feedback commentary:") # Attention Check attention_check_done = models.BooleanField(initial=False) attention_check = models.StringField(initial="-9999") # Comprehension Questions compQ_1 = models.StringField() compQ_2 = models.StringField() compQ_3 = models.StringField() compQ_4 = models.StringField() compQ_5 = models.StringField() # PAGES class taskExplain(Page): form_model = "player" form_fields = [ "feedback_generalTask", "envelopeSelect" ] @staticmethod def is_displayed(player): # Only in the first round and correct study return (player.round_number == 1) and (player.participant.studyName == thisStudyId) @staticmethod def js_vars(player: Player): return dict( testing = player.session.config["testing"], ) @staticmethod def vars_for_template(player: Player): envelopeNum = list(player.participant.typeMatching.keys()) amount = [val[1][0] for val in player.participant.typeMatching.items()] return dict( testing = player.session.config["testing"], numEnvelopes = len(envelopeNum), envelopeNum = envelopeNum, minAmount = '£%.2f' %min(amount), maxAmount = '£%.2f' %max(amount), ) @staticmethod def before_next_page(player, timeout_happened): player.participant.type = player.envelopeSelect class option1(Page): form_model = "player" form_fields = [ "feedback_option1", "choice_Instructions", "outcome_Instructions", ] @staticmethod def is_displayed(player: Player): # Only in the first round and correct study return (player.round_number == 1) and (player.participant.studyName == thisStudyId) @staticmethod def js_vars(player: Player): return dict( #payoffs = ['🍐', '🍒'], payoffs = ['£1.50', '£0.50'], treatment = player.participant.treatment ) @staticmethod def vars_for_template(player: Player): return dict( testing = player.session.config["testing"], numChoices = 21, ) class option2(Page): form_model = "player" form_fields = [ "feedback_option2", ] @staticmethod def is_displayed(player: Player): # Only in the first round and correct study return (player.round_number == 1) and (player.participant.studyName == thisStudyId) @staticmethod def js_vars(player: Player): studyKey = list(expParts.keys())[player.participant.study] studyProps = expParts[studyKey] payoffs = [] for elem in studyProps[2]: payoffs.append(elem[0]) return dict( #payoffs = payoffs, payoffs = ['High', 'Low'], ) @staticmethod def vars_for_template(player: Player): amount = [val[1][0] for val in player.participant.typeMatching.items()] return dict( testing = player.session.config["testing"], #minAmount = '£%.2f' %min(amount), #maxAmount = '£%.2f' %max(amount), ) class atnQuest(Page): form_model = "player" form_fields = [ "feedback_attentionQuestion", ] @staticmethod def live_method(player, data): player.attention_check_done = True player.attention_check = str(data) return @staticmethod def is_displayed(player: Player): # Only in the first round and correct study return (player.round_number == 1) and (player.participant.studyName == thisStudyId) @staticmethod def vars_for_template(player: Player): return dict( testing = player.session.config["testing"], ) @staticmethod def js_vars(player: Player): return dict( stopEntry = player.attention_check_done, submittedAnswer = player.attention_check, ) class compQuest(Page): form_model = "player" form_fields = [ "feedback_compQuestion", "compQ_1", "compQ_2", "compQ_3", ] @staticmethod def is_displayed(player: Player): # Only in the first round and correct study return (player.round_number == 1) and (player.participant.studyName == thisStudyId) @staticmethod def vars_for_template(player: Player): fixedAmount = [0.50, 1.50] increment = 0.10 rows = int((max(fixedAmount) - min(fixedAmount))/increment) + 1 allAmounts = np.linspace(min(fixedAmount),max(fixedAmount), num=rows, endpoint=True ).tolist() amount = [] for index, element in enumerate(allAmounts): amount.append([index, '%.2f' % element]) return dict( amounts = amount, numOptions = amount[-1][0] + 1, testing = player.session.config["testing"], #showVerify = (player.participant.treatment == 0), showVerify = False, ) @staticmethod def js_vars(player: Player): return dict( payoffs = ['£1.50', '£0.50'], treatment = player.participant.treatment, ) class verExpl(Page): form_model = "player" form_fields = [ "compQ_4", "compQ_5", ] @staticmethod def is_displayed(player: Player): # Only in the first round and correct study return (player.round_number == 1) and (player.participant.studyName == thisStudyId) and (player.participant.treatment == 0) @staticmethod def vars_for_template(player: Player): fixedAmount = [0.50, 1.50] increment = 0.10 rows = int((max(fixedAmount) - min(fixedAmount))/increment) + 1 allAmounts = np.linspace(min(fixedAmount),max(fixedAmount), num=rows, endpoint=True ).tolist() amount = [] for index, element in enumerate(allAmounts): amount.append([index, '%.2f' % element]) return dict( amounts = amount, numOptions = amount[-1][0] + 1, testing = player.session.config["testing"], #showVerify = (player.participant.treatment == 0), showVerify = False, ) @staticmethod def js_vars(player: Player): return dict( payoffs = ['£1.50', '£0.50'], treatment = player.participant.treatment, ) class attentionScreen(Page): form_model = "player" form_fields = [ "feedback_attentionScreen" ] @staticmethod def is_displayed(player: Player): # Only in the first round and correct study return (player.round_number == 1) and (player.participant.studyName == thisStudyId) @staticmethod def vars_for_template(player: Player): return dict( testing = player.session.config["testing"], #showVerify = (player.participant.treatment == 0), showVerify = False, ) @staticmethod def js_vars(player: Player): minTime = 0 if player.participant.study == 2: minTime = player.session.config["minTimeOnPage"], return dict( testing = player.session.config["testing"], minTime = minTime, ) class task(Page): form_model = "player" form_fields = [ "feedback_task", "choice_Study2" ] @staticmethod def live_method(player, data): player.multiSwitch += 1 player.inconsistentSwitches = json.dumps(data) def error_message(player, values): if values["choice_Study2"] == -9999: msg = "Please select a switching row before proceeding." return msg @staticmethod def is_displayed(player: Player): # Only in the first round and correct study return (player.round_number == 1) and (player.participant.studyName == thisStudyId) @staticmethod def js_vars(player: Player): studyKey = list(expParts.keys())[player.participant.study] studyProps = expParts[studyKey] payoffs = [] probabilities = [] for elem in studyProps[2]: payoffs.append(elem[0]) probabilities.append(elem[1]) allAmounts = [val[0] for val in player.participant.typeMatching.values()] allAmounts.sort() amount = [] for index, element in enumerate(allAmounts): amount.append([index, '%.2f' % element]) return dict( payoffs = payoffs, probabilities = probabilities, fixedAmounts = amount, ) @staticmethod def vars_for_template(player: Player): allAmounts = [val[0] for val in player.participant.typeMatching.values()] allAmounts.sort() amount = [] for index, element in enumerate(allAmounts): amount.append([index, '%.2f' % element]) return dict( amounts = amount, numOptions = len(amount), testing = player.session.config["testing"], ) @staticmethod def app_after_this_page(player, upcoming_apps): # Always go to risk resolution return 'riskResolution' @staticmethod def before_next_page(player, timeout_happened): player.participant.singleChoice = player.choice_Study2 class exitPage(Page): form_model = "player" form_fields = [ "feedback_exitPage" ] @staticmethod def is_displayed(player): return player.attention_check == str(False) # Need to keep string here @staticmethod def vars_for_template(player: Player): return dict( testing = player.session.config["testing"], ) page_sequence = [ taskExplain, option1, option2, atnQuest, exitPage, compQuest, verExpl, attentionScreen, task ]