import ast from otree.api import * import os import random doc = """ TODO """ def choose_object_description(player): with open('_static/text_options.txt') as f: # read descriptions of objects txt_dic = ast.literal_eval(f.read()) # use ast.literal_eval to read as a dictionary stim_options = txt_dic['stim{}'.format(player.current_stim)] chosen_stim_option = random.choice(stim_options) return chosen_stim_option class C(BaseConstants): NAME_IN_URL = 'sc_exp_pilot' PLAYERS_PER_GROUP = None NUM_ROUNDS = 12 INSTRUCTIONS_TEMPLATE = 'sc_exp_pilot/instructions.html' class Subsession(BaseSubsession): pass def creating_session(subsession: Subsession): # followed this: https://www.otreehub.com/forum/91/ if subsession.round_number == 1: for p in subsession.get_players(): stim_list = list(range(1, 13)) random.shuffle(stim_list) p.participant.random_stim_order = stim_list #print(p.participant.random_stim_order) class Group(BaseGroup): pass class Player(BasePlayer): prolific_id = models.StringField(default=str(" ")) video_choice = models.StringField() text = models.StringField() current_stim = models.IntegerField() random_stim_order = models.StringField() confidence = models.FloatField() trial_video_left = models.StringField() trial_video_right = models.StringField() slider_video_left = models.StringField() slider_video_right = models.StringField() def get_text(self): if self.field_maybe_none('text') == None: # https://otree.readthedocs.io/en/latest/misc/tips_and_tricks.html#field-maybe-none self.text = choose_object_description(self) return self.text def set_current_stim(self): if self.field_maybe_none('current_stim') == None: # if it has already been set this round, no need to redo it self.current_stim = self.participant.random_stim_order[self.round_number - 1] return self.current_stim def set_random_stim_order(self): if self.field_maybe_none('random_stim_order') == None: # if it has already been set this round, no need to redo it self.random_stim_order = self.participant.random_stim_order return self.random_stim_order def set_prolific_id(self): if self.field_maybe_none('prolific_id') == None: self.prolific_id = self.participant.label return self.prolific_id # PAGES class Consent(Page): form_model = 'player' @staticmethod def before_next_page(player, timeout_happened): player.set_prolific_id() #print(self.participant.label) @staticmethod def is_displayed(player: Player): return player.round_number == 1 class Introduction(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): return player.round_number == 1 class PreTrial(Page): form_model = 'player' @staticmethod def vars_for_template(player): player.set_current_stim() return dict( text_to_display=player.get_text(), image_path='images/stim{}.jpg'.format(player.current_stim), trial_number=player.round_number ) class Trial(Page): form_model = 'player' form_fields = ['video_choice'] @staticmethod def vars_for_template(player): video_paths = [] package_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) # need to go up one level video_filenames = os.path.join(package_dir + '/_static/videos/stim{}'.format(player.current_stim)) for file in os.listdir(video_filenames): updated_filename = os.path.join('videos/stim{}/'.format(player.current_stim) + file) video_paths.append(updated_filename) random.shuffle(video_paths) player.trial_video_left = video_paths[0] player.trial_video_right = video_paths[1] return dict( # sent to Trial.html text_to_display=player.get_text(), image_path='images/stim{}.jpg'.format(player.current_stim), video_paths=video_paths, trial_number=player.round_number ) class Slider2(Page): #https://www.accountingexperiments.com/post/sliders/ form_model = 'player' form_fields = ['confidence'] @staticmethod def vars_for_template(player): video_paths = [] package_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) # need to go up one level video_filenames = os.path.join(package_dir + '/_static/videos/stim{}'.format(player.current_stim)) for file in os.listdir(video_filenames): updated_filename = os.path.join('videos/stim{}/'.format(player.current_stim) + file) video_paths.append(updated_filename) random.shuffle(video_paths) player.slider_video_left = video_paths[0] player.slider_video_right = video_paths[1] return dict( # sent to Trial.html video1=video_paths[0], video2=video_paths[1], trial_number=player.round_number ) class PreOutro(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): return player.round_number == 12 class Outro(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): return player.round_number == 12 @staticmethod def js_vars(player: Player): return dict(completionlink=player.subsession.session.config['completionlink']) page_sequence = [Consent, Introduction, PreTrial, Trial, Slider2, PreOutro, Outro]