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. """ class Constants(BaseConstants): name_in_url = 'quiz' players_per_group = None with open('Chris - Quiz/quiz.csv') as f: questions = list(csv.DictReader(f)) num_rounds = len(questions) class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): question_id = models.PositiveIntegerField() question = models.CharField() solution = models.CharField() submitted_answer = models.CharField(widget=widgets.RadioSelect) is_correct = models.BooleanField() # FUNCTIONS def creating_session(subsession: Subsession): if subsession.round_number == 1: subsession.session.vars['questions'] = Constants.questions.copy() ## ALTERNATIVE DESIGN: ## to randomize the order of the questions, you could instead do: # import random # randomized_questions = random.sample(Constants.questions, len(Constants.questions)) # self.session.vars['questions'] = randomized_questions ## and to randomize differently for each participant, you could use ## the random.sample technique, but assign into participant.vars ## instead of session.vars. for p in subsession.get_players(): question_data = current_question(p) p.question_id = question_data['id'] p.question = question_data['question'] p.solution = question_data['solution'] def current_question(player: Player): return player.session.vars['questions'][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'] @staticmethod def before_next_page(player: Player, timeout_happened): check_correct(player) class Results(Page): @staticmethod def is_displayed(player: Player): return player.round_number == Constants.num_rounds @staticmethod def vars_for_template(player: Player): player_in_all_rounds = player.in_all_rounds() return { 'player_in_all_rounds': player_in_all_rounds, 'questions_correct': sum([p.is_correct for p in player_in_all_rounds]), } page_sequence = [Question, Results]