2 votos

Experimento de laboratorio flexible en otree

Estoy construyendo un experimento de laboratorio a través de otree , ``un marco basado en Django para implementar juegos de estrategia de decisión multijugador".

Información básica sobre los formularios de otree

Este es un ejemplo de cómo otree consigue que los jugadores informen de sus elecciones (basado en el juego "matching_pennies" que forma parte de las plantillas proporcionadas por otree).

En un archivo llamado model.py se encuentra el siguiente código

class Player(otree.models.BasePlayer):

[...]

penny_side = models.CharField(choices=['Heads', 'Tails'])

[...]

Entonces en views.py se encuentra

class Choice(Page):

form_model = models.Player
form_fields = ['penny_side']

Por último, el formulario se muestra al usuario final a través de choice.html insertando

{% formfield player.penny_side with label="I choose:" %}

Lo que me gustaría hacer

es crear un experimento flexible en el que el número de elecciones que tienen que hacer los jugadores varía con un parámetro x . Es decir, quiero que todo el marco genere x posibles opciones con sólo establecer un parámetro x y no tener que ir a actualizar todos los archivos manualmente. Esto es con el fin de hacer mi vida más fácil si alguna vez cambiamos el diseño experimental, y para hacer que el código sea útil para otros con diferente diseño experimental (planeo liberarlo en Github en algún momento).

Parece que debería ser bastante fácil de hacer con un par de bucles, pero estoy teniendo problemas para utilizar las listas dada la forma otree está estructurado.

Por lo que entiendo, sólo veo una muy desagradable manera de hacer que el número de opciones dependa de un parámetro x . Primero doy a cada opción un nombre diferente en model.py Por ejemplo

class Player(otree.models.BasePlayer):

[...]

for i in range(x):
        exec("""choice%d = models.IntegerField(
        choices= ['Heads','Tails'])""" %i)

[...]

y luego pasar el nombre de todas esas opciones a view.py Por ejemplo

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

y, por último, encontrar una manera de bucle a través de todas las formas en Choice.html; algo así como (Sé que el código de abajo no funciona, sólo para dar la esencia de la misma)

{% for p in range(x)  %}

{% formfield player.choice{{p}} with label="I choose:" %}

{% endfor %}

Mis preguntas son:

  • Todo esto es muy sucio, y parece demasiado complicado: las listas se han inventado para evitar este tipo de proceso de nomenclatura loco. ¿Ves alguna manera de hacer que esto funcione con listas en su lugar?
  • Si esa es la única manera de hackear otree y que el número de opciones dependa de un parámetro x que así sea. Pero todavía no soy capaz de encontrar una manera de generar el conjunto deseado de formas a través de un bucle en Django (obviamente el ejemplo anterior no funciona, por muchas razones.).

1voto

Jader Dias Puntos 714

He encontrado una respuesta a la segunda parte de la pregunta aquí https://github.com/oTree-org/otree-docs/issues/2 .

Resulta que en oTree la variable form que se pasa a la plantilla es iterable. Así, el siguiente código hace el trabajo:

{% for field in form %}
        {% formfield field %}
    {% endfor %}

En cuanto a la primera parte de la pregunta, me puse en contacto con un programador que trabaja en oTree. Me confirmó que, en su versión actual, oTree sólo puede definir un número fijo de campos. Aconsejó definir en model.py un gran número máximo de campos y luego utilizar get_form_fields en views.py para devolver dinámicamente una lista con el subconjunto de campos deseado.

Tenga en cuenta que si quiere crear un número máximo de campos realmente grande, el truco presentado en la pregunta utilizando loop y exec sigue siendo -creo- la forma más fácil de proceder.

Finanhelp.com

FinanHelp es una comunidad para personas con conocimientos de economía y finanzas, o quiere aprender. Puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X