Experiment actions
backend.experiment.actions.base_action#
BaseAction
#
Bases: object
Base class for all experiment actions in the MUSCLE framework.
This class serves as the foundation for various action types that configure frontend components. All action classes (e.g., Score, Playback, Form, etc.) inherit from this base class to ensure consistent behavior and structure.
Key Features: - Provides a standardized way to serialize actiolinkn data for frontend components - Handles frontend styling configuration - Ensures each action has a unique identifier through the ID class variable - Implements a common interface for action serialization via the action() method
Example
Note
When creating a new action type:
-
Inherit from
BaseAction -
Define a unique
viewclass variable -
Initialize with required parameters
-
Override
action()method if custom serialization is needed
Source code in backend/experiment/actions/base_action.py
action()
#
Serialize the action configuration for frontend consumption.
This method creates a standardized dictionary format that frontend components expect. All instance variables are included, and the action’s ID is added to identify the correct frontend component.
Returns:
| Name | Type | Description |
|---|---|---|
dict |
dict
|
A dictionary containing: - All instance variables from dict - ‘view’: The action’s ID for frontend component mapping |
Source code in backend/experiment/actions/base_action.py
backend.experiment.actions.consent#
Consent
#
Bases: BaseAction
Handles experiment consent form generation and rendering and provides the consent form data to the frontend.
This class manages the display and processing of informed consent forms for experiments. It can handle consent text from multiple sources (file upload, URL template, or default text) and supports both HTML and Markdown formats.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
File
|
A Django File object containing the consent form content. If provided, this takes precedence over the URL parameter. |
required |
title
|
Optional[str]
|
The heading displayed above the consent form. Defaults to “Informed consent”. |
'Informed consent'
|
confirm
|
Optional[str]
|
Text for the confirmation button. Defaults to “I agree”. |
required |
deny
|
Optional[str]
|
Text for the rejection button. Defaults to “Stop”. |
required |
url
|
Optional[str]
|
Template path to load consent content if no text file is provided. Supports both HTML (default) and Markdown files. |
''
|
Example
Note
- The text file is normally uploaded via the admin interface for the experiment, so most of the time (and by default) you will use an experiment’s
texts.consentfile. - This component is used in conjunction with the frontend Consent.tsx component
- HTML templates can use Django template language
- Markdown files are automatically converted to HTML
- Priority order for content: 1) uploaded file, 2) template URL, 3) default text
Source code in backend/experiment/actions/consent.py
get_render_format(url)
#
Detect markdown file based on file extension
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
url
|
str
|
Url of the consent file |
required |
Returns:
| Type | Description |
|---|---|
Literal['HTML', 'MARKDOWN']
|
File format of the consent file (HTML or MARKDOWN) |
Source code in backend/experiment/actions/consent.py
render_html_or_markdown(dry_text, render_format)
#
render html or markdown
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
dry_text
|
str
|
contents of a markdown or html file |
required |
render_format
|
Literal['HTML', 'MARKDOWN']
|
type of contents, either ‘HTML’ or ‘MARKDOWN’ |
required |
Returns:
| Type | Description |
|---|---|
str
|
Content rendered to html. |
Source code in backend/experiment/actions/consent.py
backend.experiment.actions.explainer#
Explainer
#
Bases: BaseAction
Provide data for a explainer that explains the experiment steps
Relates to client component: Explainer.tsx
Explainer view automatically proceeds to the following view after timer (in ms) expires. If timer=None, explainer view will proceed to the next view only after a click of a button. Intro explainers should always have timer=None (i.e. interaction with a browser is required), otherwise the browser will not autoplay the first segment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
instruction
|
str
|
Instruction for the explainer |
required |
steps
|
List[Step]
|
List of steps to explain |
required |
button
|
Optional[Button]
|
Configure button that proceeds to the next view |
Button("Let's go!", 'colorPrimary')
|
timer
|
Optional[int]
|
Timer in ms |
None
|
step_numbers
|
Optional[bool]
|
Show step numbers |
False
|
Source code in backend/experiment/actions/explainer.py
Step
#
Bases: object
A step in an explainer
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
description
|
str
|
Description of the step |
required |
number
|
Optional[int]
|
Optional number of the step |
None
|
Source code in backend/experiment/actions/explainer.py
action(number=None)
#
Create an explainer step, with description and optional number
Source code in backend/experiment/actions/explainer.py
backend.experiment.actions.final#
Final
#
Bases: BaseAction
Provide data for a “final” view, typically shown at the end of an experiment or session.
This view displays the participant’s final score and, optionally, their rank or performance category.
It can also present navigation elements, such as a “Play again” button or links to other parts of the site.
Branding elements like a logo or social sharing options can be included to enhance user engagement.
A feedback section may also be provided if feedback_info is supplied.
The returned data aligns with FinalActionResponse, ensuring type consistency and making the structure
clear for both developers and documentation readers. It can be consumed by a frontend component
(e.g.,
Final.tsx) to render the final screen.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session
|
Session
|
The current session object associated with the participant. |
required |
title
|
str
|
The title displayed at the top of the final view. Defaults to a localized “Final score”. |
gettext_lazy('Final score')
|
final_text
|
Optional[str]
|
An optional concluding message (e.g., “Thanks for participating!”). |
None
|
button
|
Optional[ButtonConfiguration]
|
Optional button configuration. For example:
{“text”: “Play again”, “link”: “/{experiment_identifier}”}. If not provided, a default button with label “Next” will be rendered, unless the experiment is not replayable.
If the passed in button does not specify a link, |
None
|
points
|
Optional[str]
|
The label for the score units (e.g., “points”). Defaults to a localized “points”. |
None
|
rank
|
Optional[str]
|
The participant’s rank (e.g., “GOLD”). If not provided, no rank is displayed. |
None
|
show_profile_link
|
bool
|
If True, display a link to the participant’s profile. |
False
|
show_participant_link
|
bool
|
If True, display a participant-related link or information. |
False
|
show_participant_id_only
|
bool
|
If True, only the participant ID is shown, without a link. |
False
|
feedback_info
|
Optional[Dict[str, str]]
|
Optional dictionary containing feedback-related data. For example: {“header”: “Feedback”, “prompt”: “Tell us what you think”, “button_text”: “Submit”}. |
None
|
total_score
|
Optional[float]
|
Explicit final score. If None, this is derived from the session. |
None
|
logo
|
Optional[LogoConfiguration]
|
Optional logo configuration for branding. For example: {“image”: “/static/logo.png”, “link”: “https://example.com”}. |
None
|
Note
The action() method returns a FinalActionResponse that can be consumed by the frontend
to render the final screen.
Source code in backend/experiment/actions/final.py
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 | |
get_button(button, session)
#
Render a button in the Final action if the link back to the experiment page is valid
Source code in backend/experiment/actions/final.py
wrap_plain_final_text()
#
check if final_text starts with a html tag
If not, wrap it in a <center> element for better alignment
Source code in backend/experiment/actions/final.py
LogoConfiguration
#
Bases: TypedDict
Logo configuration for branding or visual identification on the final screen.
Attributes:
| Name | Type | Description |
|---|---|---|
image |
str
|
The URL of the logo image to display. |
link |
str
|
The URL to navigate to when the logo is clicked. |
Source code in backend/experiment/actions/final.py
backend.experiment.actions.form#
Form
#
Bases: BaseAction
The Form action is a view which brings together an array of questions with a submit and an optional skip button.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
form
|
List[Question]
|
List of question components |
required |
submit_button
|
Button
|
Button object specifying label and color of submit button |
Button(gettext_lazy('Submit'), 'colorPrimary')
|
skip_button
|
Button
|
Button object specifying label and color of skip button |
Button(gettext_lazy('Skip'), 'colorGrey')
|
Example
Source code in backend/experiment/actions/form.py
backend.experiment.actions.html#
HTML
#
Bases: BaseAction
An action that renders HTML content. See also the HTML.tsx component in the frontend project.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
body
|
str
|
The HTML body content |
required |
Examples:
To render a simple HTML snippet with a title and a paragraph:
Source code in backend/experiment/actions/html.py
backend.experiment.actions.info#
Info
#
Bases: BaseAction
Provide data for a view that presents information using HTML to the participant, along with a customizable (link) button.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
body
|
str
|
HTML body |
required |
heading
|
str
|
title/heading on top |
''
|
button
|
Button
|
properties of the button shown under the body |
None
|
Example
Note
Relates to the Info.tsx component in the frontend.
Source code in backend/experiment/actions/info.py
backend.experiment.actions.playback#
Autoplay
#
Bases: Playback
Player that starts playing automatically.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sections List[AudioSection]
|
List of audio sections to play. Currently does not support more than one section. |
required | |
**kwargs
|
Additional arguments passed to |
{}
|
Note
If show_animation is True, displays a countdown and moving histogram.
Source code in backend/experiment/actions/playback.py
ImagePlaybackSection
#
Bases: PlaybackSection
A special type of PlaybackSection that shows an image along a play button
Source code in backend/experiment/actions/playback.py
MatchingPairs
#
Bases: Playback
Multiplayer where buttons are represented as cards and where the cards need to be matched based on audio.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sections
|
List[Section]
|
List of audio sections to play. |
required |
show_animation
|
bool
|
Whether to show an animated histogram during playback of a card. |
required |
score_feedback_display
|
ScoreFeedbackDisplay
|
How to display score feedback. Defaults to “large-top” (pick from “small-bottom-right”, “large-top”, “hidden”). |
'large-top'
|
**kwargs
|
Any
|
Additional arguments passed to Multiplayer. |
{}
|
Example
python
MatchingPairs(
# You will need an even number of sections (ex. 16)
[section1, section2, section3, section4, section5, section6, section7, section8, section9, section10, section11, section12, section13, section14, section15, section16],
score_feedback_display="large-top",
Source code in backend/experiment/actions/playback.py
PlayButtons
#
Bases: Playback
Player that shows buttons for each to trigger playback.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sections
|
List of audio sections to play. |
required | |
play_once
|
bool
|
Whether button should be disabled after one play. Defaults to False. |
False
|
**kwargs
|
Any
|
Additional arguments passed to Playback. |
{}
|
Example
Source code in backend/experiment/actions/playback.py
Playback
#
Bases: BaseAction
Base class for different kinds of audio players.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sections
|
List[PlaybackSection]
|
List of audio sections to play. |
required |
preload_message
|
str
|
Text to display during preload. |
''
|
instruction
|
str
|
Text to display during presentation. |
''
|
show_animation
|
bool
|
Whether to show playback animation. |
True
|
mute
|
bool
|
Whether to mute audio. |
False
|
resume_play
|
bool
|
Whether to resume from previous position. |
False
|
show_animation
|
bool
|
Whether to show an animated histogram during playback (applies for AutoPlay & MatchingPairs) |
True
|
style
|
Optional[list[str]]
|
CSS class name(s) set in the frontend for styling |
None
|
Source code in backend/experiment/actions/playback.py
PlaybackSection
#
Bases: Button
An object to represent a section to be played Args: link (str): Link to audio file label (Optional[str]): Label of play button (not shown in autoplay mode) color (Optional[str]): Color of play button (not shown in autoplay mode) play_from (float): Start position of the audio file in seconds
Infers a playback method for this section, i.e., whether the frontend will use webAudio and whether it will buffer. Currently there is no support for mixed playback methods.
Source code in backend/experiment/actions/playback.py
PlaybackSectionAction
#
Bases: TypedDict
This type is similar to the ButtonAction type, but here link is the only required argument.
Source code in backend/experiment/actions/playback.py
get_play_method(section)
#
Determine which play method to use based on section properties.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
section
|
PlaybackSection
|
Audio section object. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
str |
PlayMethods
|
Play method constant (PLAY_NOAUDIO, PLAY_EXTERNAL, PLAY_HTML, or PLAY_BUFFER). |
Source code in backend/experiment/actions/playback.py
is_audio_file(filename)
#
Check if filename has an audio extension.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filename
|
str
|
Name of the file to check. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
bool |
bool
|
True if file has an audio extension. |
Source code in backend/experiment/actions/playback.py
backend.experiment.actions.question#
Types of questions to be presented to participants
AutoCompleteQuestion
#
Bases: ChoiceQuestionAction
A question with an autocomplete input.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
choices
|
dict
|
dictionary of answer options |
required |
**kwargs
|
Any
|
additional Question arguments |
{}
|
Example
Source code in backend/experiment/actions/question.py
ButtonArrayQuestion
#
Bases: ChoiceQuestionAction
A question showing buttons for each choice. If choices specify color values from the theme, buttons will be colored. Not practical to use for more than 5 choices.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
choices
|
List[Choice]
|
list of dictionaries with value, label and optional color for choice |
required |
**kwargs
|
Any
|
Additional Question arguments |
{}
|
Example
Source code in backend/experiment/actions/question.py
CheckBoxQuestion
#
Bases: ChoiceQuestionAction
A question with (multiple) choice options represented as check boxes
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
choices
|
List[Choice]
|
Available options |
required |
min_values
|
int
|
Minimum number of selections required |
1
|
**kwargs
|
Any
|
Additional Question arguments |
{}
|
Example
Source code in backend/experiment/actions/question.py
Choice
#
Bases: TypedDict
The structure of the dictionary for a question choice Note that color (optional) is only shown in ButtonArrayQuestion and TextRangeQuestion
Source code in backend/experiment/actions/question.py
ChoiceQuestionAction
#
Bases: QuestionAction
An action class with choices
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
choices
|
dict
|
a dictionary of answer options |
required |
min_values
|
Optional[int]
|
the minimal number of options to be selected by user |
None
|
Source code in backend/experiment/actions/question.py
DropdownQuestion
#
Bases: ChoiceQuestionAction
A question with a dropdown menu.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
choices
|
List[Choice]
|
Available options |
required |
**kwargs
|
Any
|
Additional Question arguments |
{}
|
Example
Source code in backend/experiment/actions/question.py
NumberQuestion
#
Bases: OpenQuestionAction
A question showing numeric input. NOTE: cannot set min value to avoid input rejecting keyboard input
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
max_value
|
int
|
Maximum allowed value |
120
|
**kwargs
|
Any
|
Additional Question arguments |
{}
|
Source code in backend/experiment/actions/question.py
OpenQuestionAction
#
Bases: QuestionAction
A question class showing a text / number or range field
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
min_value
|
Optional[int]
|
minimum value (for number / range questions) |
None
|
max_value
|
Optional[int]
|
maximum value (for number / range questions) |
None
|
max_length
|
Optional[int]
|
maximum number of characters (for text questions) |
None
|
Source code in backend/experiment/actions/question.py
QuestionAction
#
Bases: BaseAction
A base object for question actions. Do not use direcly, use subtypes instead.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
identifier
|
str
|
a unique identifier with which the question is logged to the database |
required |
result_id
|
int
|
the identifier of the |
None
|
text
|
str
|
the text shown to the user |
''
|
explainer
|
str
|
optionally, an instruction for the user of how to use the shown widget |
''
|
view
|
str
|
the view (widget) shown to the user, set in the subclasses |
''
|
Source code in backend/experiment/actions/question.py
RadiosQuestion
#
Bases: ChoiceQuestionAction
A question with radio buttons.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
choices
|
List[Choice]
|
Available options |
required |
**kwargs
|
Any
|
Additional Question arguments |
{}
|
Example
Source code in backend/experiment/actions/question.py
RangeQuestion
#
Bases: OpenQuestionAction
A question with a range slider.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
min_value
|
int
|
Minimum value |
0
|
max_value
|
int
|
Maximum value |
0
|
**kwargs
|
Any
|
Additional Question arguments |
{}
|
Example
Source code in backend/experiment/actions/question.py
TextQuestion
#
Bases: OpenQuestionAction
A question that accepts text input.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
max_length
|
int
|
Maximum character length |
64
|
**kwargs
|
Any
|
Additional Question arguments |
{}
|
Source code in backend/experiment/actions/question.py
TextRangeQuestion
#
Bases: ChoiceQuestionAction
A question with a slider, usually used for a Likert scale.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
choices
|
List[Choice]
|
list of answer options |
required |
**kwargs
|
Any
|
Additional Question arguments |
{}
|
Example
question = TextRangeQuestion(
identifier="satisfaction",
text="How satisfied are you with MUSCLE?",
explainer="Please rate your satisfaction.",
choices=[
{"value": 1, "label": _("Very satisfied")},
{"value": 2, "label": _("Satisfied")},
{"value": 3, "label": _("Neutral")},
{"value": 4, "label": _("Disappointed")},
{"value": 5, "label": _("Very disappointed)}
]
)
Source code in backend/experiment/actions/question.py
backend.experiment.actions.redirect#
Redirect
#
Bases: BaseAction
Redirect Action
This action is used to redirect the user to a specified URL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
url
|
str
|
The URL to redirect to. |
required |
Source code in backend/experiment/actions/redirect.py
backend.experiment.actions.score#
Score
#
Bases: BaseAction
Provide data for a score view, presenting feedback to a participant after a Trial.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session
|
Session
|
a Session object |
required |
title
|
str
|
the title of the score page |
''
|
result
|
Optional[Result]
|
the result for which section and/or score should be reported |
None
|
score
|
Optional[float]
|
the score to report, will override result.score |
None
|
score_message
|
str
|
a function which constructs feedback text based on the score |
''
|
config
|
Optional[ScoreConfig]
|
a dict with the following settings: - show_section (bool): whether to show the previous section - show_total_score (bool): whether to show the total score |
None
|
button
|
Button
|
a button to continue to the next view |
Button(gettext('Next'), 'colorPrimary')
|
icon
|
Optional[str]
|
the name of a fontawesome icon shown with the view or None |
None
|
timer
|
Optional[int]
|
int or None. If int, wait for as many seconds until showing the next view |
None
|
feedback
|
Optional[str]
|
An additional feedback text |
None
|
Note
Relates to the Score.tsx component in the frontend
Source code in backend/experiment/actions/score.py
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | |
action()
#
Serialize score data
Returns:
| Type | Description |
|---|---|
dict
|
dictionary with the relevant data for the Score.tsx view |
Source code in backend/experiment/actions/score.py
default_score_message(score)
#
Fallback to generate a message for the given score
Source code in backend/experiment/actions/score.py
get_score(score=None, result=None)
#
Retrieve the last relevant score, fall back to session.last_score() if neither score nor result are defined
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
score
|
Optional[float]
|
the score passed from the rules file (optional) |
None
|
result
|
Optional[Result]
|
a Result object passed from the rules file (opional) |
None
|
Source code in backend/experiment/actions/score.py
ScoreConfig
#
Bases: TypedDict
Configuration for the Score action
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
show_section
|
whether metadata of the previous section should be shown, often the title of the last played song |
required | |
show_total_score
|
whether the total score should be shown in the view |
required |
Source code in backend/experiment/actions/score.py
backend.experiment.actions.trial#
Trial
#
Bases: BaseAction
A view that may include Playback and/or a Form to be displayed to the participant.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
playback
|
Optional[Playback]
|
Player(s) to be displayed in this view (e.g. audio, video, image) |
None
|
html
|
Optional[str]
|
HTML to be displayed in this view |
None
|
feedback_form
|
Optional[Form]
|
array of form elements |
None
|
title
|
Optional(str)
|
page title - defaults to empty |
''
|
response_time
|
int
|
time in seconds for the participant to react |
5.0
|
auto_advance
|
bool
|
whether the view automatically forwards to the next after response_time |
False
|
listen_first
|
bool
|
whether the controls are blocked while audio is playing |
False
|
continue_button
|
Button
|
optionally configure label and color of button below the Trial. Not shown if form with submit_button is passed. Set to |
Button(gettext_lazy('Continue'), 'colorPrimary')
|
break_round_on
|
dict
|
conditions under which the current round should be abandoned, to query |
None
|
Example
identifier = 'test_trial'
section = session.playlist.get_section()
question = BooleanQuestion(
text=_(
"Do you like this song?"),
identifier=identifier,
result_id=prepare_result(identifier, session, section=section),
)
form = Form([question])
playback = Autoplay(sections=[PlaybackSection(section)])
view = Trial(
playback=playback,
feedback_form=form,
title=_('Test block'),
)
Note
Relates to client component: Trial.tsx
Source code in backend/experiment/actions/trial.py
action()
#
Serialize data for a block action
Source code in backend/experiment/actions/trial.py
backend.experiment.actions.utils#
camelize(input_str)
#
convert a snake_case to camelCase string
get_average_difference(session, num_turnpoints, initial_value)
#
Description: Calculate and return the average difference in milliseconds participants could hear (from the last num_turnpoints records).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session
|
Session
|
The current session. |
required |
num_turnpoints
|
int
|
The number of last turnpoints to consider. |
required |
initial_value
|
float
|
A fallback initial value. |
required |
Returns:
| Type | Description |
|---|---|
float
|
The average difference in milliseconds. |
Source code in backend/experiment/actions/utils.py
get_average_difference_level_based(session, num_turnpoints, initial_value)
#
Description: Calculate the difference level based on exponential decay.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session
|
Session
|
The current session. |
required |
num_turnpoints
|
int
|
The number of last turnpoints to consider. |
required |
initial_value
|
float
|
The starting reference value. |
required |
Returns:
| Type | Description |
|---|---|
float
|
The average difference in milliseconds. |
Source code in backend/experiment/actions/utils.py
get_experiment_url(session)
#
Description: Retrieve the URL for the current experiment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session
|
Session
|
The current user experiment session. |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
The URL for the current experiment. |
Note
Returns None if there is no experiment identifier.
Source code in backend/experiment/actions/utils.py
get_fallback_result(session)
#
Description: Retrieve a fallback result if no turnpoints are found.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session
|
Session
|
The current session. |
required |
Returns:
| Type | Description |
|---|---|
Result | None
|
The fallback result. |
Source code in backend/experiment/actions/utils.py
get_last_n_turnpoints(session, num_turnpoints)
#
Description: Return the specified number of most recent turnpoint results from the session.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session
|
Session
|
The current session. |
required |
num_turnpoints
|
int
|
How many latest turnpoint results to retrieve. |
required |
Returns:
| Type | Description |
|---|---|
QuerySet[Result]
|
The latest turnpoint results. |
Source code in backend/experiment/actions/utils.py
randomize_playhead(min_jitter, max_jitter, continuation_correctness)
#
Description: Randomly add to the playhead offset. If continuation_correctness=True, this function returns 0, and has no effect on the playhead.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
min_jitter
|
float
|
Minimum offset. |
required |
max_jitter
|
float
|
Maximum offset. |
required |
continuation_correctness
|
bool
|
whether to add a random increment to the continued audio |
required |
Returns:
| Type | Description |
|---|---|
float
|
The random offset. |
Source code in backend/experiment/actions/utils.py
render_feedback_trivia(feedback, trivia)
#
Description: Render feedback and trivia into the final template.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
feedback
|
str
|
The feedback text. |
required |
trivia
|
str
|
The trivia text. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The rendered HTML. |
Note: Can be used as the final_text parameter in the Final action
Source code in backend/experiment/actions/utils.py
backend.experiment.actions.wrappers#
TwoAlternativeForced
#
Bases: Trial
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session
|
Session
|
Session for which to generate TwoAlternativeForced Trial |
required |
section
|
Section
|
Section to be played in TwoAlternativeForced Trial |
required |
choices
|
dict
|
choices to be presented to participant |
required |
expected_response
|
str
|
expected response, if applicable |
None
|
comment
|
str
|
comment to be logged with the result |
''
|
scoring_rule
|
Optional[str]
|
scoring rule to score the participant’s response |
None
|
**kwargs
|
additional arguments to initialize the Trial object (e.g., title or response_time) |
{}
|
Returns:
| Type | Description |
|---|---|
Trial
|
Configured trial containing a playback, a question, and a feedback form. |
Example
Source code in backend/experiment/actions/wrappers.py
song_sync(session, section, title, recognition_time=15, sync_time=15, min_jitter=10, max_jitter=15)
#
Description: Provide a series of Trials for song recognition and sync, including optional jitter.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
session
|
Session
|
Current user session. |
required |
section
|
Section
|
Section to use for playback and silence intervals. |
required |
title
|
str
|
Title to be displayed for the trials. |
required |
recognition_time
|
int
|
Response time for recognition. |
15
|
sync_time
|
int
|
Response time for syncing continuation. |
15
|
min_jitter
|
int
|
Minimum playback offset for continuation correctness trial. |
10
|
max_jitter
|
int
|
Maximum playback offset for continuity trial. |
15
|
Returns:
| Type | Description |
|---|---|
list
|
A list of Trials (recognize, silence, correct_place). |
Source code in backend/experiment/actions/wrappers.py
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | |