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
db239c69
Commit
db239c69
authored
Apr 28, 2014
by
jmclaus
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Tolerance expressed in percentage now computes correctly. [BLD-522]
parent
a8bb7689
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
133 additions
and
20 deletions
+133
-20
CHANGELOG.rst
+2
-0
common/lib/capa/capa/tests/test_responsetypes.py
+14
-3
common/lib/capa/capa/tests/test_util.py
+82
-0
common/lib/capa/capa/util.py
+35
-17
No files found.
CHANGELOG.rst
View file @
db239c69
...
@@ -5,6 +5,8 @@ These are notable changes in edx-platform. This is a rolling list of changes,
...
@@ -5,6 +5,8 @@ These are notable changes in edx-platform. This is a rolling list of changes,
in roughly chronological order, most recent first. Add your entries at or near
in roughly chronological order, most recent first. Add your entries at or near
the top. Include a label indicating the component affected.
the top. Include a label indicating the component affected.
Blades: Tolerance expressed in percentage now computes correctly. BLD-522.
Studio: Add drag-and-drop support to the container page. STUD-1309.
Studio: Add drag-and-drop support to the container page. STUD-1309.
Common: Add extensible third-party auth module.
Common: Add extensible third-party auth module.
...
...
common/lib/capa/capa/tests/test_responsetypes.py
View file @
db239c69
...
@@ -20,6 +20,7 @@ from capa.responsetypes import LoncapaProblemError, \
...
@@ -20,6 +20,7 @@ from capa.responsetypes import LoncapaProblemError, \
StudentInputError
,
ResponseError
StudentInputError
,
ResponseError
from
capa.correctmap
import
CorrectMap
from
capa.correctmap
import
CorrectMap
from
capa.util
import
convert_files_to_filenames
from
capa.util
import
convert_files_to_filenames
from
capa.util
import
compare_with_tolerance
from
capa.xqueue_interface
import
dateformat
from
capa.xqueue_interface
import
dateformat
from
pytz
import
UTC
from
pytz
import
UTC
...
@@ -1120,7 +1121,6 @@ class NumericalResponseTest(ResponseTest):
...
@@ -1120,7 +1121,6 @@ class NumericalResponseTest(ResponseTest):
# We blend the line between integration (using evaluator) and exclusively
# We blend the line between integration (using evaluator) and exclusively
# unit testing the NumericalResponse (mocking out the evaluator)
# unit testing the NumericalResponse (mocking out the evaluator)
# For simple things its not worth the effort.
# For simple things its not worth the effort.
def
test_grade_range_tolerance
(
self
):
def
test_grade_range_tolerance
(
self
):
problem_setup
=
[
problem_setup
=
[
# [given_asnwer, [list of correct responses], [list of incorrect responses]]
# [given_asnwer, [list of correct responses], [list of incorrect responses]]
...
@@ -1177,9 +1177,20 @@ class NumericalResponseTest(ResponseTest):
...
@@ -1177,9 +1177,20 @@ class NumericalResponseTest(ResponseTest):
self
.
assert_multiple_grade
(
problem
,
correct_responses
,
incorrect_responses
)
self
.
assert_multiple_grade
(
problem
,
correct_responses
,
incorrect_responses
)
def
test_grade_percent_tolerance
(
self
):
def
test_grade_percent_tolerance
(
self
):
# Positive only range
problem
=
self
.
build_problem
(
answer
=
4
,
tolerance
=
"10
%
"
)
problem
=
self
.
build_problem
(
answer
=
4
,
tolerance
=
"10
%
"
)
correct_responses
=
[
"4.0"
,
"4.3"
,
"3.7"
,
"4.30"
,
"3.70"
]
correct_responses
=
[
"4.0"
,
"4.00"
,
"4.39"
,
"3.61"
]
incorrect_responses
=
[
""
,
"4.5"
,
"3.5"
,
"0"
]
incorrect_responses
=
[
""
,
"4.41"
,
"3.59"
,
"0"
]
self
.
assert_multiple_grade
(
problem
,
correct_responses
,
incorrect_responses
)
# Negative only range
problem
=
self
.
build_problem
(
answer
=-
4
,
tolerance
=
"10
%
"
)
correct_responses
=
[
"-4.0"
,
"-4.00"
,
"-4.39"
,
"-3.61"
]
incorrect_responses
=
[
""
,
"-4.41"
,
"-3.59"
,
"0"
]
self
.
assert_multiple_grade
(
problem
,
correct_responses
,
incorrect_responses
)
# Mixed negative/positive range
problem
=
self
.
build_problem
(
answer
=
1
,
tolerance
=
"200
%
"
)
correct_responses
=
[
"1"
,
"1.00"
,
"2.99"
,
"0.99"
]
incorrect_responses
=
[
""
,
"3.01"
,
"-1.01"
]
self
.
assert_multiple_grade
(
problem
,
correct_responses
,
incorrect_responses
)
self
.
assert_multiple_grade
(
problem
,
correct_responses
,
incorrect_responses
)
def
test_floats
(
self
):
def
test_floats
(
self
):
...
...
common/lib/capa/capa/tests/test_util.py
0 → 100644
View file @
db239c69
"""Tests capa util"""
import
unittest
import
textwrap
from
.
import
test_capa_system
from
capa.util
import
compare_with_tolerance
class
UtilTest
(
unittest
.
TestCase
):
"""Tests for util"""
def
setUp
(
self
):
super
(
UtilTest
,
self
)
.
setUp
()
self
.
system
=
test_capa_system
()
def
test_compare_with_tolerance
(
self
):
# Test default tolerance '0.001%' (it is relative)
result
=
compare_with_tolerance
(
100.0
,
100.0
)
self
.
assertTrue
(
result
)
result
=
compare_with_tolerance
(
100.001
,
100.0
)
self
.
assertTrue
(
result
)
result
=
compare_with_tolerance
(
101.0
,
100.0
)
self
.
assertFalse
(
result
)
# Test absolute percentage tolerance
result
=
compare_with_tolerance
(
109.9
,
100.0
,
'10
%
'
,
False
)
self
.
assertTrue
(
result
)
result
=
compare_with_tolerance
(
110.1
,
100.0
,
'10
%
'
,
False
)
self
.
assertFalse
(
result
)
# Test relative percentage tolerance
result
=
compare_with_tolerance
(
111.0
,
100.0
,
'10
%
'
,
True
)
self
.
assertTrue
(
result
)
result
=
compare_with_tolerance
(
112.0
,
100.0
,
'10
%
'
,
True
)
self
.
assertFalse
(
result
)
# Test absolute tolerance (string)
result
=
compare_with_tolerance
(
109.9
,
100.0
,
'10.0'
,
False
)
self
.
assertTrue
(
result
)
result
=
compare_with_tolerance
(
110.1
,
100.0
,
'10.0'
,
False
)
self
.
assertFalse
(
result
)
# Test relative tolerance (string)
result
=
compare_with_tolerance
(
111.0
,
100.0
,
'0.1'
,
True
)
self
.
assertTrue
(
result
)
result
=
compare_with_tolerance
(
112.0
,
100.0
,
'0.1'
,
True
)
self
.
assertFalse
(
result
)
# Test absolute tolerance (float)
result
=
compare_with_tolerance
(
109.9
,
100.0
,
10.0
,
False
)
self
.
assertTrue
(
result
)
result
=
compare_with_tolerance
(
110.1
,
100.0
,
10.0
,
False
)
self
.
assertFalse
(
result
)
# Test relative tolerance (float)
result
=
compare_with_tolerance
(
111.0
,
100.0
,
0.1
,
True
)
self
.
assertTrue
(
result
)
result
=
compare_with_tolerance
(
112.0
,
100.0
,
0.1
,
True
)
self
.
assertFalse
(
result
)
##### Infinite values #####
infinity
=
float
(
'Inf'
)
# Test relative tolerance (float)
result
=
compare_with_tolerance
(
infinity
,
100.0
,
1.0
,
True
)
self
.
assertFalse
(
result
)
result
=
compare_with_tolerance
(
100.0
,
infinity
,
1.0
,
True
)
self
.
assertFalse
(
result
)
result
=
compare_with_tolerance
(
infinity
,
infinity
,
1.0
,
True
)
self
.
assertTrue
(
result
)
# Test absolute tolerance (float)
result
=
compare_with_tolerance
(
infinity
,
100.0
,
1.0
,
False
)
self
.
assertFalse
(
result
)
result
=
compare_with_tolerance
(
100.0
,
infinity
,
1.0
,
False
)
self
.
assertFalse
(
result
)
result
=
compare_with_tolerance
(
infinity
,
infinity
,
1.0
,
False
)
self
.
assertTrue
(
result
)
# Test relative tolerance (string)
result
=
compare_with_tolerance
(
infinity
,
100.0
,
'1.0'
,
True
)
self
.
assertFalse
(
result
)
result
=
compare_with_tolerance
(
100.0
,
infinity
,
'1.0'
,
True
)
self
.
assertFalse
(
result
)
result
=
compare_with_tolerance
(
infinity
,
infinity
,
'1.0'
,
True
)
self
.
assertTrue
(
result
)
# Test absolute tolerance (string)
result
=
compare_with_tolerance
(
infinity
,
100.0
,
'1.0'
,
False
)
self
.
assertFalse
(
result
)
result
=
compare_with_tolerance
(
100.0
,
infinity
,
'1.0'
,
False
)
self
.
assertFalse
(
result
)
result
=
compare_with_tolerance
(
infinity
,
infinity
,
'1.0'
,
False
)
self
.
assertTrue
(
result
)
common/lib/capa/capa/util.py
View file @
db239c69
...
@@ -7,16 +7,29 @@ from cmath import isinf
...
@@ -7,16 +7,29 @@ from cmath import isinf
default_tolerance
=
'0.001
%
'
default_tolerance
=
'0.001
%
'
def
compare_with_tolerance
(
complex1
,
complex2
,
tolerance
=
default_tolerance
,
relative_tolerance
=
False
):
def
compare_with_tolerance
(
student_complex
,
instructor_complex
,
tolerance
=
default_tolerance
,
relative_tolerance
=
False
):
"""
"""
Compare
complex1 to complex2 with maximum tolerance tol
.
Compare
student_complex to instructor_complex with maximum tolerance tolerance
.
If tolerance is type string, then it is counted as relative if it ends in
%
; otherwise, it is absolute.
- student_complex : student result (float complex number)
- instructor_complex : instructor result (float complex number)
- tolerance : float, or string (representing a float or a percentage)
- relative_tolerance: bool, to explicitly use passed tolerance as relative
- complex1 : student result (float complex number)
Note: when a tolerance is a percentage (i.e. '10
%
'), it will compute that
- complex2 : instructor result (float complex number)
percentage of the instructor result and yield a number.
- tolerance : string representing a number or float
- relative_tolerance: bool, used when`tolerance` is float to explicitly use passed tolerance as relative.
If relative_tolerance is set to False, it will use that value and the
instructor result to define the bounds of valid student result:
instructor_complex = 10, tolerance = '10
%
' will give [9.0, 11.0].
If relative_tolerance is set to True, it will use that value and both
instructor result and student result to define the bounds of valid student
result:
instructor_complex = 10, student_complex = 20, tolerance = '10
%
' will give
[8.0, 12.0].
This is typically used internally to compare float, with a
default_tolerance = '0.001
%
'.
Default tolerance of 1e-3
%
is added to compare two floats for
Default tolerance of 1e-3
%
is added to compare two floats for
near-equality (to handle machine representation errors).
near-equality (to handle machine representation errors).
...
@@ -29,23 +42,28 @@ def compare_with_tolerance(complex1, complex2, tolerance=default_tolerance, rela
...
@@ -29,23 +42,28 @@ def compare_with_tolerance(complex1, complex2, tolerance=default_tolerance, rela
In [212]: 1.9e24 - 1.9*10**24
In [212]: 1.9e24 - 1.9*10**24
Out[212]: 268435456.0
Out[212]: 268435456.0
"""
"""
if
isinstance
(
tolerance
,
str
):
if
tolerance
==
default_tolerance
:
relative_tolerance
=
True
if
tolerance
.
endswith
(
'
%
'
):
tolerance
=
evaluator
(
dict
(),
dict
(),
tolerance
[:
-
1
])
*
0.01
if
not
relative_tolerance
:
tolerance
=
tolerance
*
abs
(
instructor_complex
)
else
:
tolerance
=
evaluator
(
dict
(),
dict
(),
tolerance
)
if
relative_tolerance
:
if
relative_tolerance
:
tolerance
=
tolerance
*
max
(
abs
(
complex1
),
abs
(
complex2
))
tolerance
=
tolerance
*
max
(
abs
(
student_complex
),
abs
(
instructor_complex
))
elif
tolerance
.
endswith
(
'
%
'
):
tolerance
=
evaluator
(
dict
(),
dict
(),
tolerance
[:
-
1
])
*
0.01
tolerance
=
tolerance
*
max
(
abs
(
complex1
),
abs
(
complex2
))
else
:
tolerance
=
evaluator
(
dict
(),
dict
(),
tolerance
)
if
isinf
(
complex1
)
or
isinf
(
complex2
):
if
isinf
(
student_complex
)
or
isinf
(
instructor_complex
):
# If an input is infinite, we can end up with `abs(
complex1-complex2
)` and
# If an input is infinite, we can end up with `abs(
student_complex-instructor_complex
)` and
# `tolerance` both equal to infinity. Then, below we would have
# `tolerance` both equal to infinity. Then, below we would have
# `inf <= inf` which is a fail. Instead, compare directly.
# `inf <= inf` which is a fail. Instead, compare directly.
return
complex1
==
complex2
return
student_complex
==
instructor_complex
else
:
else
:
# v1 and v2 are, in general, complex numbers:
# v1 and v2 are, in general, complex numbers:
# there are some notes about backward compatibility issue: see responsetypes.get_staff_ans()).
# there are some notes about backward compatibility issue: see responsetypes.get_staff_ans()).
return
abs
(
complex1
-
complex2
)
<=
tolerance
return
abs
(
student_complex
-
instructor_complex
)
<=
tolerance
def
contextualize_text
(
text
,
context
):
# private
def
contextualize_text
(
text
,
context
):
# private
...
...
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