from otree.api import * import random doc = """ Read quiz questions from a CSV (complex version). See also the 'simple' version. It would be much simpler to implement this using rounds (1 question per round), as is done in the 'simple' version; however, this approach has faster gameplay since it's all done in 1 page, and leads to a more compact data export. Consider using this version if you have many questions or if speed is a high priority. """ class C(BaseConstants): NAME_IN_URL = 'Analogy' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 def read_csv(): import csv import random f = open(__name__ + '/nums.csv', encoding='utf-8-sig') rows = list(csv.DictReader(f)) print(rows) return rows # def analogy_csv(): # import csv # d = open(__name__ + '/analogy.csv', encoding='utf-8-sig') # arows = list(csv.DictReader(d)) # print(arows) # return arows class Subsession(BaseSubsession): pass def creating_session(subsession: Subsession): for q in subsession.get_players(): astimuli = read_csv() q.num_trials_1 = len(astimuli) rand_index = random.randint(0, len(astimuli)-1) Numb.create(player=q, **astimuli[rand_index]) # for stim in stimuli: # # print('stim is', stim) # # ** is the Python operator to unpack the dict # Trial.create(player=p, **stim) class Group(BaseGroup): pass class Player(BasePlayer): num_correct = models.IntegerField(initial=0) raw_responses = models.LongStringField() num_trials_1 = models.IntegerField() points = models.IntegerField() user_input = models.IntegerField() class Numb(ExtraModel): player = models.Link(Player) question = models.StringField() solution = models.StringField() choice = models.StringField() is_correct = models.BooleanField() def to_dict(tnumb: Numb): return dict( question=tnumb.question, id=tnumb.id, ) # PAGES class Stimuli(Page): form_model = 'player' form_fields = ['user_input'] @staticmethod def js_vars(player: Player): astimuli = [to_dict(tnumb) for tnumb in Numb.filter(player=player)] return dict(trials=astimuli) @staticmethod def before_next_page(player: Player, timeout_happened): Player.user_input == Player.num_correct return { Player.num_correct * 2 } # import json # responses = json.loads(player.raw_responses) # for trial in Trial.filter(player=player): # # have to use str() because Javascript implicitly converts keys to strings # trial.choice = responses[str(trial.id)] # trial.is_correct = trial.choice == trial.solution # # convert True/False to 1/0 # player.num_correct += int(trial.is_correct) # player.points = player.num_correct * 2 # # don't need it anymore # player.raw_responses = '' # class Results(Page): # @staticmethod # def vars_for_template(player: Player): # return dict(trials=Trial.filter(player=player)) # def custom_export(players): yield ['participant', 'question', 'choice', 'is_correct'] for player in players: participant = player.participant tnumb = Numb.filter(player=player) for t in tnumb: yield [participant.code, t.question, t.choice, t.is_correct] page_sequence = [Stimuli]