from otree.api import *
import settings
author = 'Patricia Zauchner (zauchner@uni-bremen.de)'
doc = """
Effort task: Slider Task as suggested by Gill and Prowse 2018 ("Measuring costly effort using the slider task").
Important: Only works on Chrome (not Firefox) because of the deactivation of pointer events in CSS/task.html
"""
# Models
class C(BaseConstants):
NAME_IN_URL = 'slider'
PLAYERS_PER_GROUP = 5 # Not really necessary in effort tasks. But so it looks better in the data
NUM_ROUNDS = 1
TASK_TIMER = settings.task_timer # 60
POINTS_PER_CORRECT_ANSWER = 0.5
class Subsession(BaseSubsession):
pass
def creating_session(subsession: Subsession):
#
# Copy the group and player id structure of the first app
if "id_matrix" in subsession.session.vars:
subsession.set_group_matrix(subsession.session.vars['id_matrix'])
else:
subsession.group_randomly() # oTree function
subsession.session.vars['id_matrix'] = subsession.get_group_matrix()
print("ID Matrix created in app effort_slider", subsession.session.vars['id_matrix'])
#
#
try:
subsession.session.vars["do_effort_task"] = subsession.session.config["do_effort_task"]
except KeyError:
subsession.session.vars["do_effort_task"] = getattr(settings, "do_effort_task", True)
# Set session vars (For counting number of effort apps in effort_intro)
subsession.session.vars["DoEffort_Slider"] = True
#
def calc_points(player):
return player.sum * C.POINTS_PER_CORRECT_ANSWER
class Group(BaseGroup):
pass
class Player(BasePlayer):
sum = models.FloatField(
doc='''Number of correct slides. Is already calculated at the task page'''
)
# Sliders: Gill and Prowse (2012) had 48 of them.
s1 = models.IntegerField(initial=0, min=0, max=100)
s2 = models.IntegerField(initial=0, min=0, max=100)
s3 = models.IntegerField(initial=0, min=0, max=100)
s4 = models.IntegerField(initial=0, min=0, max=100)
s5 = models.IntegerField(initial=0, min=0, max=100)
s6 = models.IntegerField(initial=0, min=0, max=100)
s7 = models.IntegerField(initial=0, min=0, max=100)
s8 = models.IntegerField(initial=0, min=0, max=100)
s9 = models.IntegerField(initial=0, min=0, max=100)
s10 = models.IntegerField(initial=0, min=0, max=100)
s11 = models.IntegerField(initial=0, min=0, max=100)
s12 = models.IntegerField(initial=0, min=0, max=100)
s13 = models.IntegerField(initial=0, min=0, max=100)
s14 = models.IntegerField(initial=0, min=0, max=100)
s15 = models.IntegerField(initial=0, min=0, max=100)
s16 = models.IntegerField(initial=0, min=0, max=100)
s17 = models.IntegerField(initial=0, min=0, max=100)
s18 = models.IntegerField(initial=0, min=0, max=100)
s19 = models.IntegerField(initial=0, min=0, max=100)
s20 = models.IntegerField(initial=0, min=0, max=100)
s21 = models.IntegerField(initial=0, min=0, max=100)
s22 = models.IntegerField(initial=0, min=0, max=100)
s23 = models.IntegerField(initial=0, min=0, max=100)
s24 = models.IntegerField(initial=0, min=0, max=100)
s25 = models.IntegerField(initial=0, min=0, max=100)
s26 = models.IntegerField(initial=0, min=0, max=100)
s27 = models.IntegerField(initial=0, min=0, max=100)
s28 = models.IntegerField(initial=0, min=0, max=100)
s29 = models.IntegerField(initial=0, min=0, max=100)
s30 = models.IntegerField(initial=0, min=0, max=100)
s31 = models.IntegerField(initial=0, min=0, max=100)
s32 = models.IntegerField(initial=0, min=0, max=100)
s33 = models.IntegerField(initial=0, min=0, max=100)
s34 = models.IntegerField(initial=0, min=0, max=100)
s35 = models.IntegerField(initial=0, min=0, max=100)
s36 = models.IntegerField(initial=0, min=0, max=100)
s37 = models.IntegerField(initial=0, min=0, max=100)
s38 = models.IntegerField(initial=0, min=0, max=100)
s39 = models.IntegerField(initial=0, min=0, max=100)
s40 = models.IntegerField(initial=0, min=0, max=100)
s41 = models.IntegerField(initial=0, min=0, max=100)
s42 = models.IntegerField(initial=0, min=0, max=100)
s43 = models.IntegerField(initial=0, min=0, max=100)
s44 = models.IntegerField(initial=0, min=0, max=100)
s45 = models.IntegerField(initial=0, min=0, max=100)
s46 = models.IntegerField(initial=0, min=0, max=100)
s47 = models.IntegerField(initial=0, min=0, max=100)
s48 = models.IntegerField(initial=0, min=0, max=100)
# Pages
class EffortPage(Page):
""" Handles if other pages are displayed """
@staticmethod
def is_displayed(player):
return player.session.vars.get("do_effort_task", True)
class Intro(EffortPage):
""" Introduction to the slider task """
pass
class Task(EffortPage):
""" Slider task """
timeout_seconds = C.TASK_TIMER # Must be 120 seconds according to Gill and Prowse (2012)
timer_text = 'Verbleibende Zeit (in Sek.): '
form_model = 'player'
@staticmethod
def get_form_fields(player):
fields = []
for i in range(1, 49):
fields.append('s{}'.format(i))
fields.append("sum")
return fields
class Results(EffortPage):
""" Results of slider task """
@staticmethod
def vars_for_template(player):
player.participant.vars['sliderpoints'] = calc_points(player)
page_sequence = [
Intro,
Task,
Results
]