from otree.api import Currency as c, currency_range from ._builtin import Page, WaitPage from .models import Constants import logging # from otreeutils.pages import ExtendedPage logger = logging.getLogger(__name__) class InstructionsOnly(Page): # custom_name_in_url = 'e' timeout_seconds = 300 # WHEN PARTICIPANTS ENTER THIS PAGE, TREATMENTS HAVE ALREADY BEEN ALLOCATED IN PREVIOUS APP (SVO) # rules for fair attention checks # https://researcher-help.prolific.co/hc/en-gb/articles/360009223553-Using-attention-checks-as-a-measure-of-data-quality def vars_for_template(self): if self.participant.vars['treatment'] == 'a': self.participant.vars['treatment_name'] = "Likely_Small" self.participant.vars['size'] = 4 self.participant.vars['blue_balls'] = 6 self.participant.vars['attention_majorityblue_correct'] = '64.8%' if self.participant.vars['treatment'] == 'b': self.participant.vars['treatment_name'] = "VeryLikely_Small" self.participant.vars['size'] = 4 self.participant.vars['blue_balls'] = 9 self.participant.vars['attention_majorityblue_correct'] = '97.2%' if self.participant.vars['treatment'] == 'c': self.participant.vars['treatment_name'] = "Likely_Big" self.participant.vars['size'] = 8 self.participant.vars['blue_balls'] = 6 self.participant.vars['attention_majorityblue_correct'] = '71.0%' if self.participant.vars['treatment'] == 'd': self.participant.vars['treatment_name'] = "VeryLikely_Big" self.participant.vars['size'] = 8 self.participant.vars['blue_balls'] = 9 self.participant.vars['attention_majorityblue_correct'] = '99.7%' self.participant.vars['red_balls'] = 10 - self.participant.vars['blue_balls'] self.player.participant.vars['nr_next_players'] = self.participant.vars['size'] - Constants.example_position # self.participant.vars['attention_majorityblue_correct']=(self.participant.vars['blue_balls']/10)^3+(self.participant.vars['red_balls']/10)*(self.participant.vars['blue_balls']/10)^2 logger.info(f"This player is in treatment: {self.player.participant.vars['treatment']}") def is_displayed(self): logger.info(f"current round {self.round_number}") if self.round_number == 1: return True else: return False def before_next_page(self): #in case the participant doesn't reach the end of the study, this bonus is registered anyway in the data: self.player.my_bret_payoff = self.player.participant.vars['my_bret_payoff'] if self.timeout_happened: self.player.timeout = 1 # participant is excluded from study if time runs out class InstructionsExample(Page): # custom_name_in_url = 'e' # timeout_seconds = Constants.comp_questions_timeout # rules for fair attention checks # https://researcher-help.prolific.co/hc/en-gb/articles/360009223553-Using-attention-checks-as-a-measure-of-data-quality def vars_for_template(self): if self.participant.vars['treatment'] == 'a': self.participant.vars['treatment_name'] = "Likely_Small" self.participant.vars['size'] = 4 self.participant.vars['blue_balls'] = 6 self.participant.vars['attention_majorityblue_correct'] = '64.8%' elif self.participant.vars['treatment'] == 'b': self.participant.vars['treatment_name'] = "VeryLikely_Small" self.participant.vars['size'] = 4 self.participant.vars['blue_balls'] = 9 self.participant.vars['attention_majorityblue_correct'] = '97.2%' elif self.participant.vars['treatment'] == 'c': self.participant.vars['treatment_name'] = "Likely_Big" self.participant.vars['size'] = 8 self.participant.vars['blue_balls'] = 6 self.participant.vars['attention_majorityblue_correct'] = '71.0%' elif self.participant.vars['treatment'] == 'd': self.participant.vars['treatment_name'] = "VeryLikely_Big" self.participant.vars['size'] = 8 self.participant.vars['blue_balls'] = 9 self.participant.vars['attention_majorityblue_correct'] = '99.7%' self.participant.vars['red_balls'] = 10 - self.participant.vars['blue_balls'] self.player.participant.vars['nr_next_players'] = self.participant.vars['size'] - Constants.example_position # self.participant.vars['attention_majorityblue_correct']=(self.participant.vars['blue_balls']/10)^3+(self.participant.vars['red_balls']/10)*(self.participant.vars['blue_balls']/10)^2 logger.info(f"This player is in treatment: {self.player.participant.vars['treatment']}") def is_displayed(self): logger.info(f"current round {self.round_number}") if self.round_number == 1: return True else: return False # def before_next_page(self): # if self.timeout_happened: # self.player.timeout = 1 # participant is excluded from study if time runs out class ComprehensionQuestions(Page): # custom_name_in_url = 'e' timeout_seconds = Constants.comp_questions_timeout #10 minutes instead of 5 minutes form_model = 'player' form_fields = ['attention_players', 'attention_position', 'attention_opportunity', 'attention_othersred', 'attention_othersblue', 'attention_majorityblue', 'attention_scenarios' ] # rules for fair attention checks # https://researcher-help.prolific.co/hc/en-gb/articles/360009223553-Using-attention-checks-as-a-measure-of-data-quality def vars_for_template(self): if self.participant.vars['treatment'] == 'a': self.participant.vars['treatment_name'] = "Likely_Small" self.participant.vars['size'] = 4 self.participant.vars['blue_balls'] = 6 self.participant.vars['attention_majorityblue_correct'] = '64.8%' if self.participant.vars['treatment'] == 'b': self.participant.vars['treatment_name'] = "VeryLikely_Small" self.participant.vars['size'] = 4 self.participant.vars['blue_balls'] = 9 self.participant.vars['attention_majorityblue_correct'] = '97.2%' if self.participant.vars['treatment'] == 'c': self.participant.vars['treatment_name'] = "Likely_Big" self.participant.vars['size'] = 8 self.participant.vars['blue_balls'] = 6 self.participant.vars['attention_majorityblue_correct'] = '71.0%' if self.participant.vars['treatment'] == 'd': self.participant.vars['treatment_name'] = "VeryLikely_Big" self.participant.vars['size'] = 8 self.participant.vars['blue_balls'] = 9 self.participant.vars['attention_majorityblue_correct'] = '99.7%' self.participant.vars['red_balls'] = 10 - self.participant.vars['blue_balls'] self.player.participant.vars['nr_next_players'] = self.participant.vars['size'] - Constants.example_position # self.participant.vars['attention_majorityblue_correct']=(self.participant.vars['blue_balls']/10)^3+(self.participant.vars['red_balls']/10)*(self.participant.vars['blue_balls']/10)^2 logger.info(f"This player is in treatment: {self.player.participant.vars['treatment']}") def error_message(self, values): solutions = dict( attention_players=self.participant.vars['size'], attention_position='2nd', attention_opportunity='When previous player(s) choose(s) blue', attention_othersred='£4', attention_othersblue='£3', attention_majorityblue=self.participant.vars['attention_majorityblue_correct'], attention_scenarios='both of the above' ) response = dict() for field_name in solutions: if values[field_name] != solutions[field_name]: response[field_name] = "Wrong answer" # If there is an error, but they are past the limit, don't return anything, they # will get bounced by the app_after_this_page process if response: # logger.info(f'Player: {self.participant.label or self.participant.code} failed comp questions.' # f' Attempt: {self.player.example_attempts}') self.player.example_attempts += 1 if (self.player.example_attempts <= Constants.practice_max_attempts): logger.info("Player got at least one answer wrong") return response else: self.participant.vars['status'] = 'failed_comprehension' self.player.failed_attention_check = 1 logger.info("Player surpassed the number of attempts allowed to get the comprehensions questions right") # # def app_after_this_page(self, upcoming_apps): # if self.player.example_attempts > Constants.practice_max_attempts: # self.participant.vars['status'] = 'failed_comprehension' # self.player.failed_attention_check = 1 # logger.info("Player surpassed the number of attempts allowed to get the comprehensions questions right") # # return upcoming_apps[-1] # # # Otherwise, note the time they left this app to wait to be grouped in the next one # # self.participant.vars['grouping_page_arrival_time'] = time.time() def is_displayed(self): logger.info(f"current round {self.round_number}") if self.round_number == 1: return True else: return False def before_next_page(self): if self.timeout_happened: self.player.timeout = 1 # participant is excluded from study if time runs out class FailedAttention(Page): def is_displayed(self): return self.round_number == 1 and self.player.failed_attention_check == 1 # can't move on to the next page because like the timeout page, they have no "next button". class Decision_blue(Page): # custom_name_in_url = 'e' timeout_seconds = 300 # This method is quite useful, it gets called just once before the page is loaded # def vars_for_template(self): form_model = 'player' form_fields = ['chose_orange'] def vars_for_template(self): if self.round_number == 1: if 'page_number' not in self.player.participant.vars: self.player.participant.vars['page_number'] = self.player.round_number else: if self.player.participant.vars['page_number'] != self.player.round_number: self.player.update_paradox_index() self.player.participant.vars['page_number'] = self.player.round_number if self.player.participant.vars['paradox_index'] == 0: self.player.participant.vars['position'] = "1st" if self.player.participant.vars['paradox_index'] == 1: self.player.participant.vars['position'] = "2nd" if self.player.participant.vars['paradox_index'] == 2: self.player.participant.vars['position'] = "3rd" if self.player.participant.vars['paradox_index'] == 3: self.player.participant.vars['position'] = "4th" if self.player.participant.vars['paradox_index'] == 4: self.player.participant.vars['position'] = "5th" if self.player.participant.vars['paradox_index'] == 5: self.player.participant.vars['position'] = "6th" if self.player.participant.vars['paradox_index'] == 6: self.player.participant.vars['position'] = "7th" if self.player.participant.vars['paradox_index'] == 7: self.player.participant.vars['position'] = "8th" def app_after_this_page(self, upcoming_apps): logger.info( f"Participant: {self.participant.id}, round: {self.round_number}. paradox index: {self.player.participant.vars['paradox_index']}") # if self.round_number > 1: # self.player.update_paradox_index() if self.round_number == self.player.get_paradox_size(): logger.info(f"Moving on to next app; finished as type blue") return upcoming_apps[0] def before_next_page(self): if self.timeout_happened: self.player.timeout = 1 # participant is excluded from study if time runs out class TimeOutNew(Page): # shown if timeout # custom_name_in_url = 'time_out' def is_displayed(self): return self.player.timeout == 1 page_sequence = [ InstructionsOnly, TimeOutNew, ComprehensionQuestions, TimeOutNew, FailedAttention, Decision_blue, TimeOutNew ]