How to use hooks#
What are hooks for?
Hooks are special functions (“methods”, because they always belong to classes in alfred3), that will be executed by alfred3 at fixed moments in the experiment. Their purpose is to be redefined by you, when you write an experiment – and that can be really powerful. Here are a few things that you can accomplish through hooks:
Use data from previous pages in the creation of following pages
Use data from previous experiment sessions in the creation of following pages
Jump to a certain page upon page submission, depending on the input given by participants.
Add many pages with a few lines of code to a section.
How do hooks work?
Most hooks (with very few exceptions) can be recognized by the fact that they strat with on_. We aim to name the hooks in a way that will tell you, at which moment in the experiment they will be executed. That’s usually the second part of the hook.
You can use a hook by defining a page or section in class style (see How to write a page in class style) and redefining the hook methods that can help you.
Example – A dynamic page
Let’s say, we wish to do a calculation with a number that a participant entered on the first page of our experiment, and show the result to her on the following page. If we use the instance style, we can’t do it - because pages that are created in instance style get filled right at the start of an experiment. At that time, our participant has obviously not yet filled in her number.
We also can’t use the on_exp_access hook - because that one only makes shure that we can access the experiment session object from our page. So, instead we utilize the on_first_show hook, which will only get executed when a page is shown for the first time. A minimal experiment would look like this:
import alfred3 as al
exp = al.Experiment()
exp += al.Page(name="page1")
exp.page1 += al.NumberEntry(toplab="Enter a number", name="n1")
@exp.member
class Page2(al.Page):
def on_first_show(self):
entered_number = self.exp.values.get("n1")
calculated_number = entered_number - 10
self += al.Text(f"The result of our calculation is: {calculated_number}")
In the sections below, you find a list of all available hooks - their documentation will contain further examples.
Page Hooks#
Note
You can define multiple hook methods on the same page. In this
case you should be aware, that elements are added to the page in order.
To change the order of the elements on your page, you can work with
the Page.elements
dictionary.
Executed once, when the |
|
Executed once, when the page is shown for the first time, before executing |
|
Executed every time the page is shown, after executing |
|
Hook for defining a page's own movement behavior, executed every time a movement from the page takes place, before |
|
Executed once, when the page is hidden for the first time, before executing |
|
Executed every time the page is hidden, before closing it and before saving data, but after executing |
|
Executed once, when the page is closed, before data saving. |
You can also use a hook to define custom page-specific validation:
Returns True, if the validation checks pass, False otherwise. |
There is also an additional hook that is defined by
alfred3.page.TimeoutPage
:
Executed once, after the timeout of the page runs out. |
Section Hooks#
Warning
We are currently questioning the four section hooks on_enter,
on_hand_over, on_resume, and on_leave. Everything that you may wish
to accomplish with these hooks can be done in page hooks. The section
versions have some caveats that make them a bit tougher
to use correctly. So, for the meantime, please avoid these hooks and
use page hooks instead. The attributes Section.first_page
and Section.last_page
may be useful for you in this regard.
The Section.on_exp_access()
hook is not going anywhere, although we may
at some point decide to introduce an alternative name for it in order
to avoid confusion with Page.on_exp_access()
.
Executed once, when the |
|
Executed every time this section is entered. |
|
Executed every time a direct subsection of this section is entered. |
|
Executed every time the experiment resumes from a direct subsection to this section. |
|
Executed every time this section is left. |
A section’s validation methods can also be used like hooks. Refer to How to customize validation behavior and the docs for these methods for more information.
Validates the current page and its elements. |
|
Called for validation on each forward move. |
|
Called for validation on each backward move. |
|
Called for validation on jumping from this section. |
|
Validates pages and their input elements within the section. |
Experiment Hooks#
Experiment hooks work in a different way than page and section hooks: They require the use of decorators. Click on the names of the hooks in the table below to get to their documentation, including examples.
Decorator for functions that work on the experiment session directly after intialization. |
|
Decorator for code to be run upon |