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
549b985e
Commit
549b985e
authored
Jun 20, 2014
by
Justin Riley
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add course_id arg and csv output filename option
Massive code clean-up as well.
parent
203df998
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
124 additions
and
124 deletions
+124
-124
lms/djangoapps/courseware/management/commands/get_submission_history_statistics.py
+124
-124
No files found.
lms/djangoapps/courseware/management/commands/get_submission_history_statistics.py
View file @
549b985e
#!/usr/bin/python
#
# Largely for 3.091-exam.
# Compute number of times a given problem has been attempted by a student,
# including StudentModuleHistory. Do this by walking through the course tree.
# For every assessment problem, look up all matching StudehtModuleHistory
# items. Count number of attempts passed, and number failed. Remove staff
# data.
#
# Compute number of times a given problem has been attempted by a student, including StudentModuleHistory.
# Do this by walking through the course tree. For every assessment problem, look up all matching
# StudehtModuleHistory items. Count number of attempts passed, and number failed. Remove staff data.
# Output table with: problem url_id, problem name, number students assigned,
# number attempts failed, number attempts succeeded
#
# Output table with: problem url_id, problem name, number students assigned, number attempts failed, number attempts succeeded
#
from
courseware.module_tree_reset
import
*
from
courseware.access
import
get_access_group_name
from
django.core.management.base
import
BaseCommand
import
json
import
csv
import
json
from
optparse
import
make_option
#-----------------------------------------------------------------------------
from
request_cache.middleware
import
RequestCache
from
xmodule.modulestore.django
import
modulestore
from
courseware.access
import
get_user_role
from
courseware.module_tree_reset
import
ProctorModuleInfo
from
courseware.models
import
StudentModule
,
StudentModuleHistory
from
django.conf
import
settings
from
xmodule.modulestore.django
import
modulestore
from
django.dispatch
import
Signal
from
request_cache.middleware
import
RequestCache
from
django.core.cache
import
get_cache
if
True
:
CACHE
=
get_cache
(
'mongo_metadata_inheritance'
)
for
store_name
in
settings
.
MODULESTORE
:
store
=
modulestore
(
store_name
)
store
.
metadata_inheritance_cache_subsystem
=
CACHE
store
.
request_cache
=
RequestCache
.
get_request_cache
()
modulestore_update_signal
=
Signal
(
providing_args
=
[
'modulestore'
,
'course_id'
,
'location'
])
store
.
modulestore_update_signal
=
modulestore_update_signal
#-----------------------------------------------------------------------------
def
ComputeStats
():
pminfo
=
ProctorModuleInfo
()
# get list of all problems
from
django.contrib.auth.models
import
User
from
django.core.management.base
import
BaseCommand
,
CommandError
CACHE
=
get_cache
(
'mongo_metadata_inheritance'
)
for
store_name
in
settings
.
MODULESTORE
:
store
=
modulestore
(
store_name
)
store
.
metadata_inheritance_cache_subsystem
=
CACHE
store
.
request_cache
=
RequestCache
.
get_request_cache
()
modulestore_update_signal
=
Signal
(
providing_args
=
[
'modulestore'
,
'course_id'
,
'location'
])
store
.
modulestore_update_signal
=
modulestore_update_signal
class
Stats
(
object
):
def
__init__
(
self
):
self
.
nassigned
=
0
self
.
nattempts
=
0
self
.
npassed
=
0
def
passed
(
state
):
if
'correct_map'
not
in
state
:
return
False
if
not
state
[
'correct_map'
]:
return
False
# must all be correct to pass
return
all
([
x
[
'correctness'
]
==
'correct'
for
x
in
state
.
get
(
'correct_map'
)
.
values
()])
def
update_stats
(
sm
,
stat
,
history
=
False
):
if
sm
.
grade
is
None
:
return
state
=
json
.
loads
(
sm
.
state
)
if
'attempts'
not
in
state
:
return
if
not
state
.
get
(
'done'
,
False
):
return
"notdone"
if
not
history
:
stat
.
nattempts
+=
state
[
'attempts'
]
if
passed
(
state
):
stat
.
npassed
+=
1
return
"passed"
return
"attempted"
def
compute_stats
(
course_id
,
csv_file
=
None
):
pminfo
=
ProctorModuleInfo
(
course_id
)
all_problems
=
[]
stats
=
[]
staffgroup
=
get_user_role
(
User
.
objects
.
get
(
username
=
'staff'
),
pminfo
.
course
.
id
)
self
=
pminfo
if
True
:
for
rpmod
in
self
.
rpmods
:
assignment_set_name
=
rpmod
.
ra_ps
.
display_name
for
ploc
in
rpmod
.
ra_rand
.
children
:
problem
=
self
.
ms
.
get_item
(
ploc
)
problem
.
assignment_set_name
=
assignment_set_name
all_problems
.
append
(
problem
)
staffgroup
=
get_access_group_name
(
self
.
course
,
'staff'
)
cnt
=
0
class
Stats
(
object
):
def
__init__
(
self
):
self
.
nassigned
=
0
self
.
nattempts
=
0
self
.
npassed
=
0
for
rpmod
in
pminfo
.
rpmods
:
assignment_set_name
=
rpmod
.
ra_ps
.
display_name
for
ploc
in
rpmod
.
ra_rand
.
children
:
problem
=
pminfo
.
ms
.
get_instance
(
pminfo
.
course
.
id
,
ploc
)
problem
.
assignment_set_name
=
assignment_set_name
all_problems
.
append
(
problem
)
for
problem
in
all_problems
:
print
problem
.
id
stat
=
Stats
()
smset0
=
StudentModule
.
objects
.
filter
(
module_state_key
=
problem
.
id
,
student__is_staff
=
False
)
smset
=
smset0
.
exclude
(
student__groups__name
=
staffgroup
)
def
passed
(
state
):
if
'correct_map'
not
in
state
:
return
False
if
not
state
[
'correct_map'
]:
# correct_map = {}
return
False
return
all
([
x
[
'correctness'
]
==
'correct'
for
x
in
state
.
get
(
'correct_map'
)
.
values
()])
# must be all correct to pass
def
update_stats
(
sm
,
stat
,
history
=
False
):
if
sm
.
grade
is
None
:
return
state
=
json
.
loads
(
sm
.
state
)
if
not
'attempts'
in
state
:
return
if
not
state
.
get
(
'done'
,
False
):
return
"notdone"
if
not
history
:
stat
.
nattempts
+=
state
[
'attempts'
]
if
passed
(
state
):
stat
.
npassed
+=
1
return
"passed"
return
"attempted"
smset0
=
StudentModule
.
objects
.
filter
(
module_state_key
=
problem
.
id
,
student__is_staff
=
False
)
smset
=
smset0
.
exclude
(
student__groups__name__icontains
=
staffgroup
)
for
sm
in
smset
:
stat
.
nassigned
+=
1
ret
=
update_stats
(
sm
,
stat
)
if
ret
in
[
'passed'
,
'attempted'
]:
continue
smhset
=
StudentModuleHistory
.
objects
.
filter
(
student_module
=
sm
)
states
=
[
json
.
loads
(
smh
.
state
)
for
smh
in
smhset
]
okset
=
[
passed
(
x
)
for
x
in
states
]
attempts
=
[
x
.
get
(
'attempts'
,
0
)
for
x
in
states
]
states
=
[
json
.
loads
(
smh
.
state
)
for
smh
in
smhset
]
okset
=
[
passed
(
x
)
for
x
in
states
]
attempts
=
[
x
.
get
(
'attempts'
,
0
)
for
x
in
states
]
stat
.
nattempts
+=
max
(
attempts
)
if
any
(
okset
):
stat
.
npassed
+=
1
#print " assigned=%d, attempts=%d, passed=%d" % (nassigned, nattempts, npassed)
stats
.
append
(
dict
(
problem_id
=
problem
.
id
,
pset
=
problem
.
assignment_set_name
,
problem_name
=
problem
.
display_name
,
due
=
str
(
problem
.
due
),
max_attempts
=
problem
.
max_attempts
,
assigned
=
stat
.
nassigned
,
attempts
=
stat
.
nattempts
,
passed
=
stat
.
npassed
,
))
cnt
+=
1
#if cnt>5:
# break
if
True
:
dddir
=
settings
.
MITX_FEATURES
.
get
(
'DOWNLOAD_DATA_DIR'
,
''
)
fndir
=
dddir
/
(
self
.
course
.
id
.
replace
(
'/'
,
'__'
))
dt
=
datetime
.
datetime
.
now
()
.
strftime
(
'
%
Y-
%
m-
%
d-
%
H
%
M'
)
fn
=
fndir
/
"problem-stats-
%
s-
%
s.csv"
%
(
self
.
course
.
id
.
split
(
'/'
)[
1
],
dt
)
print
"Saving data to
%
s"
%
fn
# fn = "stats.csv"
fieldnames
=
[
'problem_id'
,
'pset'
,
'problem_name'
,
'due'
,
'max_attempts'
,
'assigned'
,
'attempts'
,
'passed'
]
fp
=
open
(
fn
,
'w'
)
writer
=
csv
.
DictWriter
(
fp
,
fieldnames
,
dialect
=
'excel'
,
quotechar
=
'"'
,
quoting
=
csv
.
QUOTE_ALL
)
writer
.
writeheader
()
for
row
in
stats
:
try
:
writer
.
writerow
(
row
)
except
Exception
as
err
:
print
"Oops, failed to write
%
s, error=
%
s"
%
(
row
,
err
)
fp
.
close
()
#-----------------------------------------------------------------------------
print
problem
.
id
print
" assigned=
%
d, attempts=
%
d, passed=
%
d"
%
(
stat
.
nassigned
,
stat
.
nattempts
,
stat
.
npassed
)
stats
.
append
(
dict
(
problem_id
=
problem
.
id
,
pset
=
problem
.
assignment_set_name
,
problem_name
=
problem
.
display_name
,
due
=
str
(
problem
.
due
),
max_attempts
=
problem
.
max_attempts
,
assigned
=
stat
.
nassigned
,
attempts
=
stat
.
nattempts
,
passed
=
stat
.
npassed
,
))
return
stats
def
write_stats
(
stats
,
csv_filename
):
print
"Saving data to
%
s"
%
csv_filename
fieldnames
=
[
'problem_id'
,
'pset'
,
'problem_name'
,
'due'
,
'max_attempts'
,
'assigned'
,
'attempts'
,
'passed'
]
fp
=
open
(
csv_filename
,
'w'
)
writer
=
csv
.
DictWriter
(
fp
,
fieldnames
,
dialect
=
'excel'
,
quotechar
=
'"'
,
quoting
=
csv
.
QUOTE_ALL
)
writer
.
writeheader
()
for
row
in
stats
:
try
:
writer
.
writerow
(
row
)
except
Exception
as
err
:
print
"Oops, failed to write
%
s, error=
%
s"
%
(
row
,
err
)
fp
.
close
()
return
class
Command
(
BaseCommand
):
help
=
"""Generate CSV file with problem attempts statistics;
CSV file columns include problem id, assigned, max_attempts, attempts, passed
for every problem in the course. Arguments: None. Works only on 3.091-exam"""
args
=
"<course_id>"
help
=
"""Generate CSV file with problem attempts statistics; CSV file
\
columns include problem id, assigned, max_attempts, attempts, passed for
\
every problem in the course. Arguments: None. Works only on 3.091-exam"""
option_list
=
BaseCommand
.
option_list
+
(
make_option
(
'--csv-output-filename'
,
dest
=
'csv_output_filename'
,
action
=
'store'
,
default
=
None
,
help
=
'Save stats to csv file'
),
)
def
handle
(
self
,
*
args
,
**
options
):
ComputeStats
()
if
len
(
args
)
!=
1
:
raise
CommandError
(
"missing argument: <course_id>"
)
stats
=
compute_stats
(
args
[
0
])
csv_output_filename
=
options
[
'csv_output_filename'
]
if
csv_output_filename
:
write_stats
(
stats
,
csv_output_filename
)
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