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
99e7711a
Commit
99e7711a
authored
Aug 13, 2012
by
kimth
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Generic CodeResponse XML (+ support for old ExternalResponse XML)
parent
fe954ca1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
54 additions
and
23 deletions
+54
-23
common/lib/capa/capa/capa_problem.py
+2
-2
common/lib/capa/capa/responsetypes.py
+52
-21
No files found.
common/lib/capa/capa/capa_problem.py
View file @
99e7711a
...
...
@@ -41,7 +41,7 @@ response_tag_dict = dict([(x.response_tag, x) for x in responsetypes.__all__])
entry_types
=
[
'textline'
,
'schematic'
,
'textbox'
,
'imageinput'
,
'optioninput'
,
'choicegroup'
,
'radiogroup'
,
'checkboxgroup'
,
'filesubmission'
,
'javascriptinput'
]
solution_types
=
[
'solution'
]
# extra things displayed after "show answers" is pressed
response_properties
=
[
"responseparam"
,
"answer"
]
# these get captured as student responses
response_properties
=
[
"
codeparam"
,
"
responseparam"
,
"answer"
]
# these get captured as student responses
# special problem tags which should be turned into innocuous HTML
html_transforms
=
{
'problem'
:
{
'tag'
:
'div'
},
...
...
@@ -57,7 +57,7 @@ global_context = {'random': random,
'eia'
:
eia
}
# These should be removed from HTML output, including all subelements
html_problem_semantics
=
[
"responseparam"
,
"answer"
,
"script"
,
"hintgroup"
]
html_problem_semantics
=
[
"
codeparam"
,
"
responseparam"
,
"answer"
,
"script"
,
"hintgroup"
]
log
=
logging
.
getLogger
(
'mitx.'
+
__name__
)
...
...
common/lib/capa/capa/responsetypes.py
View file @
99e7711a
...
...
@@ -1024,41 +1024,70 @@ class CodeResponse(LoncapaResponse):
self
.
url
=
xml
.
get
(
'url'
,
None
)
# XML can override external resource (grader/queue) URL
self
.
queue_name
=
xml
.
get
(
'queuename'
,
self
.
system
.
xqueue
[
'default_queuename'
])
self
.
_parse_externalresponse_xml
()
# VS[compat]:
# Check if XML uses the ExternalResponse format or the generic CodeResponse format
codeparam
=
self
.
xml
.
find
(
'codeparam'
)
if
codeparam
is
None
:
self
.
_parse_externalresponse_xml
()
else
:
self
.
_parse_coderesponse_xml
(
codeparam
)
def
_parse_coderesponse_xml
(
self
,
codeparam
):
'''
Parse the new CodeResponse XML format. When successful, sets:
self.initial_display
self.answer (an answer to display to the student in the LMS)
self.payload
'''
# Note that CodeResponse is agnostic to the specific contents of grader_payload
grader_payload
=
codeparam
.
find
(
'grader_payload'
)
grader_payload
=
grader_payload
.
text
if
grader_payload
is
not
None
else
''
self
.
payload
=
{
'grader_payload'
:
grader_payload
}
answer_display
=
codeparam
.
find
(
'answer_display'
)
if
answer_display
is
not
None
:
self
.
answer
=
answer_display
.
text
else
:
self
.
answer
=
'No answer provided.'
initial_display
=
codeparam
.
find
(
'initial_display'
)
if
initial_display
is
not
None
:
self
.
initial_display
=
initial_display
.
text
else
:
self
.
initial_display
=
''
def
_parse_externalresponse_xml
(
self
):
'''
VS[compat]: Suppport for old ExternalResponse XML format. When successful, sets:
self.code
self.tests
self.answer
self.initial_display
self.answer (an answer to display to the student in the LMS)
self.payload
'''
answer
=
self
.
xml
.
find
(
'answer'
)
if
answer
is
not
None
:
answer_src
=
answer
.
get
(
'src'
)
if
answer_src
is
not
None
:
self
.
code
=
self
.
system
.
filesystem
.
open
(
'src/'
+
answer_src
)
.
read
()
code
=
self
.
system
.
filesystem
.
open
(
'src/'
+
answer_src
)
.
read
()
else
:
self
.
code
=
answer
.
text
code
=
answer
.
text
else
:
# no <answer> stanza; get code from <script>
self
.
code
=
self
.
context
[
'script_code'
]
if
not
self
.
code
:
code
=
self
.
context
[
'script_code'
]
if
not
code
:
msg
=
'
%
s: Missing answer script code for coderesponse'
%
unicode
(
self
)
msg
+=
"
\n
See XML source line
%
s"
%
getattr
(
self
.
xml
,
'sourceline'
,
'<unavailable>'
)
raise
LoncapaProblemError
(
msg
)
self
.
tests
=
self
.
xml
.
get
(
'tests'
)
tests
=
self
.
xml
.
get
(
'tests'
)
# Extract 'answer' and 'initial_display' from XML. Note that the code to be exec'ed here is:
# (1) Internal edX code, i.e. NOT student submissions, and
# (2) The code should only define the strings 'initial_display', 'answer', 'preamble', 'test_program'
# following the
6.01 problem definition convention
# following the
ExternalResponse XML format
penv
=
{}
penv
[
'__builtins__'
]
=
globals
()[
'__builtins__'
]
try
:
exec
(
self
.
code
,
penv
,
penv
)
exec
(
code
,
penv
,
penv
)
except
Exception
as
err
:
log
.
error
(
'Error in CodeResponse
%
s: Error in problem reference code'
%
err
)
raise
Exception
(
err
)
...
...
@@ -1069,6 +1098,14 @@ class CodeResponse(LoncapaResponse):
log
.
error
(
"Error in CodeResponse
%
s: Problem reference code does not define 'answer' and/or 'initial_display' in <answer>...</answer>"
%
err
)
raise
Exception
(
err
)
# Finally, make the ExternalResponse input XML format conform to the generic exteral grader interface
# The XML tagging of grader_payload is pyxserver-specific
grader_payload
=
'<pyxserver>'
grader_payload
+=
'<tests>'
+
tests
+
'</tests>
\n
'
grader_payload
+=
'<processor>'
+
code
+
'</processor>'
grader_payload
+=
'</pyxserver>'
self
.
payload
=
{
'grader_payload'
:
grader_payload
}
def
get_score
(
self
,
student_answers
):
try
:
submission
=
student_answers
[
self
.
answer_id
]
# Note that submission can be a file
...
...
@@ -1093,22 +1130,16 @@ class CodeResponse(LoncapaResponse):
queue_name
=
self
.
queue_name
)
# Generate body
# NOTE: Currently specialized to 6.00x's pyxserver, which follows the ExternalResponse interface
# We should define a common interface for external code graders to CodeResponse
contents
=
{
'xml'
:
etree
.
tostring
(
self
.
xml
,
pretty_print
=
True
),
'edX_cmd'
:
'get_score'
,
'edX_tests'
:
self
.
tests
,
'processor'
:
self
.
code
,
}
contents
=
self
.
payload
.
copy
()
# Submit request. When successful, 'msg' is the prior length of the queue
if
is_file
(
submission
):
contents
.
update
({
'
edX_
student_response'
:
submission
.
name
})
contents
.
update
({
'student_response'
:
submission
.
name
})
(
error
,
msg
)
=
qinterface
.
send_to_queue
(
header
=
xheader
,
body
=
json
.
dumps
(
contents
),
file_to_upload
=
submission
)
else
:
contents
.
update
({
'
edX_
student_response'
:
submission
})
contents
.
update
({
'student_response'
:
submission
})
(
error
,
msg
)
=
qinterface
.
send_to_queue
(
header
=
xheader
,
body
=
json
.
dumps
(
contents
))
...
...
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