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
67d0670b
Commit
67d0670b
authored
Feb 21, 2013
by
Ned Batchelder
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Symbolic response no longer runs its checker in the Python sandbox.
parent
94f6e685
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
56 additions
and
55 deletions
+56
-55
common/lib/capa/capa/responsetypes.py
+56
-55
No files found.
common/lib/capa/capa/responsetypes.py
View file @
67d0670b
...
...
@@ -927,19 +927,17 @@ class CustomResponse(LoncapaResponse):
# actual function that will re-execute the original script,
# and invoke the function with the data needed.
def
make_check_function
(
script_code
,
cfn
):
def
check_function
(
expect
,
ans
,
**
kwargs
):
code
=
[
script_code
,
"kwargs = {}"
]
for
name
,
val
in
kwargs
.
iteritems
():
if
isinstance
(
val
,
(
str
,
list
,
tuple
,
int
,
long
,
float
,
dict
)):
code
.
append
(
"kwargs[
%
r] =
%
r"
%
(
name
,
val
))
code
.
append
(
"cfn_return =
%
s(expect, ans, **kwargs)"
%
cfn
)
code
.
append
(
""
)
# a final newline
def
check_function
(
expect
,
ans
):
code
=
(
script_code
+
"
\n
"
+
"cfn_return =
%
s(expect, ans)
\n
"
%
cfn
)
globals_dict
=
{
'expect'
:
expect
,
'ans'
:
ans
,
}
locals_dict
=
{}
safe_exec
.
safe_exec
(
"
\n
"
.
join
(
code
)
,
globals_dict
,
locals_dict
)
safe_exec
.
safe_exec
(
code
,
globals_dict
,
locals_dict
)
return
locals_dict
[
'cfn_return'
]
return
check_function
...
...
@@ -958,8 +956,6 @@ class CustomResponse(LoncapaResponse):
else
:
self
.
code
=
answer
.
text
self
.
cfn_kwargs_keys
=
[]
def
get_score
(
self
,
student_answers
):
'''
student_answers is a dict with everything from request.POST, but with the first part
...
...
@@ -1038,16 +1034,30 @@ class CustomResponse(LoncapaResponse):
# pass self.system.debug to cfn
self
.
context
[
'debug'
]
=
self
.
system
.
DEBUG
# Run the check function
self
.
execute_check_function
(
idset
,
submission
)
# build map giving "correct"ness of the answer(s)
correct
=
self
.
context
[
'correct'
]
messages
=
self
.
context
[
'messages'
]
correct_map
=
CorrectMap
()
overall_message
=
self
.
clean_message_html
(
self
.
context
[
'overall_message'
]))
correct_map
.
set_overall_message
(
overall_message
)
for
k
in
range
(
len
(
idset
)):
npoints
=
self
.
maxpoints
[
idset
[
k
]]
if
correct
[
k
]
==
'correct'
else
0
correct_map
.
set
(
idset
[
k
],
correct
[
k
],
msg
=
messages
[
k
],
npoints
=
npoints
)
return
correct_map
def
execute_check_function
(
self
,
idset
,
submission
):
# exec the check function
if
isinstance
(
self
.
code
,
basestring
):
try
:
locals_dict
=
{}
safe_exec
.
safe_exec
(
self
.
code
,
self
.
context
,
locals_dict
)
self
.
context
.
update
(
locals_dict
)
correct
=
self
.
context
[
'correct'
]
messages
=
self
.
context
[
'messages'
]
overall_message
=
self
.
context
[
'overall_message'
]
except
Exception
as
err
:
self
.
_handle_exec_exception
(
err
)
...
...
@@ -1056,33 +1066,27 @@ class CustomResponse(LoncapaResponse):
# this is an interface to the Tutor2 check functions
fn
=
self
.
code
ret
=
None
log
.
debug
(
" submission =
%
s"
%
submission
)
try
:
answer_given
=
submission
[
0
]
if
(
len
(
idset
)
==
1
)
else
submission
kwargs
=
{
n
:
self
.
context
.
get
(
n
)
for
n
in
self
.
cfn_kwargs_keys
}
ret
=
fn
(
self
.
expect
,
answer_given
,
**
kwargs
)
ret
=
fn
(
self
.
expect
,
answer_given
)
except
Exception
as
err
:
self
.
_handle_exec_exception
(
err
)
if
type
(
ret
)
==
dict
:
log
.
error
(
"oops in customresponse (cfn) error
%
s"
%
err
)
# print "context = ",self.context
log
.
error
(
traceback
.
format_exc
())
raise
Exception
(
"oops in customresponse (cfn) error
%
s"
%
err
)
log
.
debug
(
"[courseware.capa.responsetypes.customresponse.get_score] ret =
%
s"
,
ret
)
if
isinstance
(
ret
,
dict
):
# One kind of dictionary the check function can return has the
# form {'ok': BOOLEAN, 'msg': STRING}
# If there are multiple inputs, they all get marked
# to the same correct/incorrect value
if
'ok'
in
ret
:
correct
=
[
'correct'
]
*
len
(
idset
)
if
ret
[
'ok'
]
else
[
'incorrect'
]
*
len
(
idset
)
msg
=
ret
.
get
(
'msg'
,
None
)
msg
=
self
.
clean_message_html
(
msg
)
# If there is only one input, apply the message to that input
# Otherwise, apply the message to the whole problem
if
len
(
idset
)
>
1
:
overall_message
=
msg
else
:
messages
[
0
]
=
msg
correct
=
[
'correct'
if
ret
[
'ok'
]
else
'incorrect'
]
*
len
(
idset
)
self
.
context
[
'messages'
][
0
]
=
self
.
clean_message_html
(
ret
[
'msg'
])
# Another kind of dictionary the check function can return has
# the form:
...
...
@@ -1104,6 +1108,7 @@ class CustomResponse(LoncapaResponse):
msg
=
(
self
.
clean_message_html
(
input_dict
[
'msg'
])
if
'msg'
in
input_dict
else
None
)
messages
.
append
(
msg
)
self
.
context
[
'messages'
]
=
messages
# Otherwise, we do not recognize the dictionary
# Raise an exception
...
...
@@ -1112,25 +1117,10 @@ class CustomResponse(LoncapaResponse):
raise
ResponseError
(
"CustomResponse: check function returned an invalid dict"
)
# The check function can return a boolean value,
# indicating whether all inputs should be marked
# correct or incorrect
else
:
n
=
len
(
idset
)
correct
=
[
'correct'
]
*
n
if
ret
else
[
'incorrect'
]
*
n
# build map giving "correct"ness of the answer(s)
correct_map
=
CorrectMap
()
overall_message
=
self
.
clean_message_html
(
overall_message
)
correct_map
.
set_overall_message
(
overall_message
)
correct
=
[
'correct'
if
ret
else
'incorrect'
]
*
len
(
idset
)
for
k
in
range
(
len
(
idset
)):
npoints
=
(
self
.
maxpoints
[
idset
[
k
]]
if
correct
[
k
]
==
'correct'
else
0
)
correct_map
.
set
(
idset
[
k
],
correct
[
k
],
msg
=
messages
[
k
],
npoints
=
npoints
)
return
correct_map
self
.
context
[
'correct'
]
=
correct
def
clean_message_html
(
self
,
msg
):
...
...
@@ -1205,12 +1195,23 @@ class SymbolicResponse(CustomResponse):
response_tag
=
'symbolicresponse'
def
setup_response
(
self
):
# No, this is not pretty.
self
.
context
[
'script_code'
]
+=
"from symmath import symmath_check
\n
"
self
.
xml
.
set
(
'cfn'
,
'symmath_check'
)
CustomResponse
.
setup_response
(
self
)
self
.
cfn_kwargs_keys
.
extend
([
'dynamath'
,
'options'
,
'debug'
])
def
execute_check_function
(
self
,
idset
,
submission
):
from
symmath
import
symmath_check
fn
=
self
.
code
try
:
answer_given
=
submission
[
0
]
if
(
len
(
idset
)
==
1
)
else
submission
ret
=
symmath_check
(
self
.
expect
,
answer_given
,
dynamath
=
self
.
context
.
get
(
'dynamath'
),
options
=
self
.
context
.
get
(
'options'
),
debug
=
self
.
context
.
get
(
'debug'
),
)
except
Exception
as
err
:
log
.
error
(
"oops in symbolicresponse (cfn) error
%
s"
%
err
)
log
.
error
(
traceback
.
format_exc
())
raise
Exception
(
"oops in symbolicresponse (cfn) error
%
s"
%
err
)
self
.
context
[
'messages'
][
0
]
=
self
.
clean_message_html
(
ret
[
'msg'
])
self
.
context
[
'correct'
]
=
[
'correct'
if
ret
[
'ok'
]
else
'incorrect'
]
*
len
(
idset
)
#-----------------------------------------------------------------------------
...
...
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