from otree.api import * class C(BaseConstants): NAME_IN_URL = 'quiz' PLAYERS_PER_GROUP = 2 NUM_ROUNDS = 1 class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): UnderstandingQuiz_1 = models.BooleanField( label='1. Each round you are randomly matched with one of the' ' other seven players who currently participate in this study' ' to form a group of two. You compete with this other player for a bonus of 10 ECU.', choices=[[True, 'True'], [False, 'False']], required=True, widget=widgets.RadioSelectHorizontal, ) UnderstandingQuiz_2 = models.StringField( label='2. You receive a random number (Number Received), which you need ' 'to report by filling it into a field on the computer screen (Number Reported). ' 'What is the range of the random number you will receive?', choices=[[1, 'Between 1 and 10'], [2, 'Between 25 and 100'], [3, 'Between 500 and 1000']], required=True, widget=widgets.RadioSelect, ) UnderstandingQuiz_3 = models.StringField( label='3. Does the player with the higher or lower Number ' 'Reported win the competition and receive a bonus of 10 ECU for that round?', choices=[[1, 'Higher'], [2, 'Lower']], required=True, widget=widgets.RadioSelectHorizontal, ) UnderstandingQuiz_4 = models.StringField( label='4. You receive information about potential misreporting of another player ' 'and can raise the flag to start an investigation of that player. Does this ' 'information and raising the flag relate to your direct competitor, or to one of ' 'the other six players in the game?', choices=[[1, 'Your direct competitor'], [2, 'Another player in the game']], required=True, widget=widgets.RadioSelectHorizontal, ) UnderstandingQuiz_5 = models.StringField( label='5. If the investigation shows that this other player ' 'misreported (the Number Reported does not match the Number Received), ' 'this other player automatically…', choices=[[1, '…wins the competition this round and receives a bonus.'], [2, '…loses the competition and receives no bonus ']], required=True, widget=widgets.RadioSelect, ) UnderstandingQuiz_6 = models.StringField( label='6. The information you receive about the other player enables you to ' 'assess for sure whether that other player misreported?', choices=[[1, 'Yes, I will know for sure whether that other player misreported the number'], [2, 'No, I will learn the true behavior of the other player with a probability ' 'between 10% and 90%, but there always remains some uncertainty. ']], required=True, widget=widgets.RadioSelect, ) UnderstandingQuiz_7 = models.StringField( label='7. Raising the flag and pointing out a player for a potential investigation reduces your own Number Reported by', choices=[[1, '1 point'], [2, '20 points']], required=True, widget=widgets.RadioSelect, ) UnderstandingQuiz_8 = models.StringField( label='8. To what extent does the outcome of an investigation ' 'matter for you, if you were the one raising the flag?', choices=[[1, 'The outcome of the investigation has no further consequences for me.'], [2, 'Depending on the outcome of the investigation I might receive an additional bonus payment.']], required=True, widget=widgets.RadioSelect, ) UnderstandingQuiz_9 = models.BooleanField( label='9. Is the following statement true or false: One of the other players receives information ' 'about your potential misreporting and can point you out for investigation.', choices=[[True, 'True'], [False, 'False']], required=True, widget=widgets.RadioSelectHorizontal, ) UnderstandingQuiz_10 = models.StringField( label='10. How many investigations can be conducted at maximum in each period?', choices=[[1, 'One'], [2, 'Two'], [4, 'Four'], [8, 'Unlimited'] ], required=True, widget=widgets.RadioSelect, ) is_correct = models.BooleanField(initial=False) correct_answers = models.IntegerField() UnderstandingMistakes = models.IntegerField(initial=0) UnderstandingUnsuccessful = models.IntegerField(initial=0) pass # FUNCTIONS def creating_session(subsession: Subsession): for player in subsession.get_players(): player.is_correct = True player.participant.error_messages = dict() # PAGES class UnderstandingQuiz(Page): form_model = 'player' form_fields = ['UnderstandingQuiz_1', 'UnderstandingQuiz_2', 'UnderstandingQuiz_3', 'UnderstandingQuiz_4', 'UnderstandingQuiz_5', 'UnderstandingQuiz_6', 'UnderstandingQuiz_7', 'UnderstandingQuiz_8', 'UnderstandingQuiz_9', 'UnderstandingQuiz_10'] # Function to validate answers and store @staticmethod def error_message(player: Player, values): correct_answers = { 'UnderstandingQuiz_1': True, 'UnderstandingQuiz_2': 2, 'UnderstandingQuiz_3': 1, 'UnderstandingQuiz_4': 2, 'UnderstandingQuiz_5': 2, 'UnderstandingQuiz_6': 2, 'UnderstandingQuiz_7': 1, 'UnderstandingQuiz_8': 1, 'UnderstandingQuiz_9': True, 'UnderstandingQuiz_10': 2, } if player.session.config['anonymous'] is False: correct_answers['UnderstandingQuiz_7'] = 2 if player.session.config['incentives'] is True: correct_answers['UnderstandingQuiz_8'] = 2 errors = dict() error_messages = dict() player.is_correct = True player.UnderstandingMistakes = 0 for key, value in correct_answers.items(): player_answer = int(values[key]) if player_answer != value: player.is_correct = False player.UnderstandingMistakes += 1 errors[key] = player_answer error_messages[key] = "Wrong answer" if player.is_correct is False: player.UnderstandingUnsuccessful += 1 player.participant.vars['error_message'] = "You have answered {} questions incorrectly.".format(player.UnderstandingMistakes) player.participant.error_messages[player.UnderstandingUnsuccessful] = errors return error_messages pass page_sequence = [UnderstandingQuiz]