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
ffd47c45
Commit
ffd47c45
authored
Mar 28, 2014
by
Calen Pennington
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2613 from edx/bugfix/ichuang/idash-raw-grades-dump
fix raw grade dump in standard instructor dashboard
parents
e1afbe50
9e58ef69
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
153 additions
and
18 deletions
+153
-18
lms/djangoapps/instructor/tests/test_legacy_raw_download_csv.py
+58
-0
lms/djangoapps/instructor/views/legacy.py
+95
-18
No files found.
lms/djangoapps/instructor/tests/test_legacy_raw_download_csv.py
0 → 100644
View file @
ffd47c45
# -*- coding: utf-8 -*-
"""
Create course and answer a problem to test raw grade CSV
"""
from
django.contrib.auth.models
import
User
from
django.core.urlresolvers
import
reverse
from
courseware.tests.test_submitting_problems
import
TestSubmittingProblems
from
student.roles
import
CourseStaffRole
class
TestRawGradeCSV
(
TestSubmittingProblems
):
"""
Tests around the instructor dashboard raw grade CSV
"""
def
setUp
(
self
):
"""
Set up a simple course for testing basic grading functionality.
"""
super
(
TestRawGradeCSV
,
self
)
.
setUp
()
self
.
instructor
=
'view2@test.com'
self
.
create_account
(
'u2'
,
self
.
instructor
,
self
.
password
)
self
.
activate_user
(
self
.
instructor
)
CourseStaffRole
(
self
.
course
.
location
)
.
add_users
(
User
.
objects
.
get
(
email
=
self
.
instructor
))
self
.
logout
()
self
.
login
(
self
.
instructor
,
self
.
password
)
self
.
enroll
(
self
.
course
)
# set up a simple course with four problems
self
.
homework
=
self
.
add_graded_section_to_course
(
'homework'
,
late
=
False
,
reset
=
False
,
showanswer
=
False
)
self
.
add_dropdown_to_section
(
self
.
homework
.
location
,
'p1'
,
1
)
self
.
add_dropdown_to_section
(
self
.
homework
.
location
,
'p2'
,
1
)
self
.
add_dropdown_to_section
(
self
.
homework
.
location
,
'p3'
,
1
)
self
.
refresh_course
()
def
test_download_raw_grades_dump
(
self
):
"""
Grab raw grade report and make sure all grades are reported.
"""
# Answer second problem correctly with 2nd user to expose bug
self
.
login
(
self
.
instructor
,
self
.
password
)
resp
=
self
.
submit_question_answer
(
'p2'
,
{
'2_1'
:
'Correct'
})
self
.
assertEqual
(
resp
.
status_code
,
200
)
url
=
reverse
(
'instructor_dashboard'
,
kwargs
=
{
'course_id'
:
self
.
course
.
id
})
msg
=
"url = {0}
\n
"
.
format
(
url
)
response
=
self
.
client
.
post
(
url
,
{
'action'
:
'Download CSV of all RAW grades'
})
msg
+=
"instructor dashboard download raw csv grades: response = '{0}'
\n
"
.
format
(
response
)
body
=
response
.
content
.
replace
(
'
\r
'
,
''
)
msg
+=
"body = '{0}'
\n
"
.
format
(
body
)
expected_csv
=
'''"ID","Username","Full Name","edX email","External email","p3","p2","p1"
"1","u1","username","view@test.com","","None","None","None"
"2","u2","username","view2@test.com","","0.0","1.0","0.0"
'''
self
.
assertEqual
(
body
,
expected_csv
,
msg
)
lms/djangoapps/instructor/views/legacy.py
View file @
ffd47c45
"""
"""
Instructor Views
Instructor Views
"""
"""
from
contextlib
import
contextmanager
import
csv
import
csv
import
json
import
json
import
logging
import
logging
...
@@ -1154,6 +1155,74 @@ def remove_user_from_role(request, username_or_email, role, group_title, event_n
...
@@ -1154,6 +1155,74 @@ def remove_user_from_role(request, username_or_email, role, group_title, event_n
return
'<font color="green">Removed {0} from {1}</font>'
.
format
(
user
,
group_title
)
return
'<font color="green">Removed {0} from {1}</font>'
.
format
(
user
,
group_title
)
class
GradeTable
(
object
):
"""
Keep track of grades, by student, for all graded assignment
components. Each student's grades are stored in a list. The
index of this list specifies the assignment component. Not
all lists have the same length, because at the start of going
through the set of grades, it is unknown what assignment
compoments exist. This is because some students may not do
all the assignment components.
The student grades are then stored in a dict, with the student
id as the key.
"""
def
__init__
(
self
):
self
.
components
=
OrderedDict
()
self
.
grades
=
{}
self
.
_current_row
=
{}
def
_add_grade_to_row
(
self
,
component
,
score
):
"""Creates component if needed, and assigns score
Args:
component (str): Course component being graded
score (float): Score of student on component
Returns:
None
"""
component_index
=
self
.
components
.
setdefault
(
component
,
len
(
self
.
components
))
self
.
_current_row
[
component_index
]
=
score
@contextmanager
def
add_row
(
self
,
student_id
):
"""Context management for a row of grades
Uses a new dictionary to get all grades of a specified student
and closes by adding that dict to the internal table.
Args:
student_id (str): Student id that is having grades set
"""
self
.
_current_row
=
{}
yield
self
.
_add_grade_to_row
self
.
grades
[
student_id
]
=
self
.
_current_row
def
get_grade
(
self
,
student_id
):
"""Retrieves padded list of grades for specified student
Args:
student_id (str): Student ID for desired grades
Returns:
list: Ordered list of grades for student
"""
row
=
self
.
grades
.
get
(
student_id
,
[])
ncomp
=
len
(
self
.
components
)
return
[
row
.
get
(
comp
,
None
)
for
comp
in
range
(
ncomp
)]
def
get_graded_components
(
self
):
"""
Return a list of components that have been
discovered so far.
"""
return
self
.
components
.
keys
()
def
get_student_grade_summary_data
(
request
,
course
,
course_id
,
get_grades
=
True
,
get_raw_scores
=
False
,
use_offline
=
False
):
def
get_student_grade_summary_data
(
request
,
course
,
course_id
,
get_grades
=
True
,
get_raw_scores
=
False
,
use_offline
=
False
):
'''
'''
Return data arrays with student identity and grades for specified course.
Return data arrays with student identity and grades for specified course.
...
@@ -1178,20 +1247,12 @@ def get_student_grade_summary_data(request, course, course_id, get_grades=True,
...
@@ -1178,20 +1247,12 @@ def get_student_grade_summary_data(request, course, course_id, get_grades=True,
)
.
prefetch_related
(
"groups"
)
.
order_by
(
'username'
)
)
.
prefetch_related
(
"groups"
)
.
order_by
(
'username'
)
header
=
[
_
(
'ID'
),
_
(
'Username'
),
_
(
'Full Name'
),
_
(
'edX email'
),
_
(
'External email'
)]
header
=
[
_
(
'ID'
),
_
(
'Username'
),
_
(
'Full Name'
),
_
(
'edX email'
),
_
(
'External email'
)]
assignments
=
[]
if
get_grades
and
enrolled_students
.
count
()
>
0
:
# just to construct the header
gradeset
=
student_grades
(
enrolled_students
[
0
],
request
,
course
,
keep_raw_scores
=
get_raw_scores
,
use_offline
=
use_offline
)
# log.debug('student {0} gradeset {1}'.format(enrolled_students[0], gradeset))
if
get_raw_scores
:
assignments
+=
[
score
.
section
for
score
in
gradeset
[
'raw_scores'
]]
else
:
assignments
+=
[
x
[
'label'
]
for
x
in
gradeset
[
'section_breakdown'
]]
header
+=
assignments
datatable
=
{
'header'
:
header
,
'
assignments'
:
assignments
,
'
students'
:
enrolled_students
}
datatable
=
{
'header'
:
header
,
'students'
:
enrolled_students
}
data
=
[]
data
=
[]
gtab
=
GradeTable
()
for
student
in
enrolled_students
:
for
student
in
enrolled_students
:
datarow
=
[
student
.
id
,
student
.
username
,
student
.
profile
.
name
,
student
.
email
]
datarow
=
[
student
.
id
,
student
.
username
,
student
.
profile
.
name
,
student
.
email
]
try
:
try
:
...
@@ -1202,15 +1263,31 @@ def get_student_grade_summary_data(request, course, course_id, get_grades=True,
...
@@ -1202,15 +1263,31 @@ def get_student_grade_summary_data(request, course, course_id, get_grades=True,
if
get_grades
:
if
get_grades
:
gradeset
=
student_grades
(
student
,
request
,
course
,
keep_raw_scores
=
get_raw_scores
,
use_offline
=
use_offline
)
gradeset
=
student_grades
(
student
,
request
,
course
,
keep_raw_scores
=
get_raw_scores
,
use_offline
=
use_offline
)
log
.
debug
(
'student={0}, gradeset={1}'
.
format
(
student
,
gradeset
))
log
.
debug
(
'student={0}, gradeset={1}'
.
format
(
student
,
gradeset
))
if
get_raw_scores
:
with
gtab
.
add_row
(
student
.
id
)
as
add_grade
:
# TODO (ichuang) encode Score as dict instead of as list, so score[0] -> score['earned']
if
get_raw_scores
:
sgrades
=
[(
getattr
(
score
,
'earned'
,
''
)
or
score
[
0
])
for
score
in
gradeset
[
'raw_scores'
]]
# TODO (ichuang) encode Score as dict instead of as list, so score[0] -> score['earned']
else
:
for
score
in
gradeset
[
'raw_scores'
]:
sgrades
=
[
x
[
'percent'
]
for
x
in
gradeset
[
'section_breakdown'
]]
add_grade
(
score
.
section
,
getattr
(
score
,
'earned'
,
score
[
0
]))
datarow
+=
sgrades
else
:
student
.
grades
=
sgrades
# store in student object
for
grade_item
in
gradeset
[
'section_breakdown'
]:
add_grade
(
grade_item
[
'label'
],
grade_item
[
'percent'
])
student
.
grades
=
gtab
.
get_grade
(
student
.
id
)
data
.
append
(
datarow
)
data
.
append
(
datarow
)
# if getting grades, need to do a second pass, and add grades to each datarow;
# on the first pass we don't know all the graded components
if
get_grades
:
for
datarow
in
data
:
# get grades for student
sgrades
=
gtab
.
get_grade
(
datarow
[
0
])
datarow
+=
sgrades
# get graded components and add to table header
assignments
=
gtab
.
get_graded_components
()
header
+=
assignments
datatable
[
'assignments'
]
=
assignments
datatable
[
'data'
]
=
data
datatable
[
'data'
]
=
data
return
datatable
return
datatable
...
...
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