Commit d116de55 by Usman Khalid

Added parsing and serialization for examples with multiple parts.

TNL-708
parent 5ea00106
...@@ -1002,7 +1002,7 @@ ...@@ -1002,7 +1002,7 @@
"name": "student-training", "name": "student-training",
"examples": [ "examples": [
{ {
"answer": "Ṫḧïṡ ïṡ äṅ äṅṡẅëṛ", "answer": ["Ṫḧïṡ ïṡ äṅ äṅṡẅëṛ 1", "Ṫḧïṡ ïṡ äṅ äṅṡẅëṛ 2"],
"options_selected": [ "options_selected": [
{ "criterion": "Not a criterion!", "option": "Ṅö" } { "criterion": "Not a criterion!", "option": "Ṅö" }
] ]
......
...@@ -90,7 +90,11 @@ ...@@ -90,7 +90,11 @@
"due": "2014-06-01T00:00:00", "due": "2014-06-01T00:00:00",
"examples": [ "examples": [
{ {
"answer": "ẗëṡẗ äṅṡẅëṛ", "answer": {
"parts": [
{"text": "ẗëṡẗ äṅṡẅëṛ"}
]
},
"options_selected": [ "options_selected": [
{ {
"criterion": "Test criterion", "criterion": "Test criterion",
...@@ -127,7 +131,11 @@ ...@@ -127,7 +131,11 @@
"due": "2014-06-01T00:00:00", "due": "2014-06-01T00:00:00",
"examples": [ "examples": [
{ {
"answer": "ẗëṡẗ äṅṡẅëṛ", "answer": {
"parts": [
{"text": "ẗëṡẗ äṅṡẅëṛ"}
]
},
"options_selected": [ "options_selected": [
{ {
"criterion": "Test criterion", "criterion": "Test criterion",
...@@ -140,7 +148,11 @@ ...@@ -140,7 +148,11 @@
] ]
}, },
{ {
"answer": "äṅöẗḧëṛ ẗëṡẗ äṅṡẅëṛ", "answer": {
"parts": [
{"text": "äṅöẗḧëṛ ẗëṡẗ äṅṡẅëṛ"}
]
},
"options_selected": [ "options_selected": [
{ {
"criterion": "Another test criterion", "criterion": "Another test criterion",
......
...@@ -10,7 +10,11 @@ ...@@ -10,7 +10,11 @@
], ],
"examples": [ "examples": [
{ {
"answer": "ẗëṡẗ äṅṡẅëṛ", "answer": {
"parts": [
{"text": "ẗëṡẗ äṅṡẅëṛ"}
]
},
"options_selected": [ "options_selected": [
{ {
"criterion": "Test criterion", "criterion": "Test criterion",
...@@ -25,12 +29,18 @@ ...@@ -25,12 +29,18 @@
"xml": [ "xml": [
"<examples>", "<examples>",
"<example>", "<example>",
"<answer>ẗëṡẗ äṅṡẅëṛ</answer>", "<answer>",
"<part>ẗëṡẗ äṅṡẅëṛ 1</part>",
"<part>ẗëṡẗ äṅṡẅëṛ 2</part>",
"</answer>",
"<select criterion=\"Test criterion\" option=\"Yes\" />", "<select criterion=\"Test criterion\" option=\"Yes\" />",
"<select criterion=\"Another test criterion\" option=\"No\" />", "<select criterion=\"Another test criterion\" option=\"No\" />",
"</example>", "</example>",
"<example>", "<example>",
"<answer>äṅöẗḧëṛ ẗëṡẗ äṅṡẅëṛ</answer>", "<answer>",
"<part>äṅöẗḧëṛ ẗëṡẗ äṅṡẅëṛ 1</part>",
"<part>äṅöẗḧëṛ ẗëṡẗ äṅṡẅëṛ 2</part>",
"</answer>",
"<select criterion=\"Another test criterion\" option=\"Yes\" />", "<select criterion=\"Another test criterion\" option=\"Yes\" />",
"<select criterion=\"Test criterion\" option=\"No\" />", "<select criterion=\"Test criterion\" option=\"No\" />",
"</example>", "</example>",
...@@ -38,7 +48,12 @@ ...@@ -38,7 +48,12 @@
], ],
"examples": [ "examples": [
{ {
"answer": "ẗëṡẗ äṅṡẅëṛ", "answer": {
"parts": [
{"text": "ẗëṡẗ äṅṡẅëṛ 1"},
{"text": "ẗëṡẗ äṅṡẅëṛ 2"}
]
},
"options_selected": [ "options_selected": [
{ {
"criterion": "Test criterion", "criterion": "Test criterion",
...@@ -51,7 +66,12 @@ ...@@ -51,7 +66,12 @@
] ]
}, },
{ {
"answer": "äṅöẗḧëṛ ẗëṡẗ äṅṡẅëṛ", "answer": {
"parts": [
{"text": "äṅöẗḧëṛ ẗëṡẗ äṅṡẅëṛ 1"},
{"text": "äṅöẗḧëṛ ẗëṡẗ äṅṡẅëṛ 2"}
]
},
"options_selected": [ "options_selected": [
{ {
"criterion": "Another test criterion", "criterion": "Another test criterion",
......
...@@ -1059,7 +1059,9 @@ ...@@ -1059,7 +1059,9 @@
"<assessments>", "<assessments>",
"<assessment name=\"student-training\" start=\"2014-02-27T09:46:28\" due=\"2014-03-01T00:00:00\">", "<assessment name=\"student-training\" start=\"2014-02-27T09:46:28\" due=\"2014-03-01T00:00:00\">",
"<example>", "<example>",
"<answer>ẗëṡẗ äṅṡẅëṛ</answer>", "<answer>",
"<part>ẗëṡẗ äṅṡẅëṛ</part>",
"</answer>",
"<select criterion=\"Test criterion\" option=\"No\" />", "<select criterion=\"Test criterion\" option=\"No\" />",
"<select criterion=\"Another test criterion\" option=\"Yes\" />", "<select criterion=\"Another test criterion\" option=\"Yes\" />",
"</example>", "</example>",
...@@ -1147,7 +1149,12 @@ ...@@ -1147,7 +1149,12 @@
"due": "2014-03-01T00:00:00", "due": "2014-03-01T00:00:00",
"examples": [ "examples": [
{ {
"answer": "ẗëṡẗ äṅṡẅëṛ", "answer": {
"parts": [
{"text": "ẗëṡẗ äṅṡẅëṛ 1"},
{"text": "ẗëṡẗ äṅṡẅëṛ 2"}
]
},
"options_selected": [ "options_selected": [
{ {
"criterion": "Test criterion", "criterion": "Test criterion",
...@@ -1160,7 +1167,12 @@ ...@@ -1160,7 +1167,12 @@
] ]
}, },
{ {
"answer": "śéćőńd téśt áńśẃéŕ", "answer": {
"parts": [
{"text": "śéćőńd téśt áńśẃéŕ 1"},
{"text": "śéćőńd téśt áńśẃéŕ 2"}
]
},
"options_selected": [ "options_selected": [
{ {
"criterion": "Test criterion", "criterion": "Test criterion",
...@@ -1181,12 +1193,18 @@ ...@@ -1181,12 +1193,18 @@
"<assessments>", "<assessments>",
"<assessment name=\"student-training\" start=\"2014-02-27T09:46:28\" due=\"2014-03-01T00:00:00\">", "<assessment name=\"student-training\" start=\"2014-02-27T09:46:28\" due=\"2014-03-01T00:00:00\">",
"<example>", "<example>",
"<answer>ẗëṡẗ äṅṡẅëṛ</answer>", "<answer>",
"<part>ẗëṡẗ äṅṡẅëṛ 1</part>",
"<part>ẗëṡẗ äṅṡẅëṛ 2</part>",
"</answer>",
"<select criterion=\"Test criterion\" option=\"No\" />", "<select criterion=\"Test criterion\" option=\"No\" />",
"<select criterion=\"Another test criterion\" option=\"Yes\" />", "<select criterion=\"Another test criterion\" option=\"Yes\" />",
"</example>", "</example>",
"<example>", "<example>",
"<answer>śéćőńd téśt áńśẃéŕ</answer>", "<answer>",
"<part>śéćőńd téśt áńśẃéŕ 1</part>",
"<part>śéćőńd téśt áńśẃéŕ 2</part>",
"</answer>",
"<select criterion=\"Test criterion\" option=\"Yes\" />", "<select criterion=\"Test criterion\" option=\"Yes\" />",
"<select criterion=\"Another test criterion\" option=\"No\" />", "<select criterion=\"Another test criterion\" option=\"No\" />",
"</example>", "</example>",
...@@ -1292,11 +1310,15 @@ ...@@ -1292,11 +1310,15 @@
"<assessments>", "<assessments>",
"<assessment name=\"example-based-assessment\" algorithm_id=\"sample-algorithm-id\">", "<assessment name=\"example-based-assessment\" algorithm_id=\"sample-algorithm-id\">",
"<example>", "<example>",
"<answer>тєѕт αηѕωєя</answer>", "<answer>",
"<part>тєѕт αηѕωєя</part>",
"</answer>",
"<select criterion=\"Test criterion\" option=\"No\" />", "<select criterion=\"Test criterion\" option=\"No\" />",
"</example>", "</example>",
"<example>", "<example>",
"<answer>тєѕт αηѕωєя TWO</answer>", "<answer>",
"<part>тєѕт αηѕωєя TWO</part>",
"</answer>",
"<select criterion=\"Test criterion\" option=\"Yes\" />", "<select criterion=\"Test criterion\" option=\"Yes\" />",
"</example>", "</example>",
"</assessment>", "</assessment>",
......
...@@ -143,13 +143,13 @@ ...@@ -143,13 +143,13 @@
"name": "student-training", "name": "student-training",
"examples": [ "examples": [
{ {
"answer": "Ṫḧïṡ ïṡ äṅ äṅṡẅëṛ", "answer": ["Ṫḧïṡ ïṡ äṅ äṅṡẅëṛ 1", "Ṫḧïṡ ïṡ äṅ äṅṡẅëṛ 2"],
"options_selected": [ "options_selected": [
{ "criterion": "тєѕт ¢яιтєяιση", "option": "Ṅö" } { "criterion": "тєѕт ¢яιтєяιση", "option": "Ṅö" }
] ]
}, },
{ {
"answer": "This is another answer", "answer": ["This is another answer 1", "This is another answer 2"],
"options_selected": [ "options_selected": [
{ "criterion": "тєѕт ¢яιтєяιση", "option": "sǝʎ" } { "criterion": "тєѕт ¢яιтєяιση", "option": "sǝʎ" }
] ]
......
...@@ -11,7 +11,7 @@ import dateutil.parser ...@@ -11,7 +11,7 @@ import dateutil.parser
from django.test import TestCase from django.test import TestCase
import ddt import ddt
from openassessment.xblock.data_conversion import create_prompts_list from openassessment.xblock.data_conversion import create_prompts_list, update_assessments_format
from openassessment.xblock.openassessmentblock import OpenAssessmentBlock from openassessment.xblock.openassessmentblock import OpenAssessmentBlock
from openassessment.xblock.xml import ( from openassessment.xblock.xml import (
serialize_content, parse_from_xml_str, _parse_prompts_xml, parse_rubric_xml, serialize_content, parse_from_xml_str, _parse_prompts_xml, parse_rubric_xml,
...@@ -120,7 +120,9 @@ class TestSerializeContent(TestCase): ...@@ -120,7 +120,9 @@ class TestSerializeContent(TestCase):
self.oa_block.submission_start = data.get('submission_start') self.oa_block.submission_start = data.get('submission_start')
self.oa_block.submission_due = data.get('submission_due') self.oa_block.submission_due = data.get('submission_due')
self.oa_block.rubric_criteria = data.get('criteria', copy.deepcopy(self.BASIC_CRITERIA)) self.oa_block.rubric_criteria = data.get('criteria', copy.deepcopy(self.BASIC_CRITERIA))
self.oa_block.rubric_assessments = data.get('assessments', copy.deepcopy(self.BASIC_ASSESSMENTS)) self.oa_block.rubric_assessments = update_assessments_format(
data.get('assessments', copy.deepcopy(self.BASIC_ASSESSMENTS))
)
self.oa_block.allow_file_upload = data.get('allow_file_upload') self.oa_block.allow_file_upload = data.get('allow_file_upload')
self.oa_block.allow_latex = data.get('allow_latex') self.oa_block.allow_latex = data.get('allow_latex')
self.oa_block.leaderboard_show = data.get('leaderboard_show', 0) self.oa_block.leaderboard_show = data.get('leaderboard_show', 0)
...@@ -183,7 +185,8 @@ class TestSerializeContent(TestCase): ...@@ -183,7 +185,8 @@ class TestSerializeContent(TestCase):
for assessment in data['assessments']: for assessment in data['assessments']:
if 'student-training' == assessment['name'] and assessment['examples']: if 'student-training' == assessment['name'] and assessment['examples']:
xml_str = serialize_examples_to_xml_str(assessment) xml_str = serialize_examples_to_xml_str(assessment)
self.assertIn(assessment['examples'][0]['answer'], xml_str) for part in assessment['examples'][0]['answer']['parts']:
self.assertIn(part['text'], xml_str)
@ddt.file_data('data/serialize.json') @ddt.file_data('data/serialize.json')
def test_serialize_assessments(self, data): def test_serialize_assessments(self, data):
...@@ -228,7 +231,7 @@ class TestSerializeContent(TestCase): ...@@ -228,7 +231,7 @@ class TestSerializeContent(TestCase):
def test_mutated_assessments_dict(self): def test_mutated_assessments_dict(self):
self._configure_xblock({}) self._configure_xblock({})
for assessment_dict in self.BASIC_ASSESSMENTS: for assessment_dict in update_assessments_format(self.BASIC_ASSESSMENTS):
for mutated_dict in self._dict_mutations(assessment_dict): for mutated_dict in self._dict_mutations(assessment_dict):
self.oa_block.rubric_assessments = [mutated_dict] self.oa_block.rubric_assessments = [mutated_dict]
xml = serialize_content(self.oa_block) xml = serialize_content(self.oa_block)
......
...@@ -464,11 +464,21 @@ def parse_examples_xml(examples): ...@@ -464,11 +464,21 @@ def parse_examples_xml(examples):
for example_el in examples: for example_el in examples:
example_dict = dict() example_dict = dict()
# Retrieve the answer from the training example # Retrieve the answers from the training example
answers_list = list()
answer_elements = example_el.findall('answer') answer_elements = example_el.findall('answer')
if len(answer_elements) != 1: if len(answer_elements) != 1:
raise UpdateFromXmlError(u'Each "example" element must contain exactly one "answer" element') raise UpdateFromXmlError(u'Each "example" element must contain exactly one "answer" element')
example_dict['answer'] = _safe_get_text(answer_elements[0])
answer_part_elements = answer_elements[0].findall('part')
if len(answer_part_elements) > 0:
for answer_part_element in answer_part_elements:
answers_list.append(_safe_get_text(answer_part_element))
else:
# Initially example answers had only one part.
answers_list.append(_safe_get_text(answer_elements[0]))
example_dict['answer'] = {"parts": [{"text": text} for text in answers_list]}
# Retrieve the options selected from the training example # Retrieve the options selected from the training example
example_dict['options_selected'] = [] example_dict['options_selected'] = []
...@@ -595,7 +605,9 @@ def serialize_training_examples(examples, assessment_el): ...@@ -595,7 +605,9 @@ def serialize_training_examples(examples, assessment_el):
# Answer provided in the example (default to empty string) # Answer provided in the example (default to empty string)
answer_el = etree.SubElement(example_el, 'answer') answer_el = etree.SubElement(example_el, 'answer')
answer_el.text = unicode(example_dict.get('answer', '')) for part in example_dict.get('answer', {}).get('parts', []):
part_el = etree.SubElement(answer_el, 'part')
part_el.text = unicode(part.get('text', u''))
# Options selected from the rubric # Options selected from the rubric
options_selected = example_dict.get('options_selected', []) options_selected = example_dict.get('options_selected', [])
......
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