Commit 8d6c774d by Dmitry Viskov Committed by Tyler Hallada

Support multi-leaf tagging (#660)

parent 250a0633
......@@ -463,10 +463,11 @@ class TagsDistributionPresenter(CourseAPIPresenterMixin, CoursePresenter):
self.available_tags = {}
for item in tags_distribution_data.values():
for tag_key, tag_value in item['tags'].iteritems():
for tag_key, tag_values in item['tags'].iteritems():
if tag_key not in self.available_tags:
self.available_tags[tag_key] = set()
self.available_tags[tag_key].add(tag_value)
for tag_value in tag_values:
self.available_tags[tag_key].add(tag_value)
return self.available_tags
def get_tags_content_nav(self, key, selected=None):
......@@ -508,7 +509,7 @@ class TagsDistributionPresenter(CourseAPIPresenterMixin, CoursePresenter):
"""
updated_structure[node_id] = origin_structure[node_id]
updated_structure[node_id]['parent'] = parent_id if parent_id else None
for child_id in origin_structure[node_id]["children"]:
for child_id in origin_structure[node_id].get("children", []):
_update_node(updated_structure, origin_structure, child_id, origin_structure[node_id]['id'])
updated_structure = OrderedDict()
......@@ -525,22 +526,23 @@ class TagsDistributionPresenter(CourseAPIPresenterMixin, CoursePresenter):
for item in tags_distribution_data.values():
if key in item['tags']:
tag_value = item['tags'][key]
if tag_value not in result:
index += 1
result[tag_value] = {
'id': tag_value,
'index': index,
'name': tag_value,
'num_modules': 0,
'total_submissions': 0,
'correct_submissions': 0,
'incorrect_submissions': 0
}
result[tag_value]['num_modules'] += 1
result[tag_value]['total_submissions'] += item['total_submissions']
result[tag_value]['correct_submissions'] += item['correct_submissions']
result[tag_value]['incorrect_submissions'] += item['incorrect_submissions']
tag_values = item['tags'][key]
for tag_value in tag_values:
if tag_value not in result:
index += 1
result[tag_value] = {
'id': tag_value,
'index': index,
'name': tag_value,
'num_modules': 0,
'total_submissions': 0,
'correct_submissions': 0,
'incorrect_submissions': 0
}
result[tag_value]['num_modules'] += 1
result[tag_value]['total_submissions'] += item['total_submissions']
result[tag_value]['correct_submissions'] += item['correct_submissions']
result[tag_value]['incorrect_submissions'] += item['incorrect_submissions']
for tag_val, item in result.iteritems():
item.update({
......@@ -562,30 +564,40 @@ class TagsDistributionPresenter(CourseAPIPresenterMixin, CoursePresenter):
available_tags = self.get_available_tags()
intermediate = OrderedDict()
def _get_tags_info(av_tags, tags):
"""
Helper function to return information about all tags connected with the current item.
"""
data = {}
for av_tag_key in av_tags:
if av_tag_key in tags and tags[av_tag_key]:
data[av_tag_key] = u', '.join(tags[av_tag_key])
else:
data[av_tag_key] = None
return data
for item in tags_distribution_data.values():
if tag_key in item['tags'] and tag_value == slugify(item['tags'][tag_key]):
val = {
'id': item['id'],
'name': item['id'],
'total_submissions': item['total_submissions'],
'correct_submissions': item['correct_submissions'],
'incorrect_submissions': item['incorrect_submissions'],
'correct_percent': utils.math.calculate_percent(item['correct_submissions'],
item['total_submissions']),
'incorrect_percent': utils.math.calculate_percent(item['incorrect_submissions'],
item['total_submissions']),
'url': reverse('courses:performance:learning_outcomes_answers_distribution',
kwargs={'course_id': self.course_id,
'tag_value': tag_value,
'problem_id': item['id']})
}
if available_tags:
for av_tag_key in available_tags:
if av_tag_key in item['tags']:
val[av_tag_key] = item['tags'][av_tag_key]
else:
val[av_tag_key] = None
intermediate[item['id']] = val
if tag_key in item['tags']:
for item_tag_val in item['tags'][tag_key]:
if tag_value == slugify(item_tag_val):
val = {
'id': item['id'],
'name': item['id'],
'total_submissions': item['total_submissions'],
'correct_submissions': item['correct_submissions'],
'incorrect_submissions': item['incorrect_submissions'],
'correct_percent': utils.math.calculate_percent(item['correct_submissions'],
item['total_submissions']),
'incorrect_percent': utils.math.calculate_percent(item['incorrect_submissions'],
item['total_submissions']),
'url': reverse('courses:performance:learning_outcomes_answers_distribution',
kwargs={'course_id': self.course_id,
'tag_value': tag_value,
'problem_id': item['id']})
}
if available_tags:
val.update(_get_tags_info(available_tags, item['tags']))
intermediate[item['id']] = val
result = []
index = 0
......
......@@ -393,10 +393,11 @@ class TagsDistributionDataFactory(CourseStructureFactory):
def get_expected_available_tags(self):
tags = {}
for item in self.tags_data_per_homework_assigment:
for key, val in item['tags'].iteritems():
if key not in tags:
tags[key] = set()
tags[key].add(val)
for key, vals in item['tags'].iteritems():
for val in vals:
if key not in tags:
tags[key] = set()
tags[key].add(val)
return tags
def get_expected_learning_outcome_tags_content_nav(self, key):
......@@ -415,25 +416,25 @@ class TagsDistributionDataFactory(CourseStructureFactory):
for val in self.tags_data_per_homework_assigment:
if tag_key in val['tags']:
tag_value = val['tags'][tag_key]
if tag_value not in expected:
index += 1
expected[tag_value] = {
"id": tag_value,
"index": index,
"name": tag_value,
"total_submissions": 0,
"correct_submissions": 0,
"incorrect_submissions": 0,
"num_modules": 0
}
incorrect_submissions = val["total_submissions"] - val["correct_submissions"]
expected[tag_value]["total_submissions"] += val["total_submissions"] * k
expected[tag_value]["correct_submissions"] += val["correct_submissions"] * k
expected[tag_value]["incorrect_submissions"] += incorrect_submissions * k
expected[tag_value]["num_modules"] += k
for tag_value in val['tags'][tag_key]:
if tag_value not in expected:
index += 1
expected[tag_value] = {
"id": tag_value,
"index": index,
"name": tag_value,
"total_submissions": 0,
"correct_submissions": 0,
"incorrect_submissions": 0,
"num_modules": 0
}
incorrect_submissions = val["total_submissions"] - val["correct_submissions"]
expected[tag_value]["total_submissions"] += val["total_submissions"] * k
expected[tag_value]["correct_submissions"] += val["correct_submissions"] * k
expected[tag_value]["incorrect_submissions"] += incorrect_submissions * k
expected[tag_value]["num_modules"] += k
url_template = '/courses/{}/performance/learning_outcomes/{}/'
......@@ -458,33 +459,43 @@ class TagsDistributionDataFactory(CourseStructureFactory):
url_template = '/courses/{}/performance/learning_outcomes/{}/problems/{}/'
def _get_tags_info(av_tags, tags):
"""
Helper function to return information about all tags connected with the current item.
"""
data = {}
if av_tags:
for av_tag_key in av_tags:
if av_tag_key in tags and tags[av_tag_key]:
data[av_tag_key] = u', '.join(tags[av_tag_key])
else:
data[av_tag_key] = None
return data
for i in xrange(1, self._count_of_homework_assignments + 1):
num = 0
for val in self.tags_data_per_homework_assigment:
num += 1
if tag_key in val['tags'] and val['tags'][tag_key] == tag_value:
display_name = 'Homework %d Problem %d' % (i, num)
incorrect_submissions = val["total_submissions"] - val["correct_submissions"]
new_item_id = 'i4x://edX/DemoX/problem/%s' % hashlib.md5(display_name).hexdigest()
index += 1
new_item = {
'id': new_item_id,
'index': index,
'name': ', '.join(['Demo Course', 'Homework %d' % i, display_name]),
'total_submissions': val['total_submissions'],
'correct_submissions': val['correct_submissions'],
'incorrect_submissions': incorrect_submissions,
'correct_percent': utils.math.calculate_percent(val['correct_submissions'],
val['total_submissions']),
'incorrect_percent': utils.math.calculate_percent(incorrect_submissions,
val['total_submissions']),
'url': url_template.format(self.course_id, slugify(tag_value), new_item_id)
}
if available_tags:
for av_tag_key in available_tags:
if av_tag_key in val['tags']:
new_item[av_tag_key] = val['tags'][av_tag_key]
else:
new_item[av_tag_key] = None
expected.append(new_item)
if tag_key in val['tags']:
for val_tag_value in val['tags'][tag_key]:
if val_tag_value == tag_value:
display_name = 'Homework %d Problem %d' % (i, num)
incorrect_submissions = val["total_submissions"] - val["correct_submissions"]
new_item_id = 'i4x://edX/DemoX/problem/%s' % hashlib.md5(display_name).hexdigest()
index += 1
new_item = {
'id': new_item_id,
'index': index,
'name': ', '.join(['Demo Course', 'Homework %d' % i, display_name]),
'total_submissions': val['total_submissions'],
'correct_submissions': val['correct_submissions'],
'incorrect_submissions': incorrect_submissions,
'correct_percent': utils.math.calculate_percent(val['correct_submissions'],
val['total_submissions']),
'incorrect_percent': utils.math.calculate_percent(incorrect_submissions,
val['total_submissions']),
'url': url_template.format(self.course_id, slugify(tag_value), new_item_id)
}
new_item.update(_get_tags_info(available_tags, val['tags']))
expected.append(new_item)
return expected
......@@ -545,9 +545,9 @@ class CoursePerformanceLearningOutcomesViewTestMixin(CoursePerformanceViewTestMi
class CoursePerformanceLearningOutcomesContentViewTests(CoursePerformanceLearningOutcomesViewTestMixin, TestCase):
viewname = 'courses:performance:learning_outcomes'
tags_factory_init_data = [{"total_submissions": 21, "correct_submissions": 5,
"tags": {"difficulty": "Hard", "learning_outcome": "Learned a few things"}},
"tags": {"difficulty": ["Hard"], "learning_outcome": ["Learned a few things"]}},
{"total_submissions": 11, "correct_submissions": 10,
"tags": {"difficulty": "Easy", "learning_outcome": "Learned nothing"}}]
"tags": {"difficulty": ["Easy"], "learning_outcome": ["Learned nothing"]}}]
@httpretty.activate
def test_invalid_course(self):
......@@ -568,17 +568,17 @@ class CoursePerformanceLearningOutcomesContentViewTests(CoursePerformanceLearnin
class CoursePerformanceLearningOutcomesSectionViewTests(CoursePerformanceLearningOutcomesViewTestMixin, TestCase):
viewname = 'courses:performance:learning_outcomes_section'
tags_factory_init_data = [{"total_submissions": 41, "correct_submissions": 10,
"tags": {"difficulty": "Hard", "learning_outcome": "Learned a few things"}},
"tags": {"difficulty": ["Hard"], "learning_outcome": ["Learned a few things"]}},
{"total_submissions": 25, "correct_submissions": 25,
"tags": {"difficulty": "Easy", "learning_outcome": "Learned nothing"}},
"tags": {"difficulty": ["Easy"], "learning_outcome": ["Learned nothing"]}},
{"total_submissions": 17, "correct_submissions": 16,
"tags": {"learning_outcome": "Learned everything"}},
"tags": {"learning_outcome": ["Learned everything"]}},
{"total_submissions": 10, "correct_submissions": 5,
"tags": {"difficulty": "Hard"}},
"tags": {"difficulty": ["Hard"]}},
{"total_submissions": 35, "correct_submissions": 31,
"tags": {"learning_outcome": "Learned nothing"}},
"tags": {"learning_outcome": ["Learned nothing"]}},
{"total_submissions": 105, "correct_submissions": 10,
"tags": {"difficulty": "Hard", "learning_outcome": "Learned everything"}}]
"tags": {"difficulty": ["Hard"], "learning_outcome": ["Learned everything"]}}]
def path(self, **kwargs):
kwargs.update({
......@@ -612,17 +612,17 @@ class CoursePerformanceLearningOutcomesAnswersDistributionViewTests(
viewname = 'courses:performance:learning_outcomes_answers_distribution'
tags_factory_init_data = [{"total_submissions": 41, "correct_submissions": 10,
"tags": {"difficulty": "Hard", "learning_outcome": "Learned a few things"}},
"tags": {"difficulty": ["Hard"], "learning_outcome": ["Learned a few things"]}},
{"total_submissions": 25, "correct_submissions": 25,
"tags": {"difficulty": "Easy", "learning_outcome": "Learned nothing"}},
"tags": {"difficulty": ["Easy"], "learning_outcome": ["Learned nothing"]}},
{"total_submissions": 17, "correct_submissions": 16,
"tags": {"learning_outcome": "Learned everything"}},
"tags": {"learning_outcome": ["Learned everything"]}},
{"total_submissions": 10, "correct_submissions": 5,
"tags": {"difficulty": "Hard"}},
"tags": {"difficulty": ["Hard"]}},
{"total_submissions": 35, "correct_submissions": 31,
"tags": {"learning_outcome": "Learned nothing"}},
"tags": {"learning_outcome": ["Learned nothing"]}},
{"total_submissions": 105, "correct_submissions": 10,
"tags": {"difficulty": "Hard", "learning_outcome": "Learned everything"}}]
"tags": {"difficulty": ["Hard"], "learning_outcome": ["Learned everything"]}}]
def path(self, **kwargs):
kwargs.update({
......
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