Skip to content

Commit

Permalink
docs: Improve type annotations and documentation for two_alternative_…
Browse files Browse the repository at this point in the history
…forced and song_sync functions in `wrappers.py`
  • Loading branch information
drikusroor committed Jan 2, 2025
1 parent 5f4a3d5 commit bc1bb83
Showing 1 changed file with 88 additions and 44 deletions.
132 changes: 88 additions & 44 deletions backend/experiment/actions/wrappers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import random
from typing import Optional

from django.utils.translation import gettext as _

Expand All @@ -12,18 +13,42 @@
from session.models import Session


def two_alternative_forced(session, section, choices, expected_response=None, style={}, comment='', scoring_rule=None, title='', config=None):
def two_alternative_forced(
session: Session,
section: Section,
choices: dict,
expected_response=None,
style: dict = {},
comment: str = "",
scoring_rule=None,
title: str = "",
config: Optional[dict] = None,
):
"""
Provide data for a Two Alternative Forced view that (auto)plays a section,
shows a question and has two customizable buttons
Description: Provide data for a two-alternative forced choice (2AFC) view, with an optional comment and scoring.
Args:
session (Session): Current user session.
section (Section): Section to use in the playback or question.
choices (dict): Possible choices presented to the user.
expected_response (str, optional): The expected user response.
style (dict, optional): Additional style configurations for buttons.
comment (str, optional): Comment or additional info about the session.
scoring_rule (str, optional): Rule for scoring the user's response.
title (str, optional): Title to be displayed in the trial.
config (dict, optional): Additional configuration parameters.
Returns:
(Trial): Configured trial containing a playback, a question, and a feedback form.
Example:
```python
trial = two_alternative_forced(session, section, {"yes": "Yes", "no": "No"}, expected_response="yes", title=_("Two Alternative Forced Choice"))
```
"""
playback = PlayButton(
[section],
{"listen_once": True}
)
key = 'choice'
button_style = {'invisible-text': True,
'buttons-large-gap': True, 'buttons-large-text': True}
playback = PlayButton([section], {"listen_once": True})
key = "choice"
button_style = {"invisible-text": True, "buttons-large-gap": True, "buttons-large-text": True}
button_style.update(style)
question = ChoiceQuestion(
key=key,
Expand All @@ -33,57 +58,76 @@ def two_alternative_forced(session, section, choices, expected_response=None, st
section=section,
expected_response=expected_response,
scoring_rule=scoring_rule,
comment=comment
comment=comment,
),
choices=choices,
view='BUTTON_ARRAY',
view="BUTTON_ARRAY",
submits=True,
style=button_style
style=button_style,
)
feedback_form = Form([question])
trial = Trial(playback=playback, feedback_form=feedback_form,
title=title, config=config)
trial = Trial(playback=playback, feedback_form=feedback_form, title=title, config=config)
return trial


def song_sync(session: Session, section: Section, title: str,
recognition_time=15, sync_time=15,
min_jitter=10, max_jitter=15):
trial_config = {
'response_time': recognition_time,
'auto_advance': True
}
def song_sync(
session: Session, section: Section, title: str, 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.
Args:
session (Session): Current user session.
section (Section): Section to use for playback and silence intervals.
title (str): Title to be displayed for the trials.
recognition_time (int, optional): Response time for recognition.
sync_time (int, optional): Response time for syncing continuation.
min_jitter (int, optional): Minimum playback offset for continuity trial.
max_jitter (int, optional): Maximum playback offset for continuity trial.
Returns:
(list): A list of Trials (recognize, silence, correct_place).
Example:
```python
trials = song_sync(session, section, _("Song Sync"), recognition_time=10)
```
"""
trial_config = {"response_time": recognition_time, "auto_advance": True}
recognize = Trial(
feedback_form=Form([BooleanQuestion(
key='recognize',
result_id=prepare_result(
'recognize', session, section=section, scoring_rule='SONG_SYNC_RECOGNITION'),
submits=True
)]),
playback=Autoplay([section], show_animation=True,
preload_message=_('Get ready!'),
instruction=_('Do you recognize the song?'),
),
config={**trial_config,
'break_round_on': {'EQUALS': ['TIMEOUT', 'no']}},
title=title
feedback_form=Form(
[
BooleanQuestion(
key="recognize",
result_id=prepare_result(
"recognize", session, section=section, scoring_rule="SONG_SYNC_RECOGNITION"
),
submits=True,
)
]
),
playback=Autoplay(
[section],
show_animation=True,
preload_message=_("Get ready!"),
instruction=_("Do you recognize the song?"),
),
config={**trial_config, "break_round_on": {"EQUALS": ["TIMEOUT", "no"]}},
title=title,
)
silence_time = 4
silence = Trial(
playback=Autoplay([section],
show_animation=True,
instruction=_('Keep imagining the music'),
mute=True),
playback=Autoplay([section], show_animation=True, instruction=_("Keep imagining the music"), mute=True),
config={
'response_time': silence_time,
'auto_advance': True,
'show_continue_button': False,
"response_time": silence_time,
"auto_advance": True,
"show_continue_button": False,
},
title=title
title=title,
)
continuation_correctness = random.choice([True, False])
jitter = randomize_playhead(min_jitter, max_jitter, continuation_correctness)
trial_config['response_time'] = sync_time
trial_config["response_time"] = sync_time
correct_place = Trial(
feedback_form=Form(
[
Expand Down

0 comments on commit bc1bb83

Please sign in to comment.