from otree.api import * import random import pandas as pd from collections import Counter from numpy import random as rnd from checkFunctions import addCheckVars import numpy as np doc = """ Your app description """ class C(BaseConstants): NAME_IN_URL = 'Intro2' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 # Setup/Experiment variables iPracticeRounds = 3 iOptions = 21 # iNumTrials = 5 iNumTrials = iPracticeRounds + 3*iOptions # Template variables AvgDur = '30' iBonus = '2 pounds' # Practice trials lPracticeTrials = [['115W3','111W3'],['555W3','551M5'],['234M3','123W1']] # Figs/Files paths figUvA_logo = 'global/figures/UvA_logo.png' path1 = 'global/figures/example1.png' pathTaskImg = 'global/figures/task-explanation.png' pathTaskImg1 = 'global/figures/task-1.png' pathTaskImg2 = 'global/figures/task-2.png' pathTaskImg3 = 'global/figures/task-3.png' pathDemoMouse = 'global/figures/demoMouse.gif' pathDemoMouseCrop = 'global/figures/demoMouseCrop.gif' pathTrials = '_static/global/files/Data4Exp.csv' pathAnswers = '_static/global/files/decisions_evaluators.csv' # Links sLinkReturn = "https://app.prolific.com/submissions/complete?cc=C400541Z" sLinkReturnCal = "https://app.prolific.com/submissions/complete?cc=C11B5C8R" sLinkOtherBrowser = "https://selection-game.herokuapp.com/room/room1" SubmitLink = 'https://app.prolific.com/submissions/complete?cc=CE8EX1LQ' imgCandidate = "global/figures/candidate.png" imgNumbers = "global/figures/numbers/n_" class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): pass # FUNCTIONS def bin2gender(bin): if bin==1: return "W" else: return "M" def creating_session(subsession): # Load Session variables s = subsession.session s.dbTrials = dbTrials = pd.read_csv(C.pathTrials) s.dbAnswers = dbAnswers = pd.read_csv(C.pathAnswers) if subsession.round_number ==1: for player in subsession.get_players(): p = player.participant # detect if participant timed-out player.participant.bTimeout = False # Load treatment conditions - Gender if s.config['vars']['gender']=='random': p.sEmployerGender = random.choice(['Man','Woman']) else: p.sEmployerGender = s.config['vars']['gender'] # Load treatment conditions - Age if s.config['vars']['age']=='random': p.sEmployerAge = random.choice(['20-30','31-40']) else: p.sEmployerAge = s.config['vars']['age'] # Load treatment conditions - Math if s.config['vars']['math']=='random': p.sEmployerMath = random.choice(['low','high']) else: p.sEmployerMath = s.config['vars']['math'] # Order of Employer characteristics listOrder = [0,1,2] random.shuffle(listOrder) p.lEmployerOrder = listOrder # Attributte position # 1. Shuffle main attributes lPos = ['gender','gma','int','con'] random.shuffle(lPos) # 2. Add random on the bottom lPos.append('rand') p.lPos = lPos # Randomly selected trial p.iSelectedTrial = random.randint(C.iPracticeRounds,C.iNumTrials) # Create complete set of trials lTrials = [] iTrial = 0 for iPair in range(len(dbTrials)): for genderC in ['01','10','Eq']: if genderC == 'Eq': # In equal condition, gender is the same # We select one at random gA = gB = random.sample([0,1],1)[0] else: # If not, use the gender correspondent to the trial gA = int(genderC[0]) gB = int(genderC[1]) candA = dbTrials.loc[iPair,'candA'] candB = dbTrials.loc[iPair,'candB'] randA = dbAnswers[(dbAnswers.candidate==candA) & (dbAnswers.igender==gA)]['irandom'].values[0] randB = dbAnswers[(dbAnswers.candidate==candB) & (dbAnswers.igender==gB)]['irandom'].values[0] valueA = f"{int(candA)}{bin2gender(gA)}{randA}" valueB = f"{int(candB)}{bin2gender(gB)}{randB}" lT = [valueA,valueB] random.shuffle(lT) lTrials.append(lT) ## If this is the selected trial. Save data for results iTrial +=1 # Store trials random.shuffle(lTrials) lPTrials = C.lPracticeTrials[:] lPTrials.extend(lTrials) p.lTrials = lPTrials ########## Determine info for payoff ########### trial = int(p.iSelectedTrial-1-C.iPracticeRounds) candA,candB = lTrials[trial] iCandA = int(candA[0:3]) iCandB = int(candB[0:3]) gA = int(str(candA[3])=="W") gB = int(str(candB[3])=="W") rA = int(candA[4]) rB = int(candB[4]) # get level, and evaluations for both iLvl = dbAnswers[(dbAnswers.candidate==iCandA) & (dbAnswers.igender==gA) & (dbAnswers.irandom==rA)]['lvl'].values[0] # get opponent dbOpponents = dbAnswers[(dbAnswers.candidate!=candA) & (dbAnswers.candidate!=candB) & (dbAnswers.lvl==iLvl)] dbOpponent = dbOpponents.iloc[rnd.randint(len(dbOpponents)),:] # evaluator column name sEval = f"d{decryptEvaluator(p)}" # Store results info for last page ResultValues = dict( trial = p.iSelectedTrial, candA = candA, candB = candB, opponent = f"{int(dbOpponent.candidate)}{bin2gender(dbOpponent.igender)}{dbOpponent.irandom}", evaluator = sEval, decOpponent = dbOpponent[sEval], decA = dbAnswers[(dbAnswers.candidate==iCandA) & (dbAnswers.igender==gA) & (dbAnswers.irandom==rA)][sEval].tolist()[0], decB = dbAnswers[(dbAnswers.candidate==iCandB) & (dbAnswers.igender==gB) & (dbAnswers.irandom==rB)][sEval].tolist()[0], ) p.ResultValues = ResultValues def decryptEvaluator(p): sGender = p.sEmployerGender sAge = p.sEmployerAge sMath = p.sEmployerMath match sGender: case 'Man': iF = 0 case 'Woman': iF = 1 match sAge: case "20-30": iA = 0 case "31-40": iA = 1 match sMath: case "low": iM = 0 case "high": iM = 1 return f"{iA}{iM}{iF}" def text4Attr(obj): match obj['type']: case 'gender': sText = f"is a {obj['value']}" case 'math': sText = f"has {obj['value']} math skills" case 'age': sText = f"is {obj['value']} years old" return sText def attr2answers(sValue): value = sValue.lower() match value: case 'man': ans = 'a' case 'woman': ans = 'b' case '20-30': ans = 'a' case '31-40': ans = 'b' case 'low': ans = 'a' case 'mid': ans = 'b' case 'high': ans = 'c' return ans # PAGES class Instructions(Page): form_model = 'player' form_fields = [] @staticmethod def js_vars(player: Player): p = player.participant # ansGender = attr2answers(p.sEmployerGender) ansAge = attr2answers(p.sEmployerAge) # ansMath = attr2answers(p.sEmployerMath) return dict( lSolutions = [ # 'a','b', ansGender, ansAge, ansMath, C.iNumTrials 'a','b', ansAge, str(C.iNumTrials) ] ) @staticmethod def vars_for_template(player: Player): p = player.participant lAttr0 = [ {'type': 'gender', 'value': p.sEmployerGender}, {'type': 'age', 'value': p.sEmployerAge}, {'type': 'math', 'value': p.sEmployerMath}, ] lAttr = [text4Attr(lAttr0[i]) for i in p.lEmployerOrder] return dict( lAttr = lAttr ) page_sequence = [Instructions] addCheckVars(Player, page_sequence)