Flexible lab experiment in otree

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(

[...]


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.).
• See meta.economics.stackexchange.com/questions/1432/… for a discussion on whether this kind of question is appropriate here. – Martin Van der Linden Sep 11 '15 at 2:21
• i think you would get a better result using the regular stack exchange. My python questions get answered quickly on there. This is definitely more of a language question than economics. – lost Sep 15 '15 at 18:46
• @lost: I thought so too and first published the question on Stackoverflow, but the question did not get any attention. My hope posting it here was to come across users who are familiar with otree. From what I understand of the problem, someone with a good knowledge of otree might do a better job at answering than someone knowing Pyhton/Django. Anyways, might have to give another try at Stackoverflow eventually... – Martin Van der Linden Sep 15 '15 at 20:38
• I think this is a perfectly valid Econ.SE question. oTree and zTree are languages almost exclusively used in economics (and probably polsci). However, I don't think there are many experimental economists here, so I would be surprised to see an answer to this question. – The Almighty Bob Sep 17 '15 at 18:58
• Btw, I think that lab-experiment is too similar to experimental-economics, but I didn't really wanted to edit your question for this. – The Almighty Bob Sep 17 '15 at 19:01

It turns out that in oTree, the variable form which is passed to the template is iterable. Thus one the following code does the job:
{% for field in form %}

Regarding the first part of the question, I contacted a programmer working at oTree. He confirmed that, in its current version, oTree can only define a fixed number of field. He advised to define in model.py a large maximal number of fields and then use get_form_fields in views.py to dynamically return a list with desired subset of fields.
Notice that if you want to create a really large maximal number of fields, the trick presented in the question using loop and exec remains — I believe — the easiest way to proceed.