oTree Forum >

Initialize Session Field

#1 by zahra_rahmani

I want to have a quota for my participants and found this helpful forum post: https://groups.google.com/g/otree/c/E6BbIS64VRE/m/1pcmx-O9AQAJ

It tells me to define a session variable, set it to zero initially and then increment it each time a participant fulfills a condition. 

However, I am stuck at step 2: How/ where can I initialize a session field? 

Thanks a lot for your help!

#2 by BonnEconLab (edited )

See https://otree.readthedocs.io/en/latest/rounds.html#session-fields. The documentation is quite sparse, though.

The following should work: For example, you could add

SESSION_FIELDS = [
    'num_participants_finished_intro',
    'num_participants_finished_decisions',
    'num_participants_finished_experiment',
]

to your settings.py file. You should then be able to increment session.vars['num_participants_finished_intro'] etc. depending on the respective conditions.

#3 by BonnEconLab

To be clear, you will probably have to write player.session.vars['num_participants_finished_intro'] = 0 etc. (not only session.vars['num_participants_finished_intro'] = 0 etc.).

#4 by zahra_rahmani

Thank you very much for your help! 

Yes, I was unsure about where to set it to zero because I wanted to avoid that it would be resetted to zero for each player/participant. 

I now implemented the following in my init.py file and it seems to work okay after some testing: 

def creating_session(subsession: Subsession):
    for player in subsession.get_players():
        if subsession.round_number == 1:
            subsession.session.countCondition = 0

#5 by BonnEconLab

I’m glad that it works. The following – simpler – code should also do it:

def creating_session(subsession):
    if subsession.round_number == 1:
        subsession.session.countCondition = 0

#6 by BonnEconLab (edited )

Ah, just one caveat: Be careful where exactly you increment the counter! Say, you intended to use vars_for_template for incrementing your counter, like this:

    @staticmethod
    def vars_for_template(player):
        player.subsession.session.countCondition = player.subsession.session.countCondition + 1

Then the counter would be incremented each time a participant refreshes the respective page. This is probably not what you want, unless you use a dedicated page for this single purpose that is shown, say, for a mere second.

Better places are probably after_all_players_arrive(subsession) on a wait page or before_next_page(player) on a welcome page.

#7 by zahra_rahmani

That is an important comment, thank you! 

I currently increment it in an "is_displayed" function of a page, and I it seems safe when I test it, but I wonder if you think that this is not a good position? 

class sorryFull(Page):
    form_model = 'player'
    @staticmethod
    def is_displayed(player: Player):
        countCondition = player.countCondition==1
        limit = 15
        if (countCondition == True):
            player.session.vars['countCondition'] += 1
            return player.session.vars['countCondition'] > limit
        else:
            return False

#8 by BonnEconLab

Hmmm, no I don’t think that including it in is_displayed is safe. I did a quick test: is_displayed is also executed repeatedly whenever I refresh the respective page.

To my knowledge, that does not apply to before_next_page. So, I would include a welcome page before your “sorryFull“ page and add before_next_page(player) to the welcome page to increment the counter.

#9 by the_dirk

Hi,
as BonnEconLab suggested, when before_next_page is used to increment the counter, refreshing the page does not result in unwanted completions.
If anybody is still struggling to implement a quota to their project, I have provided a very simple code snippet here: https://github.com/DStierand/otree-quota
Cheers
Dirk

Write a reply

Set forum username