from otree.api import * import numpy as np # Import information about risks from input.riskParams import expParts doc = """ Your app description """ # Function to make feedback field def make_field(label): return models.LongStringField( blank=True, label=label, ) class C(BaseConstants): NAME_IN_URL = 'resolution' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): feedback_understanding = models.IntegerField( label="Was the experiment well explained?", choices=[ [1, "No"], [2, "Rather no"], #[3, "So and so"], [3, "Rather yes"], [4, "Yes"], ], widget=widgets.RadioSelectHorizontal, ) feedback_certain = models.IntegerField( label="How certain are you about your choice?", choices=[ [1, "Uncertain"], [2, "Rather uncertain"], #[3, "So and so"], [3, "Rather certain"], [4, "Certain"], ], widget=widgets.RadioSelectHorizontal, ) feedback_trust = models.IntegerField( label="Do you believe that your bonus is determined fairly, exactly as described?", choices=[ [1, "No"], [2, "Rather no"], #[3, "So and so"], [3, "Rather yes"], [4, "Yes"], ], widget=widgets.RadioSelectHorizontal, ) feedback_WVS = models.IntegerField( label="Generally speaking, would you say that most people can be trusted or that you need to be very careful in dealing with people?", choices=[ [1, "Cannot be too careful in dealing with people"], [2, "Must be rather careful in dealing with people"], #[3, "So and so"], [3, "People can rather be trusted"], [4, "Most people can be trusted"], ], widget=widgets.RadioSelectHorizontal, ) feedback_final_remarks = models.LongStringField( label="Do you have further feedback for us?", blank=True ) # Risk-resolution choice riskResolution = models.IntegerField( choices = [ [0, "Option 1"], [1, "Option 2"], ] ) # Save payoff-relevant variables chosenObject = models.IntegerField(initial=-100) totalBonus = models.FloatField() # Save if verification-password was shown verificationShown = models.BooleanField(blank=True, initial = False) # Save if verification-page was printed verificationPrint = models.IntegerField(initial = 0) # Internal Feedback feedback_singleChoiceRisk = make_field("Feedback commentary:") feedback_bonusPayment = make_field("Feedback commentary:") # PAGES class Questionnaire(Page): form_model = "player" form_fields = [ "feedback_understanding", "feedback_certain", "feedback_trust", "feedback_WVS", "feedback_final_remarks", ] @staticmethod def is_displayed(player): return player.round_number == 1 @staticmethod def vars_for_template(player: Player): bonusFiles = False #MARK: Check conditions! ''' if player.session.study == 2: bonusFiles = True ''' return dict( testing = player.session.config["testing"], bonusFiles = bonusFiles, studyName = player.participant.studyName, ) @staticmethod def before_next_page(player, timeout_happened): ## Best to determine safe payoff here dataKey = list(expParts.keys())[player.participant.study] data = expParts[dataKey] # Determine to which Option player is routed riskyPayoff = False if player.participant.studyName == "binaryChoice": # Single Choice if player.participant.singleChoice == 1: riskyPayoff = True else: safePayoff = data[3] elif player.participant.studyName == "priceList": # MPL switchRow = player.participant.singleChoice # Row where Option 1 is chosen last chosenType = player.participant.type typeMatching = player.participant.typeMatching relevantRow = typeMatching[chosenType][1] if relevantRow <= switchRow: # Risk riskyPayoff = True else: # Safe payoff allAmounts = [val[2] for val in player.participant.typeMatching.values()] allAmounts.sort() safePayoff = allAmounts[relevantRow] elif player.participant.studyName == "priceList_new": # MPL switchRow = player.participant.singleChoice # Row where Option 1 is chosen last chosenType = player.participant.type typeMatching = player.participant.typeMatching relevantRow = typeMatching[chosenType][1] if relevantRow <= switchRow: # Risk riskyPayoff = True else: # Safe payoff safePayoff = typeMatching[chosenType][0] elif player.participant.studyName == "probMatching": # Probability matching thresholdProb = player.participant.singleChoice chosenType = player.participant.type typeMatching = player.participant.typeMatching riskProb = typeMatching[chosenType][2] if riskProb >= int(thresholdProb): # Risk riskyPayoff = True else: #Safe payoff safePayoff = data[3] if riskyPayoff: player.riskResolution = 0 # Option 1 else: player.riskResolution = 1 # Option 2 player.totalBonus = safePayoff class RevealPWD(Page): @staticmethod def is_displayed(player: Player): # Only shown if study has bonus files return False @staticmethod def js_vars(player): return dict( password = player.participant.password_bonus, ) @staticmethod def vars_for_template(player): return dict( user_chosen_decision = player.participant.chosenBF, testing = player.session.config["testing"]) class option1(Page): form_model = "player" form_fields = [ "feedback_singleChoiceRisk" ] @staticmethod def live_method(player, data): if data == "verificationShown": player.verificationShown = True elif data == "verificationPrint": player.verificationPrint +=1 elif player.chosenObject == -100: player.chosenObject = int(data) if player.participant.studyName == "probMatching": dataKey = list(expParts.keys())[player.participant.study] data = expParts[dataKey] _, _, risk, _ = data payoffs = [tmp[0] for tmp in risk] # Probability matching chosenType = player.participant.type typeMatching = player.participant.typeMatching riskProb = typeMatching[chosenType][2] if riskProb > player.chosenObject: player.totalBonus = payoffs[0] else: player.totalBonus = payoffs[1] else: player.totalBonus = player.participant.shuffledPayoff[player.chosenObject] @staticmethod def is_displayed(player: Player): # Only shown if study is single choice and risk was chosen return (player.riskResolution == 0) @staticmethod def js_vars(player): dataKey = list(expParts.keys())[player.participant.study] data = expParts[dataKey] studyName, resolutionType, risk, _ = data shuffledPayoff = player.participant.shuffledPayoff payoffs = [tmp[0] for tmp in risk] probabilities = [tmp[1] for tmp in risk] rowPay = 0 if studyName == "priceList": # MPL typeRow = player.participant.type rowPay = player.participant.typeMatching[typeRow][-1] elif studyName == "priceList_new": partType = player.participant.type typeRow = player.participant.typeMatching[partType][-1] rowPay = player.participant.typeMatching[partType][0] elif studyName == "probMatching": # Probability Matching chosenType = player.participant.type typeMatching = player.participant.typeMatching winningProb = typeMatching[chosenType][2] / 100 probabilities = [round(winningProb,2), round(1-winningProb,2) ] payoffs = ["£" + '%.2f' %pay for pay in payoffs] return dict( payoffs = payoffs, probabilities = probabilities, shuffledPayoff = [ "£" + '%.2f' %item for item in shuffledPayoff], shuffledPosition = shuffledPayoff, # Relevant for cards payoffSameOrder = (shuffledPayoff == payoffs), treatment = (player.participant.treatment == 0), chosenObject = player.chosenObject, # Send chosen shell to page to prevent reload rowPay = "£" + '%.2f' %rowPay, studyName = studyName, resolutionType = resolutionType, ) @staticmethod def vars_for_template(player): dataKey = list(expParts.keys())[player.participant.study] data = expParts[dataKey] studyName, resolutionType, _, _ = data safeAmount = 0 winningProb = 0 colorScheme = [] if studyName == "priceList": # MPL with colors switchRow = player.participant.singleChoice allAmounts = [val[2] for val in player.participant.typeMatching.values()] allAmounts.sort() safeAmount = allAmounts[switchRow] colorScheme = [ [idx,val[0], "£" + '%.2f' %val[-1] ] for idx, val in player.participant.typeMatching.items()] elif studyName == "priceList_new": # MPL with envelopes typeMatch = player.participant.typeMatching playerType = player.participant.type safeAmount = typeMatch[playerType][0] colorScheme = [ [idx, "£" + '%.2f' %val[0] ] for idx, val in player.participant.typeMatching.items()] elif studyName == "probMatching": chosenType = player.participant.type typeMatching = player.participant.typeMatching winningProb = typeMatching[chosenType][2] colorScheme = [ [idx, val[0], val[1], val[2]] for idx, val in player.participant.typeMatching.items() ] colorScheme = [colorScheme[x:x+10] for x in range(0, len(colorScheme), 10)] return dict( testing = player.session.config["testing"], treatment = (player.participant.treatment == 0), passwordVerification = player.participant.password_verification, studyName = studyName, safeAmount = "£" + '%.2f' %safeAmount, colorScheme = colorScheme, winningProb = winningProb, resolutionType = resolutionType, ) class option2(Page): form_model = "player" form_fields = [ "feedback_bonusPayment", "verificationShown", ] @staticmethod def is_displayed(player: Player): # Only shown if study is single choice and amount was chosen return (player.riskResolution == 1) @staticmethod def live_method(player, data): if data == "verificationShown": player.verificationShown = True elif data == "verificationPrint": player.verificationPrint +=1 @staticmethod def js_vars(player): dataKey = list(expParts.keys())[player.participant.study] data = expParts[dataKey] studyName, resolutionType, risk, _ = data payoffs = [tmp[0] for tmp in risk] probabilities = [tmp[1] for tmp in risk] if studyName == "probMatching": # Probability Matching payoffs = ["£" + '%.2f' %pay for pay in payoffs] chosenType = player.participant.type typeMatching = player.participant.typeMatching winningProb = typeMatching[chosenType][2] / 100 probabilities = [round(winningProb,2), round(1-winningProb,2) ] shuffledPayoff = player.participant.shuffledPayoff return dict( shuffledPayoff = ["£" + '%.2f' %item for item in shuffledPayoff], shuffledPosition = shuffledPayoff, # Relevant for cards payoffs = payoffs, probabilities = probabilities, selectedShell = player.chosenObject, safeAmount = "£" + '%.2f' %player.totalBonus, resolutionType = resolutionType, ) @staticmethod def vars_for_template(player): winningProb = 0 colorScheme = [] if player.participant.studyName == "priceList": # MPL colorScheme = [ [idx,val[0], "£" + '%.2f' %val[-1] ] for idx, val in player.participant.typeMatching.items()] elif player.participant.studyName == "priceList_new": colorScheme = [ [idx, "£" + '%.2f' %val[0] ] for idx, val in player.participant.typeMatching.items()] elif player.participant.studyName == "probMatching": # Probability matching chosenType = player.participant.type typeMatching = player.participant.typeMatching winningProb = typeMatching[chosenType][2] colorScheme = [ [idx, val[0], val[1], val[2]] for idx, val in player.participant.typeMatching.items() ] colorScheme = [colorScheme[x:x+10] for x in range(0, len(colorScheme), 10)] return dict( #user_chosen_decision = player.participant.chosenBF, totalBonus = "£" + '%.2f' %player.totalBonus, testing = player.session.config["testing"], passwordVerification = player.participant.password_verification, treatment = (player.participant.treatment == 0), studyName = player.participant.studyName, colorScheme = colorScheme, winningProb = winningProb, ) page_sequence = [ Questionnaire, RevealPWD, option1, option2, ]