from otree.api import * from otree import settings import numpy as np import pandas as pd doc = """Experiment 2 for Social Inference project """ # TO DOs --------------------------------------------------------------------------------------------------------------- # Questions whether participants thought it was a real human partner # Screen at the end of training phase that the experiment starts now # NOTES TO SELF -------------------------------------------------------------------------------------------------------- # A player is initialized per session, i.e., in every session I will have x players # Otree initializes a participant code that is valid across different subsessions # I can create 1 room and in that 1 room I have 3 session configs that the experimenter can select. Then, # once a session config is selected the experimenter can create however many links they need and share it with the participants. # OTREE CLASSES -------------------------------------------------------------------------------------------------------- class C(BaseConstants): NAME_IN_URL = 'SI_Exp2_Training_IntroObsB' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): One_comprehension_check_task = models.IntegerField(label="What does Observer B do?", widget=widgets.RadioSelect, choices=[[1, 'a) Observer B observers the player playing a game.'], [2, 'b) Observer B is the player.'],] ) One_result = models.IntegerField() page_name = models.StringField() counter = models.IntegerField(default=0) IV_num_choice_only = models.IntegerField() inferred_reward = models.IntegerField( min=0, max=500, label='What reward did the player get on the previous trial?', blank=True, null=True, doc="""This player's decision""") inferred_choice = models.StringField( max_length=500, blank=True, null=True) predicted_reward = models.IntegerField( min=0, max=500, label='What reward will the player get on the next trial?', blank=True, null=True, doc="""This player's decision""") predicted_choice = models.StringField( max_length=500, blank=True, null=True) predicted_choice_row = models.IntegerField( max_length=500, blank=True, null=True) predicted_choice_column = models.IntegerField( max_length=500, blank=True, null=True) RT_inferred_reward = models.FloatField(initial=None, null=True, blank=True) RT_inferred_choice = models.FloatField(initial=None, null=True, blank=True) RT_predicted_reward = models.FloatField(initial=None, null=True, blank=True) RT_predicted_choice = models.FloatField(initial=None, null=True, blank=True) round_data_field = models.IntegerField() performance = models.FloatField() payout = models.FloatField() participant_code = models.StringField() ObsB_predicted_reward = models.IntegerField(field_maybe_none=True) ObsB_inferred_reward = models.IntegerField(field_maybe_none=True) ObsB_highlight_index_row = models.IntegerField(field_maybe_none=True) ObsB_highlight_index_column = models.IntegerField(field_maybe_none=True) ObsB_inf_highlight_index_row = models.IntegerField(field_maybe_none=True) ObsB_inf_highlight_index_column = models.IntegerField(field_maybe_none=True) cheat_stay_on_page = models.IntegerField() def store_round_data(self): self.round_data_field = self.round_number # Storing round number as an example def before_next_page(self): self.store_round_data() def increment_counter(self): self.counter += 1 return self.counter class Row(ExtraModel): player = models.Link(Player) SN = models.IntegerField() participant_label = models.IntegerField() participant_code = models.StringField() IV_number_choice_only_trials = models.IntegerField() trial_index = models.IntegerField() trial = models.IntegerField() trial_type = models.StringField() inferred_reward = models.IntegerField( min=0, max=500, label='What reward did the player get on the previous trial?', blank=True, doc="""This player's decision""") inferred_choice = models.StringField( max_length=500, blank=True) predicted_reward = models.IntegerField( min=0, max=500, label='What reward will the player get on the next trial?', blank=True, null=True, doc="""This player's decision""") predicted_choice = models.StringField( max_length=500, blank=True) RT_inferred_reward = models.FloatField(initial=None) RT_inferred_choice = models.FloatField(initial=None) RT_predicted_reward = models.FloatField(initial=None) RT_predicted_choice = models.FloatField(initial=None) reward_inference_query = models.BooleanField() choice_inference_query = models.BooleanField() reward_prediction_query = models.BooleanField() choice_prediction_query = models.BooleanField() demonstrator_choice_index = models.IntegerField() demonstrator_choice_index_row = models.IntegerField() demonstrator_choice_index_column = models.IntegerField() demonstrator_noisy_rescaled_reward = models.IntegerField() demonstrator_choice_probs = models.StringField() demonstrator_noisy_rescaled_all_rewards = models.StringField() mean_reward = models.FloatField() x1_index = models.IntegerField() x2_index = models.IntegerField() money = models.FloatField(initial=0) # per trial # fields I have to create, but hopefully not save Demonstrator_for_SN = models.IntegerField() environment = models.IntegerField() scale = models.IntegerField() demonstrator_choice_prob = models.FloatField() demonstrator_true_all_rewards = models.LongStringField() demonstrator_noisy_reward = models.FloatField() ObsB_predicted_reward = models.IntegerField(field_maybe_none=True) ObsB_inferred_reward = models.IntegerField(field_maybe_none=True) ObsB_predicted_choice_row = models.IntegerField(field_maybe_none=True) ObsB_predicted_choice_col = models.IntegerField(field_maybe_none=True) ObsB_inferred_choice_row = models.IntegerField(field_maybe_none=True) ObsB_inferred_choice_col = models.IntegerField(field_maybe_none=True) # PAGES ---------------------------------------------------------------------------------------------------------------- class IntroObsB(Page): template_name = 'SI_Exp2_Training_IntroObsB/IntroObsB.html' def vars_for_template(player: Player): grid_numbers = np.empty((11, 11)) grid_data = [] for row_idx, row in enumerate(grid_numbers): grid_row = [] for col_idx, value in enumerate(row): cell = {'value': value, 'row_index': row_idx, 'column_index': col_idx} grid_row.append(cell) grid_data.append(grid_row) return {'grid_data':grid_data, 'Explanation': ''} class Explanation1(Page): template_name = 'SI_Exp2_Training_IntroObsB/Explanation.html' def vars_for_template(player: Player): return {'Explanation': "You will work together with someone else, who is called Observer B. Like you, Observer B is watching the player play."} class Explanation2(Page): template_name = 'SI_Exp2_Training_IntroObsB/Explanation.html' def vars_for_template(player: Player): return {'Explanation': "You and Observer B may have access to the same information or may both be missing the same information, as in the following example."} class Explanation3(Page): template_name = 'SI_Exp2_Training_IntroObsB/Explanation.html' def vars_for_template(player: Player): return {'Explanation': "Alternatively, sometimes Observer B may have access to information you do not have access to. Other times, you may have access to information Observer B does not have access to. For example, you may have access to the player’s selection and Observer B to the player’s points, as in the following example."} class Explanation4(Page): template_name = 'SI_Exp2_Training_IntroObsB/Explanation.html' def vars_for_template(player: Player): return {'Explanation': "Like you, Observer B will sometimes be asked to guess what the player selected and how many points the player got. The answers to these questions will be shared among you two. That means you will have access to Observer B’s answers and Observer B will have access to your answers. You and Observer B may be asked the same question, as in the following example."} class Explanation5(Page): template_name = 'SI_Exp2_Training_IntroObsB/Explanation.html' def vars_for_template(player: Player): return {'Explanation': 'Alternatively, Observer B and you may be asked different questions, as in the following example.'} class Explanation6(Page): template_name = 'SI_Exp2_Training_IntroObsB/Explanation.html' def vars_for_template(player: Player): return {'Explanation': 'Please note that you have to provide a response in order to progress through the task. Both you and Observer B will not be able to move forward until both of you have answered your respective questions. To facilitate a smooth experience for both of you, we kindly ask you to stay focused on the task and make steady progress. This will help ensure that neither you nor Observer B have to wait unnecessarily long. Your cooperation and attention to the task are greatly appreciated.'} class empty_grid(Page): template_name = 'SI_Exp2_Training_IntroObsB/empty_grid.html' counter = 0 def is_displayed(player: Player): # "Next round" should not be shown on first trial if player.round_number > 1: return True def vars_for_template(self): my_array = np.empty((11, 11)) grid_number = my_array.tolist() return {'grid_number': grid_number} timeout_seconds = 4 class predict_choice_both(Page): template_name = 'SI_Exp2_Training_IntroObsB/predict_choice.html' form_model = 'player' form_fields = ['predicted_choice', 'RT_predicted_choice'] #cheat_stay_on_page def vars_for_template(self): # this just gives the grid grid_numbers = np.empty((11, 11)) grid_data = [] for row_idx, row in enumerate(grid_numbers): grid_row = [] for col_idx, value in enumerate(row): cell = {'value': value, 'row_index': row_idx, 'column_index': col_idx} grid_row.append(cell) grid_data.append(grid_row) ObsA_query_row1 = 'Which cell do you think the player will select next?' ObsA_query_row2 = '(Please click into the respective cell and then submit)' show_form_field = 1 ObsB_query_row1 = 'Which cell do you think the player will select next?' ObsB_query_row2 = '(Please click into the respective cell and then submit)' # The following is a placerholder because I take the real demonstrators value and just add some small noise ObsB_highlight_index_row = 1 ObsB_highlight_index_column = 10 ObsB_show_form_field = 1 ObsB_show_guess_text = 'Observer B\'s prediction is shown in purple.' return {'grid_data': grid_data, 'ObsB_highlight_index_row': ObsB_highlight_index_row, 'ObsB_highlight_index_column': ObsB_highlight_index_column, 'ObsA_query_row1':ObsA_query_row1, 'ObsA_query_row2':ObsA_query_row2, 'ObsB_query_row1':ObsB_query_row1, 'ObsB_query_row2':ObsB_query_row2, 'show_form_field':show_form_field, 'ObsB_show_form_field':ObsB_show_form_field, 'ObsB_show_guess_text': ObsB_show_guess_text} @staticmethod def live_method(player: Player, data): if player.id_in_group == 1: if data["predicted_choice"] == 'NA,NA': return {1: {"predicted_choice": '', "predicted_choice_row": '', "predicted_choice_column": ''}} # else: strings = data["predicted_choice"].split(',') return {1: {"predicted_choice":data["predicted_choice"], "predicted_choice_row":int(strings[0]), "predicted_choice_column":int(strings[1])}} # if player.id_in_group == 2: if data["predicted_choice"] == 'NA,NA': return {2: {"predicted_choice": '', "predicted_choice_row": '', "predicted_choice_column": ''}} # else: strings = data["predicted_choice"].split(',') return {2: {"predicted_choice":data["predicted_choice"], "predicted_choice_row":int(strings[0]), "predicted_choice_column":int(strings[1])}} # if player.id_in_group == 3: if data["predicted_choice"] == 'NA,NA': return {3: {"predicted_choice": '', "predicted_choice_row": '', "predicted_choice_column": ''}} # else: strings = data["predicted_choice"].split(',') return {3: {"predicted_choice":data["predicted_choice"], "predicted_choice_row":int(strings[0]), "predicted_choice_column":int(strings[1])}} # if player.id_in_group == 4: if data["predicted_choice"] == 'NA,NA': return {4: {"predicted_choice": '', "predicted_choice_row": '', "predicted_choice_column": ''}} # else: strings = data["predicted_choice"].split(',') return {4: {"predicted_choice":data["predicted_choice"], "predicted_choice_row":int(strings[0]), "predicted_choice_column":int(strings[1])}} # class choice_phase_missingChoiceObsB(Page): template_name = 'SI_Exp2_Training_IntroObsB/choice_phase.html' def vars_for_template(self): # this just gives the grid grid_numbers = np.empty((11, 11)) #print('grid_numbers', grid_numbers) grid_data = [] for row_idx, row in enumerate(grid_numbers): grid_row = [] #print('row_idx', row_idx) #print('row', row) for col_idx, value in enumerate(row): #print('col_idx', col_idx) #print('value', value) cell = {'value': value, 'row_index': row_idx, 'column_index': col_idx} grid_row.append(cell) grid_data.append(grid_row) #print('grid_data', grid_data) ObsA_query_row1 = 'See player\'s selection' ObsA_query_row2 = '' highlight_index_row = 1 highlight_index_column = 5 ObsA_sees = True ObsB_query_row1 = '?' ObsB_query_row2 = '' ObsB_sees = False return {'grid_data': grid_data, 'highlight_index_row': highlight_index_row, 'highlight_index_column': highlight_index_column, 'ObsA_query_row1':ObsA_query_row1, 'ObsA_query_row2':ObsA_query_row2, 'ObsB_query_row1':ObsB_query_row1, 'ObsB_query_row2':ObsB_query_row2, 'ObsA_sees':ObsA_sees, 'ObsB_sees':ObsB_sees} timeout_seconds = 6 class choice_phase_missingChoiceObsA(Page): template_name = 'SI_Exp2_Training_IntroObsB/choice_phase.html' def vars_for_template(self): # this just gives the grid grid_numbers = np.empty((11, 11)) #print('grid_numbers', grid_numbers) grid_data = [] for row_idx, row in enumerate(grid_numbers): grid_row = [] #print('row_idx', row_idx) #print('row', row) for col_idx, value in enumerate(row): #print('col_idx', col_idx) #print('value', value) cell = {'value': value, 'row_index': row_idx, 'column_index': col_idx} grid_row.append(cell) grid_data.append(grid_row) #print('grid_data', grid_data) ObsA_query_row1 = '?' ObsA_query_row2 = '' highlight_index_row = np.NaN highlight_index_column = np.NaN ObsA_sees = False ObsB_query_row1 = 'See player\'s selection' ObsB_query_row2 = '' ObsB_sees = True return {'grid_data': grid_data, 'highlight_index_row': highlight_index_row, 'highlight_index_column': highlight_index_column, 'ObsA_query_row1':ObsA_query_row1, 'ObsA_query_row2':ObsA_query_row2, 'ObsB_query_row1':ObsB_query_row1, 'ObsB_query_row2':ObsB_query_row2, 'ObsA_sees':ObsA_sees, 'ObsB_sees':ObsB_sees} timeout_seconds = 6 class choice_phase_bothSee(Page): template_name = 'SI_Exp2_Training_IntroObsB/choice_phase.html' def vars_for_template(self): # this just gives the grid grid_numbers = np.empty((11, 11)) #print('grid_numbers', grid_numbers) grid_data = [] for row_idx, row in enumerate(grid_numbers): grid_row = [] #print('row_idx', row_idx) #print('row', row) for col_idx, value in enumerate(row): #print('col_idx', col_idx) #print('value', value) cell = {'value': value, 'row_index': row_idx, 'column_index': col_idx} grid_row.append(cell) grid_data.append(grid_row) #print('grid_data', grid_data) ObsA_query_row1 = 'See player\'s selection' ObsA_query_row2 = '' highlight_index_row = 2 highlight_index_column = 6 ObsA_sees = True ObsB_query_row1 = 'See player\'s selection' ObsB_query_row2 = '' ObsB_sees = True return {'grid_data': grid_data, 'highlight_index_row': highlight_index_row, 'highlight_index_column': highlight_index_column, 'ObsA_query_row1':ObsA_query_row1, 'ObsA_query_row2':ObsA_query_row2, 'ObsB_query_row1':ObsB_query_row1, 'ObsB_query_row2':ObsB_query_row2, 'ObsA_sees':ObsA_sees, 'ObsB_sees':ObsB_sees} timeout_seconds = 6 class predict_reward_ObsBOnly(Page): template_name = 'SI_Exp2_Training_IntroObsB//predict_reward.html' form_model = 'player' form_fields = ['predicted_reward', 'RT_predicted_reward'] def vars_for_template(self): grid_numbers = np.empty((11, 11)) # Restructure data to include indices grid_data = [] for row_idx, row in enumerate(grid_numbers): grid_row = [] for col_idx, value in enumerate(row): cell = {'value': value, 'row_index': row_idx, 'column_index': col_idx} grid_row.append(cell) grid_data.append(grid_row) demonstrator_reward = 50 ObsA_query_row1 = 'Wait' ObsA_query_row2 = '' current_highlight_index_row = np.NaN current_highlight_index_column = np.NaN show_form_field = 0 ObsA_show_guess = '' ObsB_query_row1 = 'How many points do you think the player will receive for their selection?' ObsB_query_row2 = '' ObsB_show_guess = 'Observer B predicted a reward of: ' show_form_field_ObsB = 1 # THIS IS A PLACEHOLDER. TAKING THE REAL REWARD VALUE AND PUTTING A NORMAL DISTRIBUTION ON IT ObsB_predicted_reward = 45 ObsA_sees = False ObsB_sees = True ObsB_trial_type = 1 return {'grid_data': grid_data, 'current_highlight_index_row': current_highlight_index_row, 'current_highlight_index_column': current_highlight_index_column, 'ObsA_query_row1':ObsA_query_row1, 'ObsA_query_row2':ObsA_query_row2, 'ObsB_query_row1':ObsB_query_row1, 'ObsB_query_row2':ObsB_query_row2, 'show_form_field':show_form_field, 'show_form_field_ObsB':show_form_field_ObsB, 'ObsB_predicted_reward': ObsB_predicted_reward, 'ObsA_show_guess':ObsA_show_guess, 'ObsB_show_guess':ObsB_show_guess, 'ObsA_sees':ObsA_sees, 'ObsB_sees':ObsB_sees, 'ObsB_trial_type':ObsB_trial_type} @staticmethod def live_method(player: Player, data): if player.id_in_group == 1: return {1: {"result":data["result"]}} if player.id_in_group == 2: return {2: {"result":data["result"]}} if player.id_in_group == 3: return {3: {"result":data["result"]}} if player.id_in_group == 4: return {4: {"result":data["result"]}} class reward_phase_bothSee(Page): template_name = 'SI_Exp2_Training_IntroObsB/reward_phase.html' def vars_for_template(self): # This block gives which choice should be highlighted highlight_index_row = 10 highlight_index_column = 5 grid_data = [] grid_numbers = np.empty((11, 11)) # here I need to get the value that corresponds to the choice row and column index for row_idx, row in enumerate(grid_numbers): grid_row = [] for col_idx, value in enumerate(row): reward = 34 cell = {'reward': reward, 'row_index': row_idx, 'column_index': col_idx} grid_row.append(cell) grid_data.append(grid_row) ObsA_query_row1 = 'See player\'s points' ObsA_query_row2 = '' ObsA_sees = True # I have this in there 2x because I don't know any better. I need it within cell to be referenced in grid, and just the one value to be referenced below grid ObsA_reward = 34 ObsB_query_row1 = 'See player\'s points' ObsB_query_row2 = '' ObsB_sees = True ObsB_trial_type = 1 #print('int(ObsA_this_trials_data[trial_type])', int(ObsA_this_trials_data['trial_type'])) return {'grid_data': grid_data, 'highlight_index_row': highlight_index_row, 'highlight_index_column': highlight_index_column, 'ObsA_reward_below':ObsA_reward, 'trial_type':3, 'ObsA_query_row1':ObsA_query_row1, 'ObsA_query_row2':ObsA_query_row2, 'ObsB_query_row1':ObsB_query_row1, 'ObsB_query_row2':ObsB_query_row2, 'ObsA_sees':ObsA_sees, 'ObsB_sees':ObsB_sees, 'ObsB_trial_type':ObsB_trial_type} timeout_seconds = 6 class reward_phase_MissingInfoObsA(Page): template_name = 'SI_Exp2_Training_IntroObsB/reward_phase.html' def vars_for_template(self): # This block gives which choice should be highlighted highlight_index_row = 1 highlight_index_column = 5 grid_data = [] grid_numbers = np.empty((11, 11)) # here I need to get the value that corresponds to the choice row and column index for row_idx, row in enumerate(grid_numbers): grid_row = [] for col_idx, value in enumerate(row): reward = '' cell = {'reward': reward, 'row_index': row_idx, 'column_index': col_idx} grid_row.append(cell) grid_data.append(grid_row) ObsA_query_row1 = '?' ObsA_query_row2 = '' ObsA_reward ='?' ObsA_sees = False ObsB_query_row1 = 'See player\'s points' ObsB_query_row2 = '' ObsB_sees = True ObsB_trial_type = 3 #print('int(ObsA_this_trials_data[trial_type])', int(ObsA_this_trials_data['trial_type'])) return {'grid_data': grid_data, 'highlight_index_row': highlight_index_row, 'highlight_index_column': highlight_index_column, 'ObsA_reward_below':ObsA_reward, 'trial_type':int(2), 'ObsA_query_row1':ObsA_query_row1, 'ObsA_query_row2':ObsA_query_row2, 'ObsB_query_row1':ObsB_query_row1, 'ObsB_query_row2':ObsB_query_row2, 'ObsA_sees':ObsA_sees, 'ObsB_sees':ObsB_sees, 'ObsB_trial_type':ObsB_trial_type} timeout_seconds = 6 class reward_phase_bothMiss(Page): template_name = 'SI_Exp2_Training_IntroObsB/reward_phase.html' def vars_for_template(self): # This block gives which choice should be highlighted highlight_index_row = 2 highlight_index_column = 6 grid_data = [] grid_numbers = np.empty((11, 11)) # here I need to get the value that corresponds to the choice row and column index for row_idx, row in enumerate(grid_numbers): grid_row = [] for col_idx, value in enumerate(row): reward = '' cell = {'reward': reward, 'row_index': row_idx, 'column_index': col_idx} grid_row.append(cell) grid_data.append(grid_row) ObsA_query_row1 = '?' ObsA_query_row2 = '' ObsA_reward ='?' ObsA_sees = False ObsB_query_row1 = '?' ObsB_query_row2 = '' ObsB_sees = False ObsB_trial_type = 2 #print('int(ObsA_this_trials_data[trial_type])', int(ObsA_this_trials_data['trial_type'])) return {'grid_data': grid_data, 'highlight_index_row': highlight_index_row, 'highlight_index_column': highlight_index_column, 'ObsA_reward_below':ObsA_reward, 'trial_type':int(2), 'ObsA_query_row1':ObsA_query_row1, 'ObsA_query_row2':ObsA_query_row2, 'ObsB_query_row1':ObsB_query_row1, 'ObsB_query_row2':ObsB_query_row2, 'ObsA_sees':ObsA_sees, 'ObsB_sees':ObsB_sees, 'ObsB_trial_type':ObsB_trial_type} timeout_seconds = 6 # CONTINUE WITH INFER CHOICE HTML class infer_choice_ObsAOnly(Page): template_name = 'SI_Exp2_Training_IntroObsB/infer_choice.html' # Define form fields form_model = 'player' form_fields = ['inferred_choice', 'RT_inferred_choice'] def vars_for_template(self): # THIS WILL JUST GIVE THE GRID NUMBERS TO HTML grid_numbers = np.empty((11, 11)) #grid_number = my_array.tolist() grid_data = [] for row_idx, row in enumerate(grid_numbers): grid_row = [] for col_idx, value in enumerate(row): cell = {'value': value, 'row_index': row_idx, 'column_index': col_idx} grid_row.append(cell) grid_data.append(grid_row) ObsA_query_row1 = 'Which cell do you think the player selected to receive ' + str(34) + ' points?' ObsA_query_row2 = '(Please click into the respective cell and then submit)' show_form_field = 1 demo_reward_for_html = {'value': 34} ObsB_query_row1 = 'Wait' ObsB_query_row2 = '' ObsB_inf_highlight_index_row = '' ObsB_inf_highlight_index_column = '' ObsB_show_form_field = 0 ObsB_show_guess_text = '' ObsA_sees = True ObsB_sees = False return {'grid_data': grid_data, 'demo_reward_for_html':demo_reward_for_html, 'ObsB_inf_highlight_index_row': ObsB_inf_highlight_index_row, 'ObsB_inf_highlight_index_column': ObsB_inf_highlight_index_column, 'ObsA_query_row1':ObsA_query_row1, 'ObsA_query_row2':ObsA_query_row2, 'ObsB_query_row1':ObsB_query_row1, 'ObsB_query_row2':ObsB_query_row2, 'show_form_field':show_form_field, 'ObsB_show_form_field':ObsB_show_form_field, 'ObsB_show_guess_text': ObsB_show_guess_text, 'ObsA_sees':ObsA_sees, 'ObsB_sees':ObsB_sees} @staticmethod def live_method(player: Player, data): if player.id_in_group == 1: strings = data["inferred_choice"].split(',') return {1: {"inferred_choice":data["inferred_choice"], "inferred_choice_row":int(strings[0]), "inferred_choice_column":int(strings[1])}} if player.id_in_group == 2: strings = data["inferred_choice"].split(',') return {2: {"inferred_choice": data["inferred_choice"], "inferred_choice_row": int(strings[0]), "inferred_choice_column": int(strings[1])}} if player.id_in_group == 3: strings = data["inferred_choice"].split(',') return {3: {"inferred_choice": data["inferred_choice"], "inferred_choice_row": int(strings[0]), "inferred_choice_column": int(strings[1])}} if player.id_in_group == 4: strings = data["inferred_choice"].split(',') return {4: {"inferred_choice": data["inferred_choice"], "inferred_choice_row": int(strings[0]), "inferred_choice_column": int(strings[1])}} class ComprehensionCheck(Page): form_model = "player" form_fields = ["One_comprehension_check_task"] def is_displayed(player: Player): if player.round_number == 1: return True else: return player.participant.vars["ComprehensionCheckFailed"] def before_next_page(player: Player, timeout_happened): if player.One_comprehension_check_task == 1: player.participant.vars["ComprehensionCheckFailed"] = False else: player.participant.vars["ComprehensionCheckFailed"] = True #else: # if player.One_comprehension_check_task == 1 and player.Two_comprehension_check_spatial == 1 and player.Three_comprehension_check_inference == 2: # player.participant.vars["ComprehensionCheckFailed"] = False # else: # player.participant.vars["ComprehensionCheckFailed"] = True class ComprehensionCheckFailed(Page): def is_displayed(player: Player): return player.participant.vars["ComprehensionCheckFailed"] timeout_seconds = 5 class ComprehensionCheckPassed(Page): def is_displayed(player: Player): return player.participant.vars["ComprehensionCheckFailed"] == False # need to implement that you don't have to click the next button 30 or so times def app_after_this_page(player: Player, upcoming_apps): print(upcoming_apps) if player.participant.vars["ComprehensionCheckFailed"] == False: return upcoming_apps[0] page_sequence = [Explanation1, IntroObsB, Explanation2, choice_phase_bothSee, reward_phase_bothMiss, Explanation3, choice_phase_missingChoiceObsB, reward_phase_MissingInfoObsA, # different info Obs A and Obs B Explanation4, predict_choice_both, Explanation5, choice_phase_missingChoiceObsA, predict_reward_ObsBOnly, reward_phase_bothSee, infer_choice_ObsAOnly, Explanation6, ComprehensionCheck, ComprehensionCheckFailed, ComprehensionCheckPassed]