Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
E
edx-platform-release
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Package Registry
Model registry
Operate
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Hsin-Yu Chien
edx-platform-release
Commits
67d0670b
Commit
67d0670b
authored
12 years ago
by
Ned Batchelder
Browse files
Options
Downloads
Patches
Plain Diff
Symbolic response no longer runs its checker in the Python sandbox.
parent
94f6e685
Loading
Loading
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
common/lib/capa/capa/responsetypes.py
+56
-55
56 additions, 55 deletions
common/lib/capa/capa/responsetypes.py
with
56 additions
and
55 deletions
common/lib/capa/capa/responsetypes.py
+
56
−
55
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
)
#-----------------------------------------------------------------------------
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment