Commit a70972d6 by Stephen Sanchez

Added back some dearly missed unit tests, and refactored the median score code a little more

parent 696b0cf4
...@@ -246,7 +246,7 @@ def get_assessment_median_scores(submission_id, must_be_graded_by): ...@@ -246,7 +246,7 @@ def get_assessment_median_scores(submission_id, must_be_graded_by):
try: try:
submission = Submission.objects.get(uuid=submission_id) submission = Submission.objects.get(uuid=submission_id)
scores = Assessment.get_assessment_scores_by_criterion(submission, must_be_graded_by) scores = Assessment.get_assessment_scores_by_criterion(submission, must_be_graded_by)
return Assessment.get_median_scores(scores) return Assessment.get_median_score_dict(scores)
except DatabaseError: except DatabaseError:
error_message = ( error_message = (
u"Error getting assessment median scores {}".format(submission_id) u"Error getting assessment median scores {}".format(submission_id)
......
...@@ -209,15 +209,15 @@ class Assessment(models.Model): ...@@ -209,15 +209,15 @@ class Assessment(models.Model):
return u"Assessment {}".format(self.id) return u"Assessment {}".format(self.id)
@classmethod @classmethod
def get_median_scores(cls, scores): def get_median_score_dict(cls, scores_dict):
"""Determine the median score in a dictionary of lists of scores """Determine the median score in a dictionary of lists of scores
For a dictionary of lists, where each list contains a set of scores, For a dictionary of lists, where each list contains a set of scores,
determine the median value in each list. determine the median value in each list.
Args: Args:
scores (dict): A dictionary of lists of int values. These int values scores_dict (dict): A dictionary of lists of int values. These int
are reduced to a single value that represents the median. values are reduced to a single value that represents the median.
Returns: Returns:
(dict): A dictionary with criterion name keys and median score (dict): A dictionary with criterion name keys and median score
...@@ -228,23 +228,49 @@ class Assessment(models.Model): ...@@ -228,23 +228,49 @@ class Assessment(models.Model):
>>> "foo": [1, 2, 3, 4, 5], >>> "foo": [1, 2, 3, 4, 5],
>>> "bar": [6, 7, 8, 9, 10] >>> "bar": [6, 7, 8, 9, 10]
>>> } >>> }
>>> Attribute.get_median_scores(scores) >>> Assessment.get_median_score_dict(scores)
{"foo": 3, "bar": 8} {"foo": 3, "bar": 8}
""" """
median_scores = {} median_scores = {}
for criterion, criterion_scores in scores.iteritems(): for criterion, criterion_scores in scores_dict.iteritems():
total_criterion_scores = len(scores[criterion]) criterion_score = Assessment.get_median_score(criterion_scores)
criterion_scores = sorted(criterion_scores) median_scores[criterion] = criterion_score
return median_scores
@staticmethod
def get_median_score(scores):
"""Determine the median score in a list of scores
Determine the median value in the list.
Args:
scores (list): A list of int values. These int values
are reduced to a single value that represents the median.
Returns:
(int): The median score.
Examples:
>>> scores = 1, 2, 3, 4, 5]
>>> Assessment.get_median_score(scores)
3
"""
total_criterion_scores = len(scores)
sorted_scores = sorted(scores)
median = int(math.ceil(total_criterion_scores / float(2))) median = int(math.ceil(total_criterion_scores / float(2)))
if total_criterion_scores == 0: if total_criterion_scores == 0:
criterion_score = 0 median_score = 0
elif total_criterion_scores % 2: elif total_criterion_scores % 2:
criterion_score = criterion_scores[median-1] median_score = sorted_scores[median-1]
else: else:
criterion_score = int(math.ceil(sum(criterion_scores[median-1:median+1])/float(2))) median_score = int(
median_scores[criterion] = criterion_score math.ceil(
return median_scores sum(sorted_scores[median-1:median+1])/float(2)
)
)
return median_score
@classmethod @classmethod
def get_assessment_scores_by_criterion(cls, submission, must_be_graded_by): def get_assessment_scores_by_criterion(cls, submission, must_be_graded_by):
......
...@@ -278,6 +278,15 @@ class TestApi(TestCase): ...@@ -278,6 +278,15 @@ class TestApi(TestCase):
mock_filter.side_effect = DatabaseError("Bad things happened") mock_filter.side_effect = DatabaseError("Bad things happened")
peer_api.get_assessments(submission["uuid"]) peer_api.get_assessments(submission["uuid"])
def test_choose_score(self):
self.assertEqual(0, Assessment.get_median_score([]))
self.assertEqual(5, Assessment.get_median_score([5]))
# average of 5, 6, rounded down.
self.assertEqual(6, Assessment.get_median_score([5, 6]))
self.assertEqual(14, Assessment.get_median_score([5, 6, 12, 16, 22, 53]))
self.assertEqual(14, Assessment.get_median_score([6, 5, 12, 53, 16, 22]))
self.assertEqual(16, Assessment.get_median_score([5, 6, 12, 16, 22, 53, 102]))
self.assertEqual(16, Assessment.get_median_score([16, 6, 12, 102, 22, 53, 5]))
@staticmethod @staticmethod
def _create_student_and_submission(student, answer, date=None): def _create_student_and_submission(student, answer, date=None):
......
{% extends "oa_response.html" %} {% extends "openassessmentblock/oa_response.html" %}
{% block list_item %} {% block list_item %}
<li id="openassessment__response" class="openassessment__steps__step step--response is--unavailable ui-toggle-visibility"> <li id="openassessment__response" class="openassessment__steps__step step--response is--unavailable ui-toggle-visibility">
{% endblock %} {% endblock %}
......
{% extends "oa_response.html" %} {% extends "openassessmentblock/oa_response.html" %}
{% block list_item %} {% block list_item %}
<li id="openassessment__response" class="openassessment__steps__step step--response is--graded is--collapsed ui-toggle-visibility"> <li id="openassessment__response" class="openassessment__steps__step step--response is--graded is--collapsed ui-toggle-visibility">
{% endblock %} {% endblock %}
......
{% extends "oa_response.html" %} {% extends "openassessmentblock/oa_response.html" %}
{% block list_item %} {% block list_item %}
<li id="openassessment__response" class="openassessment__steps__step step--response is--submitted is--unavailable ui-toggle-visibility"> <li id="openassessment__response" class="openassessment__steps__step step--response is--submitted is--unavailable ui-toggle-visibility">
{% endblock %} {% endblock %}
......
...@@ -165,7 +165,7 @@ class SubmissionMixin(object): ...@@ -165,7 +165,7 @@ class SubmissionMixin(object):
path = 'openassessmentblock/oa_response_graded.html' path = 'openassessmentblock/oa_response_graded.html'
elif student_submission: elif student_submission:
path = 'oa_response_submitted.html' path = 'openassessmentblock/oa_response_submitted.html'
elif due < datetime.datetime.now() and not student_submission: elif due < datetime.datetime.now() and not student_submission:
path = 'openassessmentblock/oa_response_closed.html' path = 'openassessmentblock/oa_response_closed.html'
......
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