#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 :)