Source code for nbgrader_jupyterquiz.display.dynamic.display

"""Entry point for displaying quizzes in Jupyter environments."""

import random
import string

from IPython.display import HTML, Javascript, display

from .loader import load_questions_script
from .renderer import build_script, build_styles, render_div


_DEFAULT_COLORS = {
    "--jq-multiple-choice-bg": "#392061",
    "--jq-mc-button-bg": "#fafafa",
    "--jq-mc-button-border": "#e0e0e0e0",
    "--jq-mc-button-text": "#333333",
    "--jq-mc-button-inset-shadow": "#555555",
    "--jq-many-choice-bg": "#f75c03ff",
    "--jq-numeric-bg": "#392061ff",
    "--jq-numeric-input-bg": "#c0c0c0",
    "--jq-numeric-input-label": "#101010",
    "--jq-numeric-input-shadow": "#999999",
    "--jq-string-bg": "#4c1a57",
    "--jq-incorrect-color": "#c80202",
    "--jq-select-color": "#6f78ff",
    "--jq-correct-color": "#009113",
    "--jq-text-color": "#fafafa",
    "--jq-link-color": "#9abafa",
}

_FDSP_COLORS = {
    "--jq-multiple-choice-bg": "#345995",
    "--jq-mc-button-bg": "#fafafa",
    "--jq-mc-button-border": "#e0e0e0e0",
    "--jq-mc-button-text": "#333333",
    "--jq-mc-button-inset-shadow": "#555555",
    "--jq-many-choice-bg": "#e26d5a",
    "--jq-numeric-bg": "#5bc0eb",
    "--jq-numeric-input-bg": "#c0c0c0",
    "--jq-numeric-input-label": "#101010",
    "--jq-numeric-input-shadow": "#999999",
    "--jq-string-bg": "#861657",
    "--jq-incorrect-color": "#666666",
    "--jq-select-color": "#6f78ff",
    "--jq-correct-color": "#87a878",
    "--jq-text-color": "#fafafa",
    "--jq-link-color": "#9abafa",
}


[docs] def display_quiz( ref, num=1_000_000, shuffle_questions=False, shuffle_answers=True, preserve_responses=False, border_radius=10, question_alignment="left", max_width=600, colors=None, load_js=True, grade_id=None, ): """ Display an interactive quiz in a Jupyter notebook. Parameters ---------- ref : list or str Question list, DOM element id (``#name:tag``), URL, or file path. num : int, optional Maximum number of questions to show. shuffle_questions : bool, optional Randomise question order on each display. shuffle_answers : bool, optional Randomise answer order on each display. preserve_responses : bool, optional Keep student responses visible after answering. border_radius : int, optional CSS border-radius in pixels. question_alignment : str, optional One of ``'left'``, ``'center'``, ``'right'``. max_width : int, optional Maximum quiz width in pixels. colors : dict or str, optional CSS variable overrides, or ``'fdsp'`` for the alternate palette. load_js : bool, optional Whether to inline the JavaScript source. grade_id : str, optional Nbgrader ``grade_id`` of the host task cell. When set, the JS recorder persists student responses to a ``responses.json`` sidecar file so an autograded test cell can read them via :func:`nbgrader_jupyterquiz.autograde.grade_quiz`. When ``None`` (the default for non-nbgrader callers), the recorder is a no-op. """ assert not (shuffle_questions and preserve_responses), "Preserving responses not supported when shuffling questions." assert num == 1_000_000 or (not preserve_responses), "Preserving responses not supported when num is set." assert question_alignment in ["left", "right", "center"], "question_alignment must be 'left', 'center', or 'right'" div_id = "".join(random.choice(string.ascii_letters) for _ in range(12)) color_dict = dict(_DEFAULT_COLORS) if colors == "fdsp": color_dict = dict(_FDSP_COLORS) elif isinstance(colors, dict): color_dict.update(colors) prefix_script, static, url = load_questions_script(ref, div_id) mydiv = render_div(div_id, shuffle_questions, shuffle_answers, preserve_responses, num, max_width, border_radius, question_alignment, grade_id) styles = build_styles(div_id, color_dict) javascript = build_script(prefix_script, static, url, div_id, load_js) display(HTML(mydiv + styles)) display(Javascript(javascript))