Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-ora2
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-ora2
Commits
696b0cf4
Commit
696b0cf4
authored
Feb 26, 2014
by
Stephen Sanchez
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor the methods for creating median scores
parent
468cf9db
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
77 additions
and
33 deletions
+77
-33
apps/openassessment/peer/api.py
+3
-33
apps/openassessment/peer/models.py
+74
-0
No files found.
apps/openassessment/peer/api.py
View file @
696b0cf4
...
...
@@ -6,11 +6,10 @@ the workflow for a given submission.
"""
import
copy
import
logging
import
math
from
django.db
import
DatabaseError
from
openassessment.peer.models
import
Assessment
,
AssessmentPart
from
openassessment.peer.models
import
Assessment
from
openassessment.peer.serializers
import
(
AssessmentSerializer
,
rubric_from_dict
,
get_assessment_review
)
from
submissions
import
api
as
submission_api
...
...
@@ -246,9 +245,8 @@ def get_assessment_median_scores(submission_id, must_be_graded_by):
# found in an assessment.
try
:
submission
=
Submission
.
objects
.
get
(
uuid
=
submission_id
)
assessments
=
Assessment
.
objects
.
filter
(
submission
=
submission
)
.
order_by
(
"scored_at"
)[:
must_be_graded_by
]
scores
=
Assessment
.
get_assessment_scores_by_criterion
(
submission
,
must_be_graded_by
)
return
Assessment
.
get_median_scores
(
scores
)
except
DatabaseError
:
error_message
=
(
u"Error getting assessment median scores {}"
.
format
(
submission_id
)
...
...
@@ -256,34 +254,6 @@ def get_assessment_median_scores(submission_id, must_be_graded_by):
logger
.
exception
(
error_message
)
raise
PeerAssessmentInternalError
(
error_message
)
# Iterate over every part of every assessment. Each part is associated with
# a criterion name, which becomes a key in the score dictionary, with a list
# of scores. These collected lists of scores are used to find a median value
# per criterion.
scores
=
{}
median_scores
=
{}
for
assessment
in
assessments
:
for
part
in
assessment
.
parts
.
all
():
criterion_name
=
part
.
option
.
criterion
.
name
if
criterion_name
not
in
scores
:
scores
[
criterion_name
]
=
[]
scores
[
criterion_name
]
.
append
(
part
.
option
.
points
)
# Once we have lists of values for each criterion, sort each value and set
# to the median value for each.
for
criterion
,
criterion_scores
in
scores
.
iteritems
():
total_criterion_scores
=
len
(
scores
[
criterion
])
criterion_scores
=
sorted
(
criterion_scores
)
median
=
int
(
math
.
ceil
(
total_criterion_scores
/
float
(
2
)))
if
total_criterion_scores
==
0
:
criterion_score
=
0
elif
total_criterion_scores
%
2
:
criterion_score
=
criterion_scores
[
median
-
1
]
else
:
criterion_score
=
int
(
math
.
ceil
(
sum
(
criterion_scores
[
median
-
1
:
median
+
1
])
/
float
(
2
)))
median_scores
[
criterion
]
=
criterion_score
return
median_scores
def
has_finished_required_evaluating
(
student_id
,
required_assessments
):
"""Check if a student still needs to evaluate more submissions
...
...
apps/openassessment/peer/models.py
View file @
696b0cf4
...
...
@@ -4,12 +4,14 @@ These models have to capture not only the state of assessments made for certain
submissions, but also the state of the rubrics at the time those assessments
were made.
"""
from
collections
import
defaultdict
from
copy
import
deepcopy
from
hashlib
import
sha1
import
json
from
django.db
import
models
from
django.utils.timezone
import
now
import
math
from
submissions.models
import
Submission
...
...
@@ -206,6 +208,78 @@ class Assessment(models.Model):
def
__unicode__
(
self
):
return
u"Assessment {}"
.
format
(
self
.
id
)
@classmethod
def
get_median_scores
(
cls
,
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,
determine the median value in each list.
Args:
scores (dict): A dictionary of lists of int values. These int values
are reduced to a single value that represents the median.
Returns:
(dict): A dictionary with criterion name keys and median score
values.
Examples:
>>> scores = {
>>> "foo": [1, 2, 3, 4, 5],
>>> "bar": [6, 7, 8, 9, 10]
>>> }
>>> Attribute.get_median_scores(scores)
{"foo": 3, "bar": 8}
"""
median_scores
=
{}
for
criterion
,
criterion_scores
in
scores
.
iteritems
():
total_criterion_scores
=
len
(
scores
[
criterion
])
criterion_scores
=
sorted
(
criterion_scores
)
median
=
int
(
math
.
ceil
(
total_criterion_scores
/
float
(
2
)))
if
total_criterion_scores
==
0
:
criterion_score
=
0
elif
total_criterion_scores
%
2
:
criterion_score
=
criterion_scores
[
median
-
1
]
else
:
criterion_score
=
int
(
math
.
ceil
(
sum
(
criterion_scores
[
median
-
1
:
median
+
1
])
/
float
(
2
)))
median_scores
[
criterion
]
=
criterion_score
return
median_scores
@classmethod
def
get_assessment_scores_by_criterion
(
cls
,
submission
,
must_be_graded_by
):
"""Create a dictionary of lists for scores associated with criterion
Create a key value in a dict with a list of values, for every criterion
found in an assessment.
Iterate over every part of every assessment. Each part is associated with
a criterion name, which becomes a key in the score dictionary, with a list
of scores.
Args:
submission (Submission): Obtain assessments associated with this
submission
must_be_graded_by (int): The number of assessments to include in
this score analysis.
Examples:
>>> Attribute.get_assessment_scores_by_criterion(submission, 3)
{
"foo": [1, 2, 3],
"bar": [6, 7, 8]
}
"""
assessments
=
cls
.
objects
.
filter
(
submission
=
submission
)
.
order_by
(
"scored_at"
)[:
must_be_graded_by
]
scores
=
defaultdict
(
list
)
for
assessment
in
assessments
:
for
part
in
assessment
.
parts
.
all
():
criterion_name
=
part
.
option
.
criterion
.
name
scores
[
criterion_name
]
.
append
(
part
.
option
.
points
)
return
scores
class
AssessmentPart
(
models
.
Model
):
"""Part of an Assessment corresponding to a particular Criterion.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment