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): ...@@ -136,7 +136,6 @@ class LocMapperStore(object):
if cached_value: if cached_value:
return cached_value return cached_value
maps = self.location_map.find(location_id) maps = self.location_map.find(location_id)
maps = list(maps) maps = list(maps)
if len(maps) == 0: if len(maps) == 0:
......
...@@ -258,8 +258,23 @@ class CombinedOpenEndedV1Module(): ...@@ -258,8 +258,23 @@ class CombinedOpenEndedV1Module():
if not task_states: if not task_states:
return (0, 0, state_values[OpenEndedChild.INITIAL], idx) return (0, 0, state_values[OpenEndedChild.INITIAL], idx)
final_child_state = json.loads(task_states[-1]) final_task_xml = self.task_xml[-1]
scores = [attempt.get('score', 0) for attempt in final_child_state.get('child_history', [])] 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: if scores:
best_score = max(scores) best_score = max(scores)
else: else:
......
...@@ -679,7 +679,7 @@ class OpenEndedModule(openendedchild.OpenEndedChild): ...@@ -679,7 +679,7 @@ class OpenEndedModule(openendedchild.OpenEndedChild):
return { return {
'success': success, 'success': success,
'error': error_message, '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): def update_score(self, data, system):
...@@ -738,6 +738,44 @@ class OpenEndedModule(openendedchild.OpenEndedChild): ...@@ -738,6 +738,44 @@ class OpenEndedModule(openendedchild.OpenEndedChild):
html = system.render_template('{0}/open_ended.html'.format(self.TEMPLATE_DIR), context) html = system.render_template('{0}/open_ended.html'.format(self.TEMPLATE_DIR), context)
return html 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(): class OpenEndedDescriptor():
""" """
......
...@@ -8,6 +8,9 @@ from abc import ABCMeta, abstractmethod ...@@ -8,6 +8,9 @@ from abc import ABCMeta, abstractmethod
from django.contrib.auth.models import User, Group from django.contrib.auth.models import User, Group
from xmodule.modulestore import Location 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): class CourseContextRequired(Exception):
...@@ -134,20 +137,45 @@ class CourseRole(GroupBasedRole): ...@@ -134,20 +137,45 @@ class CourseRole(GroupBasedRole):
A named role in a particular course A named role in a particular course
""" """
def __init__(self, role, location, course_context=None): def __init__(self, role, location, course_context=None):
# pylint: disable=no-member """
loc = Location(location) Location may be either a Location, a string, dict, or tuple which Location will accept
legacy_group_name = '{0}_{1}'.format(role, loc.course) in its constructor, or a CourseLocator. Handle all these giving some preference to
the preferred naming.
if loc.category.lower() == 'course': """
course_id = loc.course_id # TODO: figure out how to make the group name generation lazy so it doesn't force the
else: # 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: if course_context is None:
raise CourseContextRequired() raise CourseContextRequired()
course_id = course_context else:
groupnames.append('{0}_{1}'.format(role, course_context))
group_name = '{0}_{1}'.format(role, course_id) # pylint: disable=no-member
if isinstance(location, Location):
super(CourseRole, self).__init__([group_name, legacy_group_name]) 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): class OrgRole(GroupBasedRole):
......
...@@ -23,6 +23,17 @@ ...@@ -23,6 +23,17 @@
<h1>${_("Staff grading")}</h1> <h1>${_("Staff grading")}</h1>
<div class="breadcrumbs"></div> <div class="breadcrumbs"></div>
<div class="error-container"></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> <div class="message-container"></div>
......
...@@ -16,6 +16,17 @@ ...@@ -16,6 +16,17 @@
<section class="container"> <section class="container">
<div class="combined-notifications" data-ajax_url="${ajax_url}"> <div class="combined-notifications" data-ajax_url="${ajax_url}">
<div class="error-container">${error_text}</div> <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> <h1>${_("Open Ended Console")}</h1>
<h2>${_("Instructions")}</h2> <h2>${_("Instructions")}</h2>
......
...@@ -19,6 +19,17 @@ ...@@ -19,6 +19,17 @@
<section class="container"> <section class="container">
<div class="open-ended-problems" data-ajax_url="${ajax_url}"> <div class="open-ended-problems" data-ajax_url="${ajax_url}">
<div class="error-container">${error_text}</div> <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> <h1>${_("Flagged Open Ended Problems")}</h1>
<h2>${_("Instructions")}</h2> <h2>${_("Instructions")}</h2>
......
...@@ -16,6 +16,17 @@ ...@@ -16,6 +16,17 @@
<section class="container"> <section class="container">
<div class="open-ended-problems" data-ajax_url="${ajax_url}"> <div class="open-ended-problems" data-ajax_url="${ajax_url}">
<div class="error-container">${error_text}</div> <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> <h1>${_("Open Ended Problems")}</h1>
<h2>${_("Instructions")}</h2> <h2>${_("Instructions")}</h2>
<p>${_("Here is a list of open ended problems for this course.")}</p> <p>${_("Here is a list of open ended problems for this course.")}</p>
......
...@@ -15,6 +15,17 @@ criteria.{end_li_tag} ...@@ -15,6 +15,17 @@ criteria.{end_li_tag}
<section class="container peer-grading-container"> <section class="container peer-grading-container">
<div class="peer-grading" data-ajax-url="${ajax_url}" data-use-single-location="${use_single_location}"> <div class="peer-grading" data-ajax-url="${ajax_url}" data-use-single-location="${use_single_location}">
<div class="error-container">${error_text}</div> <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"> <div class="peer-grading-tools">
<h1 class="peer-grading-title">${_("Peer Grading")}</h1> <h1 class="peer-grading-title">${_("Peer Grading")}</h1>
<h2 class="peer-grading-instructions">${_("Instructions")}</h2> <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