I am building a lab experiment through otree, ``a Django-based framework for implementing multiplayer decision strategy games."
Basics about otree's forms
Here is an example of how otree gets the players to report their choices (based on the "matching_pennies" game which is part of the templates provided by otree).
In a file named model.py
, one finds the following code
class Player(otree.models.BasePlayer):
[...]
penny_side = models.CharField(choices=['Heads', 'Tails'])
[...]
Then in views.py
one finds
class Choice(Page):
form_model = models.Player
form_fields = ['penny_side']
Finally, the form is displayed to the end user through choice.html
by inserting
{% formfield player.penny_side with label="I choose:" %}
What I would like to do
is create a flexible experiment in which the number of choices that players have to make varies with a parameter x
. That is, I want the whole framework to generate x
possible choices by just setting a parameter x
, and not having to go update all the files manually. This is in order to make my life easier if we ever change the experimental design, and to make the code useful to others with different experimental design (I plan to release it on Github at some point).
It seems like it should be fairly easy to do with a couple of loops, but I am having trouble using lists given the way otree
is structured.
From what I understand, I only see one very nasty way to have the number of choices depend on a parameter x
. I first give each choice a different name in model.py
, e.g.
class Player(otree.models.BasePlayer):
[...]
for i in range(x):
exec("""choice%d = models.IntegerField(
choices= ['Heads','Tails'])""" %i)
[...]
then pass the name of all those choices along to view.py
, e.g.
class Choice(Page):
all_forms = list()
for i in range(x):
all_forms.append('choice%d' %i)
form_model = models.Player
form_fields = all_forms
and finally, find a way to loop through all the forms in Choice.html; something like (I know the code below does not work, just to give the gist of it)
{% for p in range(x) %}
{% formfield player.choice{{p}} with label="I choose:" %}
{% endfor %}
My question are:
- This is all very dirty, and looks overly complicated : lists have been invented to avoid this kind of crazy naming process. Do you see a way to make this work with lists instead?
- If that's the only way to hack into otree and have the number off choices depend on a parameter
x
, so be it. But I am still unable to figure out a way to generate the desired set of forms via a loop in Django (obviously the example above does not work, for many reasons.).