from otree.api import * doc = """ Comprehension test. If the user fails too many times, they exit. """ class C(BaseConstants): NAME_IN_URL = 'comprehension_test' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 PAYOFF_A = 4 PAYOFF_B = 3 PAYOFF_C = 2 PAYOFF_D = 1 INSTRUCTIONS_TEMPLATE = 'prisoner/instructions.html' class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): num_failed_attempts = models.IntegerField(initial=0) failed_too_many = models.BooleanField(initial=False) quiz1 = models.StringField(label='How many round will be played?', choices=['20', '40', 'An unknown number between 20 and 40'], ) quiz2 = models.StringField( label='How much will be your payoff in that round, if you choose Option A, your partner chooses Option B, ' 'and neither of you chooses to decrease payoffs?', choices=['1', '2', '3', '4'], ) quiz3 = models.StringField(label='When making a decision, you will be provided information on' ' decisions of the partner in the last how many rounds:', choices=['3', '4', '5', '6'], ) quiz4 = models.StringField(label="If you or the other player (or both) decrease payoffs in stage 2 of the game, " "how much will your payoff be?", choices=['0', '1', '2', '3'], ) class MyPage(Page): form_model = 'player' form_fields = ['quiz1', 'quiz2', 'quiz3', 'quiz4'] @staticmethod def error_message(player: Player, values): # alternatively, you could make quiz1_error_message, quiz2_error_message, etc. # but if you have many similar fields, this is more efficient. solutions = dict(quiz1='An unknown number between 20 and 40', quiz2='1', quiz3='5', quiz4='0') # error_message can return a dict whose keys are field names and whose # values are error messages errors = {f: 'Wrong' for f in solutions if values[f] != solutions[f]} # print('errors is', errors) if errors: return errors class Results(Page): pass class Welcome(Page): form_model = 'player' class Introduction(Page): form_model = 'player' page_sequence = [Welcome, Introduction, MyPage, Results]