from otree.api import * import csv import time from collections import defaultdict import itertools import random author = 'Marte Abts' doc = """ Beursspel """ # MODELS class Constants(BaseConstants): name_in_url = 'a_stock' history_template = 'a_stock/decodingkey.html' players_per_group = 2 # Load trial data with open('a_stock/decodeswithanswers.csv', encoding='utf-8') as f: values1 = list(csv.DictReader(f, delimiter=';')) num_rounds = len(values1) class Subsession(BaseSubsession): pass def creating_session(subsession: Subsession): import random if subsession.round_number == 1: treatments = ( ['highorder1', 'highorder2', 'loworder1', 'loworder2'] * 50 # enough for many dyads; safe upper bound ) random.shuffle(treatments) subsession.session.vars['treatment_queue'] = treatments class Group(BaseGroup): scenario_id = models.IntegerField( choices=[(1, '2: Very Low'), (2, '5: Average'), (3, '9: Very High')], label="What score do you give yourself for your performance on the decoding task?" ) show_rare_page = models.BooleanField(initial=False) employee_score1 = models.IntegerField() employee_score2 = models.IntegerField() employee_finished_testtask1 = models.BooleanField(initial=False) employee_finished_testtask2 = models.BooleanField(initial=False) employee_finished_testtask3 = models.BooleanField(initial=False) manager_finished_task = models.BooleanField(initial=False) Scenario1_rating = models.IntegerField( choices=[(i, str(i)) for i in range(1, 11)], # 1–10 label="What score do you give Player B in this scenario?" ) Scenario1_explanation = models.LongStringField( label="" ) Scenario2_rating = models.IntegerField( choices=[(i, str(i)) for i in range(1, 11)], # 1–10 label="What score do you give Player B in this scenario?" ) Scenario2_explanation = models.LongStringField( label="" ) Scenario3_rating = models.IntegerField( choices=[(i, str(i)) for i in range(1, 11)], # 1–10 label="What score do you give Player B in this scenario?" ) Scenario3_explanation = models.LongStringField( label="" ) class Player(BasePlayer): final_rating = models.IntegerField() final_explain = models.LongStringField() bonus = models.CurrencyField() totalpay= models.CurrencyField() total_performance = models.IntegerField() #Player B questions understand1 = models.IntegerField( label='The instructions of this study were easy to follow.', choices=[[1, ''], [2, ''], [3, ''], [4, ''], [5, ''], [6, ''], [7, '']], widget=widgets.RadioSelectHorizontal ) task1 = models.IntegerField( label='The decoding task was demanding.', choices=[[1, 'Totally unimportant'], [2, ''], [3, ''], [4, 'Neutral'], [5, ''], [6, ''], [7, 'Extremely important']], widget=widgets.RadioSelectHorizontal ) task2 = models.IntegerField( label='The decoding task was fun.', choices=[[1, 'Totally unimportant'], [2, ''], [3, ''], [4, 'Neutral'], [5, ''], [6, ''], [7, 'Extremely important']], widget=widgets.RadioSelectHorizontal ) task3 = models.IntegerField( label='I found the decoding task interesting.', choices=[[1, 'Totally unimportant'], [2, ''], [3, ''], [4, 'Neutral'], [5, ''], [6, ''], [7, 'Extremely important']], widget=widgets.RadioSelectHorizontal ) effort1 = models.IntegerField( label='I put high effort into decoding letter combinations.', choices=[[1, 'Totally unimportant'], [2, ''], [3, ''], [4, 'Neutral'], [5, ''], [6, ''], [7, 'Extremely important']], widget=widgets.RadioSelectHorizontal ) effort2 = models.IntegerField( label='I tried my best while decoding letter combinations.', choices=[[1, 'Totally unimportant'], [2, ''], [3, ''], [4, 'Neutral'], [5, ''], [6, ''], [7, 'Extremely important']], widget=widgets.RadioSelectHorizontal ) scenario_rating = models.IntegerField( choices=[(1, '2: Very Low'), (2, '5: Average'), (3, '9: Very High')], label="What score would you give yourself for your performance on the decoding task?" ) age = models.IntegerField(label="What is your age?", min=18, max=99) experience = models.IntegerField(label="How many years of work experience do you have?", min=0, max=60) studytype = models.IntegerField(label='How would you characterize your specializations/majors during your study? Multiple answers possible.', choices=[[1, 'Accounting, Tax and Finance'], [2, 'Strategy and General Management'], [3, 'International business and cross cultural management'], [4, 'Entrepreneurship and Innovation'],[5, 'Human Resources and Organizational Behavior'],[6, 'Mathematics and Statistics'],[7, 'Business Education'], [8, 'Economics'], [9, 'Socio-Economics'],[10, 'Other'],[11,'I have not yet made choices on my specializations/majors']],widget=widgets.RadioSelect) educationlevel = models.IntegerField(label='In which year of your study are you?', choices=[[1, '1st year bachelor'], [2, '2nd year bachelor'], [3, '3rd year bachelor'], [4, '>3rd year bachelor'], [5, '1st year master'],[6, '2nd year master'], [7, '>2nd year master']], widget=widgets.RadioSelect) gender = models.IntegerField(label='What is your gender?', choices=[[1, 'Male'], [2, 'Female'], [3, 'Non-binary'], [4, 'Prefer not to say']], widget=widgets.RadioSelect) informedconsent = models.BooleanField( label='', choices=[ [True, 'I agree to participate in this study. The study will start shortly.'], [False, 'I do not agree to participate in this study. The study will end here.'], ], widget=widgets.RadioSelect, ) experimentID = models.StringField(label="Please enter your experimental ID here: ") is_correct = models.BooleanField(initial=False) score1 = models.IntegerField(initial=0) score2 = models.IntegerField(initial=0) meanscore = models.IntegerField(initial=0) trial_id = models.StringField() treatment = models.StringField() total_correct = models.IntegerField(initial=0) question1= models.IntegerField(label='1. I am supposed to decode as many letter combinations as possible.', choices=[[1, 'True'],[2,'False']],widget=widgets.RadioSelect,) question2= models.IntegerField(label='2. I will decode letter combinations during two rounds, each lasting 2 minutes and 30 seconds.', choices=[[1, 'True'],[2,'False']],widget=widgets.RadioSelect,) question4 = models.StringField( label='4. Solve the following letter combination: ATSU', widget=widgets.TextInput ) question5 = models.StringField( label='5. Solve the following letter combination: XC', widget=widgets.TextInput ) question3 = models.IntegerField(label='3. I can earn an additional bonus of 2 EUR if my overall performance ends up in the top 25% of all participants in this session.', choices=[[1, 'True'], [2, 'False']], widget=widgets.RadioSelect, ) # Inputs for first decoding task decodedinput1 = models.IntegerField(doc="decodedinput1", label="CF=") decodedinput2 = models.IntegerField(doc="decodedinput2", label="SA=") decodedinput3 = models.IntegerField(doc="decodedinput3", label="TR=") decodedinput4 = models.IntegerField(doc="decodedinput4", label="EQ=") decodedinput5 = models.IntegerField(doc="decodedinput5", label="HM=") decodedinput6 = models.IntegerField(doc="decodedinput6", label="EFGH=") decodedinput7 = models.IntegerField(doc="decodedinput7", label="IC=") decodedinput8 = models.IntegerField(doc="decodedinput8", label="LO=") decodedinput9 = models.IntegerField(doc="decodedinput9", label="JE=") decodedinput10 = models.IntegerField(doc="decodedinput10", label="FEDC=") decodedinput11 = models.IntegerField(doc="decodedinput11", label="IJ=") decodedinput12 = models.IntegerField(doc="decodedinput12", label="YT=") decodedinput13 = models.IntegerField(doc="decodedinput13", label="MJOP=") decodedinput14 = models.IntegerField(doc="decodedinput14", label="RB=") decodedinput15 = models.IntegerField(doc="decodedinput15", label="FQ=") decodedinput16 = models.IntegerField(doc="decodedinput16", label="AB=") decodedinput17 = models.IntegerField(doc="decodedinput17", label="XY=") decodedinput18 = models.IntegerField(doc="decodedinput18", label="YAOE=") decodedinput19 = models.IntegerField(doc="decodedinput19", label="FE=") decodedinput20 = models.IntegerField(doc="decodedinput20", label="DC=") decodedinput21 = models.IntegerField(doc="decodedinput21", label="EF=") decodedinput22 = models.IntegerField(doc="decodedinput22", label="QR=") decodedinput23 = models.IntegerField(doc="decodedinput23", label="ST=") decodedinput24 = models.IntegerField(doc="decodedinput24", label="UB=") decodedinput25 = models.IntegerField(doc="decodedinput25", label="XYZY=") decodedinput26 = models.IntegerField(doc="decodedinput26", label="LM=") decodedinput27 = models.IntegerField(doc="decodedinput27", label="RS=") decodedinput28 = models.IntegerField(doc="decodedinput28", label="PO=") decodedinput29 = models.IntegerField(doc="decodedinput29", label="CFSA=") decodedinput30 = models.IntegerField(doc="decodedinput30", label="BG=") decodedinput31 = models.IntegerField(doc="decodedinput31", label="HE=") decodedinput32 = models.IntegerField(doc="decodedinput32", label="GH=") decodedinput33 = models.IntegerField(doc="decodedinput33", label="LOJE=") decodedinput34 = models.IntegerField(doc="decodedinput34", label="KL=") decodedinput35 = models.IntegerField(doc="decodedinput35", label="CD=") decodedinput36 = models.IntegerField(doc="decodedinput36", label="IS=") decodedinput37 = models.IntegerField(doc="decodedinput37", label="QC=") decodedinput38 = models.IntegerField(doc="decodedinput38", label="HMIC=") decodedinput39 = models.IntegerField(doc="decodedinput39", label="BB=") decodedinput40 = models.IntegerField(doc="decodedinput40", label="MJ=") decodedinput41 = models.IntegerField(doc="decodedinput41", label="OP=") decodedinput42 = models.IntegerField(doc="decodedinput42", label="KK=") decodedinput43 = models.IntegerField(doc="decodedinput43", label="QRST=") decodedinput44 = models.IntegerField(doc="decodedinput44", label="YA=") decodedinput45 = models.IntegerField(doc="decodedinput45", label="OE=") decodedinput46 = models.IntegerField(doc="decodedinput46", label="FR=") decodedinput47 = models.IntegerField(doc="decodedinput47", label="JJ=") decodedinput48 = models.IntegerField(doc="decodedinput48", label="KGYT=") decodedinput49 = models.IntegerField(doc="decodedinput49", label="OM=") decodedinput50 = models.IntegerField(doc="decodedinput50", label="EA=") num_correct = models.IntegerField(initial=0) # Inputs for second decoding task decodedinput1B = models.IntegerField(doc="decodedinput1B", label="AKQH=") decodedinput2B = models.IntegerField(doc="decodedinput2B", label="BMTS=") decodedinput3B = models.IntegerField(doc="decodedinput3B", label="CFWR=") decodedinput4B = models.IntegerField(doc="decodedinput4B", label="DO=") decodedinput5B = models.IntegerField(doc="decodedinput5B", label="ENXV=") decodedinput6B = models.IntegerField(doc="decodedinput6B", label="FOYK=") decodedinput7B = models.IntegerField(doc="decodedinput7B", label="GPAD=") decodedinput8B = models.IntegerField(doc="decodedinput8B", label="HMQT=") decodedinput9B = models.IntegerField(doc="decodedinput9B", label="IRWB=") decodedinput10B = models.IntegerField(doc="decodedinput10B", label="BM=") decodedinput11B = models.IntegerField(doc="decodedinput11B", label="JSZE=") decodedinput12B = models.IntegerField(doc="decodedinput12B", label="KFYR=") decodedinput13B = models.IntegerField(doc="decodedinput13B", label="LOXG=") decodedinput14B = models.IntegerField(doc="decodedinput14B", label="FV=") decodedinput15B = models.IntegerField(doc="decodedinput15B", label="BACD=") decodedinput16B = models.IntegerField(doc="decodedinput16B", label="HGFE=") decodedinput17B = models.IntegerField(doc="decodedinput17B", label="DO=") decodedinput18B = models.IntegerField(doc="decodedinput18B", label="LKJI=") decodedinput19B = models.IntegerField(doc="decodedinput19B", label="PONM=") decodedinput20B = models.IntegerField(doc="decodedinput20B", label="JZ=") decodedinput21B = models.IntegerField(doc="decodedinput21B", label="XWVU=") decodedinput22B = models.IntegerField(doc="decodedinput22B", label="AMSD=") decodedinput23B = models.IntegerField(doc="decodedinput23B", label="KZ=") decodedinput24B = models.IntegerField(doc="decodedinput24B", label="BFRT=") decodedinput25B = models.IntegerField(doc="decodedinput25B", label="ZYXW=") decodedinput26B = models.IntegerField(doc="decodedinput26B", label="CEQN=") decodedinput27B = models.IntegerField(doc="decodedinput27B", label="DGKU=") decodedinput28B = models.IntegerField(doc="decodedinput28B", label="GK=") decodedinput29B = models.IntegerField(doc="decodedinput29B", label="EHVP=") decodedinput30B = models.IntegerField(doc="decodedinput30B", label="FIWO=") decodedinput31B = models.IntegerField(doc="decodedinput31B", label="GLYX=") decodedinput32B = models.IntegerField(doc="decodedinput32B", label="HMAJ=") decodedinput33B = models.IntegerField(doc="decodedinput33B", label="INKB=") decodedinput34B = models.IntegerField(doc="decodedinput34B", label="JQCL=") decodedinput35B = models.IntegerField(doc="decodedinput35B", label="KZRF=") decodedinput36B = models.IntegerField(doc="decodedinput36B", label="DD=") decodedinput37B = models.IntegerField(doc="decodedinput37B", label="LUPD=") decodedinput38B = models.IntegerField(doc="decodedinput38B", label="MWTE=") decodedinput39B = models.IntegerField(doc="decodedinput39B", label="NOGS=") decodedinput40B = models.IntegerField(doc="decodedinput40B", label="PQHI=") decodedinput41B = models.IntegerField(doc="decodedinput41B", label="RDBM=") decodedinput42B = models.IntegerField(doc="decodedinput42B", label="SXUJ=") decodedinput43B = models.IntegerField(doc="decodedinput43B", label="TVFA=") decodedinput44B = models.IntegerField(doc="decodedinput44B", label="IW=") decodedinput45B = models.IntegerField(doc="decodedinput45B", label="WCEP=") decodedinput46B = models.IntegerField(doc="decodedinput46B", label="YLGQ=") decodedinput47B = models.IntegerField(doc="decodedinput47B", label="AQTR=") decodedinput48B = models.IntegerField(doc="decodedinput48B", label="BOMS=") decodedinput49B = models.IntegerField(doc="decodedinput49B", label="AQ=") decodedinput50B = models.IntegerField(doc="decodedinput50B", label="DXKF=") # FUNCTIONS def check_accuracy1(player: Player): correct_answers = [3063, 7177, 4968, 5229, 5746, 52634757, 7830, 4575, 1952, 63525530, 7819, 8649, 46197579, 6842, 6329, 7742, 2186, 86777552, 6352, 5530, 5263, 2968, 7149, 4942, 21862286, 4546, 6871, 7975, 30637177, 4247, 5752, 4757, 45751952, 2245, 3055, 7871, 2930, 57467830, 4242, 4619, 7579, 2222, 29687149, 8677, 7552, 6368, 1919, 22478649, 7546, 5277 ] score = 0 for i, correct_value in enumerate(correct_answers, start=1): if getattr(player, f'decodedinput{i}') == correct_value: score += 1 player.score1 = score group = player.group group.employee_score1 = player.score1 def check_accuracy2(player: Player): correct_answers = [94278152, 55611570, 38249213, 1357, 73911241, 24578727, 66239413, 52618115, 71139255, 5561, 21701273, 27248713, 43571266, 2441, 55943813, 52662473, 1357, 43272171, 23579161, 2112, 12924156, 94617013, 2712, 55241315, 12871292, 38738191, 13662756, 6627, 73524123, 24719257, 66438712, 52619421, 71912755, 21813843, 27121324, 1313, 43562313, 61921573, 91576670, 23815271, 13135561, 70125621, 15412494, 7192, 92387323, 87436681, 94811513, 55576170, 9481, 13122724] score = 0 for i, correct_value in enumerate(correct_answers, start=1): if getattr(player, f'decodedinput{i}B') == correct_value: score += 1 player.score2 = score group = player.group group.employee_score2 = player.score2 def current_round(player: Player): return player.session.vars['values'][player.round_number - 1] class Welcome(Page): def is_displayed(player): return player.round_number == 1 class InformedConsent(Page): form_model = 'player' form_fields = ['informedconsent'] def is_displayed(player): return player.round_number == 1 class BlockDropouts(Page): def is_displayed(player: Player): return player.informedconsent == False class WelcomeScreen(Page): timeout_seconds = 0.0000000001 def before_next_page(player: Player, timeout_happened): player.get_categories() print('def_get_categories') def is_displayed(player): return player.round_number == 1 class Instructions(Page): def is_displayed(player): return player.round_number == 1 # PAGE CLASSES AND SEQUENCE class Grouping(WaitPage): group_by_arrival_time = True timeout_seconds = 400 def after_all_players_arrive(group): import random # treatment treatment = group.session.vars['treatment_queue'].pop() for p in group.get_players(): p.participant.vars['treatment'] = treatment if treatment.startswith('high'): p.participant.vars['confrontation'] = 'high' else: p.participant.vars['confrontation'] = 'low' # rare page logic (NOW confrontation exists) if ( group.get_players()[0].participant.vars['confrontation'] == 'high' and random.random() < 0.01 ): group.show_rare_page = True else: group.show_rare_page = False # ===== DEBUG PRINT ===== print(f"Group {group.id_in_subsession} roles: {[p.participant.vars['type'] for p in group.get_players()]}") class DescriptionTask_manager(Page): def is_displayed(player: Player): return player.round_number == 1 class DescriptionTask_employee(Page): def is_displayed(player: Player): return player.round_number == 1 class TestTask(Page): form_model = 'player' timeout_seconds = 150 form_fields = [f'decodedinput{i}' for i in range(1, 51)] def vars_for_template(player): return dict(decoded_fields=TestTask.form_fields) def before_next_page(player: Player, timeout_happened): check_accuracy1(player) player.group.employee_finished_testtask1 = True def is_displayed(player: Player): return player.round_number == 1 class TestTask2(Page): form_model = 'player' timeout_seconds = 150 form_fields = [f'decodedinput{i}B' for i in range(1, 51)] def vars_for_template(player): return dict(decoded_fields=TestTask2.form_fields) def before_next_page(player: Player, timeout_happened): check_accuracy2(player) player.group.employee_finished_testtask2 = True def is_displayed(player: Player): return player.round_number == 1 class Assess(Page): def is_displayed(player: Player): return player.round_number == 1 class W1(WaitPage): title_text = 'Waiting Room' body_text = "Your employees are currently performing their decoding task." def is_displayed(player: Player): return player.round_number == 1 and player.participant.vars['type'] == 'manager' class END1(Page): def is_displayed(player: Player): return player.round_number == 1 class END2(Page): def is_displayed(player: Player): return player.round_number == 1 def before_next_page(player: Player, timeout_happened): player.total_performance = player.score1 + player.score2 class END3(Page): def is_displayed(player: Player): return player.round_number == 1 class Instructions2_high(Page): def is_displayed(player): return player.round_number == 1 class Instructions2_low(Page): def is_displayed(player): return player.round_number == 1 class Instructions3_high(Page): def is_displayed(player): return player.round_number == 1 class Instructions3_low(Page): def is_displayed(player): return player.round_number == 1 class Role_PlayerA(Page): def is_displayed(player): return player.round_number == 1 and player.participant.vars['type'] == 'manager' class Role_PlayerB(Page): def is_displayed(player): return player.round_number == 1 and player.participant.vars['type'] == 'employee' class Quiz_low(Page): form_model = 'player' form_fields = ['question1','question2', 'question3','question4', 'question5','question6','question8'] @staticmethod def error_message(player, values): solutions = dict( question1=1, question2="77497149", question3="2130", question4=1, question5=1, question6=1, question8=1, ) error_messages = dict() for field_name in solutions: if values[field_name] != solutions[field_name]: error_messages[field_name] = 'Wrong answer' return error_messages def is_displayed(player): return player.round_number == 1 class Quiz_high(Page): form_model = 'player' form_fields = ['question1','question2','question3','question4','question5'] @staticmethod def error_message(player, values): solutions = dict( question1=1, question2=1, question3=1, question4="77497149", question5="2130", ) error_messages = dict() for field_name in solutions: if values[field_name] != solutions[field_name]: error_messages[field_name] = 'Wrong answer' return error_messages def is_displayed(player): return player.round_number == 1 and player.round_number == 1 class StrategyM_high(Page): def is_displayed(player): return player.round_number == 1 and player.participant.vars['type'] == 'manager' and player.participant.vars['confrontation'] =="high" class StrategyM_low(Page): def is_displayed(player): return player.round_number == 1 and player.participant.vars['type'] == 'manager' and player.participant.vars['confrontation'] =="low" class StrategyM0(Page): form_model = 'group' form_fields = ['Scenario1_rating','Scenario1_explanation'] def is_displayed(player): return player.round_number == 1 and player.participant.vars['type'] == 'manager' and (player.participant.vars['treatment'] == 'highorder1' or player.participant.vars['treatment'] == 'loworder1') def vars_for_template(player): return dict( employee_score1=player.group.employee_score1, employee_score2 = player.group.employee_score2 ) class StrategyM1(Page): form_model = 'group' form_fields = ['Scenario2_rating','Scenario2_explanation'] def is_displayed(player): return player.round_number == 1 and player.participant.vars['type'] == 'manager' and (player.participant.vars['treatment'] == 'highorder1' or player.participant.vars['treatment'] == 'loworder1') def vars_for_template(player): return dict( employee_score1=player.group.employee_score1, employee_score2 = player.group.employee_score2 ) class StrategyM2(Page): form_model = 'group' form_fields = ['Scenario3_rating','Scenario3_explanation'] def is_displayed(player): return player.round_number == 1 and player.participant.vars['type'] == 'manager' and (player.participant.vars['treatment'] == 'highorder1' or player.participant.vars['treatment'] == 'loworder1') def vars_for_template(player): return dict( employee_score1=player.group.employee_score1, employee_score2 = player.group.employee_score2 ) def before_next_page(player: Player, timeout_happened): player.group.manager_finished_task= True group = player.group sid = group.scenario_id # Assign final rating to the employee(s) for p in group.get_players(): if p.participant.vars['type'] == 'employee': p.final_rating = getattr(group, f"Scenario{sid}_rating") p.final_explain = getattr(group, f"Scenario{sid}_explanation") class StrategyM0_(Page): form_model = 'group' form_fields = ['Scenario3_rating','Scenario3_explanation'] def is_displayed(player): return player.round_number == 1 and player.participant.vars['type'] == 'manager' and (player.participant.vars['treatment'] == 'highorder2' or player.participant.vars['treatment'] == 'loworder2') def vars_for_template(player): return dict( employee_score1=player.group.employee_score1, employee_score2 = player.group.employee_score2 ) class StrategyM1_(Page): form_model = 'group' form_fields = ['Scenario2_rating','Scenario2_explanation'] def is_displayed(player): return player.round_number == 1 and player.participant.vars['type'] == 'manager' and (player.participant.vars['treatment'] == 'highorder2' or player.participant.vars['treatment'] == 'loworder2') def vars_for_template(player): return dict( employee_score1=player.group.employee_score1, employee_score2 = player.group.employee_score2 ) class StrategyM2_(Page): form_model = 'group' form_fields = ['Scenario1_rating','Scenario1_explanation'] def is_displayed(player): return player.round_number == 1 and player.participant.vars['type'] == 'manager' and (player.participant.vars['treatment'] == 'highorder2' or player.participant.vars['treatment'] == 'loworder2') def vars_for_template(player): return dict( employee_score1=player.group.employee_score1, employee_score2 = player.group.employee_score2 ) def before_next_page(player: Player, timeout_happened): player.group.manager_finished_task= True group = player.group sid = group.scenario_id for p in group.get_players(): if p.participant.vars['type'] == 'employee': p.final_rating = getattr(group, f"Scenario{sid}_rating") p.final_explain = getattr(group, f"Scenario{sid}_explanation") class WaitForEmployee(WaitPage): title_text = "Please wait" body_text = "Player B is currently working on solving the first round of decodes. This can take up to 3 minutes. Please do not close this window." def is_displayed(player): return (player.round_number == 1 and player.participant.vars['type'] == 'manager' and not player.group.employee_finished_testtask1 ) class WaitForEmployee2(WaitPage): title_text = "Please wait" body_text = "Player B finished the first round and is currently working on solving the second round of decodes. This can again take up to 3 minutes. Please do not close this window." def is_displayed(player): return (player.round_number == 1 and player.participant.vars['type'] == 'manager' and not player.group.employee_finished_testtask2 ) class WaitForEmployee3(WaitPage): title_text = "Please wait" body_text = "Player B finished the decoding task. He/she is now assessing his/her own performance. Afterwards, you will be asked to fill out a performance evaluation for Player B." def is_displayed(player): return (player.round_number == 1 and player.participant.vars['type'] == 'manager' and not player.group.employee_finished_testtask3 ) class WaitForManager(WaitPage): title_text = "Please wait" body_text = "Player A is currently evaluating your performance in the decoding task. Please do not close this window." def is_displayed(player): return (player.round_number == 1 and player.participant.vars['type'] == 'employee' and not player.group.manager_finished_task ) import math class BonusWaitPage(WaitPage): wait_for_all_groups = True # important: session-wide wait page title_text = "Please wait" body_text = "Please remain seated. Your compensation is being determined. Once the system is ready, you will automatically proceed to the next page. Do not close this window." @staticmethod def after_all_players_arrive(subsession: Subsession): players = subsession.get_players() players_sorted = sorted(players, key=lambda p: p.total_performance, reverse=True) import math n_bonus = math.ceil(len(players_sorted) * 0.25) for i, p in enumerate(players_sorted): p.bonus = 2 if i < n_bonus else 0 def is_displayed(player): return player.round_number == 1 class Final2(Page): def is_displayed(player): return player.round_number == 1 class RarePage(Page): def is_displayed(player): return ( player.round_number == 1 and player.group.show_rare_page ) class Final(Page): def is_displayed(player): return ( player.round_number == 1 ) def before_next_page(player, timeout_happened): player.totalpay = 8 + player.bonus player.participant.vars['total_pay'] = player.totalpay class Final_empl(Page): def is_displayed(player): return ( player.round_number == 1 and player.participant.vars['type'] == 'employee' ) class Feedback(Page): def is_displayed(player): return player.round_number == 1 and player.participant.vars['type'] == 'employee' def vars_for_template(player): return dict( scenario1rating=player.group.Scenario1_rating, scenario1explain=player.group.Scenario1_explanation, scenario2rating=player.group.Scenario2_rating, scenario2explain=player.group.Scenario2_explanation, scenario3rating=player.group.Scenario3_rating, scenario3explain=player.group.Scenario3_explanation, ) def before_next_page(player, timeout_happened): player.totalpay = 8 + player.bonus player.participant.vars['total_pay'] = player.totalpay class Feedback_manager(Page): def is_displayed(player): return player.round_number == 1 and player.participant.vars['type'] == 'manager' class Page1PEQ(Page): form_model = 'player' form_fields = ['task1','task2','task3'] def is_displayed(player): return player.round_number == 1 class Page2PEQ(Page): form_model = 'player' form_fields = ['effort1','effort2'] def is_displayed(player): return player.round_number == 1 class Page3PEQ(Page): form_model = 'player' form_fields = ['scenario_id_alternative'] def is_displayed(player): return player.round_number == 1 class Page5PEQ(Page): form_model = 'player' form_fields = ['understand1'] def is_displayed(player): return player.round_number == 1 class Demographics(Page): form_model = 'player' form_fields = ['age','gender','experience','studytype','educationlevel'] def is_displayed(player): return player.round_number == 1 class Start_task(Page): def is_displayed(player): return (player.round_number == 1) class Payment(Page): def is_displayed(player): return player.round_number == 1 page_sequence = [Welcome, Instructions, Quiz_high, Start_task, TestTask, END1, TestTask2, END2, END3, Page1PEQ, Page2PEQ, Page3PEQ, Demographics, Page5PEQ, BonusWaitPage, Final, Final2]