Skip to content

Experiment utils

experiment.utils#

consent_upload_path(instance, filename) #

Generate path to save consent file based on experiment.slug and language

Parameters:

Name Type Description Default
instance Experiment

Experiment instance to determine folder name

required
filename str

Name of the consent file to be uploaded

required

Returns:

Name Type Description
upload_to str

Path for uploading the consent file

Note

Used by the Block model for uploading consent file

Source code in experiment/utils.py
def consent_upload_path(instance: Experiment, filename: str) -> str:
    """Generate path to save consent file based on experiment.slug and language

    Args:
        instance: Experiment instance to determine folder name
        filename: Name of the consent file to be uploaded

    Returns:
        upload_to: Path for uploading the consent file

    Note:
        Used by the Block model for uploading consent file
    """
    experiment = instance.experiment
    folder_name = experiment.slug
    language = instance.language

    join("consent", folder_name, f"{language}-{filename}")

create_player_labels(num_labels, label_style='number') #

Create player labels

Parameters:

Name Type Description Default
num_labels int

Number of labels

required
label_style str

‘number’, ‘alphabetic’, ‘roman’

'number'

Returns:

Type Description
list[str]

Player label

Source code in experiment/utils.py
def create_player_labels(num_labels: int, label_style: str = "number") -> list[str]:
    """Create player labels

    Args:
        num_labels: Number of labels
        label_style: 'number', 'alphabetic', 'roman'

    Returns:
        Player label
    """

    return [format_label(i, label_style) for i in range(num_labels)]

export_json_results(block) #

Export block JSON data as zip archive, force download

Source code in experiment/utils.py
def export_json_results(block):
        """Export block JSON data as zip archive, force download"""

        this_block = Block.objects.get(id=block)
        # Init empty querysets
        all_results = Result.objects.none()
        all_songs = Song.objects.none()
        all_sections = Section.objects.none()
        all_participants = Participant.objects.none()
        all_profiles = Result.objects.none()
        all_feedback = Feedback.objects.filter(block=this_block)

        # Collect data
        all_sessions = this_block.export_sessions().order_by("pk")

        for session in all_sessions:
            all_results |= session.result_set.all()
            all_participants |= Participant.objects.filter(pk=session.participant.pk)
            all_profiles |= session.participant.export_profiles()

        for playlist in this_block.playlists.all():
            these_sections = playlist._export_sections()
            all_sections |= these_sections
            for section in these_sections:
                if section.song:
                    all_songs |= Song.objects.filter(pk=section.song.pk)

        # create empty zip file in memory
        zip_buffer = BytesIO()
        with ZipFile(zip_buffer, "w") as new_zip:
            # serialize data to new json files within the zip file
            new_zip.writestr(
                "sessions.json", data=str(serializers.serialize("json", all_sessions))
            )
            new_zip.writestr(
                "participants.json",
                data=str(
                    serializers.serialize("json", all_participants.order_by("pk"))
                ),
            )
            new_zip.writestr(
                "profiles.json",
                data=str(
                    serializers.serialize(
                        "json", all_profiles.order_by("participant", "pk")
                    )
                ),
            )
            new_zip.writestr(
                "results.json",
                data=str(
                    serializers.serialize("json", all_results.order_by("session"))
                ),
            )
            new_zip.writestr(
                "sections.json",
                data=str(
                    serializers.serialize(
                        "json", all_sections.order_by("playlist", "pk")
                    )
                ),
            )
            new_zip.writestr(
                "songs.json",
                data=str(serializers.serialize("json", all_songs.order_by("pk"))),
            )
            new_zip.writestr(
                "feedback.json",
                data=str(serializers.serialize("json", all_feedback.order_by("pk"))),
            )

        # create forced download response
        response = HttpResponse(zip_buffer.getbuffer())
        response["Content-Type"] = "application/x-zip-compressed"
        response["Content-Disposition"] = (
            'attachment; filename="'
            + this_block.slug
            + "-"
            + timezone.now().isoformat()
            + '.zip"'
        )
        return response

external_url(text, url) #

Create a HTML element for an external url

Parameters:

Name Type Description Default
text str

Text

required
url

Url

required

Returns:

Type Description
str

HTML element

Source code in experiment/utils.py
def external_url(text: str, url) -> str:
    """Create a HTML element for an external url

    Args:
        text: Text
        url: Url

    Returns:
        HTML element
    """

    return '<a href="{}" target="_blank" rel="noopener noreferrer" >{}</a>'.format(url, text)

format_label(number, label_style) #

Generate player_label for create_player_label()

Parameters:

Name Type Description Default
number int

index

required
label_style str

‘number’, ‘alphabetic’, ‘roman’

required

Returns:

Type Description
str

Player label

Source code in experiment/utils.py
def format_label(number: int, label_style: str) -> str:
    """Generate player_label for create_player_label()

    Args:
        number: index
        label_style: 'number', 'alphabetic', 'roman'

    Returns:
        Player label
    """

    if label_style == "alphabetic":
        return chr(number + 65)
    elif label_style == "roman":
        return roman.toRoman(number + 1)
    else:
        return str(number + 1)

non_breaking_spaces(input_string) #

Convert regular spaces to non breaking spacing on the given string Args: input_string: Input string

Returns:

Type Description
str

String with non breaking spaces

Source code in experiment/utils.py
def non_breaking_spaces(input_string: str) -> str:
    """Convert regular spaces to non breaking spacing on the given string
    Args:
        input_string: Input string

    Returns:
        String with non breaking spaces
    """

    non_breaking_space = chr(160)
    return input_string.replace(" ", non_breaking_space)

slugify(text) #

Create a slug from given string

Parameters:

Name Type Description Default
text str

Input text (str)

required

Returns:

Type Description
str

slug

Source code in experiment/utils.py
def slugify(text: str) -> str:
    """Create a slug from given string

    Args:
        text: Input text (str)

    Returns:
        slug
    """

    non_url_safe = [
        '"',
        "#",
        "$",
        "%",
        "&",
        "+",
        ",",
        "/",
        ":",
        ";",
        "=",
        "?",
        "@",
        "[",
        "\\",
        "]",
        "^",
        "`",
        "{",
        "|",
        "}",
        "~",
        "'",
    ]
    translate_table = {ord(char): "" for char in non_url_safe}
    text = text.translate(translate_table)
    text = "_".join(text.split())
    return text.lower()