ctreffe / alfred

Alfred - A library for rapid experiment development
MIT License
10 stars 1 forks source link

ListRandomizer does not seem to respect version #215

Closed slussinator closed 2 years ago

slussinator commented 2 years ago

While using my alfred3 experiment on mortimer, the ListRandomizer does not respect the experiment version. Not even after adding "respect-version = True"

jobrachem commented 2 years ago

Hey @slussinator, thanks for opening an issue! 😊👋 It would be most helpful if you could give us a step-by-step description of how to reproduce the problem with a minimal experiment.

jobrachem commented 2 years ago

Almost there :) Now, please reduce your code example to the minimum. In this case, I think your code example should have only 1 page and 2 conditions in the randomizer and should not depend on external files.

Please also confirm that the problem can be reproduced with the minimal example and give a step-by-step description of how to reproduce the problem.

slussinator commented 2 years ago

like so?

@exp.member
class Welcome(al.Page):
    title = "Herzlich willkommen!"
    def on_exp_access(self):
        self += al.Text("welcome")

    def on_first_hide(self):
        randomizer = al.ListRandomizer(
            ("condition1", 0),
            ("condition2", 1),
            respect_version = True,
            exp=self.exp  
        )
        self.exp.condition = randomizer.get_condition()

        if self.exp.condition == "condition1":
            my_section += condition1_Page(name=condition1Page)

        elif self.exp.condition == "condition2":
            my_section += condition1_Page(name=condition2Page)
jobrachem commented 2 years ago

Almost. Please provide a fully working minimal experiment, including the imports and the exp = al.Experiment() line.

Are the if statements in your code example relevant to the problem?

Please also confirm that the problem can be reproduced with the minimal example and give a step-by-step description of how to reproduce the problem.

jobrachem commented 2 years ago

Using a minimal experiment, I cannot reproduce the issue.

Code:

import alfred3 as al

exp = al.Experiment()

@exp.setup
def setup(exp):
    rand = al.ListRandomizer.balanced("A", "B", n=1, exp=exp)
    exp.condition = rand.get_condition()

@exp.member
class DisplayCondition(al.Page):

    def on_first_show(self):
        self += al.Text(self.exp.condition, align="center", font_size=20)

if __name__ == "__main__":
    exp.run()

Steps:

  1. Create a new experiment on Mortimer (alfredo3)
  2. Start the experiment, observe the condition, and finish the experiment. The first slot is filled now.
  3. Start the experiment, observe the condition, and finish the experiment. The second slot is filled now.
  4. Start the experiment a third time: The "full" page is displayed.
  5. Increase the experiment version.
  6. Repeat steps 2-4. It works as expected: Two new sessions are allowed in.

I am closing this issue. It can be reopened with a step-by-step instruction of how to reproduce the issue. Otherwise, I will assume for now that the ListRandomizer works as expected.

jbengelsdorf commented 2 years ago

Using a minimal experiment, I was able to reproduce the issue.

Code:

import alfred3 as al

exp = al.Experiment()

@exp.setup
def setup(exp):
    rand = al.ListRandomizer(("cond1", 1), ("cond2", 1), exp=exp)
    exp.condition = rand.get_condition()

@exp.member
class DisplayCondition(al.Page):
    title = "Condition Display"
    name = "condition_display"

    def on_first_show(self):
        self += al.Text(self.exp.condition)

if __name__ == "__main__":
    exp.run()

Steps:

  1. Create a new experiment locally as displayed in the minimal experiment (using alfred3-version 2.3.3).
  2. Start the experiment, observe the condition, and finish the experiment. The first slot is filled now.
  3. Start the experiment, observe the condition, and finish the experiment. The second slot is filled now.
  4. Start the experiment a third time: The "full" page is displayed.
  5. Change nslots in ListRandomizer to ("cond1", 0), ("cond2", 1).
  6. Increase the experiment version.
  7. Start the experiment, get "Internal Server Error" and the following Error: alfred3.exceptions.ConditionInconsistency: Condition data is inconsistent with randomizer specification. You can set 'respect_version' to True and increase the experiment version.

I assume that this issue only occurs as soon as the nslots for a condition are set to zero. However, this use case may occur more frequently in the form of post-collection of missing conditions due to exclusion.

jobrachem commented 2 years ago

Thanks a lot! I'll look into it.

jbengelsdorf commented 2 years ago

After looking into the issue a bit more, I came to the following conclusion: The use case that nslots are set to zero was probably not foreseen. However, there is a very simple solution for this use case, namely deleting the conditions that are to be set to zero. For example, the post-collection of a "cond2"-condition could be implemented as follows:

import alfred3 as al

exp = al.Experiment()

@exp.setup
def setup(exp):
    rand = al.ListRandomizer(("cond2", 1), exp=exp)
    exp.condition = rand.get_condition()

@exp.member
class DisplayCondition(al.Page):
    title = "Condition Display"
    name = "condition_display"

    def on_first_show(self):
        self += al.Text(self.exp.condition)

if __name__ == "__main__":
    exp.run()
jobrachem commented 2 years ago

Nice solution @jbengelsdorf!

46c45008a5236784e30ce8917a4091c0384bc71d introduces a change into the next release that will allow for the specification of conditions with 0 slots.