#1 by mlt_123
I'm quite aware of the random_task_order snippet, and it works in principle. Yet i'd like to collect the data within a single round, any help would be appreciated. Below you can find my _init_p.y. Thanks from otree.api import * import random class C(BaseConstants): NAME_IN_URL = 'embody' PLAYERS_PER_GROUP = None NUM_FIELDS =14 TASKS = ["pyField" + str(i+1) for i in range(NUM_FIELDS)] #print(TASKS) NUM_ROUNDS = len(TASKS) class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): pyField1 = models.LongStringField(blank=True) pyField2 = models.LongStringField(blank=True) pyField3 = models.LongStringField(blank=True) pyField4 = models.LongStringField(blank=True) pyField5 = models.LongStringField(blank=True) pyField6 = models.LongStringField(blank=True) pyField7 = models.LongStringField(blank=True) pyField8 = models.LongStringField(blank=True) pyField9 = models.LongStringField(blank=True) pyField10 = models.LongStringField(blank=True) pyField11 = models.LongStringField(blank=True) pyField12 = models.LongStringField(blank=True) pyField13 = models.LongStringField(blank=True) pyField14 = models.LongStringField(blank=True) rand_page_sequence = models.StringField() # FUNCTIONS def creating_session(subsession: Subsession): if subsession.round_number == 1: for p in subsession.get_players(): round_numbers = list(range(1, C.NUM_ROUNDS + 1)) random.shuffle(round_numbers) task_rounds = dict(zip(C.TASKS, round_numbers)) print('player', p.id_in_subsession) print('task_rounds is', task_rounds) p.participant.task_rounds = task_rounds p.rand_page_sequence = str(list(task_rounds.values())).strip('[]') # PAGES class Field1(Page): form_model = 'player' form_fields = ['pyField1'] def is_displayed(player: Player): participant = player.participant return player.round_number == participant.task_rounds['pyField1'] class Field2(Page): form_model = 'player' form_fields = ['pyField2'] def is_displayed(player: Player): participant = player.participant return player.round_number == participant.task_rounds['pyField2'] class Field3(Page): form_model = 'player' form_fields = ['pyField3'] def is_displayed(player: Player): participant = player.participant return player.round_number == participant.task_rounds['pyField3'] class Field4(Page): form_model = 'player' form_fields = ['pyField4'] def is_displayed(player: Player): participant = player.participant return player.round_number == participant.task_rounds['pyField4'] class Field5(Page): form_model = 'player' form_fields = ['pyField5'] def is_displayed(player: Player): participant = player.participant return player.round_number == participant.task_rounds['pyField5'] class Field6(Page): form_model = 'player' form_fields = ['pyField6'] def is_displayed(player: Player): participant = player.participant return player.round_number == participant.task_rounds['pyField6'] class Field7(Page): form_model = 'player' form_fields = ['pyField7'] def is_displayed(player: Player): participant = player.participant return player.round_number == participant.task_rounds['pyField7'] class Field8(Page): form_model = 'player' form_fields = ['pyField8'] def is_displayed(player: Player): participant = player.participant return player.round_number == participant.task_rounds['pyField8'] class Field9(Page): form_model = 'player' form_fields = ['pyField9'] def is_displayed(player: Player): participant = player.participant return player.round_number == participant.task_rounds['pyField9'] class Field10(Page): form_model = 'player' form_fields = ['pyField10'] def is_displayed(player: Player): participant = player.participant return player.round_number == participant.task_rounds['pyField10'] class Field11(Page): form_model = 'player' form_fields = ['pyField11'] def is_displayed(player: Player): participant = player.participant return player.round_number == participant.task_rounds['pyField11'] class Field12(Page): form_model = 'player' form_fields = ['pyField12'] def is_displayed(player: Player): participant = player.participant return player.round_number == participant.task_rounds['pyField12'] class Field13(Page): form_model = 'player' form_fields = ['pyField13'] def is_displayed(player: Player): participant = player.participant return player.round_number == participant.task_rounds['pyField13'] class Field14(Page): form_model = 'player' form_fields = ['pyField14'] def is_displayed(player: Player): participant = player.participant return player.round_number == participant.task_rounds['pyField14'] page_sequence = [Field1,Field2,Field3,Field4,Field5,Field6,Field7,Field8,Field9,Field10,Field11,Field12,Field13,Field14]
#2
by
BonnEconLab
I haven’t tried this – but shouldn’t adding page_sequence = random.sample(page_sequence, len(page_sequence)) after your final line work?
#3 by mlt_123
I believe that'd define the same (random) page sequence for all participants?
#4
by
BonnEconLab
Yes, that would probably set the same random page sequence for all participants. If you desire an individually drawn sequence for each participant and simultaneously avoid using multiple rounds, I think you have to stick to a single page only and show/hide the respective questions via JavaScript. Below is some code that works, according to my testing. In *settings.py*, add PARTICIPANT_FIELDS = ['rand_q_sequence'] *** Contents of __init__.py: *** from otree.api import * import random doc = """ Questions in random order on a single page """ class C(BaseConstants): NAME_IN_URL = 'Random_divs' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): pyField1 = models.LongStringField(blank=False) pyField2 = models.LongStringField(blank=False) pyField3 = models.LongStringField(blank=False) pyField4 = models.LongStringField(blank=False) pyField5 = models.LongStringField(blank=False) pyField6 = models.LongStringField(blank=False) pyField7 = models.LongStringField(blank=False) pyField8 = models.LongStringField(blank=False) pyField9 = models.LongStringField(blank=False) pyField10 = models.LongStringField(blank=False) pyField11 = models.LongStringField(blank=False) pyField12 = models.LongStringField(blank=False) pyField13 = models.LongStringField(blank=False) pyField14 = models.LongStringField(blank=False) rand_q_sequence = models.StringField() # FUNCTIONS def creating_session(subsession: Subsession): if subsession.round_number == 1: for p in subsession.get_players(): p.participant.rand_q_sequence = random.sample(range(0, 14), 14) # PAGES class Questionnaire(Page): form_model = 'player' form_fields = [ 'pyField1', 'pyField2', 'pyField3', 'pyField4', 'pyField5', 'pyField6', 'pyField7', 'pyField8', 'pyField9', 'pyField10', 'pyField11', 'pyField12', 'pyField13', 'pyField14', ] def vars_for_template(player): return dict( pyFields_shuffled = [Questionnaire.form_fields[i] for i in player.participant.rand_q_sequence], ) page_sequence = [Questionnaire] *** Contents of Questionnaire.html **** {% block title %} <code>div</code>s in random order with oTree {% endblock %} {% block scripts %} <script type="text/javascript"> function displayDiv(div_id, inc) { document.getElementById("QDiv" + div_id).style.display = "none"; document.getElementById("QDiv" + (div_id + inc)).style.display = "block"; } </script> {% endblock %} {% block content %} {% for pyField in pyFields_shuffled %} <div id="QDiv{{ forloop.counter }}" style="display: {% if forloop.counter == 1 %} block {% else %} none {% endif %}; width: 100%;"> <div> <h4><code>div</code> no. {{ forloop.counter }}</h4> {% formfield pyField %} </div> <div> <table style="width: 100%;"> <tr> <td style="width: 50%; text-align: left; vertical-align: top;"> {% if forloop.counter == 1 %} {% else %} <button type="button" id="previous" class="btn btn-outline-primary" onclick="displayDiv({{ forloop.counter}}, -1)">Previous question</button> {% endif %} </td> <td style="width: 50%; text-align: right; vertical-align: top;"> {% if forloop.counter == 14 %} {{ next_button }} {% else %} <button type="button" id="next" class="btn btn-outline-primary" onclick="displayDiv({{ forloop.counter}}, +1)">Next question</button> {% endif %} </td> </tr> </table> </div> </div> {% endfor %} {% endblock %}
#5 by mlt_123
That's quite a bit of work you put into that, great work. I appreciate it greatly. Thanks :)