Commit 8d354302 by muhammad-ammar

address christina's feedback

parent e11a4f38
...@@ -737,7 +737,7 @@ class LoncapaProblem(object): ...@@ -737,7 +737,7 @@ class LoncapaProblem(object):
context['extra_files'] = extra_files or None context['extra_files'] = extra_files or None
return context return context
def _extract_html(self, problemtree, question_id=0): # private def _extract_html(self, problemtree): # private
""" """
Main (private) function which converts Problem XML tree to HTML. Main (private) function which converts Problem XML tree to HTML.
Calls itself recursively. Calls itself recursively.
...@@ -822,22 +822,17 @@ class LoncapaProblem(object): ...@@ -822,22 +822,17 @@ class LoncapaProblem(object):
# otherwise, render children recursively, and copy over attributes # otherwise, render children recursively, and copy over attributes
tree = etree.Element(problemtree.tag) tree = etree.Element(problemtree.tag)
for item in problemtree: for item in problemtree:
item_xhtml = self._extract_html(item, question_id) item_xhtml = self._extract_html(item)
if item.tag == 'question':
item_xhtml.set('class', 'question')
item_xhtml.set('id', 'question-{}'.format(question_id))
question_id += 1
if item_xhtml is not None: if item_xhtml is not None:
tree.append(item_xhtml) tree.append(item_xhtml)
if tree.tag in html_transforms: if tree.tag in html_transforms:
tree.tag = html_transforms[problemtree.tag]['tag'] tree.tag = html_transforms[problemtree.tag]['tag']
else:
# copy attributes over if not innocufying # copy attributes over if not innocufying
for (key, value) in problemtree.items(): for (key, value) in problemtree.items():
tree.set(key, value) tree.set(key, value)
tree.text = problemtree.text tree.text = problemtree.text
tree.tail = problemtree.tail tree.tail = problemtree.tail
...@@ -901,3 +896,11 @@ class LoncapaProblem(object): ...@@ -901,3 +896,11 @@ class LoncapaProblem(object):
for solution in tree.findall('.//solution'): for solution in tree.findall('.//solution'):
solution.attrib['id'] = "%s_solution_%i" % (self.problem_id, solution_id) solution.attrib['id'] = "%s_solution_%i" % (self.problem_id, solution_id)
solution_id += 1 solution_id += 1
# Assign unique ids to <question>...</question>
question_index = 0
for question in tree.findall('.//question'):
question.attrib['class'] = "question"
question.attrib['id'] = "%s_question_%i" % (self.problem_id, question_index)
question.attrib['question_index'] = str(question_index)
question_index += 1
<%page expression_filter="h"/>
<%! from django.utils.translation import ugettext as _ %> <%! from django.utils.translation import ugettext as _ %>
<div class="action demandhint"> <div class="action demandhint">
<div class="problem-hint" aria-live="polite"></div> <div class="problem-hint" aria-live="polite"></div>
......
...@@ -15,19 +15,30 @@ class CapaHtmlRenderTest(unittest.TestCase): ...@@ -15,19 +15,30 @@ class CapaHtmlRenderTest(unittest.TestCase):
super(CapaHtmlRenderTest, self).setUp() super(CapaHtmlRenderTest, self).setUp()
self.capa_system = test_capa_system() self.capa_system = test_capa_system()
def test_blank_problem(self): def problem_question(self, xml_str, capa_system=None):
"""
It's important that blank problems don't break, since that's
what you start with in studio.
""" """
xml_str = "<problem> </problem>" Create CAPA problem from `xml_str`.
Return question element and rendered HTML.
"""
# Create the problem # Create the problem
problem = new_loncapa_problem(xml_str) problem = new_loncapa_problem(xml_str, capa_system=capa_system or self.capa_system)
# Render the HTML # Render the HTML
etree.XML(problem.get_html()) rendered_html = etree.XML(problem.get_html())
# TODO: This test should inspect the rendered html and assert one or more things about it
# get question
question = rendered_html.find(".//div[@class='question']")
return question, rendered_html
def test_blank_problem(self):
"""
It's important that blank problems don't break, since that's
what you start with in studio.
"""
xml_str = "<problem><question></question></problem>"
self.assertIsNotNone(self.problem_question(xml_str)[0])
def test_include_html(self): def test_include_html(self):
# Create a test file to include # Create a test file to include
...@@ -43,14 +54,7 @@ class CapaHtmlRenderTest(unittest.TestCase): ...@@ -43,14 +54,7 @@ class CapaHtmlRenderTest(unittest.TestCase):
</problem> </problem>
""") """)
# Create the problem question, _ = self.problem_question(xml_str)
problem = new_loncapa_problem(xml_str, capa_system=self.capa_system)
# Render the HTML
rendered_html = etree.XML(problem.get_html())
# get question
question = rendered_html.find(".//div[@class='question']")
# Expect that the include file was embedded in the problem # Expect that the include file was embedded in the problem
test_element = question.find("test") test_element = question.find("test")
...@@ -65,14 +69,7 @@ class CapaHtmlRenderTest(unittest.TestCase): ...@@ -65,14 +69,7 @@ class CapaHtmlRenderTest(unittest.TestCase):
</problem> </problem>
""") """)
# Create the problem question, _ = self.problem_question(xml_str)
problem = new_loncapa_problem(xml_str)
# Render the HTML
rendered_html = etree.XML(problem.get_html())
# get question
question = rendered_html.find(".//div[@class='question']")
# Expect that the <startouttext /> and <endouttext /> # Expect that the <startouttext /> and <endouttext />
# were converted to <span></span> tags # were converted to <span></span> tags
...@@ -87,14 +84,7 @@ class CapaHtmlRenderTest(unittest.TestCase): ...@@ -87,14 +84,7 @@ class CapaHtmlRenderTest(unittest.TestCase):
</problem> </problem>
""") """)
# Create the problem question, _ = self.problem_question(xml_str)
problem = new_loncapa_problem(xml_str)
# Render the HTML
rendered_html = etree.XML(problem.get_html())
# get question
question = rendered_html.find(".//div[@class='question']")
# Expect that the anonymous_student_id was converted to "student" # Expect that the anonymous_student_id was converted to "student"
span_element = question.find('span') span_element = question.find('span')
...@@ -108,14 +98,10 @@ class CapaHtmlRenderTest(unittest.TestCase): ...@@ -108,14 +98,10 @@ class CapaHtmlRenderTest(unittest.TestCase):
</problem> </problem>
""") """)
# Create the problem question, _ = self.problem_question(xml_str)
problem = new_loncapa_problem(xml_str)
# Render the HTML
rendered_html = etree.XML(problem.get_html())
# Expect that the script element has been removed from the rendered HTML # Expect that the script element has been removed from the rendered HTML
script_element = rendered_html.find('script') script_element = question.find('script')
self.assertEqual(None, script_element) self.assertEqual(None, script_element)
def test_render_javascript(self): def test_render_javascript(self):
...@@ -126,11 +112,7 @@ class CapaHtmlRenderTest(unittest.TestCase): ...@@ -126,11 +112,7 @@ class CapaHtmlRenderTest(unittest.TestCase):
</problem> </problem>
""") """)
# Create the problem _, rendered_html = self.problem_question(xml_str)
problem = new_loncapa_problem(xml_str)
# Render the HTML
rendered_html = etree.XML(problem.get_html())
# expect the javascript is still present in the rendered html # expect the javascript is still present in the rendered html
self.assertIn( self.assertIn(
...@@ -153,16 +135,11 @@ class CapaHtmlRenderTest(unittest.TestCase): ...@@ -153,16 +135,11 @@ class CapaHtmlRenderTest(unittest.TestCase):
the_system.render_template = mock.Mock() the_system.render_template = mock.Mock()
the_system.render_template.return_value = "<div>Input Template Render</div>" the_system.render_template.return_value = "<div>Input Template Render</div>"
# Create the problem and render the HTML question, rendered_html = self.problem_question(xml_str, capa_system=the_system)
problem = new_loncapa_problem(xml_str, capa_system=the_system)
rendered_html = etree.XML(problem.get_html())
# Expect problem has been turned into a <div> # Expect problem has been turned into a <div>
self.assertEqual(rendered_html.tag, "div") self.assertEqual(rendered_html.tag, "div")
# get question
question = rendered_html.find(".//div[@class='question']")
# Expect question text is in a <p> child # Expect question text is in a <p> child
question_element = question.find("p") question_element = question.find("p")
self.assertEqual(question_element.text, "Test question") self.assertEqual(question_element.text, "Test question")
...@@ -259,12 +236,7 @@ class CapaHtmlRenderTest(unittest.TestCase): ...@@ -259,12 +236,7 @@ class CapaHtmlRenderTest(unittest.TestCase):
</problem> </problem>
""") """)
# Create the problem and render the HTML question, _ = self.problem_question(xml_str)
problem = new_loncapa_problem(xml_str)
rendered_html = etree.XML(problem.get_html())
# get question
question = rendered_html.find(".//div[@class='question']")
# Expect that the variable $test has been replaced with its value # Expect that the variable $test has been replaced with its value
span_element = question.find('span') span_element = question.find('span')
...@@ -288,7 +260,10 @@ class CapaHtmlRenderTest(unittest.TestCase): ...@@ -288,7 +260,10 @@ class CapaHtmlRenderTest(unittest.TestCase):
# Render the HTML # Render the HTML
the_html = problem.get_html() the_html = problem.get_html()
self.assertRegexpMatches(the_html, r"<div class=\"question\" id=\"question-0\">\s+</div>") self.assertRegexpMatches(
the_html,
r"<div class=\"question\" id=\"1_question_0\" question_index=\"0\">\s+</div>"
)
def _create_test_file(self, path, content_str): def _create_test_file(self, path, content_str):
test_fp = self.capa_system.filestore.open(path, "w") test_fp = self.capa_system.filestore.open(path, "w")
......
...@@ -155,7 +155,11 @@ class CapaFields(object): ...@@ -155,7 +155,11 @@ class CapaFields(object):
{"display_name": _("Per Student"), "value": RANDOMIZATION.PER_STUDENT} {"display_name": _("Per Student"), "value": RANDOMIZATION.PER_STUDENT}
] ]
) )
data = String(help=_("XML data for the problem"), scope=Scope.content, default="<problem></problem>") data = String(
help=_("XML data for the problem"),
scope=Scope.content,
default="<problem><question></question></problem>"
)
correct_map = Dict(help=_("Dictionary with the correctness of current student answers"), correct_map = Dict(help=_("Dictionary with the correctness of current student answers"),
scope=Scope.user_state, default={}) scope=Scope.user_state, default={})
input_state = Dict(help=_("Dictionary for maintaining the state of inputtypes"), scope=Scope.user_state) input_state = Dict(help=_("Dictionary for maintaining the state of inputtypes"), scope=Scope.user_state)
...@@ -659,9 +663,9 @@ class CapaMixin(CapaFields): ...@@ -659,9 +663,9 @@ class CapaMixin(CapaFields):
else: else:
check_button = False check_button = False
check_button_checking = False check_button_checking = False
content = { content = {
'name': self.display_name_with_default_escaped, 'name': self.display_name,
'html': html, 'html': html,
'weight': self.weight, 'weight': self.weight,
} }
......
...@@ -57,7 +57,6 @@ h2 { ...@@ -57,7 +57,6 @@ h2 {
&.problem-header { &.problem-header {
display: inline-block; display: inline-block;
margin-bottom: 0;
section.staff { section.staff {
margin-top: ($baseline*1.5); margin-top: ($baseline*1.5);
font-size: 80%; font-size: 80%;
...@@ -154,6 +153,10 @@ div.problem { ...@@ -154,6 +153,10 @@ div.problem {
div.question:not(:last-child) { div.question:not(:last-child) {
margin-bottom: $baseline; margin-bottom: $baseline;
} }
h3.problem-header {
margin-bottom: 0 !important; // needed to overrided the %hd-2 margin-bottom
}
} }
// +Problem - Choice Group // +Problem - Choice Group
......
...@@ -65,7 +65,7 @@ var options = { ...@@ -65,7 +65,7 @@ var options = {
specFiles: [ specFiles: [
{pattern: 'spec/helper.js', included: true, ignoreCoverage: true}, // Helper which depends on source files. {pattern: 'spec/helper.js', included: true, ignoreCoverage: true}, // Helper which depends on source files.
{pattern: 'spec/problem/*.js', included: true} {pattern: 'spec/**/*.js', included: true}
], ],
fixtureFiles: [ fixtureFiles: [
......
...@@ -5,6 +5,7 @@ describe 'MarkdownEditingDescriptor', -> ...@@ -5,6 +5,7 @@ describe 'MarkdownEditingDescriptor', ->
return { return {
compare: (actual, expected) -> compare: (actual, expected) ->
{ {
# compare the actual and expected XMLs by removing all the whitespace characters.
pass: actual.replace(/\s+/g, '') == expected.replace(/\s+/g, '') pass: actual.replace(/\s+/g, '') == expected.replace(/\s+/g, '')
} }
} }
...@@ -108,6 +109,9 @@ describe 'MarkdownEditingDescriptor', -> ...@@ -108,6 +109,9 @@ describe 'MarkdownEditingDescriptor', ->
expect(revisedSelection).toEqual('[explanation]\nmy text\n[explanation]') expect(revisedSelection).toEqual('[explanation]\nmy text\n[explanation]')
describe 'markdownToXml', -> describe 'markdownToXml', ->
it 'converts blank common problem to correct XML', ->
data = MarkdownEditingDescriptor.markdownToXml('')
expect(data).toXMLEqual('<problem><question></question></problem>')
it 'converts raw text to paragraph', -> it 'converts raw text to paragraph', ->
data = MarkdownEditingDescriptor.markdownToXml('foo') data = MarkdownEditingDescriptor.markdownToXml('foo')
expect(data).toEqual('<problem>\n<question>\n<p>foo</p>\n</question>\n</problem>') expect(data).toEqual('<problem>\n<question>\n<p>foo</p>\n</question>\n</problem>')
......
...@@ -25,8 +25,6 @@ class @Problem ...@@ -25,8 +25,6 @@ class @Problem
window.update_schematics() window.update_schematics()
debugger
problem_prefix = @element_id.replace(/problem_/,'') problem_prefix = @element_id.replace(/problem_/,'')
@inputs = @$("[id^='input_#{problem_prefix}_']") @inputs = @$("[id^='input_#{problem_prefix}_']")
@$('div.action button').click @refreshAnswers @$('div.action button').click @refreshAnswers
...@@ -228,7 +226,6 @@ class @Problem ...@@ -228,7 +226,6 @@ class @Problem
### ###
check_fd: => check_fd: =>
# If there are no file inputs in the problem, we can fall back on @check # If there are no file inputs in the problem, we can fall back on @check
debugger
if @el.find('input:file').length == 0 if @el.find('input:file').length == 0
@check() @check()
return return
...@@ -809,7 +806,7 @@ class @Problem ...@@ -809,7 +806,7 @@ class @Problem
hint_button: (event)=> hint_button: (event)=>
# Store the index of the currently shown hint as an attribute. # Store the index of the currently shown hint as an attribute.
# Use that to compute the next hint number when the button is clicked. # Use that to compute the next hint number when the button is clicked.
debugger
question = $(event.target).closest('div.question') question = $(event.target).closest('div.question')
hint_container = question.find('.problem-hint') hint_container = question.find('.problem-hint')
hint_index = hint_container.attr('hint_index') hint_index = hint_container.attr('hint_index')
...@@ -819,7 +816,7 @@ class @Problem ...@@ -819,7 +816,7 @@ class @Problem
next_index = parseInt(hint_index) + 1 next_index = parseInt(hint_index) + 1
data = data =
question_id: question.attr('id').split('-')[1] question_id: question.attr('question_index')
hint_index: next_index hint_index: next_index
input_id: @id input_id: @id
......
...@@ -580,11 +580,16 @@ class @MarkdownEditingDescriptor extends XModule.Descriptor ...@@ -580,11 +580,16 @@ class @MarkdownEditingDescriptor extends XModule.Descriptor
}` }`
questionsXML = [] questionsXML = []
# TODO! Should we change it to markdown.split('\n---\n'). What is the right choice? questionsMarkdown = markdown.split('\n---\n')
questionsMarkdown = markdown.split('---')
_.each questionsMarkdown, (questionMarkdown, index) -> _.each questionsMarkdown, (questionMarkdown, index) ->
if questionMarkdown.trim().length > 0 if questionMarkdown.trim().length > 0
questionsXML.push toXml(questionMarkdown) questionsXML.push toXml(questionMarkdown)
# add <question></question> when markdown is an empty string
# this is needed to handle blank_common.yaml where OLX is not
# in correct format after conversion
if markdown.trim().length == 0
questionsXML.push('<question></question>')
# make all questions descendants of a single problem element # make all questions descendants of a single problem element
return '<problem>\n' + questionsXML.join('\n\n') + '\n</problem>' return '<problem>\n' + questionsXML.join('\n\n') + '\n</problem>'
...@@ -2,4 +2,8 @@ ...@@ -2,4 +2,8 @@
metadata: metadata:
display_name: Blank Common Problem display_name: Blank Common Problem
markdown: "" markdown: ""
data: "<problem><question></question></problem>" data: |
<problem>
<question>
</question>
</problem>
...@@ -24,26 +24,26 @@ metadata: ...@@ -24,26 +24,26 @@ metadata:
data: | data: |
<problem> <problem>
<question> <question>
<p>Checkbox problems allow learners to select multiple options. Learners can see all the options along with the problem text.</p> <p>Checkbox problems allow learners to select multiple options. Learners can see all the options along with the problem text.</p>
<p>When you add the component, be sure to select <strong>Settings</strong> <p>When you add the component, be sure to select <strong>Settings</strong>
to specify a <strong>Display Name</strong> and other values that apply.</p> to specify a <strong>Display Name</strong> and other values that apply.</p>
<p>You can use the following example problem as a model.</p> <p>You can use the following example problem as a model.</p>
<p>The following languages are in the Indo-European family:</p> <p>The following languages are in the Indo-European family:</p>
<choiceresponse> <choiceresponse>
<checkboxgroup> <checkboxgroup>
<choice correct="true" name="urdu">Urdu</choice> <choice correct="true" name="urdu">Urdu</choice>
<choice correct="false" name="finnish">Finnish</choice> <choice correct="false" name="finnish">Finnish</choice>
<choice correct="true" name="marathi">Marathi</choice> <choice correct="true" name="marathi">Marathi</choice>
<choice correct="true" name="french">French</choice> <choice correct="true" name="french">French</choice>
<choice correct="false" name="hungarian">Hungarian</choice> <choice correct="false" name="hungarian">Hungarian</choice>
</checkboxgroup> </checkboxgroup>
</choiceresponse> </choiceresponse>
<p><strong>Note</strong>: Make sure you select all of the correct options—there may be more than one!</p> <p><strong>Note</strong>: Make sure you select all of the correct options—there may be more than one!</p>
<solution> <solution>
<div class="detailed-solution"> <div class="detailed-solution">
<p>Explanation</p> <p>Explanation</p>
<p>Urdu, Marathi, and French are all Indo-European languages, while Finnish and Hungarian are in the Uralic family.</p> <p>Urdu, Marathi, and French are all Indo-European languages, while Finnish and Hungarian are in the Uralic family.</p>
</div> </div>
</solution> </solution>
</question> </question>
</problem> </problem>
\ No newline at end of file
...@@ -30,41 +30,41 @@ metadata: ...@@ -30,41 +30,41 @@ metadata:
hinted: true hinted: true
data: | data: |
<problem> <problem>
<question> <question>
<p>You can provide feedback for each option in a checkbox problem, with distinct feedback depending on whether or not the learner selects that option.</p> <p>You can provide feedback for each option in a checkbox problem, with distinct feedback depending on whether or not the learner selects that option.</p>
<p>You can also provide compound feedback for a specific combination of answers. For example, if you have three possible answers in the problem, you can configure specific feedback for when a learner selects each combination of possible answers.</p> <p>You can also provide compound feedback for a specific combination of answers. For example, if you have three possible answers in the problem, you can configure specific feedback for when a learner selects each combination of possible answers.</p>
<p>You can also add hints for learners.</p> <p>You can also add hints for learners.</p>
<p>Use the following example problem as a model.</p> <p>Use the following example problem as a model.</p>
<p>Which of the following is a fruit? Check all that apply.</p> <p>Which of the following is a fruit? Check all that apply.</p>
<choiceresponse> <choiceresponse>
<checkboxgroup> <checkboxgroup>
<choice correct="true">apple <choice correct="true">apple
<choicehint selected="true">You are correct that an apple is a fruit because it is the fertilized ovary that comes from an apple tree and contains seeds.</choicehint> <choicehint selected="true">You are correct that an apple is a fruit because it is the fertilized ovary that comes from an apple tree and contains seeds.</choicehint>
<choicehint selected="false">Remember that an apple is also a fruit.</choicehint> <choicehint selected="false">Remember that an apple is also a fruit.</choicehint>
</choice> </choice>
<choice correct="true">pumpkin <choice correct="true">pumpkin
<choicehint selected="true">You are correct that a pumpkin is a fruit because it is the fertilized ovary of a squash plant and contains seeds.</choicehint> <choicehint selected="true">You are correct that a pumpkin is a fruit because it is the fertilized ovary of a squash plant and contains seeds.</choicehint>
<choicehint selected="false">Remember that a pumpkin is also a fruit.</choicehint> <choicehint selected="false">Remember that a pumpkin is also a fruit.</choicehint>
</choice> </choice>
<choice correct="false">potato <choice correct="false">potato
<choicehint selected="true">A potato is a vegetable, not a fruit, because it does not come from a flower and does not contain seeds.</choicehint> <choicehint selected="true">A potato is a vegetable, not a fruit, because it does not come from a flower and does not contain seeds.</choicehint>
<choicehint selected="false">You are correct that a potato is a vegetable because it is an edible part of a plant in tuber form.</choicehint> <choicehint selected="false">You are correct that a potato is a vegetable because it is an edible part of a plant in tuber form.</choicehint>
</choice> </choice>
<choice correct="true">tomato <choice correct="true">tomato
<choicehint selected="true">You are correct that a tomato is a fruit because it is the fertilized ovary of a tomato plant and contains seeds.</choicehint> <choicehint selected="true">You are correct that a tomato is a fruit because it is the fertilized ovary of a tomato plant and contains seeds.</choicehint>
<choicehint selected="false">Many people mistakenly think a tomato is a vegetable. However, because a tomato is the fertilized ovary of a tomato plant and contains seeds, it a fruit.</choicehint> <choicehint selected="false">Many people mistakenly think a tomato is a vegetable. However, because a tomato is the fertilized ovary of a tomato plant and contains seeds, it a fruit.</choicehint>
</choice> </choice>
<compoundhint value="A B D">An apple, pumpkin, and tomato are all fruits as they all are fertilized ovaries of a plant and contain seeds.</compoundhint> <compoundhint value="A B D">An apple, pumpkin, and tomato are all fruits as they all are fertilized ovaries of a plant and contain seeds.</compoundhint>
<compoundhint value="A B C D">You are correct that an apple, pumpkin, and tomato are all fruits as they all are fertilized ovaries of a plant and contain seeds. However, a potato is not a fruit as it is an edible part of a plant in tuber form and is classified as a vegetable.</compoundhint> <compoundhint value="A B C D">You are correct that an apple, pumpkin, and tomato are all fruits as they all are fertilized ovaries of a plant and contain seeds. However, a potato is not a fruit as it is an edible part of a plant in tuber form and is classified as a vegetable.</compoundhint>
</checkboxgroup> </checkboxgroup>
</choiceresponse> </choiceresponse>
<demandhint> <demandhint>
<hint>A fruit is the fertilized ovary from a flower.</hint> <hint>A fruit is the fertilized ovary from a flower.</hint>
<hint>A fruit contains seeds of the plant.</hint> <hint>A fruit contains seeds of the plant.</hint>
</demandhint> </demandhint>
</question> </question>
</problem> </problem>
...@@ -4,90 +4,90 @@ metadata: ...@@ -4,90 +4,90 @@ metadata:
markdown: !!null markdown: !!null
data: | data: |
<problem> <problem>
<question> <question>
<p> <p>
Circuit schematic problems allow students to create virtual circuits by Circuit schematic problems allow students to create virtual circuits by
arranging elements such as voltage sources, capacitors, resistors, and arranging elements such as voltage sources, capacitors, resistors, and
MOSFETs on an interactive grid. The system evaluates a DC, AC, or MOSFETs on an interactive grid. The system evaluates a DC, AC, or
transient analysis of the circuit. transient analysis of the circuit.
</p> </p>
<p> <p>
For more information, see For more information, see
<a href="http://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/exercises_tools/circuit_schematic_builder.html" target="_blank"> <a href="http://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/exercises_tools/circuit_schematic_builder.html" target="_blank">
Circuit Schematic Builder Problem</a> in <i>Building and Running an edX Course</i>. Circuit Schematic Builder Problem</a> in <i>Building and Running an edX Course</i>.
</p> </p>
<p> <p>
When you add the problem, be sure to select <strong>Settings</strong> When you add the problem, be sure to select <strong>Settings</strong>
to specify a <strong>Display Name</strong> and other values that apply. to specify a <strong>Display Name</strong> and other values that apply.
</p> </p>
<p>You can use the following example problems as models.</p> <p>You can use the following example problems as models.</p>
<p>Make a voltage divider that splits the provided voltage evenly.</p> <p>Make a voltage divider that splits the provided voltage evenly.</p>
<schematicresponse> <schematicresponse>
<center> <center>
<schematic height="500" width="600" parts="g,r" analyses="dc" <schematic height="500" width="600" parts="g,r" analyses="dc"
initial_value="[[&quot;v&quot;,[168,144,0],{&quot;value&quot;:&quot;dc(1)&quot;,&quot;_json_&quot;:0},[&quot;1&quot;,&quot;0&quot;]],[&quot;r&quot;,[296,120,0],{&quot;r&quot;:&quot;1&quot;,&quot;_json_&quot;:1},[&quot;1&quot;,&quot;output&quot;]],[&quot;L&quot;,[296,168,3],{&quot;label&quot;:&quot;output&quot;,&quot;_json_&quot;:2},[&quot;output&quot;]],[&quot;w&quot;,[296,216,168,216]],[&quot;w&quot;,[168,216,168,192]],[&quot;w&quot;,[168,144,168,120]],[&quot;w&quot;,[168,120,296,120]],[&quot;g&quot;,[168,216,0],{&quot;_json_&quot;:7},[&quot;0&quot;]],[&quot;view&quot;,-67.49999999999994,-78.49999999999994,1.6000000000000003,&quot;50&quot;,&quot;10&quot;,&quot;1G&quot;,null,&quot;100&quot;,&quot;1&quot;,&quot;1000&quot;]]"/> initial_value="[[&quot;v&quot;,[168,144,0],{&quot;value&quot;:&quot;dc(1)&quot;,&quot;_json_&quot;:0},[&quot;1&quot;,&quot;0&quot;]],[&quot;r&quot;,[296,120,0],{&quot;r&quot;:&quot;1&quot;,&quot;_json_&quot;:1},[&quot;1&quot;,&quot;output&quot;]],[&quot;L&quot;,[296,168,3],{&quot;label&quot;:&quot;output&quot;,&quot;_json_&quot;:2},[&quot;output&quot;]],[&quot;w&quot;,[296,216,168,216]],[&quot;w&quot;,[168,216,168,192]],[&quot;w&quot;,[168,144,168,120]],[&quot;w&quot;,[168,120,296,120]],[&quot;g&quot;,[168,216,0],{&quot;_json_&quot;:7},[&quot;0&quot;]],[&quot;view&quot;,-67.49999999999994,-78.49999999999994,1.6000000000000003,&quot;50&quot;,&quot;10&quot;,&quot;1G&quot;,null,&quot;100&quot;,&quot;1&quot;,&quot;1000&quot;]]"/>
</center> </center>
<answer type="loncapa/python"> <answer type="loncapa/python">
dc_value = "dc analysis not found" dc_value = "dc analysis not found"
for response in submission[0]: for response in submission[0]:
if response[0] == 'dc': if response[0] == 'dc':
for node in response[1:]: for node in response[1:]:
dc_value = node['output'] dc_value = node['output']
if dc_value == .5: if dc_value == .5:
correct = ['correct'] correct = ['correct']
else: else:
correct = ['incorrect'] correct = ['incorrect']
</answer> </answer>
</schematicresponse> </schematicresponse>
<solution> <solution>
<div class="detailed-solution"> <div class="detailed-solution">
<p>Explanation</p> <p>Explanation</p>
<p> <p>
You can form a voltage divider that evenly divides the input You can form a voltage divider that evenly divides the input
voltage with two identically valued resistors, with the sampled voltage with two identically valued resistors, with the sampled
voltage taken in between the two. voltage taken in between the two.
</p> </p>
<p><img src="/static/images/voltage_divider.png" alt=""/></p> <p><img src="/static/images/voltage_divider.png" alt=""/></p>
</div> </div>
</solution> </solution>
</question> </question>
<question> <question>
<p>Make a high-pass filter.</p> <p>Make a high-pass filter.</p>
<schematicresponse> <schematicresponse>
<center> <center>
<schematic height="500" width="600" parts="g,r,s,c" analyses="ac" <schematic height="500" width="600" parts="g,r,s,c" analyses="ac"
submit_analyses="{&quot;ac&quot;:[[&quot;NodeA&quot;,1,9]]}" submit_analyses="{&quot;ac&quot;:[[&quot;NodeA&quot;,1,9]]}"
initial_value="[[&quot;v&quot;,[160,152,0],{&quot;name&quot;:&quot;v1&quot;,&quot;value&quot;:&quot;sin(0,1,1,0,0)&quot;,&quot;_json_&quot;:0},[&quot;1&quot;,&quot;0&quot;]],[&quot;w&quot;,[160,200,240,200]],[&quot;g&quot;,[160,200,0],{&quot;_json_&quot;:2},[&quot;0&quot;]],[&quot;L&quot;,[240,152,3],{&quot;label&quot;:&quot;NodeA&quot;,&quot;_json_&quot;:3},[&quot;NodeA&quot;]],[&quot;s&quot;,[240,152,0],{&quot;color&quot;:&quot;cyan&quot;,&quot;offset&quot;:&quot;0&quot;,&quot;_json_&quot;:4},[&quot;NodeA&quot;]],[&quot;view&quot;,64.55878906250004,54.114697265625054,2.5000000000000004,&quot;50&quot;,&quot;10&quot;,&quot;1G&quot;,null,&quot;100&quot;,&quot;1&quot;,&quot;1000&quot;]]"/> initial_value="[[&quot;v&quot;,[160,152,0],{&quot;name&quot;:&quot;v1&quot;,&quot;value&quot;:&quot;sin(0,1,1,0,0)&quot;,&quot;_json_&quot;:0},[&quot;1&quot;,&quot;0&quot;]],[&quot;w&quot;,[160,200,240,200]],[&quot;g&quot;,[160,200,0],{&quot;_json_&quot;:2},[&quot;0&quot;]],[&quot;L&quot;,[240,152,3],{&quot;label&quot;:&quot;NodeA&quot;,&quot;_json_&quot;:3},[&quot;NodeA&quot;]],[&quot;s&quot;,[240,152,0],{&quot;color&quot;:&quot;cyan&quot;,&quot;offset&quot;:&quot;0&quot;,&quot;_json_&quot;:4},[&quot;NodeA&quot;]],[&quot;view&quot;,64.55878906250004,54.114697265625054,2.5000000000000004,&quot;50&quot;,&quot;10&quot;,&quot;1G&quot;,null,&quot;100&quot;,&quot;1&quot;,&quot;1000&quot;]]"/>
</center> </center>
<answer type="loncapa/python"> <answer type="loncapa/python">
ac_values = None ac_values = None
for response in submission[0]: for response in submission[0]:
if response[0] == 'ac': if response[0] == 'ac':
for node in response[1:]: for node in response[1:]:
ac_values = node['NodeA'] ac_values = node['NodeA']
print "the ac analysis value:", ac_values print "the ac analysis value:", ac_values
if ac_values == None: if ac_values == None:
correct = ['incorrect'] correct = ['incorrect']
elif ac_values[0][1] &lt; ac_values[1][1]: elif ac_values[0][1] &lt; ac_values[1][1]:
correct = ['correct'] correct = ['correct']
else: else:
correct = ['incorrect'] correct = ['incorrect']
</answer> </answer>
</schematicresponse> </schematicresponse>
<solution> <solution>
<div class="detailed-solution"> <div class="detailed-solution">
<p>Explanation</p> <p>Explanation</p>
<p> <p>
You can form a simple high-pass filter without any further You can form a simple high-pass filter without any further
constraints by simply putting a resistor in series with a constraints by simply putting a resistor in series with a
capacitor. The actual values of the components do not really capacitor. The actual values of the components do not really
matter in this problem. matter in this problem.
</p> </p>
<p><img src="/static/images/high_pass_filter.png" alt=""/></p> <p><img src="/static/images/high_pass_filter.png" alt=""/></p>
</div> </div>
</solution> </solution>
</question> </question>
</problem> </problem>
...@@ -76,6 +76,6 @@ data: | ...@@ -76,6 +76,6 @@ data: |
who is unable to see the image."/> who is unable to see the image."/>
</div> </div>
</solution> </solution>
<question> </question>
</problem> </problem>
\ No newline at end of file
...@@ -5,86 +5,88 @@ metadata: ...@@ -5,86 +5,88 @@ metadata:
showanswer: never showanswer: never
data: | data: |
<problem> <problem>
<question> <question>
<p> <p>
In drag and drop problems, students respond to a question by dragging text or objects to a specific location on an image. In drag and drop problems, students respond to a question by dragging text or objects to a specific location on an image.
</p> </p>
<p> <p>
For more information, see For more information, see
<a href="http://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/exercises_tools/drag_and_drop_deprecated.html" target="_blank"> <a href="http://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/exercises_tools/drag_and_drop_deprecated.html" target="_blank">
Drag and Drop Problem (Deprecated)</a> in <i>Building and Running an edX Course</i>.</p> Drag and Drop Problem (Deprecated)</a> in <i>Building and Running an edX Course</i>.
<p>When you add the problem, be sure to select <strong>Settings</strong> </p>
to specify a <strong>Display Name</strong> and other values that apply.</p> <p>
<p>You can use the following example problems as models.</p> When you add the problem, be sure to select <strong>Settings</strong>
<hr /> to specify a <strong>Display Name</strong> and other values that apply.
<customresponse> </p>
<h3>Simple Drag and Drop</h3> <p>You can use the following example problems as models.</p>
<p>Drag each word in the scrollbar to the bucket that matches the number of letters in the word.</p> <hr />
<drag_and_drop_input img="https://studio.edx.org/c4x/edX/DemoX/asset/L9_buckets.png"> <customresponse>
<draggable id="1" label="a"/> <h3>Simple Drag and Drop</h3>
<draggable id="2" label="bog"/> <p>Drag each word in the scrollbar to the bucket that matches the number of letters in the word.</p>
<draggable id="3" label="droll"/> <drag_and_drop_input img="https://studio.edx.org/c4x/edX/DemoX/asset/L9_buckets.png">
<draggable id="4" label="oboe"/> <draggable id="1" label="a"/>
<draggable id="5" label="swain"/> <draggable id="2" label="bog"/>
<draggable id="6" label="in"/> <draggable id="3" label="droll"/>
<draggable id="7" label="onyx"/> <draggable id="4" label="oboe"/>
<draggable id="8" label="of"/> <draggable id="5" label="swain"/>
<draggable id="9" label="tap"/> <draggable id="6" label="in"/>
<draggable id="10" label="strop"/> <draggable id="7" label="onyx"/>
<draggable id="11" label="few"/> <draggable id="8" label="of"/>
</drag_and_drop_input> <draggable id="9" label="tap"/>
<answer type="loncapa/python"> <draggable id="10" label="strop"/>
correct_answer = { <draggable id="11" label="few"/>
'1': [[70, 150], 121], </drag_and_drop_input>
'6': [[190, 150], 121], <answer type="loncapa/python">
'8': [[190, 150], 121], correct_answer = {
'2': [[310, 150], 121], '1': [[70, 150], 121],
'9': [[310, 150], 121], '6': [[190, 150], 121],
'11': [[310, 150], 121], '8': [[190, 150], 121],
'4': [[420, 150], 121], '2': [[310, 150], 121],
'7': [[420, 150], 121], '9': [[310, 150], 121],
'3': [[550, 150], 121], '11': [[310, 150], 121],
'5': [[550, 150], 121], '4': [[420, 150], 121],
'10': [[550, 150], 121]} '7': [[420, 150], 121],
if draganddrop.grade(submission[0], correct_answer): '3': [[550, 150], 121],
correct = ['correct'] '5': [[550, 150], 121],
else: '10': [[550, 150], 121]}
correct = ['incorrect'] if draganddrop.grade(submission[0], correct_answer):
</answer> correct = ['correct']
</customresponse> else:
correct = ['incorrect']
</question> </answer>
</customresponse>
</question>
<question> <question>
<customresponse> <customresponse>
<h3>Drag and Drop with Outline</h3> <h3>Drag and Drop with Outline</h3>
<p>Label the hydrogen atoms connected with the left carbon atom.</p> <p>Label the hydrogen atoms connected with the left carbon atom.</p>
<drag_and_drop_input img="https://studio.edx.org/c4x/edX/DemoX/asset/ethglycol.jpg" target_outline="true" one_per_target="true" no_labels="true" label_bg_color="rgb(222, 139, 238)"> <drag_and_drop_input img="https://studio.edx.org/c4x/edX/DemoX/asset/ethglycol.jpg" target_outline="true" one_per_target="true" no_labels="true" label_bg_color="rgb(222, 139, 238)">
<draggable id="1" label="Hydrogen" /> <draggable id="1" label="Hydrogen" />
<draggable id="2" label="Hydrogen" /> <draggable id="2" label="Hydrogen" />
<target id="t1_o" x="10" y="67" w="100" h="100"/> <target id="t1_o" x="10" y="67" w="100" h="100"/>
<target id="t2" x="133" y="3" w="70" h="70"/> <target id="t2" x="133" y="3" w="70" h="70"/>
<target id="t3" x="2" y="384" w="70" h="70"/> <target id="t3" x="2" y="384" w="70" h="70"/>
<target id="t4" x="95" y="386" w="70" h="70"/> <target id="t4" x="95" y="386" w="70" h="70"/>
<target id="t5_c" x="94" y="293" w="91" h="91"/> <target id="t5_c" x="94" y="293" w="91" h="91"/>
<target id="t6_c" x="328" y="294" w="91" h="91"/> <target id="t6_c" x="328" y="294" w="91" h="91"/>
<target id="t7" x="393" y="463" w="70" h="70"/> <target id="t7" x="393" y="463" w="70" h="70"/>
<target id="t8" x="344" y="214" w="70" h="70"/> <target id="t8" x="344" y="214" w="70" h="70"/>
<target id="t9_o" x="445" y="162" w="100" h="100"/> <target id="t9_o" x="445" y="162" w="100" h="100"/>
<target id="t10" x="591" y="132" w="70" h="70"/> <target id="t10" x="591" y="132" w="70" h="70"/>
</drag_and_drop_input> </drag_and_drop_input>
<answer type="loncapa/python"> <answer type="loncapa/python">
correct_answer = [{ correct_answer = [{
'draggables': ['1', '2'], 'draggables': ['1', '2'],
'targets': ['t2', 't3', 't4' ], 'targets': ['t2', 't3', 't4' ],
'rule':'anyof' 'rule':'anyof'
}] }]
if draganddrop.grade(submission[0], correct_answer): if draganddrop.grade(submission[0], correct_answer):
correct = ['correct'] correct = ['correct']
else: else:
correct = ['incorrect'] correct = ['incorrect']
</answer> </answer>
</customresponse> </customresponse>
</question> </question>
</problem> </problem>
...@@ -57,4 +57,4 @@ data: | ...@@ -57,4 +57,4 @@ data: |
</formularesponse> </formularesponse>
</question> </question>
</problem> </problem>
\ No newline at end of file
...@@ -3,35 +3,41 @@ metadata: ...@@ -3,35 +3,41 @@ metadata:
display_name: Image Mapped Input display_name: Image Mapped Input
markdown: !!null markdown: !!null
data: | data: |
<problem> <problem>
<question> <question>
<p> <p>
In an image mapped input problem, also known as a "pointing on a picture" In an image mapped input problem, also known as a "pointing on a picture"
problem, students click inside a defined region in an image. You define this problem, students click inside a defined region in an image. You define this
region by including coordinates in the body of the problem. You can define region by including coordinates in the body of the problem. You can define
one rectangular region, multiple rectangular regions, or one non-rectangular one rectangular region, multiple rectangular regions, or one non-rectangular
region. For more information, see region. For more information, see
<a href="http://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/exercises_tools/image_mapped_input.html" target="_blank">Image Mapped Input <a href="http://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/exercises_tools/image_mapped_input.html" target="_blank">Image Mapped Input
Problem</a> in <i>Building and Running an edx Course</i>. Problem</a> in <i>Building and Running an edx Course</i>.
</p> </p>
<p>When you add the problem, be sure to select <strong>Settings</strong> <p>
to specify a <strong>Display Name</strong> and other values that apply.</p> When you add the problem, be sure to select <strong>Settings</strong>
<p>You can use the following example problem as a model.</p> to specify a <strong>Display Name</strong> and other values that apply.
</p>
<p>You can use the following example problem as a model.</p>
<p>What country is home to the Great Pyramid of Giza as well as the cities <p>
of Cairo and Memphis? Click the country on the map below.</p> What country is home to the Great Pyramid of Giza as well as the cities
<imageresponse> of Cairo and Memphis? Click the country on the map below.
<imageinput src="https://studio.edx.org/c4x/edX/DemoX/asset/Africa.png" </p>
width="600" height="638" rectangle="(338,98)-(412,168)" alt="Map of <imageresponse>
Africa"/> <imageinput src="https://studio.edx.org/c4x/edX/DemoX/asset/Africa.png"
</imageresponse> width="600" height="638" rectangle="(338,98)-(412,168)" alt="Map of
<solution> Africa"/>
<div class="detailed-solution"> </imageresponse>
<p>Explanation</p> <solution>
<p>Egypt is home to not only the Pyramids, Cairo, and Memphis, but also <div class="detailed-solution">
the Sphinx and the ancient Royal Library of Alexandria.</p> <p>Explanation</p>
</div> <p>
</solution> Egypt is home to not only the Pyramids, Cairo, and Memphis, but also
</question> the Sphinx and the ancient Royal Library of Alexandria.
</problem> </p>
</div>
</solution>
</question>
</problem>
...@@ -67,4 +67,4 @@ data: | ...@@ -67,4 +67,4 @@ data: |
sop="false"/> sop="false"/>
</customresponse> </customresponse>
</question> </question>
</problem> </problem>
\ No newline at end of file
...@@ -24,32 +24,36 @@ metadata: ...@@ -24,32 +24,36 @@ metadata:
data: | data: |
<problem> <problem>
<question> <question>
<p>Multiple choice problems allow learners to select only one option. <p>
Learners can see all the options along with the problem text.</p> Multiple choice problems allow learners to select only one option.
<p>When you add the problem, be sure to select <strong>Settings</strong> Learners can see all the options along with the problem text.
to specify a <strong>Display Name</strong> and other values that apply.</p> </p>
<p>You can use the following example problem as a model.</p> <p>
<p>Which of the following countries has the largest population?</p> When you add the problem, be sure to select <strong>Settings</strong>
<multiplechoiceresponse> to specify a <strong>Display Name</strong> and other values that apply.
<choicegroup type="MultipleChoice"> </p>
<choice correct="false" name="brazil">Brazil <p>You can use the following example problem as a model.</p>
<choicehint>timely feedback -- explain why an almost correct answer is wrong</choicehint> <p>Which of the following countries has the largest population?</p>
</choice> <multiplechoiceresponse>
<choice correct="false" name="germany">Germany</choice> <choicegroup type="MultipleChoice">
<choice correct="true" name="indonesia">Indonesia</choice> <choice correct="false" name="brazil">Brazil
<choice correct="false" name="russia">Russia</choice> <choicehint>timely feedback -- explain why an almost correct answer is wrong</choicehint>
</choicegroup> </choice>
</multiplechoiceresponse> <choice correct="false" name="germany">Germany</choice>
<solution> <choice correct="true" name="indonesia">Indonesia</choice>
<div class="detailed-solution"> <choice correct="false" name="russia">Russia</choice>
<p>Explanation</p> </choicegroup>
<p>According to September 2014 estimates:</p> </multiplechoiceresponse>
<p>The population of Indonesia is approximately 250 million.</p> <solution>
<p>The population of Brazil is approximately 200 million.</p> <div class="detailed-solution">
<p>The population of Russia is approximately 146 million.</p> <p>Explanation</p>
<p>The population of Germany is approximately 81 million.</p> <p>According to September 2014 estimates:</p>
</div> <p>The population of Indonesia is approximately 250 million.</p>
</solution> <p>The population of Brazil is approximately 200 million.</p>
</question> <p>The population of Russia is approximately 146 million.</p>
<p>The population of Germany is approximately 81 million.</p>
</div>
</solution>
</question>
</problem> </problem>
\ No newline at end of file
...@@ -22,26 +22,26 @@ metadata: ...@@ -22,26 +22,26 @@ metadata:
hinted: true hinted: true
data: | data: |
<problem> <problem>
<question> <question>
<p>You can provide feedback for each option in a multiple choice problem.</p> <p>You can provide feedback for each option in a multiple choice problem.</p>
<p>You can also add hints for learners.</p> <p>You can also add hints for learners.</p>
<p>Use the following example problem as a model.</p> <p>Use the following example problem as a model.</p>
<p>Which of the following is a vegetable?</p> <p>Which of the following is a vegetable?</p>
<multiplechoiceresponse> <multiplechoiceresponse>
<choicegroup type="MultipleChoice"> <choicegroup type="MultipleChoice">
<choice correct="false">apple <choicehint>An apple is the fertilized ovary that comes from an apple tree and contains seeds, meaning it is a fruit.</choicehint></choice> <choice correct="false">apple <choicehint>An apple is the fertilized ovary that comes from an apple tree and contains seeds, meaning it is a fruit.</choicehint></choice>
<choice correct="false">pumpkin <choicehint>A pumpkin is the fertilized ovary of a squash plant and contains seeds, meaning it is a fruit.</choicehint></choice> <choice correct="false">pumpkin <choicehint>A pumpkin is the fertilized ovary of a squash plant and contains seeds, meaning it is a fruit.</choicehint></choice>
<choice correct="true">potato <choicehint>A potato is an edible part of a plant in tuber form and is a vegetable.</choicehint></choice> <choice correct="true">potato <choicehint>A potato is an edible part of a plant in tuber form and is a vegetable.</choicehint></choice>
<choice correct="false">tomato <choicehint>Many people mistakenly think a tomato is a vegetable. However, because a tomato is the fertilized ovary of a tomato plant and contains seeds, it is a fruit.</choicehint></choice> <choice correct="false">tomato <choicehint>Many people mistakenly think a tomato is a vegetable. However, because a tomato is the fertilized ovary of a tomato plant and contains seeds, it is a fruit.</choicehint></choice>
</choicegroup> </choicegroup>
</multiplechoiceresponse> </multiplechoiceresponse>
<demandhint> <demandhint>
<hint>A fruit is the fertilized ovary from a flower.</hint> <hint>A fruit is the fertilized ovary from a flower.</hint>
<hint>A fruit contains seeds of the plant.</hint> <hint>A fruit contains seeds of the plant.</hint>
</demandhint> </demandhint>
</question> </question>
</problem> </problem>
...@@ -24,44 +24,47 @@ metadata: ...@@ -24,44 +24,47 @@ metadata:
-100 is the square of 10 times the imaginary number, i. -100 is the square of 10 times the imaginary number, i.
[explanation] [explanation]
data: | data: |
<problem> <problem>
<question> <question>
<p>In a numerical input problem, learners enter numbers or a specific and <p>
relatively simple mathematical expression. Learners enter the response in In a numerical input problem, learners enter numbers or a specific and
plain text, and the system then converts the text to a symbolic expression relatively simple mathematical expression. Learners enter the response in
that learners can see below the response field.</p> plain text, and the system then converts the text to a symbolic expression
that learners can see below the response field.
</p>
<p>The system can handle several types of characters, including basic <p>
operators, fractions, exponents, and common constants such as i. You can The system can handle several types of characters, including basic
refer learners to operators, fractions, exponents, and common constants such as i. You can
<a href="http://edx.readthedocs.io/projects/edx-guide-for-students/en/latest/completing_assignments/SFD_mathformatting.html#math-formatting" target="_blank">Entering Mathematical and Scientific Expressions</a> in the <i>EdX Learner's Guide</i> for information about how to enter text into the field.</p> refer learners to
<p>When you add the problem, be sure to select <strong>Settings</strong> <a href="http://edx.readthedocs.io/projects/edx-guide-for-students/en/latest/completing_assignments/SFD_mathformatting.html#math-formatting" target="_blank">Entering Mathematical and Scientific Expressions</a> in the <i>EdX Learner's Guide</i> for information about how to enter text into the field.</p>
to specify a <strong>Display Name</strong> and other values that apply.</p> <p>When you add the problem, be sure to select <strong>Settings</strong>
to specify a <strong>Display Name</strong> and other values that apply.
</p>
<p>You can use the following example problems as models.</p> <p>You can use the following example problems as models.</p>
<p>How many miles away from Earth is the sun? Use scientific notation to answer.</p> <p>How many miles away from Earth is the sun? Use scientific notation to answer.</p>
<numericalresponse answer="9.3*10^7"> <numericalresponse answer="9.3*10^7">
<formulaequationinput label="How many million miles are between Earth and the sun? Use scientific notation to answer." /> <formulaequationinput label="How many million miles are between Earth and the sun? Use scientific notation to answer." />
</numericalresponse> </numericalresponse>
<solution>
<div class="detailed-solution">
<p>Explanation</p>
<p>The sun is 93,000,000, or 9.3*10^7, miles away from Earth.</p>
</div>
</solution>
</question>
<solution> <question>
<div class="detailed-solution"> <p>The square of what number is -100?</p>
<p>Explanation</p> <numericalresponse answer="10*i">
<p>The sun is 93,000,000, or 9.3*10^7, miles away from Earth.</p> <formulaequationinput label="The square of what number is -100?" />
</div> </numericalresponse>
</solution> <solution>
</question> <div class="detailed-solution">
<p>Explanation</p>
<question> <p>-100 is the square of 10 times the imaginary number, i.</p>
<p>The square of what number is -100?</p> </div>
<numericalresponse answer="10*i"> </solution>
<formulaequationinput label="The square of what number is -100?" /> </question>
</numericalresponse> </problem>
<solution>
<div class="detailed-solution">
<p>Explanation</p>
<p>-100 is the square of 10 times the imaginary number, i.</p>
</div>
</solution>
</question>
</problem>
...@@ -26,30 +26,30 @@ metadata: ...@@ -26,30 +26,30 @@ metadata:
hinted: true hinted: true
data: | data: |
<problem> <problem>
<question> <question>
<p>You can provide feedback for correct answers in numerical input problems. You cannot provide feedback for incorrect answers.</p> <p>You can provide feedback for correct answers in numerical input problems. You cannot provide feedback for incorrect answers.</p>
<p>Use feedback for the correct answer to reinforce the process for arriving at the numerical value.</p> <p>Use feedback for the correct answer to reinforce the process for arriving at the numerical value.</p>
<p>Use the following example problem as a model.</p> <p>Use the following example problem as a model.</p>
<p>What is the arithmetic mean for the following set of numbers? (1, 5, 6, 3, 5)</p> <p>What is the arithmetic mean for the following set of numbers? (1, 5, 6, 3, 5)</p>
<numericalresponse answer="4"> <numericalresponse answer="4">
<formulaequationinput label="What is the arithmetic mean for the following set of numbers? (1, 5, 6, 3, 5)" /> <formulaequationinput label="What is the arithmetic mean for the following set of numbers? (1, 5, 6, 3, 5)" />
<correcthint>The mean for this set of numbers is 20 / 5, which equals 4.</correcthint> <correcthint>The mean for this set of numbers is 20 / 5, which equals 4.</correcthint>
</numericalresponse> </numericalresponse>
<solution> <solution>
<div class="detailed-solution"> <div class="detailed-solution">
<p>Explanation</p> <p>Explanation</p>
<p>The mean is calculated by summing the set of numbers and dividing by n. In this case: (1 + 5 + 6 + 3 + 5) / 5 = 20 / 5 = 4.</p> <p>The mean is calculated by summing the set of numbers and dividing by n. In this case: (1 + 5 + 6 + 3 + 5) / 5 = 20 / 5 = 4.</p>
</div> </div>
</solution> </solution>
<demandhint> <demandhint>
<hint>The mean is calculated by summing the set of numbers and dividing by n.</hint> <hint>The mean is calculated by summing the set of numbers and dividing by n.</hint>
<hint>n is the count of items in the set.</hint> <hint>n is the count of items in the set.</hint>
</demandhint> </demandhint>
<question> </question>
</problem> </problem>
\ No newline at end of file \ No newline at end of file
...@@ -16,23 +16,25 @@ metadata: ...@@ -16,23 +16,25 @@ metadata:
India became an independent nation on August 15, 1947. India became an independent nation on August 15, 1947.
[explanation] [explanation]
data: | data: |
<problem> <problem>
<question> <question>
<p>Dropdown problems allow learners to select only one option from a list of options.</p> <p>Dropdown problems allow learners to select only one option from a list of options.</p>
<p>When you add the problem, be sure to select <strong>Settings</strong> <p>
to specify a <strong>Display Name</strong> and other values that apply.</p> When you add the problem, be sure to select <strong>Settings</strong>
<p>You can use the following example problem as a model.</p> to specify a <strong>Display Name</strong> and other values that apply.
<p>Which of the following countries celebrates its independence on August 15?</p> </p>
<br/> <p>You can use the following example problem as a model.</p>
<optionresponse> <p>Which of the following countries celebrates its independence on August 15?</p>
<optioninput options="('India','Spain','China','Bermuda')" correct="India"></optioninput> <br/>
</optionresponse> <optionresponse>
<solution> <optioninput options="('India','Spain','China','Bermuda')" correct="India"></optioninput>
<div class="detailed-solution"> </optionresponse>
<p>Explanation</p> <solution>
<p>India became an independent nation on August 15, 1947.</p> <div class="detailed-solution">
</div> <p>Explanation</p>
</solution> <p>India became an independent nation on August 15, 1947.</p>
</question> </div>
</problem> </solution>
</question>
</problem>
...@@ -25,28 +25,28 @@ metadata: ...@@ -25,28 +25,28 @@ metadata:
hinted: true hinted: true
data: | data: |
<problem> <problem>
<question> <question>
<p>You can provide feedback for each available option in a dropdown problem.</p> <p>You can provide feedback for each available option in a dropdown problem.</p>
<p>You can also add hints for learners.</p> <p>You can also add hints for learners.</p>
<p>Use the following example problem as a model.</p> <p>Use the following example problem as a model.</p>
<p> A/an ________ is a vegetable.</p> <p> A/an ________ is a vegetable.</p>
<br/> <br/>
<optionresponse> <optionresponse>
<optioninput> <optioninput>
<option correct="False">apple <optionhint>An apple is the fertilized ovary that comes from an apple tree and contains seeds, meaning it is a fruit.</optionhint></option> <option correct="False">apple <optionhint>An apple is the fertilized ovary that comes from an apple tree and contains seeds, meaning it is a fruit.</optionhint></option>
<option correct="False">pumpkin <optionhint>A pumpkin is the fertilized ovary of a squash plant and contains seeds, meaning it is a fruit.</optionhint></option> <option correct="False">pumpkin <optionhint>A pumpkin is the fertilized ovary of a squash plant and contains seeds, meaning it is a fruit.</optionhint></option>
<option correct="True">potato <optionhint>A potato is an edible part of a plant in tuber form and is a vegetable.</optionhint></option> <option correct="True">potato <optionhint>A potato is an edible part of a plant in tuber form and is a vegetable.</optionhint></option>
<option correct="False">tomato <optionhint>Many people mistakenly think a tomato is a vegetable. However, because a tomato is the fertilized ovary of a tomato plant and contains seeds, it is a fruit.</optionhint></option> <option correct="False">tomato <optionhint>Many people mistakenly think a tomato is a vegetable. However, because a tomato is the fertilized ovary of a tomato plant and contains seeds, it is a fruit.</optionhint></option>
</optioninput> </optioninput>
</optionresponse> </optionresponse>
<demandhint> <demandhint>
<hint>A fruit is the fertilized ovary from a flower.</hint> <hint>A fruit is the fertilized ovary from a flower.</hint>
<hint>A fruit contains seeds of the plant.</hint> <hint>A fruit contains seeds of the plant.</hint>
</demandhint> </demandhint>
</question> </question>
</problem> </problem>
...@@ -46,4 +46,4 @@ data: | ...@@ -46,4 +46,4 @@ data: |
</label> </label>
</text> </text>
</question> </question>
</problem> </problem>
\ No newline at end of file
...@@ -48,47 +48,48 @@ metadata: ...@@ -48,47 +48,48 @@ metadata:
\edXabox{type="custom" cfn='test_str' expect='python' hintfn='hint_fn'} \edXabox{type="custom" cfn='test_str' expect='python' hintfn='hint_fn'}
markdown: !!null markdown: !!null
data: | data: |
<problem> <problem>
<question> <question>
<text> <text>
<p> <p>
<h4>Problem With Adaptive Hint</h4> <h4>Problem With Adaptive Hint</h4>
</p> </p>
<p> <p>
This problem demonstrates a question with hints, based on using the <tt class="tt">hintfn</tt> method. </p> This problem demonstrates a question with hints, based on using the <tt class="tt">hintfn</tt> method.
<script type="text/python" system_path="python_lib"> </p>
def test_str(expect, ans): <script type="text/python" system_path="python_lib">
print expect, ans def test_str(expect, ans):
ans = ans.strip("'") print expect, ans
ans = ans.strip('"') ans = ans.strip("'")
return expect == ans.lower() ans = ans.strip('"')
return expect == ans.lower()
def hint_fn(answer_ids, student_answers, new_cmap, old_cmap): def hint_fn(answer_ids, student_answers, new_cmap, old_cmap):
aid = answer_ids[0] aid = answer_ids[0]
ans = str(student_answers[aid]).lower() ans = str(student_answers[aid]).lower()
print 'hint_fn called, ans=', ans print 'hint_fn called, ans=', ans
hint = '' hint = ''
if 'java' in ans: if 'java' in ans:
hint = 'that is only good for drinking' hint = 'that is only good for drinking'
elif 'perl' in ans: elif 'perl' in ans:
hint = 'not that rich' hint = 'not that rich'
elif 'pascal' in ans: elif 'pascal' in ans:
hint = 'that is a beatnick language' hint = 'that is a beatnick language'
elif 'fortran' in ans: elif 'fortran' in ans:
hint = 'those were the good days' hint = 'those were the good days'
elif 'clu' in ans: elif 'clu' in ans:
hint = 'you must be invariant' hint = 'you must be invariant'
if hint: if hint:
hint = "&lt;font color='blue'&gt;Hint: {0}&lt;/font&gt;".format(hint) hint = "&lt;font color='blue'&gt;Hint: {0}&lt;/font&gt;".format(hint)
new_cmap.set_hint_and_mode(aid,hint,'always') new_cmap.set_hint_and_mode(aid,hint,'always')
</script> </script>
<label> <label>
What is the best programming language that exists today? You may enter your answer in upper or lower case, with or without quotes. What is the best programming language that exists today? You may enter your answer in upper or lower case, with or without quotes.
<customresponse cfn="test_str" expect="python"> <customresponse cfn="test_str" expect="python">
<textline correct_answer="python"/> <textline correct_answer="python"/>
<hintgroup hintfn="hint_fn"/> <hintgroup hintfn="hint_fn"/>
</customresponse> </customresponse>
</label> </label>
</text> </text>
</question> </question>
</problem> </problem>
...@@ -19,27 +19,29 @@ metadata: ...@@ -19,27 +19,29 @@ metadata:
[explanation] [explanation]
data: | data: |
<problem> <problem>
<question> <question>
<p>In text input problems, also known as "fill-in-the-blank" problems, <p>
learners enter text into a response field. The text that the learner enters In text input problems, also known as "fill-in-the-blank" problems,
must match your specified answer text exactly. You can specify more than learners enter text into a response field. The text that the learner enters
one correct answer. Learners must enter a response that matches one of the must match your specified answer text exactly. You can specify more than
correct answers exactly.</p> one correct answer. Learners must enter a response that matches one of the
<p>When you add the problem, be sure to select <strong>Settings</strong> correct answers exactly.
to specify a <strong>Display Name</strong> and other values that apply.</p> </p>
<p> You can use the following example problem as a model.</p> <p>When you add the problem, be sure to select <strong>Settings</strong>
<p>What was the first post-secondary school in China to allow both male and female students?</p> to specify a <strong>Display Name</strong> and other values that apply.</p>
<stringresponse answer="Nanjing Higher Normal Institute" type="ci" > <p> You can use the following example problem as a model.</p>
<additional_answer>National Central University</additional_answer> <p>What was the first post-secondary school in China to allow both male and female students?</p>
<additional_answer>Nanjing University</additional_answer> <stringresponse answer="Nanjing Higher Normal Institute" type="ci" >
<textline label="What was the first post-secondary school in China to allow both male and female students?" size="40"/> <additional_answer>National Central University</additional_answer>
</stringresponse> <additional_answer>Nanjing University</additional_answer>
<solution> <textline label="What was the first post-secondary school in China to allow both male and female students?" size="40"/>
<div class="detailed-solution"> </stringresponse>
<p>Explanation</p> <solution>
<p>Nanjing Higher Normal Institute first admitted female students in 1920.</p> <div class="detailed-solution">
</div> <p>Explanation</p>
</solution> <p>Nanjing Higher Normal Institute first admitted female students in 1920.</p>
</question> </div>
</problem> </solution>
</question>
</problem>
...@@ -25,30 +25,30 @@ metadata: ...@@ -25,30 +25,30 @@ metadata:
hinted: true hinted: true
data: | data: |
<problem> <problem>
<question> <question>
<p>You can provide feedback for the correct answer in text input problems, as well as for specific incorrect answers.</p> <p>You can provide feedback for the correct answer in text input problems, as well as for specific incorrect answers.</p>
<p>Use feedback on expected incorrect answers to address common misconceptions and to provide guidance on how to arrive at the correct answer.</p> <p>Use feedback on expected incorrect answers to address common misconceptions and to provide guidance on how to arrive at the correct answer.</p>
<p>Use the following example problem as a model.</p> <p>Use the following example problem as a model.</p>
<p>Which U.S. state has the largest land area?</p>
<stringresponse answer="Alaska" type="ci" > <p>Which U.S. state has the largest land area?</p>
<correcthint>Alaska is 576,400 square miles, more than double the land area of the second largest state, Texas.</correcthint> <stringresponse answer="Alaska" type="ci" >
<stringequalhint answer="Texas">While many people think Texas is the largest state, it is actually the second largest, with 261,797 square miles.</stringequalhint> <correcthint>Alaska is 576,400 square miles, more than double the land area of the second largest state, Texas.</correcthint>
<stringequalhint answer="California">California is the third largest state, with 155,959 square miles.</stringequalhint> <stringequalhint answer="Texas">While many people think Texas is the largest state, it is actually the second largest, with 261,797 square miles.</stringequalhint>
<textline label="Which U.S. state has the largest land area?" size="20"/> <stringequalhint answer="California">California is the third largest state, with 155,959 square miles.</stringequalhint>
</stringresponse>
<demandhint> <textline label="Which U.S. state has the largest land area?" size="20"/>
<hint>Consider the square miles, not population.</hint> </stringresponse>
<hint>Consider all 50 states, not just the continental United States.</hint>
</demandhint> <demandhint>
</question> <hint>Consider the square miles, not population.</hint>
</problem> <hint>Consider all 50 states, not just the continental United States.</hint>
</demandhint>
</question>
</problem>
...@@ -12,7 +12,7 @@ class ProblemPage(PageObject): ...@@ -12,7 +12,7 @@ class ProblemPage(PageObject):
url = None url = None
CSS_PROBLEM_HEADER = '.problem-header' CSS_PROBLEM_HEADER = '.problem-header'
# There can be multiple questions in a problem, so we need to make query selector specific to question # Used to make question specific css selector
question_id = 0 question_id = 0
def is_browser_on_page(self): def is_browser_on_page(self):
...@@ -28,7 +28,7 @@ class ProblemPage(PageObject): ...@@ -28,7 +28,7 @@ class ProblemPage(PageObject):
Returns: Returns:
str: Element selector specific to a question. str: Element selector specific to a question.
""" """
return 'div.problem #question-{}.question {}'.format(self.question_id, selector) return 'div.problem [question_index="{}"] {}'.format(self.question_id, selector)
@property @property
def problem_name(self): def problem_name(self):
......
...@@ -38,9 +38,12 @@ class ProblemsTest(UniqueCourseTest): ...@@ -38,9 +38,12 @@ class ProblemsTest(UniqueCourseTest):
) )
problem = self.get_problem() problem = self.get_problem()
problems = (problem,) * self.get_num_problems()
course_fixture.add_children( course_fixture.add_children(
XBlockFixtureDesc('chapter', 'Test Section').add_children( XBlockFixtureDesc('chapter', 'Test Section').add_children(
XBlockFixtureDesc('sequential', 'Test Subsection').add_children(problem) XBlockFixtureDesc('sequential', 'Test Subsection').add_children(
XBlockFixtureDesc('vertical', 'Test Unit').add_children(*problems)
)
) )
).install() ).install()
...@@ -58,6 +61,12 @@ class ProblemsTest(UniqueCourseTest): ...@@ -58,6 +61,12 @@ class ProblemsTest(UniqueCourseTest):
""" Subclasses should override this to complete the fixture """ """ Subclasses should override this to complete the fixture """
raise NotImplementedError() raise NotImplementedError()
def get_num_problems(self):
"""
Tells how many problems to create. Defaults to 1.
"""
return 1
class ProblemClarificationTest(ProblemsTest): class ProblemClarificationTest(ProblemsTest):
""" """
...@@ -470,3 +479,72 @@ class LogoutDuringAnswering(ProblemsTest): ...@@ -470,3 +479,72 @@ class LogoutDuringAnswering(ProblemsTest):
self.assertTrue(problem_page.is_browser_on_page()) self.assertTrue(problem_page.is_browser_on_page())
self.assertEqual(problem_page.problem_name, 'TEST PROBLEM') self.assertEqual(problem_page.problem_name, 'TEST PROBLEM')
# @attr('a11y')
class CAPAProblemQuestionA11yTest(ProblemsTest):
"""
TestCase Class for CAPA problem questions
"""
def get_problem(self):
"""
Problem structure.
"""
xml = dedent("""
<problem>
<question>
<p>question text</p>
<stringresponse answer="A">
<stringequalhint answer="C"><a href="#">aa bb</a> cc</stringequalhint>
<textline size="20"/>
</stringresponse>
<demandhint>
<hint>question 1 hint 1</hint>
<hint>question 1 hint 2</hint>
</demandhint>
</question>
<question>
<p>That is the question</p>
<multiplechoiceresponse>
<choicegroup type="MultipleChoice">
<choice correct="false">Alpha <choicehint>A hint</choicehint></choice>
<choice correct="true">Beta</choice>
</choicegroup>
</multiplechoiceresponse>
<demandhint>
<hint>question 2 hint 1</hint>
<hint>question 2 hint 2</hint>
</demandhint>
</question>
</problem>
""")
return XBlockFixtureDesc('problem', 'Problem Question TEST', data=xml)
def get_num_problems(self):
"""
Create two problems.
"""
return 2
def test_questions_have_unique_ids(self):
"""
Scenario: Verifies that each question has a unique id.
Given I am enrolled in a course.
And I visit a unit page with two CAPA problems where each problem has 2 questions
Then I check if questions have unique IDs
"""
self.courseware_page.visit()
problem_page = ProblemPage(self.browser)
# Set the scope to the problem question
problem_page.a11y_audit.config.set_scope(
include=['div.question']
)
# Check only for duplicate ids
problem_page.a11y_audit.config.set_rules({
"apply": ['duplicate-id'],
})
# Run the accessibility audit.
problem_page.a11y_audit.check_for_accessibility_errors()
<%! from django.utils.translation import ugettext as _ %> <%page expression_filter="h"/>
<%!
from django.utils.translation import ugettext as _
from openedx.core.djangolib.markup import HTML
%>
<%namespace name='static' file='static_content.html'/> <%namespace name='static' file='static_content.html'/>
<h3 class="hd hd-2 problem-header"> <h3 class="hd hd-2 problem-header">
...@@ -8,7 +12,7 @@ ...@@ -8,7 +12,7 @@
<div class="problem-progress"></div> <div class="problem-progress"></div>
<div class="problem"> <div class="problem">
${ problem['html'] } ${ HTML(problem['html']) }
<div class="action"> <div class="action">
<input type="hidden" name="problem_id" value="${ problem['name'] }" /> <input type="hidden" name="problem_id" value="${ problem['name'] }" />
% if check_button: % if check_button:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment