Capa (Problem) Architecture
This page is meant to capture the current architecture of capa problems within the LMS and Studio.
UML Diagram
Overview
With Methods
Rendering of a Capa Problem
The following chart shows the breakdown of templates used when rendering the sections of a Capa Problem.
Message Flow Diagram of Rendering
Other client interactions that follow the same basic pattern as "Submit" are:
- Submit with file submission (after doing validation of the file(s) selected, calls problem_check).
- Problem reset (calls problem_reset).
- Render if no HTML content is provided to the method (calls problem_get), though it is not clear if this code path gets executed anymore with caching of content HTML.
Client interactions that do not re-render the problem HTML in the ajax callback handler:
- Show answer (calls problem_show). In the ajax callback handler, injects answers into the HTML that is already being displayed.
- Save answer (calls problem_save). In the ajax callback handler, shows the save notification in the HTML that is already being displayed.
- Show hint (calls hint_button). In the ajax callback handler, shows the hint area in the HTML that is already being displayed
Submit with poll, used by Python Custom Grader
The polling will continue until the problem is graded (with exponential back off on polling times)
Response Types
Response Type | Tags | Allowed Input Fields |
---|---|---|
CodeResponse | coderesponse | 'textbox', 'filesubmission', 'matlabinput' |
NumericalResponse | numericalresponse | 'textline', 'formulaequationinput' |
FormulaResponse | formularesponse | 'textline', 'formulaequationinput' |
CustomResponse | customresponse | 'textline', 'textbox', 'crystallography', |
SchematicResponse | schematicresponse | schematic |
ExternalResponse | externalresponse | 'textline', 'textbox' |
ImageResponse | imageresponse | imageinput |
OptionResponse | optionresponse | optioninput |
SymbolicResponse | symbolicresponse | |
StringResponse | stringresponse | textline |
ChoiceResponse | choiceresponse | 'checkboxgroup', 'radiogroup' |
MultipleChoiceResponse | multiplechoiceresponse | choicegroup |
TrueFalseResponse | truefalseresponse | |
AnnotationResponse | annotationresponse | annotationinput |
ChoiceTextResponse | choicetextresponse | 'choicetextgroup', |
Markdown Lifecycle
Markdown is stored in CapaFields as an XBlock field with scope Scope.settings:
markdown = String(help=_("Markdown source of this module"), default=None, scope=Scope.settings)
It gets sent to the front end in the CapaDescriptor context.
def get_context(self): _context = RawDescriptor.get_context(self) _context.update({ 'markdown': self.markdown, 'enable_markdown': self.markdown is not None, 'enable_latex_compiler': self.use_latex_compiler, }) return _context
In Studio, "Common Problem Types" expose the markdown initially; clicking on "Advanced Editor" will convert the markdown to XML (and if saved, there is no way to go back to markdown). Note that when a problem is first instantiated, it is possible for the markdown not to match the stored XML, which is stored in "data" (this was the case for some of our templates). Once the problem is first saved, the markdown is converted to XML, and at that point they are guaranteed to match.
Conversion of markdown to XML happens in MarkdownEditingDescriptor.markdownToXml (in problem/edit.js), via regular expressions. It is persisted on the server side when when Save is pressed, if the markdown editor is being displayed.
if (this.current_editor === this.markdown_editor) { return { data: MarkdownEditingDescriptor.markdownToXml(this.markdown_editor.getValue()), metadata: { markdown: this.markdown_editor.getValue() } }; } else { return { data: this.xml_editor.getValue(), nullout: ['markdown'] }; }
Additional resources
- /wiki/spaces/AN/pages/102367645
- /wiki/spaces/A11Y/pages/30966057
- OLX documentation
- Problem Course Author Documentation