import csv from otree.api import * from . import models author = 'Your name here' doc = """ A quiz app that reads its questions from a spreadsheet (see quiz.csv in this directory). There is 1 question per page; the number of pages in the game is determined by the number of questions in the CSV. See the comment below about how to randomize the order of pages. Manual Changes: - topic_list - update number of topics - topic_switch = [3] - """ class Constants(BaseConstants): name_in_url = 'quiz_hist_geo' players_per_group = None with open('hist_geo/24xx_history_geography.csv', encoding="utf-8-sig") as f: questions_hist_geo = list(csv.DictReader(f)) #num_rounds = len(questions) num_rounds = 10 piece_rate = 0.15 total_time = 20 part_number_total = 3 class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): question_id = models.StringField() question = models.CharField() solution = models.CharField() submitted_answer = models.CharField(widget=widgets.RadioSelect, blank = True, initial=0) is_correct = models.BooleanField() topic = models.CharField() graphics_name = models.CharField() round_number_total = models.PositiveIntegerField() questions_correct = models.PositiveIntegerField() quiz_payoff = models.FloatField() # FUNCTIONS def creating_session(subsession: Subsession): if subsession.round_number == 1: for self in subsession.get_players(): import random randomized_questions = random.sample(Constants.questions_hist_geo, len(Constants.questions_hist_geo)) self.participant.vars['questions_hist_geo'] = randomized_questions for player in subsession.get_players(): participant = player.participant number_current = participant.part_number_current participant.part_number_current = number_current + 1 participant.part_number_hist_geo = number_current + 1 for p in subsession.get_players(): question_data = current_question(p) # print('question_data', question_data) p.question_id = question_data['id'] p.question = question_data['question'] p.solution = question_data['solution'] p.topic = question_data['topic'] p.graphics_name = question_data['graphics_name'] p.round_number_total = Constants.num_rounds def current_question(player: Player): return player.participant.vars['questions_hist_geo'][player.round_number - 1] def check_correct(player: Player): player.is_correct = player.submitted_answer == player.solution def submitted_answer_choices(player: Player): qd = current_question(player) return [ qd['choice1'], qd['choice2'], qd['choice3'], qd['choice4'], ] # PAGES class Question(Page): form_model = 'player' form_fields = ['submitted_answer'] timeout_seconds = 30 @staticmethod def before_next_page(player: Player, timeout_happened): check_correct(player) @staticmethod def vars_for_template(player: Player): graphics_name = player.graphics_name question_id = player.question_id return dict( image_path='quiz/{}.png'.format(graphics_name), graphics_name_page = graphics_name, question_id=question_id, ) class Instructions(Page): @staticmethod def is_displayed(player: Player): topic_switch = [1] return player.round_number in topic_switch @staticmethod def vars_for_template(player: Player): topic_player = player.topic part_current = player.participant.part_number_hist_geo return { 'topic': topic_player, 'part_current': part_current } class Quiz_Completed(Page): @staticmethod def is_displayed(player: Player): return player.round_number == Constants.num_rounds @staticmethod def vars_for_template(player: Player): topic_player = player.topic return { 'topic': topic_player, } @staticmethod def before_next_page(player, timeout_happened): player_in_all_rounds = player.in_all_rounds() player.questions_correct = sum([p.is_correct for p in player_in_all_rounds]) player.quiz_payoff = player.questions_correct * Constants.piece_rate page_sequence = [Instructions, Question, Quiz_Completed]