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):
...
@@ -927,19 +927,17 @@ class CustomResponse(LoncapaResponse):
# actual function that will re-execute the original script,
# actual function that will re-execute the original script,
# and invoke the function with the data needed.
# and invoke the function with the data needed.
def
make_check_function
(
script_code
,
cfn
):
def
make_check_function
(
script_code
,
cfn
):
def
check_function
(
expect
,
ans
,
**
kwargs
):
def
check_function
(
expect
,
ans
):
code
=
[
script_code
,
"kwargs = {}"
]
code
=
(
for
name
,
val
in
kwargs
.
iteritems
():
script_code
+
"
\n
"
+
if
isinstance
(
val
,
(
str
,
list
,
tuple
,
int
,
long
,
float
,
dict
)):
"cfn_return =
%
s(expect, ans)
\n
"
%
cfn
code
.
append
(
"kwargs[
%
r] =
%
r"
%
(
name
,
val
))
)
code
.
append
(
"cfn_return =
%
s(expect, ans, **kwargs)"
%
cfn
)
code
.
append
(
""
)
# a final newline
globals_dict
=
{
globals_dict
=
{
'expect'
:
expect
,
'expect'
:
expect
,
'ans'
:
ans
,
'ans'
:
ans
,
}
}
locals_dict
=
{}
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
locals_dict
[
'cfn_return'
]
return
check_function
return
check_function
...
@@ -958,8 +956,6 @@ class CustomResponse(LoncapaResponse):
...
@@ -958,8 +956,6 @@ class CustomResponse(LoncapaResponse):
else
:
else
:
self
.
code
=
answer
.
text
self
.
code
=
answer
.
text
self
.
cfn_kwargs_keys
=
[]
def
get_score
(
self
,
student_answers
):
def
get_score
(
self
,
student_answers
):
'''
'''
student_answers is a dict with everything from request.POST, but with the first part
student_answers is a dict with everything from request.POST, but with the first part
...
@@ -1038,16 +1034,30 @@ class CustomResponse(LoncapaResponse):
...
@@ -1038,16 +1034,30 @@ class CustomResponse(LoncapaResponse):
# pass self.system.debug to cfn
# pass self.system.debug to cfn
self
.
context
[
'debug'
]
=
self
.
system
.
DEBUG
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
# exec the check function
if
isinstance
(
self
.
code
,
basestring
):
if
isinstance
(
self
.
code
,
basestring
):
try
:
try
:
locals_dict
=
{}
locals_dict
=
{}
safe_exec
.
safe_exec
(
self
.
code
,
self
.
context
,
locals_dict
)
safe_exec
.
safe_exec
(
self
.
code
,
self
.
context
,
locals_dict
)
self
.
context
.
update
(
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
:
except
Exception
as
err
:
self
.
_handle_exec_exception
(
err
)
self
.
_handle_exec_exception
(
err
)
...
@@ -1056,33 +1066,27 @@ class CustomResponse(LoncapaResponse):
...
@@ -1056,33 +1066,27 @@ class CustomResponse(LoncapaResponse):
# this is an interface to the Tutor2 check functions
# this is an interface to the Tutor2 check functions
fn
=
self
.
code
fn
=
self
.
code
ret
=
None
log
.
debug
(
" submission =
%
s"
%
submission
)
log
.
debug
(
" submission =
%
s"
%
submission
)
try
:
try
:
answer_given
=
submission
[
0
]
if
(
len
(
idset
)
==
1
)
else
submission
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
)
ret
=
fn
(
self
.
expect
,
answer_given
,
**
kwargs
)
except
Exception
as
err
:
except
Exception
as
err
:
self
.
_handle_exec_exception
(
err
)
log
.
error
(
"oops in customresponse (cfn) error
%
s"
%
err
)
# print "context = ",self.context
if
type
(
ret
)
==
dict
:
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
# One kind of dictionary the check function can return has the
# form {'ok': BOOLEAN, 'msg': STRING}
# form {'ok': BOOLEAN, 'msg': STRING}
# If there are multiple inputs, they all get marked
# If there are multiple inputs, they all get marked
# to the same correct/incorrect value
# to the same correct/incorrect value
if
'ok'
in
ret
:
if
'ok'
in
ret
:
correct
=
[
'correct'
]
*
len
(
idset
)
if
ret
[
correct
=
[
'correct'
if
ret
[
'ok'
]
else
'incorrect'
]
*
len
(
idset
)
'ok'
]
else
[
'incorrect'
]
*
len
(
idset
)
self
.
context
[
'messages'
][
0
]
=
self
.
clean_message_html
(
ret
[
'msg'
])
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
# Another kind of dictionary the check function can return has
# Another kind of dictionary the check function can return has
# the form:
# the form:
...
@@ -1104,6 +1108,7 @@ class CustomResponse(LoncapaResponse):
...
@@ -1104,6 +1108,7 @@ class CustomResponse(LoncapaResponse):
msg
=
(
self
.
clean_message_html
(
input_dict
[
'msg'
])
msg
=
(
self
.
clean_message_html
(
input_dict
[
'msg'
])
if
'msg'
in
input_dict
else
None
)
if
'msg'
in
input_dict
else
None
)
messages
.
append
(
msg
)
messages
.
append
(
msg
)
self
.
context
[
'messages'
]
=
messages
# Otherwise, we do not recognize the dictionary
# Otherwise, we do not recognize the dictionary
# Raise an exception
# Raise an exception
...
@@ -1112,25 +1117,10 @@ class CustomResponse(LoncapaResponse):
...
@@ -1112,25 +1117,10 @@ class CustomResponse(LoncapaResponse):
raise
ResponseError
(
raise
ResponseError
(
"CustomResponse: check function returned an invalid dict"
)
"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
:
else
:
n
=
len
(
idset
)
correct
=
[
'correct'
if
ret
else
'incorrect'
]
*
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
)
for
k
in
range
(
len
(
idset
)):
self
.
context
[
'correct'
]
=
correct
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
clean_message_html
(
self
,
msg
):
def
clean_message_html
(
self
,
msg
):
...
@@ -1205,12 +1195,23 @@ class SymbolicResponse(CustomResponse):
...
@@ -1205,12 +1195,23 @@ class SymbolicResponse(CustomResponse):
response_tag
=
'symbolicresponse'
response_tag
=
'symbolicresponse'
def
setup_response
(
self
):
def
execute_check_function
(
self
,
idset
,
submission
):
# No, this is not pretty.
from
symmath
import
symmath_check
self
.
context
[
'script_code'
]
+=
"from symmath import symmath_check
\n
"
fn
=
self
.
code
self
.
xml
.
set
(
'cfn'
,
'symmath_check'
)
try
:
CustomResponse
.
setup_response
(
self
)
answer_given
=
submission
[
0
]
if
(
len
(
idset
)
==
1
)
else
submission
self
.
cfn_kwargs_keys
.
extend
([
'dynamath'
,
'options'
,
'debug'
])
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