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
54262bc8
Commit
54262bc8
authored
Dec 08, 2015
by
Sarina Canelake
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove ORA1 management commands
parent
2431baff
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
0 additions
and
461 deletions
+0
-461
lms/djangoapps/instructor/management/commands/openended_post.py
+0
-133
lms/djangoapps/instructor/management/commands/openended_stats.py
+0
-136
lms/djangoapps/instructor/management/tests/test_openended_commands.py
+0
-192
No files found.
lms/djangoapps/instructor/management/commands/openended_post.py
deleted
100644 → 0
View file @
2431baff
"""
Command to manually re-post open ended submissions to the grader.
"""
from
django.contrib.auth.models
import
User
from
django.core.management.base
import
BaseCommand
from
optparse
import
make_option
from
xmodule.modulestore.django
import
modulestore
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
from
xmodule.open_ended_grading_classes.openendedchild
import
OpenEndedChild
from
xmodule.open_ended_grading_classes.open_ended_module
import
OpenEndedModule
from
courseware.courses
import
get_course
from
instructor.utils
import
get_module_for_student
class
Command
(
BaseCommand
):
"""
Command to manually re-post open ended submissions to the grader.
"""
help
=
(
"Usage: openended_post <course_id> <problem_location> <student_ids.txt> <hostname> --dry-run --task-number=<task_number>
\n
"
"The text file should contain a User.id in each line."
)
option_list
=
BaseCommand
.
option_list
+
(
make_option
(
'-n'
,
'--dry-run'
,
action
=
'store_true'
,
dest
=
'dry_run'
,
default
=
False
,
help
=
"Do everything except send the submission to the grader. "
),
make_option
(
'--task-number'
,
type
=
'int'
,
default
=
0
,
help
=
"Task number that needs to be submitted."
),
)
def
handle
(
self
,
*
args
,
**
options
):
dry_run
=
options
[
'dry_run'
]
task_number
=
options
[
'task_number'
]
if
len
(
args
)
==
4
:
course_id
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
args
[
0
])
location
=
course_id
.
make_usage_key_from_deprecated_string
(
args
[
1
])
students_ids
=
[
line
.
strip
()
for
line
in
open
(
args
[
2
])]
hostname
=
args
[
3
]
else
:
print
self
.
help
return
try
:
course
=
get_course
(
course_id
)
except
ValueError
as
err
:
print
err
return
descriptor
=
modulestore
()
.
get_item
(
location
,
depth
=
0
)
if
descriptor
is
None
:
print
"Location not found in course"
return
if
dry_run
:
print
"Doing a dry run."
students
=
User
.
objects
.
filter
(
id__in
=
students_ids
)
.
order_by
(
'username'
)
print
"Number of students: {0}"
.
format
(
students
.
count
())
for
student
in
students
:
post_submission_for_student
(
student
,
course
,
location
,
task_number
,
dry_run
=
dry_run
,
hostname
=
hostname
)
def
post_submission_for_student
(
student
,
course
,
location
,
task_number
,
dry_run
=
True
,
hostname
=
None
):
"""If the student's task child_state is ASSESSING post submission to grader."""
print
"{0}:{1}"
.
format
(
student
.
id
,
student
.
username
)
request
=
DummyRequest
()
request
.
user
=
student
request
.
host
=
hostname
try
:
module
=
get_module_for_student
(
student
,
location
,
request
=
request
,
course
=
course
)
if
module
is
None
:
print
" WARNING: No state found."
return
False
latest_task
=
module
.
child_module
.
get_task_number
(
task_number
)
if
latest_task
is
None
:
print
" WARNING: No task state found."
return
False
if
not
isinstance
(
latest_task
,
OpenEndedModule
):
print
" ERROR: Not an OpenEndedModule task."
return
False
latest_task_state
=
latest_task
.
child_state
if
latest_task_state
==
OpenEndedChild
.
INITIAL
:
print
" WARNING: No submission."
elif
latest_task_state
==
OpenEndedChild
.
POST_ASSESSMENT
or
latest_task_state
==
OpenEndedChild
.
DONE
:
print
" WARNING: Submission already graded."
elif
latest_task_state
==
OpenEndedChild
.
ASSESSING
:
latest_answer
=
latest_task
.
latest_answer
()
if
dry_run
:
print
" Skipped sending submission to grader: {0!r}"
.
format
(
latest_answer
[:
100
]
.
encode
(
'utf-8'
))
else
:
latest_task
.
send_to_grader
(
latest_answer
,
latest_task
.
system
)
print
" Sent submission to grader: {0!r}"
.
format
(
latest_answer
[:
100
]
.
encode
(
'utf-8'
))
return
True
else
:
print
"WARNING: Invalid task_state: {0}"
.
format
(
latest_task_state
)
except
Exception
as
err
:
# pylint: disable=broad-except
print
err
return
False
class
DummyRequest
(
object
):
"""Dummy request"""
META
=
{}
def
__init__
(
self
):
self
.
session
=
{}
self
.
user
=
None
self
.
host
=
None
self
.
secure
=
True
def
get_host
(
self
):
"""Return a default host."""
return
self
.
host
def
is_secure
(
self
):
"""Always secure."""
return
self
.
secure
lms/djangoapps/instructor/management/commands/openended_stats.py
deleted
100644 → 0
View file @
2431baff
"""
Command to get statistics about open ended problems.
"""
import
csv
import
time
from
django.core.management.base
import
BaseCommand
from
optparse
import
make_option
from
xmodule.modulestore.django
import
modulestore
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
from
xmodule.open_ended_grading_classes.openendedchild
import
OpenEndedChild
from
courseware.courses
import
get_course
from
courseware.models
import
StudentModule
from
student.models
import
anonymous_id_for_user
,
CourseEnrollment
from
instructor.utils
import
get_module_for_student
class
Command
(
BaseCommand
):
"""
Command to get statistics about open ended problems.
"""
help
=
"Usage: openended_stats <course_id> <problem_location> --task-number=<task_number>
\n
"
option_list
=
BaseCommand
.
option_list
+
(
make_option
(
'--task-number'
,
type
=
'int'
,
default
=
0
,
help
=
"Task number to get statistics about."
),
)
def
handle
(
self
,
*
args
,
**
options
):
"""Handler for command."""
task_number
=
options
[
'task_number'
]
if
len
(
args
)
==
2
:
course_id
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
args
[
0
])
usage_key
=
course_id
.
make_usage_key_from_deprecated_string
(
args
[
1
])
else
:
print
self
.
help
return
try
:
course
=
get_course
(
course_id
)
except
ValueError
as
err
:
print
err
return
descriptor
=
modulestore
()
.
get_item
(
usage_key
,
depth
=
0
)
if
descriptor
is
None
:
print
"Location {0} not found in course"
.
format
(
usage_key
)
return
try
:
enrolled_students
=
CourseEnrollment
.
objects
.
users_enrolled_in
(
course_id
)
print
"Total students enrolled in {0}: {1}"
.
format
(
course_id
,
enrolled_students
.
count
())
calculate_task_statistics
(
enrolled_students
,
course
,
usage_key
,
task_number
)
except
KeyboardInterrupt
:
print
"
\n
Operation Cancelled"
def
calculate_task_statistics
(
students
,
course
,
location
,
task_number
,
write_to_file
=
True
):
"""Print stats of students."""
stats
=
{
OpenEndedChild
.
INITIAL
:
0
,
OpenEndedChild
.
ASSESSING
:
0
,
OpenEndedChild
.
POST_ASSESSMENT
:
0
,
OpenEndedChild
.
DONE
:
0
}
students_with_saved_answers
=
[]
students_with_ungraded_submissions
=
[]
# pylint: disable=invalid-name
students_with_graded_submissions
=
[]
# pylint: disable=invalid-name
students_with_no_state
=
[]
student_modules
=
StudentModule
.
objects
.
filter
(
module_state_key
=
location
,
student__in
=
students
)
.
order_by
(
'student'
)
print
"Total student modules: {0}"
.
format
(
student_modules
.
count
())
for
index
,
student_module
in
enumerate
(
student_modules
):
if
index
%
100
==
0
:
print
"--- {0} students processed ---"
.
format
(
index
)
student
=
student_module
.
student
print
"{0}:{1}"
.
format
(
student
.
id
,
student
.
username
)
module
=
get_module_for_student
(
student
,
location
,
course
=
course
)
if
module
is
None
:
print
" WARNING: No state found"
students_with_no_state
.
append
(
student
)
continue
latest_task
=
module
.
child_module
.
get_task_number
(
task_number
)
if
latest_task
is
None
:
print
" No task state found"
students_with_no_state
.
append
(
student
)
continue
task_state
=
latest_task
.
child_state
stats
[
task_state
]
+=
1
print
" State: {0}"
.
format
(
task_state
)
if
task_state
==
OpenEndedChild
.
INITIAL
:
if
latest_task
.
stored_answer
is
not
None
:
students_with_saved_answers
.
append
(
student
)
elif
task_state
==
OpenEndedChild
.
ASSESSING
:
students_with_ungraded_submissions
.
append
(
student
)
elif
task_state
==
OpenEndedChild
.
POST_ASSESSMENT
or
task_state
==
OpenEndedChild
.
DONE
:
students_with_graded_submissions
.
append
(
student
)
print
"----------------------------------"
print
"Time: {0}"
.
format
(
time
.
strftime
(
"
%
Y
%
b
%
d
%
H:
%
M:
%
S +0000"
,
time
.
gmtime
()))
print
"Course: {0}"
.
format
(
course
.
id
)
print
"Location: {0}"
.
format
(
location
)
print
"No state: {0}"
.
format
(
len
(
students_with_no_state
))
print
"Initial State: {0}"
.
format
(
stats
[
OpenEndedChild
.
INITIAL
]
-
len
(
students_with_saved_answers
))
print
"Saved answers: {0}"
.
format
(
len
(
students_with_saved_answers
))
print
"Submitted answers: {0}"
.
format
(
stats
[
OpenEndedChild
.
ASSESSING
])
print
"Received grades: {0}"
.
format
(
stats
[
OpenEndedChild
.
POST_ASSESSMENT
]
+
stats
[
OpenEndedChild
.
DONE
])
print
"----------------------------------"
if
write_to_file
:
filename
=
"stats.{0}.{1}"
.
format
(
location
.
course
,
location
.
name
)
time_stamp
=
time
.
strftime
(
"
%
Y
%
m
%
d-
%
H
%
M
%
S"
)
with
open
(
'{0}.{1}.csv'
.
format
(
filename
,
time_stamp
),
'wb'
)
as
csv_file
:
writer
=
csv
.
writer
(
csv_file
,
delimiter
=
' '
,
quoting
=
csv
.
QUOTE_MINIMAL
)
for
student
in
students_with_ungraded_submissions
:
writer
.
writerow
((
"ungraded"
,
student
.
id
,
anonymous_id_for_user
(
student
,
None
),
student
.
username
))
for
student
in
students_with_graded_submissions
:
writer
.
writerow
((
"graded"
,
student
.
id
,
anonymous_id_for_user
(
student
,
None
),
student
.
username
))
return
stats
lms/djangoapps/instructor/management/tests/test_openended_commands.py
deleted
100644 → 0
View file @
2431baff
"""Test the openended_post management command."""
from
datetime
import
datetime
import
json
from
mock
import
patch
from
pytz
import
UTC
from
django.conf
import
settings
from
opaque_keys.edx.locations
import
Location
import
capa.xqueue_interface
as
xqueue_interface
from
courseware.courses
import
get_course_with_access
from
courseware.tests.factories
import
StudentModuleFactory
,
UserFactory
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
xmodule.modulestore.xml_importer
import
import_course_from_xml
from
xmodule.open_ended_grading_classes.openendedchild
import
OpenEndedChild
from
xmodule.tests.test_util_open_ended
import
(
STATE_INITIAL
,
STATE_ACCESSING
,
STATE_POST_ASSESSMENT
)
from
student.models
import
anonymous_id_for_user
from
instructor.management.commands.openended_post
import
post_submission_for_student
from
instructor.management.commands.openended_stats
import
calculate_task_statistics
from
instructor.utils
import
get_module_for_student
TEST_DATA_DIR
=
settings
.
COMMON_TEST_DATA_ROOT
class
OpenEndedPostTest
(
ModuleStoreTestCase
):
"""Test the openended_post management command."""
def
setUp
(
self
):
super
(
OpenEndedPostTest
,
self
)
.
setUp
()
self
.
user
=
UserFactory
()
store
=
modulestore
()
course_items
=
import_course_from_xml
(
store
,
self
.
user
.
id
,
TEST_DATA_DIR
,
[
'open_ended'
])
# pylint: disable=maybe-no-member
self
.
course
=
course_items
[
0
]
self
.
course_id
=
self
.
course
.
id
self
.
problem_location
=
Location
(
"edX"
,
"open_ended"
,
"2012_Fall"
,
"combinedopenended"
,
"SampleQuestion"
)
self
.
self_assessment_task_number
=
0
self
.
open_ended_task_number
=
1
self
.
student_on_initial
=
UserFactory
()
self
.
student_on_accessing
=
UserFactory
()
self
.
student_on_post_assessment
=
UserFactory
()
StudentModuleFactory
.
create
(
course_id
=
self
.
course_id
,
module_state_key
=
self
.
problem_location
,
student
=
self
.
student_on_initial
,
grade
=
0
,
max_grade
=
1
,
state
=
STATE_INITIAL
)
StudentModuleFactory
.
create
(
course_id
=
self
.
course_id
,
module_state_key
=
self
.
problem_location
,
student
=
self
.
student_on_accessing
,
grade
=
0
,
max_grade
=
1
,
state
=
STATE_ACCESSING
)
StudentModuleFactory
.
create
(
course_id
=
self
.
course_id
,
module_state_key
=
self
.
problem_location
,
student
=
self
.
student_on_post_assessment
,
grade
=
0
,
max_grade
=
1
,
state
=
STATE_POST_ASSESSMENT
)
def
test_post_submission_for_student_on_initial
(
self
):
course
=
get_course_with_access
(
self
.
student_on_initial
,
'load'
,
self
.
course_id
)
dry_run_result
=
post_submission_for_student
(
self
.
student_on_initial
,
course
,
self
.
problem_location
,
self
.
open_ended_task_number
,
dry_run
=
True
)
self
.
assertFalse
(
dry_run_result
)
result
=
post_submission_for_student
(
self
.
student_on_initial
,
course
,
self
.
problem_location
,
self
.
open_ended_task_number
,
dry_run
=
False
)
self
.
assertFalse
(
result
)
def
test_post_submission_for_student_on_accessing
(
self
):
course
=
get_course_with_access
(
self
.
student_on_accessing
,
'load'
,
self
.
course_id
)
dry_run_result
=
post_submission_for_student
(
self
.
student_on_accessing
,
course
,
self
.
problem_location
,
self
.
open_ended_task_number
,
dry_run
=
True
)
self
.
assertFalse
(
dry_run_result
)
with
patch
(
'capa.xqueue_interface.XQueueInterface.send_to_queue'
)
as
mock_send_to_queue
:
mock_send_to_queue
.
return_value
=
(
0
,
"Successfully queued"
)
module
=
get_module_for_student
(
self
.
student_on_accessing
,
self
.
problem_location
)
module
.
child_module
.
get_task_number
(
self
.
open_ended_task_number
)
student_response
=
"Here is an answer."
student_anonymous_id
=
anonymous_id_for_user
(
self
.
student_on_accessing
,
None
)
submission_time
=
datetime
.
strftime
(
datetime
.
now
(
UTC
),
xqueue_interface
.
dateformat
)
result
=
post_submission_for_student
(
self
.
student_on_accessing
,
course
,
self
.
problem_location
,
self
.
open_ended_task_number
,
dry_run
=
False
)
self
.
assertTrue
(
result
)
mock_send_to_queue_body_arg
=
json
.
loads
(
mock_send_to_queue
.
call_args
[
1
][
'body'
])
self
.
assertEqual
(
mock_send_to_queue_body_arg
[
'max_score'
],
2
)
self
.
assertEqual
(
mock_send_to_queue_body_arg
[
'student_response'
],
student_response
)
body_arg_student_info
=
json
.
loads
(
mock_send_to_queue_body_arg
[
'student_info'
])
self
.
assertEqual
(
body_arg_student_info
[
'anonymous_student_id'
],
student_anonymous_id
)
self
.
assertGreaterEqual
(
body_arg_student_info
[
'submission_time'
],
submission_time
)
def
test_post_submission_for_student_on_post_assessment
(
self
):
course
=
get_course_with_access
(
self
.
student_on_post_assessment
,
'load'
,
self
.
course_id
)
dry_run_result
=
post_submission_for_student
(
self
.
student_on_post_assessment
,
course
,
self
.
problem_location
,
self
.
open_ended_task_number
,
dry_run
=
True
)
self
.
assertFalse
(
dry_run_result
)
result
=
post_submission_for_student
(
self
.
student_on_post_assessment
,
course
,
self
.
problem_location
,
self
.
open_ended_task_number
,
dry_run
=
False
)
self
.
assertFalse
(
result
)
def
test_post_submission_for_student_invalid_task
(
self
):
course
=
get_course_with_access
(
self
.
student_on_accessing
,
'load'
,
self
.
course_id
)
result
=
post_submission_for_student
(
self
.
student_on_accessing
,
course
,
self
.
problem_location
,
self
.
self_assessment_task_number
,
dry_run
=
False
)
self
.
assertFalse
(
result
)
out_of_bounds_task_number
=
3
result
=
post_submission_for_student
(
self
.
student_on_accessing
,
course
,
self
.
problem_location
,
out_of_bounds_task_number
,
dry_run
=
False
)
self
.
assertFalse
(
result
)
class
OpenEndedStatsTest
(
ModuleStoreTestCase
):
"""Test the openended_stats management command."""
def
setUp
(
self
):
super
(
OpenEndedStatsTest
,
self
)
.
setUp
()
self
.
user
=
UserFactory
()
store
=
modulestore
()
course_items
=
import_course_from_xml
(
store
,
self
.
user
.
id
,
TEST_DATA_DIR
,
[
'open_ended'
])
# pylint: disable=maybe-no-member
self
.
course
=
course_items
[
0
]
self
.
course_id
=
self
.
course
.
id
self
.
problem_location
=
Location
(
"edX"
,
"open_ended"
,
"2012_Fall"
,
"combinedopenended"
,
"SampleQuestion"
)
self
.
task_number
=
1
self
.
invalid_task_number
=
3
self
.
student_on_initial
=
UserFactory
()
self
.
student_on_accessing
=
UserFactory
()
self
.
student_on_post_assessment
=
UserFactory
()
StudentModuleFactory
.
create
(
course_id
=
self
.
course_id
,
module_state_key
=
self
.
problem_location
,
student
=
self
.
student_on_initial
,
grade
=
0
,
max_grade
=
1
,
state
=
STATE_INITIAL
)
StudentModuleFactory
.
create
(
course_id
=
self
.
course_id
,
module_state_key
=
self
.
problem_location
,
student
=
self
.
student_on_accessing
,
grade
=
0
,
max_grade
=
1
,
state
=
STATE_ACCESSING
)
StudentModuleFactory
.
create
(
course_id
=
self
.
course_id
,
module_state_key
=
self
.
problem_location
,
student
=
self
.
student_on_post_assessment
,
grade
=
0
,
max_grade
=
1
,
state
=
STATE_POST_ASSESSMENT
)
self
.
students
=
[
self
.
student_on_initial
,
self
.
student_on_accessing
,
self
.
student_on_post_assessment
]
def
test_calculate_task_statistics
(
self
):
course
=
get_course_with_access
(
self
.
student_on_accessing
,
'load'
,
self
.
course_id
)
stats
=
calculate_task_statistics
(
self
.
students
,
course
,
self
.
problem_location
,
self
.
task_number
,
write_to_file
=
False
)
self
.
assertEqual
(
stats
[
OpenEndedChild
.
INITIAL
],
1
)
self
.
assertEqual
(
stats
[
OpenEndedChild
.
ASSESSING
],
1
)
self
.
assertEqual
(
stats
[
OpenEndedChild
.
POST_ASSESSMENT
],
1
)
self
.
assertEqual
(
stats
[
OpenEndedChild
.
DONE
],
0
)
stats
=
calculate_task_statistics
(
self
.
students
,
course
,
self
.
problem_location
,
self
.
invalid_task_number
,
write_to_file
=
False
)
self
.
assertEqual
(
stats
[
OpenEndedChild
.
INITIAL
],
0
)
self
.
assertEqual
(
stats
[
OpenEndedChild
.
ASSESSING
],
0
)
self
.
assertEqual
(
stats
[
OpenEndedChild
.
POST_ASSESSMENT
],
0
)
self
.
assertEqual
(
stats
[
OpenEndedChild
.
DONE
],
0
)
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