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
c34a81a8
Commit
c34a81a8
authored
Jul 10, 2013
by
Felix Sun
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactored formula response grader to expose formula-evaluating to outside world.
In preparation for adding hints to formula response.
parent
69380756
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
47 additions
and
41 deletions
+47
-41
common/lib/capa/capa/responsetypes.py
+47
-41
No files found.
common/lib/capa/capa/responsetypes.py
View file @
c34a81a8
...
@@ -1778,46 +1778,24 @@ class FormulaResponse(LoncapaResponse):
...
@@ -1778,46 +1778,24 @@ class FormulaResponse(LoncapaResponse):
self
.
correct_answer
,
given
,
self
.
samples
)
self
.
correct_answer
,
given
,
self
.
samples
)
return
CorrectMap
(
self
.
answer_id
,
correctness
)
return
CorrectMap
(
self
.
answer_id
,
correctness
)
def
check_formula
(
self
,
expected
,
given
,
samples
):
def
hash_answers
(
self
,
answer
,
var_dict_list
):
variables
=
samples
.
split
(
'@'
)[
0
]
.
split
(
','
)
"""
numsamples
=
int
(
samples
.
split
(
'@'
)[
1
]
.
split
(
'#'
)[
1
])
Takes in an answer and a list of dictionaries mapping variables to values.
sranges
=
zip
(
*
map
(
lambda
x
:
map
(
float
,
x
.
split
(
","
)),
Each dictionary represents a test case for the answer.
samples
.
split
(
'@'
)[
1
]
.
split
(
'#'
)[
0
]
.
split
(
':'
)))
Returns a tuple of formula evaluation results.
"""
ranges
=
dict
(
zip
(
variables
,
sranges
))
out
=
[]
for
_
in
range
(
numsamples
):
for
var_dict
in
var_dict_list
:
instructor_variables
=
self
.
strip_dict
(
dict
(
self
.
context
))
student_variables
=
{}
# ranges give numerical ranges for testing
for
var
in
ranges
:
# TODO: allow specified ranges (i.e. integers and complex numbers) for random variables
value
=
random
.
uniform
(
*
ranges
[
var
])
instructor_variables
[
str
(
var
)]
=
value
student_variables
[
str
(
var
)]
=
value
# log.debug('formula: instructor_vars=%s, expected=%s' %
# (instructor_variables,expected))
# Call `evaluator` on the instructor's answer and get a number
instructor_result
=
evaluator
(
instructor_variables
,
{},
expected
,
case_sensitive
=
self
.
case_sensitive
)
try
:
try
:
# log.debug('formula: student_vars=%s, given=%s' %
out
.
append
(
evaluator
(
# (student_variables,given))
var_dict
,
dict
(),
# Call `evaluator` on the student's answer; look for exceptions
answer
,
student_result
=
evaluator
(
cs
=
self
.
case_sensitive
,
student_variables
,
))
{},
given
,
case_sensitive
=
self
.
case_sensitive
)
except
UndefinedVariable
as
uv
:
except
UndefinedVariable
as
uv
:
log
.
debug
(
log
.
debug
(
'formularesponse: undefined variable in given=
%
s'
,
'formularesponse: undefined variable in formula=
%
s'
%
answer
)
given
)
raise
StudentInputError
(
raise
StudentInputError
(
"Invalid input: "
+
uv
.
message
+
" not permitted in answer"
"Invalid input: "
+
uv
.
message
+
" not permitted in answer"
)
)
...
@@ -1840,15 +1818,43 @@ class FormulaResponse(LoncapaResponse):
...
@@ -1840,15 +1818,43 @@ class FormulaResponse(LoncapaResponse):
# If non-factorial related ValueError thrown, handle it the same as any other Exception
# If non-factorial related ValueError thrown, handle it the same as any other Exception
log
.
debug
(
'formularesponse: error {0} in formula'
.
format
(
ve
))
log
.
debug
(
'formularesponse: error {0} in formula'
.
format
(
ve
))
raise
StudentInputError
(
"Invalid input: Could not parse '
%
s' as a formula"
%
raise
StudentInputError
(
"Invalid input: Could not parse '
%
s' as a formula"
%
cgi
.
escape
(
given
))
cgi
.
escape
(
answer
))
except
Exception
as
err
:
except
Exception
as
err
:
# traceback.print_exc()
# traceback.print_exc()
log
.
debug
(
'formularesponse: error
%
s in formula'
,
err
)
log
.
debug
(
'formularesponse: error
%
s in formula'
,
err
)
raise
StudentInputError
(
"Invalid input: Could not parse '
%
s' as a formula"
%
raise
StudentInputError
(
"Invalid input: Could not parse '
%
s' as a formula"
%
cgi
.
escape
(
given
))
cgi
.
escape
(
answer
))
return
tuple
(
out
)
def
randomize_variables
(
self
,
samples
):
"""
Returns a list of dictionaries mapping variables to random values in range,
as expected by hash_answers.
"""
variables
=
samples
.
split
(
'@'
)[
0
]
.
split
(
','
)
numsamples
=
int
(
samples
.
split
(
'@'
)[
1
]
.
split
(
'#'
)[
1
])
sranges
=
zip
(
*
map
(
lambda
x
:
map
(
float
,
x
.
split
(
","
)),
samples
.
split
(
'@'
)[
1
]
.
split
(
'#'
)[
0
]
.
split
(
':'
)))
ranges
=
dict
(
zip
(
variables
,
sranges
))
out
=
[]
for
i
in
range
(
numsamples
):
var_dict
=
{}
# ranges give numerical ranges for testing
for
var
in
ranges
:
# TODO: allow specified ranges (i.e. integers and complex numbers) for random variables
value
=
random
.
uniform
(
*
ranges
[
var
])
var_dict
[
str
(
var
)]
=
value
out
.
append
(
var_dict
)
return
out
def
check_formula
(
self
,
expected
,
given
,
samples
):
var_dict_list
=
self
.
randomize_variables
(
samples
)
student_result
=
self
.
hash_answers
(
given
,
var_dict_list
)
instructor_result
=
self
.
hash_answers
(
expected
,
var_dict_list
)
# No errors in student's response--actually test for correctness
for
i
in
xrange
(
len
(
instructor_result
)):
if
not
compare_with_tolerance
(
student_result
,
instructor_result
,
self
.
tolerance
):
if
not
compare_with_tolerance
(
student_result
[
i
],
instructor_result
[
i
]
,
self
.
tolerance
):
return
"incorrect"
return
"incorrect"
return
"correct"
return
"correct"
...
...
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