Commit 4de51c8f by e0d

Merge pull request #1960 from edx/e0d/release-merge

E0d/release merge
parents 319091a2 d52b959f
......@@ -136,7 +136,6 @@ class LocMapperStore(object):
if cached_value:
return cached_value
maps = self.location_map.find(location_id)
maps = list(maps)
if len(maps) == 0:
......
......@@ -258,8 +258,23 @@ class CombinedOpenEndedV1Module():
if not task_states:
return (0, 0, state_values[OpenEndedChild.INITIAL], idx)
final_child_state = json.loads(task_states[-1])
scores = [attempt.get('score', 0) for attempt in final_child_state.get('child_history', [])]
final_task_xml = self.task_xml[-1]
final_child_state_json = task_states[-1]
final_child_state = json.loads(final_child_state_json)
tag_name = self.get_tag_name(final_task_xml)
children = self.child_modules()
task_descriptor = children['descriptors'][tag_name](self.system)
task_parsed_xml = task_descriptor.definition_from_xml(etree.fromstring(final_task_xml), self.system)
task = children['modules'][tag_name](
self.system,
self.location,
task_parsed_xml,
task_descriptor,
self.static_data,
instance_state=final_child_state_json,
)
scores = task.all_scores()
if scores:
best_score = max(scores)
else:
......
......@@ -679,7 +679,7 @@ class OpenEndedModule(openendedchild.OpenEndedChild):
return {
'success': success,
'error': error_message,
'student_response': data['student_answer'].replace("\n","<br/>")
'student_response': data['student_answer'].replace("\n", "<br/>")
}
def update_score(self, data, system):
......@@ -738,6 +738,44 @@ class OpenEndedModule(openendedchild.OpenEndedChild):
html = system.render_template('{0}/open_ended.html'.format(self.TEMPLATE_DIR), context)
return html
def latest_score(self):
"""None if not available"""
if not self.child_history:
return None
return self.score_for_attempt(-1)
def all_scores(self):
"""None if not available"""
if not self.child_history:
return None
return [self.score_for_attempt(index) for index in xrange(0, len(self.child_history))]
def score_for_attempt(self, index):
"""
Return sum of rubric scores for ML grading otherwise return attempt["score"].
"""
attempt = self.child_history[index]
score = attempt.get('score')
post_assessment_data = self._parse_score_msg(attempt.get('post_assessment'), self.system)
grader_types = post_assessment_data.get('grader_types')
# According to _parse_score_msg in ML grading there should be only one grader type.
if len(grader_types) == 1 and grader_types[0] == 'ML':
rubric_scores = post_assessment_data.get("rubric_scores")
# Similarly there should be only one list of rubric scores.
if len(rubric_scores) == 1:
rubric_scores_sum = sum(rubric_scores[0])
log.debug("""Score normalized for location={loc}, old_score={old_score},
new_score={new_score}, rubric_score={rubric_score}""".format(
loc=self.location_string,
old_score=score,
new_score=rubric_scores_sum,
rubric_score=rubric_scores
))
return rubric_scores_sum
return score
class OpenEndedDescriptor():
"""
......
......@@ -8,6 +8,9 @@ from abc import ABCMeta, abstractmethod
from django.contrib.auth.models import User, Group
from xmodule.modulestore import Location
from xmodule.modulestore.exceptions import InvalidLocationError, ItemNotFoundError
from xmodule.modulestore.django import loc_mapper
from xmodule.modulestore.locator import CourseLocator
class CourseContextRequired(Exception):
......@@ -134,20 +137,45 @@ class CourseRole(GroupBasedRole):
A named role in a particular course
"""
def __init__(self, role, location, course_context=None):
# pylint: disable=no-member
loc = Location(location)
legacy_group_name = '{0}_{1}'.format(role, loc.course)
if loc.category.lower() == 'course':
course_id = loc.course_id
else:
"""
Location may be either a Location, a string, dict, or tuple which Location will accept
in its constructor, or a CourseLocator. Handle all these giving some preference to
the preferred naming.
"""
# TODO: figure out how to make the group name generation lazy so it doesn't force the
# loc mapping?
if not hasattr(location, 'course_id'):
location = Location(location)
# direct copy from auth.authz.get_all_course_role_groupnames will refactor to one impl asap
groupnames = []
try:
groupnames.append('{0}_{1}'.format(role, location.course_id))
except InvalidLocationError: # will occur on old locations where location is not of category course
if course_context is None:
raise CourseContextRequired()
course_id = course_context
else:
groupnames.append('{0}_{1}'.format(role, course_context))
group_name = '{0}_{1}'.format(role, course_id)
super(CourseRole, self).__init__([group_name, legacy_group_name])
# pylint: disable=no-member
if isinstance(location, Location):
try:
locator = loc_mapper().translate_location(location.course_id, location, False, False)
groupnames.append('{0}_{1}'.format(role, locator.course_id))
except (InvalidLocationError, ItemNotFoundError):
# if it's never been mapped, the auth won't be via the Locator syntax
pass
# least preferred legacy role_course format
groupnames.append('{0}_{1}'.format(role, location.course))
elif isinstance(location, CourseLocator):
# handle old Location syntax
old_location = loc_mapper().translate_locator_to_location(location, get_course=True)
if old_location:
# the slashified version of the course_id (myu/mycourse/myrun)
groupnames.append('{0}_{1}'.format(role, old_location.course_id))
# add the least desirable but sometimes occurring format.
groupnames.append('{0}_{1}'.format(role, old_location.course))
super(CourseRole, self).__init__(groupnames)
class OrgRole(GroupBasedRole):
......
......@@ -23,6 +23,17 @@
<h1>${_("Staff grading")}</h1>
<div class="breadcrumbs"></div>
<div class="error-container"></div>
<br>
<div style="color:red;">
<b>
The issue we had between Dec 3 and Dec 5 with the visibility
of student responses has now been resolved. All responses
should now be visible. Thank you for your patience!
--the edX team
</b>
</div>
<br>
<hr>
<div class="message-container"></div>
......
......@@ -16,6 +16,17 @@
<section class="container">
<div class="combined-notifications" data-ajax_url="${ajax_url}">
<div class="error-container">${error_text}</div>
<br>
<div style="color:red;">
<b>
The issue we had between Dec 3 and Dec 5 with the visibility
of student responses has now been resolved. All responses
should now be visible. Thank you for your patience!
--the edX team
</b>
</div>
<br>
<hr>
<h1>${_("Open Ended Console")}</h1>
<h2>${_("Instructions")}</h2>
......
......@@ -19,6 +19,17 @@
<section class="container">
<div class="open-ended-problems" data-ajax_url="${ajax_url}">
<div class="error-container">${error_text}</div>
<br>
<div style="color:red;">
<b>
The issue we had between Dec 3 and Dec 5 with the visibility
of student responses has now been resolved. All responses
should now be visible. Thank you for your patience!
--the edX team
</b>
</div>
<br>
<hr>
<h1>${_("Flagged Open Ended Problems")}</h1>
<h2>${_("Instructions")}</h2>
......
......@@ -16,6 +16,17 @@
<section class="container">
<div class="open-ended-problems" data-ajax_url="${ajax_url}">
<div class="error-container">${error_text}</div>
<br>
<div style="color:red;">
<b>
The issue we had between Dec 3 and Dec 5 with the visibility
of student responses has now been resolved. All responses
should now be visible. Thank you for your patience!
--the edX team
</b>
</div>
<br>
<hr>
<h1>${_("Open Ended Problems")}</h1>
<h2>${_("Instructions")}</h2>
<p>${_("Here is a list of open ended problems for this course.")}</p>
......
......@@ -15,6 +15,17 @@ criteria.{end_li_tag}
<section class="container peer-grading-container">
<div class="peer-grading" data-ajax-url="${ajax_url}" data-use-single-location="${use_single_location}">
<div class="error-container">${error_text}</div>
<br>
<div style="color:red;">
<b>
The issue we had between Dec 3 and Dec 5 with the visibility
of student responses has now been resolved. All responses
should now be visible. Thank you for your patience!
--the edX team
</b>
</div>
<br>
<hr>
<div class="peer-grading-tools">
<h1 class="peer-grading-title">${_("Peer Grading")}</h1>
<h2 class="peer-grading-instructions">${_("Instructions")}</h2>
......
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