from otree.api import Currency as c, currency_range from ._builtin import Page, WaitPage from .models import Constants import random from typing import List # from otree.api import * # from .models import * import logging import math import time # logging.config.fileConfig('logging.conf') logger = logging.getLogger(__name__) ERROR_START = "You have some errors: " class Consent(Page): timeout_seconds = Constants.consent_timeout form_model = 'player' form_fields = ['consent'] timeout_submission = {'consent': False} def vars_for_template(self): return {'consent_timeout_min': math.ceil(Constants.consent_timeout / 60)} def consent_error_message(self, value): if not value: return 'You must accept the consent form in order to proceed with the study!' def before_next_page(self): if self.timeout_happened: self.player.consent = False self.participant.vars['status'] = 'consent_dropout' def app_after_this_page(self, upcoming_apps): if self.player.consent == False: logger.info("Player did not consent, moving them on") return upcoming_apps[-1] else: logger.info("Player consented and is good to go...") # # class Overview(Page): # timeout_seconds = Constants.overview_timeout # # # TODO Only needed for debugging, as I skip all of the other pages in this app # def before_next_page(self, timeout_happened): # self.participant.vars['grouping_page_arrival_time'] = time.time() # class PayoffCalculations(Page): # timeout_seconds = Constants.payoff_calc_timeout # # # class PayoffExample1(Page): # timeout_seconds = Constants.payoff_example1_timeout # # # class PayoffExample2(Page): # timeout_seconds = Constants.payoff_example2_timeout # # # class BonusNote(Page): # # TODO 3min # timeout_seconds = Constants.bonus_timeout class ComprehensionQuestions(Page): timeout_seconds = Constants.comp_questions_timeout form_model = 'player' form_fields = ['attention_players', 'attention_position', 'attention_opportunity', 'attention_othersred', 'attention_othersblue', 'attention_majorityblue' ] # 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 error_message(self, values: List): solutions = dict( attention_players=Constants.attention_ans[0], attention_position=Constants.attention_ans[1], attention_opportunity=Constants.attention_ans[2], attention_othersred=Constants.attention_ans[3], attention_othersblue=Constants.attention_ans[4], attention_majorityblue=Constants.attention_ans[5] ) 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() class ErrorMessage(Page): timeout_seconds = Constants.error_message_timeout class FailedAttention(Page): def is_displayed(self): return self.player.failed_attention_check == 1 # can't move on to the next page because like the timeout page, they have no "next button". page_sequence = [ Consent, # Overview, # PayoffCalculations, # PayoffExample1, # PayoffExample2, # BonusNote, # ComprehensionQuestions, # FailedAttention # ErrorMessage ] # TODO This page sequence is just for testing, put the one above back # page_sequence = [Overview]