Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
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-platform
Commits
189f53bc
Commit
189f53bc
authored
May 19, 2014
by
Sarina Canelake
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix grades management commands
parent
1e27f177
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
88 additions
and
52 deletions
+88
-52
common/djangoapps/student/management/commands/get_grades.py
+23
-7
lms/djangoapps/instructor/management/commands/compute_grades.py
+19
-11
lms/djangoapps/instructor/management/commands/dump_grades.py
+21
-12
lms/djangoapps/instructor/offline_gradecalc.py
+13
-10
lms/djangoapps/instructor/views/legacy.py
+12
-12
No files found.
common/djangoapps/student/management/commands/get_grades.py
View file @
189f53bc
...
...
@@ -3,6 +3,9 @@ from certificates.models import GeneratedCertificate
from
django.test.client
import
RequestFactory
from
django.core.management.base
import
BaseCommand
,
CommandError
import
os
from
opaque_keys
import
InvalidKeyError
from
xmodule.modulestore.keys
import
CourseKey
from
xmodule.modulestore.locations
import
SlashSeparatedCourseKey
from
django.contrib.auth.models
import
User
from
optparse
import
make_option
import
datetime
...
...
@@ -62,24 +65,37 @@ class Command(BaseCommand):
options
[
'output'
]))
STATUS_INTERVAL
=
100
course_id
=
options
[
'course'
]
print
"Fetching enrolled students for {0}"
.
format
(
course_id
)
# parse out the course into a coursekey
if
options
[
'course'
]:
try
:
course_key
=
CourseKey
.
from_string
(
options
[
'course'
])
# if it's not a new-style course key, parse it from an old-style
# course key
except
InvalidKeyError
:
course_key
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
options
[
'course'
])
print
"Fetching enrolled students for {0}"
.
format
(
course_key
)
enrolled_students
=
User
.
objects
.
filter
(
courseenrollment__course_id
=
course_id
)
courseenrollment__course_id
=
course_key
)
factory
=
RequestMock
()
request
=
factory
.
get
(
'/'
)
total
=
enrolled_students
.
count
()
print
"Total enrolled: {0}"
.
format
(
total
)
course
=
courses
.
get_course_by_id
(
course_
id
)
course
=
courses
.
get_course_by_id
(
course_
key
)
total
=
enrolled_students
.
count
()
start
=
datetime
.
datetime
.
now
()
rows
=
[]
header
=
None
print
"Fetching certificate data"
cert_grades
=
{
cert
.
user
.
username
:
cert
.
grade
for
cert
in
list
(
GeneratedCertificate
.
objects
.
filter
(
course_id
=
course_id
)
.
prefetch_related
(
'user'
))}
cert_grades
=
{
cert
.
user
.
username
:
cert
.
grade
for
cert
in
list
(
GeneratedCertificate
.
objects
.
filter
(
course_id
=
course_key
)
.
prefetch_related
(
'user'
)
)
}
print
"Grading students"
for
count
,
student
in
enumerate
(
enrolled_students
):
count
+=
1
...
...
lms/djangoapps/instructor/management/commands/compute_grades.py
View file @
189f53bc
...
...
@@ -6,6 +6,9 @@
from
instructor.offline_gradecalc
import
offline_grade_calculation
from
courseware.courses
import
get_course_by_id
from
xmodule.modulestore.django
import
modulestore
from
opaque_keys
import
InvalidKeyError
from
xmodule.modulestore.keys
import
CourseKey
from
xmodule.modulestore.locations
import
SlashSeparatedCourseKey
from
django.core.management.base
import
BaseCommand
...
...
@@ -25,19 +28,24 @@ class Command(BaseCommand):
else
:
print
self
.
help
return
course_key
=
None
# parse out the course id into a coursekey
try
:
course_key
=
CourseKey
.
from_string
(
course_id
)
# if it's not a new-style course key, parse it from an old-style
# course key
except
InvalidKeyError
:
course_key
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id
)
try
:
course
=
get_course_by_id
(
course_
id
)
course
=
get_course_by_id
(
course_
key
)
except
Exception
as
err
:
if
course_id
in
modulestore
()
.
courses
:
course
=
modulestore
()
.
courses
[
course_id
]
else
:
print
"-----------------------------------------------------------------------------"
print
"Sorry, cannot find course
%
s"
%
course_id
print
"Please provide a course ID or course data directory name, eg content-mit-801rq"
return
print
"-----------------------------------------------------------------------------"
print
"Sorry, cannot find course with id {}"
.
format
(
course_id
)
print
"Got exception {}"
.
format
(
err
)
print
"Please provide a course ID or course data directory name, eg content-mit-801rq"
return
print
"-----------------------------------------------------------------------------"
print
"Computing grades for
%
s"
%
(
course
.
id
)
print
"Computing grades for
{}"
.
format
(
course_
id
)
offline_grade_calculation
(
course
.
id
)
offline_grade_calculation
(
course
_key
)
lms/djangoapps/instructor/management/commands/dump_grades.py
View file @
189f53bc
...
...
@@ -7,6 +7,9 @@ import csv
from
instructor.views.legacy
import
get_student_grade_summary_data
from
courseware.courses
import
get_course_by_id
from
opaque_keys
import
InvalidKeyError
from
xmodule.modulestore.keys
import
CourseKey
from
xmodule.modulestore.locations
import
SlashSeparatedCourseKey
from
xmodule.modulestore.django
import
modulestore
from
django.core.management.base
import
BaseCommand
...
...
@@ -39,20 +42,26 @@ class Command(BaseCommand):
get_raw_scores
=
args
[
2
]
.
lower
()
==
'raw'
request
=
DummyRequest
()
# parse out the course into a coursekey
try
:
course
=
get_course_by_id
(
course_id
)
except
Exception
:
if
course_id
in
modulestore
()
.
courses
:
course
=
modulestore
()
.
courses
[
course_id
]
else
:
print
"-----------------------------------------------------------------------------"
print
"Sorry, cannot find course
%
s"
%
course_id
print
"Please provide a course ID or course data directory name, eg content-mit-801rq"
return
course_key
=
CourseKey
.
from_string
(
course_id
)
# if it's not a new-style course key, parse it from an old-style
# course key
except
InvalidKeyError
:
course_key
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
course_id
)
try
:
course
=
get_course_by_id
(
course_key
)
except
Exception
as
err
:
print
"-----------------------------------------------------------------------------"
print
"Sorry, cannot find course with id {}"
.
format
(
course_id
)
print
"Got exception {}"
.
format
(
err
)
print
"Please provide a course ID or course data directory name, eg content-mit-801rq"
return
print
"-----------------------------------------------------------------------------"
print
"Dumping grades from
%
s to file
%
s (get_raw_scores=
%
s)"
%
(
course
.
id
,
fn
,
get_raw_scores
)
datatable
=
get_student_grade_summary_data
(
request
,
course
,
course
.
id
,
get_raw_scores
=
get_raw_scores
)
print
"Dumping grades from
{} to file {} (get_raw_scores={})"
.
format
(
course
.
id
,
fn
,
get_raw_scores
)
datatable
=
get_student_grade_summary_data
(
request
,
course
,
get_raw_scores
=
get_raw_scores
)
fp
=
open
(
fn
,
'w'
)
...
...
@@ -63,4 +72,4 @@ class Command(BaseCommand):
writer
.
writerow
(
encoded_row
)
fp
.
close
()
print
"Done:
%
d records dumped"
%
len
(
datatable
[
'data'
]
)
print
"Done:
{} records dumped"
.
format
(
len
(
datatable
[
'data'
])
)
lms/djangoapps/instructor/offline_gradecalc.py
View file @
189f53bc
...
...
@@ -26,21 +26,21 @@ class MyEncoder(JSONEncoder):
yield
chunk
def
offline_grade_calculation
(
course_
id
):
def
offline_grade_calculation
(
course_
key
):
'''
Compute grades for all students for a specified course, and save results to the DB.
'''
tstart
=
time
.
time
()
enrolled_students
=
User
.
objects
.
filter
(
courseenrollment__course_id
=
course_
id
,
courseenrollment__course_id
=
course_
key
,
courseenrollment__is_active
=
1
)
.
prefetch_related
(
"groups"
)
.
order_by
(
'username'
)
enc
=
MyEncoder
()
print
"
%
d enrolled students"
%
len
(
enrolled_students
)
course
=
get_course_by_id
(
course_
id
)
print
"
{} enrolled students"
.
format
(
len
(
enrolled_students
)
)
course
=
get_course_by_id
(
course_
key
)
for
student
in
enrolled_students
:
request
=
DummyRequest
()
...
...
@@ -49,7 +49,7 @@ def offline_grade_calculation(course_id):
gradeset
=
grades
.
grade
(
student
,
request
,
course
,
keep_raw_scores
=
True
)
gs
=
enc
.
encode
(
gradeset
)
ocg
,
created
=
models
.
OfflineComputedGrade
.
objects
.
get_or_create
(
user
=
student
,
course_id
=
course_
id
)
ocg
,
created
=
models
.
OfflineComputedGrade
.
objects
.
get_or_create
(
user
=
student
,
course_id
=
course_
key
)
ocg
.
gradeset
=
gs
ocg
.
save
()
print
"
%
s done"
%
student
# print statement used because this is run by a management command
...
...
@@ -57,18 +57,18 @@ def offline_grade_calculation(course_id):
tend
=
time
.
time
()
dt
=
tend
-
tstart
ocgl
=
models
.
OfflineComputedGradeLog
(
course_id
=
course_
id
,
seconds
=
dt
,
nstudents
=
len
(
enrolled_students
))
ocgl
=
models
.
OfflineComputedGradeLog
(
course_id
=
course_
key
,
seconds
=
dt
,
nstudents
=
len
(
enrolled_students
))
ocgl
.
save
()
print
ocgl
print
"All Done!"
def
offline_grades_available
(
course_
id
):
def
offline_grades_available
(
course_
key
):
'''
Returns False if no offline grades available for specified course.
Otherwise returns latest log field entry about the available pre-computed grades.
'''
ocgl
=
models
.
OfflineComputedGradeLog
.
objects
.
filter
(
course_id
=
course_
id
)
ocgl
=
models
.
OfflineComputedGradeLog
.
objects
.
filter
(
course_id
=
course_
key
)
if
not
ocgl
:
return
False
return
ocgl
.
latest
(
'created'
)
...
...
@@ -86,7 +86,10 @@ def student_grades(student, request, course, keep_raw_scores=False, use_offline=
try
:
ocg
=
models
.
OfflineComputedGrade
.
objects
.
get
(
user
=
student
,
course_id
=
course
.
id
)
except
models
.
OfflineComputedGrade
.
DoesNotExist
:
return
dict
(
raw_scores
=
[],
section_breakdown
=
[],
msg
=
'Error: no offline gradeset available for
%
s,
%
s'
%
(
student
,
course
.
id
))
return
dict
(
raw_scores
=
[],
section_breakdown
=
[],
msg
=
'Error: no offline gradeset available for {}, {}'
.
format
(
student
,
course
.
id
)
)
return
json
.
loads
(
ocg
.
gradeset
)
lms/djangoapps/instructor/views/legacy.py
View file @
189f53bc
...
...
@@ -226,19 +226,19 @@ def instructor_dashboard(request, course_id):
if
action
==
'Dump list of enrolled students'
or
action
==
'List enrolled students'
:
log
.
debug
(
action
)
datatable
=
get_student_grade_summary_data
(
request
,
course
,
course_key
,
get_grades
=
False
,
use_offline
=
use_offline
)
datatable
=
get_student_grade_summary_data
(
request
,
course
,
get_grades
=
False
,
use_offline
=
use_offline
)
datatable
[
'title'
]
=
_
(
'List of students enrolled in {course_key}'
)
.
format
(
course_key
=
course_key
.
to_deprecated_string
())
track
.
views
.
server_track
(
request
,
"list-students"
,
{},
page
=
"idashboard"
)
elif
'Dump Grades'
in
action
:
log
.
debug
(
action
)
datatable
=
get_student_grade_summary_data
(
request
,
course
,
course_key
,
get_grades
=
True
,
use_offline
=
use_offline
)
datatable
=
get_student_grade_summary_data
(
request
,
course
,
get_grades
=
True
,
use_offline
=
use_offline
)
datatable
[
'title'
]
=
_
(
'Summary Grades of students enrolled in {course_key}'
)
.
format
(
course_key
=
course_key
.
to_deprecated_string
())
track
.
views
.
server_track
(
request
,
"dump-grades"
,
{},
page
=
"idashboard"
)
elif
'Dump all RAW grades'
in
action
:
log
.
debug
(
action
)
datatable
=
get_student_grade_summary_data
(
request
,
course
,
course_key
,
get_grades
=
True
,
datatable
=
get_student_grade_summary_data
(
request
,
course
,
get_grades
=
True
,
get_raw_scores
=
True
,
use_offline
=
use_offline
)
datatable
[
'title'
]
=
_
(
'Raw Grades of students enrolled in {course_key}'
)
.
format
(
course_key
=
course_key
)
track
.
views
.
server_track
(
request
,
"dump-grades-raw"
,
{},
page
=
"idashboard"
)
...
...
@@ -246,12 +246,12 @@ def instructor_dashboard(request, course_id):
elif
'Download CSV of all student grades'
in
action
:
track
.
views
.
server_track
(
request
,
"dump-grades-csv"
,
{},
page
=
"idashboard"
)
return
return_csv
(
'grades_{0}.csv'
.
format
(
course_key
.
to_deprecated_string
()),
get_student_grade_summary_data
(
request
,
course
,
course_key
,
use_offline
=
use_offline
))
get_student_grade_summary_data
(
request
,
course
,
use_offline
=
use_offline
))
elif
'Download CSV of all RAW grades'
in
action
:
track
.
views
.
server_track
(
request
,
"dump-grades-csv-raw"
,
{},
page
=
"idashboard"
)
return
return_csv
(
'grades_{0}_raw.csv'
.
format
(
course_key
.
to_deprecated_string
()),
get_student_grade_summary_data
(
request
,
course
,
course_key
,
get_raw_scores
=
True
,
use_offline
=
use_offline
))
get_student_grade_summary_data
(
request
,
course
,
get_raw_scores
=
True
,
use_offline
=
use_offline
))
elif
'Download CSV of answer distributions'
in
action
:
track
.
views
.
server_track
(
request
,
"dump-answer-dist-csv"
,
{},
page
=
"idashboard"
)
...
...
@@ -539,7 +539,7 @@ def instructor_dashboard(request, course_id):
elif
action
==
'List assignments available for this course'
:
log
.
debug
(
action
)
allgrades
=
get_student_grade_summary_data
(
request
,
course
,
course_key
,
get_grades
=
True
,
use_offline
=
use_offline
)
allgrades
=
get_student_grade_summary_data
(
request
,
course
,
get_grades
=
True
,
use_offline
=
use_offline
)
assignments
=
[[
x
]
for
x
in
allgrades
[
'assignments'
]]
datatable
=
{
'header'
:
[
_
(
'Assignment Name'
)]}
...
...
@@ -549,7 +549,7 @@ def instructor_dashboard(request, course_id):
msg
+=
'assignments=<pre>
%
s</pre>'
%
assignments
elif
action
==
'List enrolled students matching remote gradebook'
:
stud_data
=
get_student_grade_summary_data
(
request
,
course
,
course_key
,
get_grades
=
False
,
use_offline
=
use_offline
)
stud_data
=
get_student_grade_summary_data
(
request
,
course
,
get_grades
=
False
,
use_offline
=
use_offline
)
msg2
,
rg_stud_data
=
_do_remote_gradebook
(
request
.
user
,
course
,
'get-membership'
)
datatable
=
{
'header'
:
[
'Student email'
,
'Match?'
]}
rg_students
=
[
x
[
'email'
]
for
x
in
rg_stud_data
[
'retdata'
]]
...
...
@@ -568,7 +568,7 @@ def instructor_dashboard(request, course_id):
if
not
aname
:
msg
+=
"<font color='red'>{text}</font>"
.
format
(
text
=
_
(
"Please enter an assignment name"
))
else
:
allgrades
=
get_student_grade_summary_data
(
request
,
course
,
course_key
,
get_grades
=
True
,
use_offline
=
use_offline
)
allgrades
=
get_student_grade_summary_data
(
request
,
course
,
get_grades
=
True
,
use_offline
=
use_offline
)
if
aname
not
in
allgrades
[
'assignments'
]:
msg
+=
"<font color='red'>{text}</font>"
.
format
(
text
=
_
(
"Invalid assignment name '{name}'"
)
.
format
(
name
=
aname
)
...
...
@@ -1354,8 +1354,8 @@ class GradeTable(object):
return
self
.
components
.
keys
()
def
get_student_grade_summary_data
(
request
,
course
,
course_key
,
get_grades
=
True
,
get_raw_scores
=
False
,
use_offline
=
False
):
'''
def
get_student_grade_summary_data
(
request
,
course
,
get_grades
=
True
,
get_raw_scores
=
False
,
use_offline
=
False
):
"""
Return data arrays with student identity and grades for specified course.
course = CourseDescriptor
...
...
@@ -1370,8 +1370,8 @@ def get_student_grade_summary_data(request, course, course_key, get_grades=True,
data = list (one per student) of lists of data corresponding to the fields
If get_raw_scores=True, then instead of grade summaries, the raw grades for all graded modules are returned.
'''
"""
course_key
=
course
.
id
enrolled_students
=
User
.
objects
.
filter
(
courseenrollment__course_id
=
course_key
,
courseenrollment__is_active
=
1
,
...
...
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