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
5e8d2ce4
Commit
5e8d2ce4
authored
May 20, 2013
by
Peter Baratta
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Start making comprehensive calc tests
parent
f63a4432
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
266 additions
and
0 deletions
+266
-0
common/lib/calc/tests/test_calc.py
+266
-0
No files found.
common/lib/calc/tests/test_calc.py
0 → 100644
View file @
5e8d2ce4
"""
unittests for calc.py
Run like this:
rake test_common/lib/calc ??
"""
import
unittest
import
numpy
import
calc
class
EvaluatorTest
(
unittest
.
TestCase
):
''' Run tests for calc.evaluator
Go through all functionalities as specifically as possible--
work from number input to functions and complex expressions
Also test custom variable substitutions (i.e.
`evaluator({'x':3.0},{}, '3*x')`
gives 9.0) and more.
'''
def
test_number_input
(
self
):
''' Test different kinds of float inputs '''
easy_eval
=
lambda
x
:
calc
.
evaluator
({},
{},
x
)
self
.
assertEqual
(
easy_eval
(
"13"
),
13
)
self
.
assertEqual
(
easy_eval
(
"3.14"
),
3.14
)
self
.
assertEqual
(
easy_eval
(
".618033989"
),
0.618033989
)
self
.
assertEqual
(
easy_eval
(
"-13"
),
-
13
)
self
.
assertEqual
(
easy_eval
(
"-3.14"
),
-
3.14
)
self
.
assertEqual
(
easy_eval
(
"-.618033989"
),
-
0.618033989
)
# see also test_exponential_answer
# and test_si_suffix
def
test_exponential_answer
(
self
):
''' Test for correct interpretation of scientific notation'''
answer
=
50
correct_responses
=
[
"50"
,
"50.0"
,
"5e1"
,
"5e+1"
,
"50e0"
,
"50.0e0"
,
"500e-1"
]
incorrect_responses
=
[
""
,
"3.9"
,
"4.1"
,
"0"
,
"5.01e1"
]
for
input_str
in
correct_responses
:
result
=
calc
.
evaluator
({},
{},
input_str
)
fail_msg
=
"Failed when checking '{0}' against {1} (expected equality)"
.
format
(
input_str
,
answer
)
self
.
assertEqual
(
answer
,
result
,
msg
=
fail_msg
)
for
input_str
in
incorrect_responses
:
result
=
calc
.
evaluator
({},
{},
input_str
)
fail_msg
=
"Failed when checking '{0}' against {1} (expected inequality)"
.
format
(
input_str
,
answer
)
self
.
assertNotEqual
(
answer
,
result
,
msg
=
fail_msg
)
def
test_si_suffix
(
self
):
''' Test calc.py's unique functionality of interpreting si 'suffixes'.
For instance 'k' stand for 'kilo-' so '1k' should be 1,000 '''
test_mapping
=
[(
'4.2
%
'
,
0.042
),
(
'2.25k'
,
2250
),
(
'8.3M'
,
8300000
),
(
'9.9G'
,
9.9e9
),
(
'1.2T'
,
1.2e12
),
(
'7.4c'
,
0.074
),
(
'5.4m'
,
0.0054
),
(
'8.7u'
,
0.0000087
),
(
'5.6n'
,
5.6e-9
),
(
'4.2p'
,
4.2e-12
)]
for
(
expr
,
answer
)
in
test_mapping
:
tolerance
=
answer
*
1e-6
# Testing exactly fails for the large values
fail_msg
=
"Failure in testing suffix '{0}': '{1}' was not {2}"
.
format
(
expr
[
-
1
],
expr
,
answer
)
self
.
assertAlmostEqual
(
calc
.
evaluator
({},
{},
expr
),
answer
,
delta
=
tolerance
,
msg
=
fail_msg
)
def
test_operator_sanity
(
self
):
''' Test for simple things like "5+2" and "5/2"'''
var1
=
5.0
var2
=
2.0
operators
=
[(
'+'
,
7
),
(
'-'
,
3
),
(
'*'
,
10
),
(
'/'
,
2.5
),
(
'^'
,
25
)]
for
(
operator
,
answer
)
in
operators
:
input_str
=
"{0} {1} {2}"
.
format
(
var1
,
operator
,
var2
)
result
=
calc
.
evaluator
({},
{},
input_str
)
fail_msg
=
"Failed on operator '{0}': '{1}' was not {2}"
.
format
(
operator
,
input_str
,
answer
)
self
.
assertEqual
(
answer
,
result
,
msg
=
fail_msg
)
self
.
assertRaises
(
ZeroDivisionError
,
calc
.
evaluator
,
{},
{},
'1/0'
)
def
test_parallel_resistors
(
self
):
''' Test the special operator ||
The formula is given by
a || b || c ...
= 1 / (1/a + 1/b + 1/c + ...)
It is the resistance of a parallel circuit of resistors with resistance
a, b, c, etc&. See if this evaulates correctly.'''
self
.
assertEqual
(
calc
.
evaluator
({},
{},
'1||1'
),
0.5
)
self
.
assertEqual
(
calc
.
evaluator
({},
{},
'1||1||2'
),
0.4
)
# I don't know why you would want this, but it works.
self
.
assertEqual
(
calc
.
evaluator
({},
{},
"j||1"
),
0.5
+
0.5
j
)
self
.
assertRaises
(
ZeroDivisionError
,
calc
.
evaluator
,
{},
{},
'0||1'
)
def
assert_function_values
(
self
,
fname
,
ins
,
outs
,
tolerance
=
1e-3
):
''' Helper function to test many values at once
Test the accuracy of evaluator's use of the function given by fname
Specifically, the equality of `fname(ins[i])` against outs[i].
Used later to test a whole bunch of f(x) = y at a time '''
for
(
arg
,
val
)
in
zip
(
ins
,
outs
):
input_str
=
"{0}({1})"
.
format
(
fname
,
arg
)
result
=
calc
.
evaluator
({},
{},
input_str
)
fail_msg
=
"Failed on function {0}: '{1}' was not {2}"
.
format
(
fname
,
input_str
,
val
)
self
.
assertAlmostEqual
(
val
,
result
,
delta
=
tolerance
,
msg
=
fail_msg
)
def
test_trig_functions
(
self
):
"""Test the trig functions provided in common/lib/calc/calc.py"""
# which are: sin, cos, tan, arccos, arcsin, arctan
angles
=
[
'-pi/4'
,
'0'
,
'pi/6'
,
'pi/5'
,
'5*pi/4'
,
'9*pi/4'
,
'j'
,
'1 + j'
]
sin_values
=
[
-
0.707
,
0
,
0.5
,
0.588
,
-
0.707
,
0.707
,
1.175
j
,
1.298
+
0.635
j
]
cos_values
=
[
0.707
,
1
,
0.866
,
0.809
,
-
0.707
,
0.707
,
1.543
,
0.834
-
0.989
j
]
tan_values
=
[
-
1
,
0
,
0.577
,
0.727
,
1
,
1
,
0.762
j
,
0.272
+
1.084
j
]
# Cannot test tan(pi/2) b/c pi/2 is a float and not precise...
self
.
assert_function_values
(
'sin'
,
angles
,
sin_values
)
self
.
assert_function_values
(
'cos'
,
angles
,
cos_values
)
self
.
assert_function_values
(
'tan'
,
angles
,
tan_values
)
# include those where the real part is between -pi/2 and pi/2
arcsin_inputs
=
[
'-0.707'
,
'0'
,
'0.5'
,
'0.588'
,
'1.298 + 0.635*j'
]
arcsin_angles
=
[
-
0.785
,
0
,
0.524
,
0.629
,
1
+
1
j
]
self
.
assert_function_values
(
'arcsin'
,
arcsin_inputs
,
arcsin_angles
)
# rather than throwing an exception, numpy.arcsin gives nan
# self.assertTrue(numpy.isnan(calc.evaluator({}, {}, 'arcsin(-1.1)')))
# self.assertTrue(numpy.isnan(calc.evaluator({}, {}, 'arcsin(1.1)')))
# disabled for now because they are giving a runtime warning... :-/
# include those where the real part is between 0 and pi
arccos_inputs
=
[
'1'
,
'0.866'
,
'0.809'
,
'0.834-0.989*j'
]
arccos_angles
=
[
0
,
0.524
,
0.628
,
1
+
1
j
]
self
.
assert_function_values
(
'arccos'
,
arccos_inputs
,
arccos_angles
)
# self.assertTrue(numpy.isnan(calc.evaluator({}, {}, 'arccos(-1.1)')))
# self.assertTrue(numpy.isnan(calc.evaluator({}, {}, 'arccos(1.1)')))
# has the same range as arcsin
arctan_inputs
=
[
'-1'
,
'0'
,
'0.577'
,
'0.727'
,
'0.272 + 1.084*j'
]
arctan_angles
=
arcsin_angles
self
.
assert_function_values
(
'arctan'
,
arctan_inputs
,
arctan_angles
)
def
test_other_functions
(
self
):
"""Test the other functions provided in common/lib/calc/calc.py"""
# sqrt, log10, log2, ln, abs,
# fact, factorial
# test sqrt
self
.
assert_function_values
(
'sqrt'
,
[
0
,
1
,
2
,
1024
],
# -1
[
0
,
1
,
1.414
,
32
])
# 1j
# sqrt(-1) is NAN not j (!!).
# test logs
self
.
assert_function_values
(
'log10'
,
[
0.1
,
1
,
3.162
,
1000000
,
'1+j'
],
[
-
1
,
0
,
0.5
,
6
,
0.151
+
0.341
j
])
self
.
assert_function_values
(
'log2'
,
[
0.5
,
1
,
1.414
,
1024
,
'1+j'
],
[
-
1
,
0
,
0.5
,
10
,
0.5
+
1.133
j
])
self
.
assert_function_values
(
'ln'
,
[
0.368
,
1
,
1.649
,
2.718
,
42
,
'1+j'
],
[
-
1
,
0
,
0.5
,
1
,
3.738
,
0.347
+
0.785
j
])
# test abs
self
.
assert_function_values
(
'abs'
,
[
-
1
,
0
,
1
,
'j'
],
[
1
,
0
,
1
,
1
])
# test factorial
fact_inputs
=
[
0
,
1
,
3
,
7
]
fact_values
=
[
1
,
1
,
6
,
5040
]
self
.
assert_function_values
(
'fact'
,
fact_inputs
,
fact_values
)
self
.
assert_function_values
(
'factorial'
,
fact_inputs
,
fact_values
)
self
.
assertRaises
(
ValueError
,
calc
.
evaluator
,
{},
{},
"fact(-1)"
)
self
.
assertRaises
(
ValueError
,
calc
.
evaluator
,
{},
{},
"fact(0.5)"
)
self
.
assertRaises
(
ValueError
,
calc
.
evaluator
,
{},
{},
"factorial(-1)"
)
self
.
assertRaises
(
ValueError
,
calc
.
evaluator
,
{},
{},
"factorial(0.5)"
)
def
test_constants
(
self
):
"""Test the default constants provided in common/lib/calc/calc.py"""
# which are: j (complex number), e, pi, k, c, T, q
# ('expr', python value, tolerance (or None for exact))
default_variables
=
[(
'j'
,
1
j
,
None
),
(
'e'
,
2.7183
,
1e-3
),
(
'pi'
,
3.1416
,
1e-3
),
# c = speed of light
(
'c'
,
2.998e8
,
1e5
),
# 0 deg C = T Kelvin
(
'T'
,
298.15
,
0.01
),
# note k = scipy.constants.k = 1.3806488e-23
(
'k'
,
1.3806488e-23
,
1e-26
),
# note q = scipy.constants.e = 1.602176565e-19
(
'q'
,
1.602176565e-19
,
1e-22
)]
for
(
variable
,
value
,
tolerance
)
in
default_variables
:
fail_msg
=
"Failed on constant '{0}', not within bounds"
.
format
(
variable
)
result
=
calc
.
evaluator
({},
{},
variable
)
if
tolerance
is
None
:
self
.
assertEqual
(
value
,
result
,
msg
=
fail_msg
)
else
:
self
.
assertAlmostEqual
(
value
,
result
,
delta
=
tolerance
,
msg
=
fail_msg
)
def
test_complex_expression
(
self
):
"""We've only tried simple things so far, make sure it can handle a
more complexity than this."""
self
.
assertAlmostEqual
(
calc
.
evaluator
({},
{},
"(2^2+1.0)/sqrt(5e0)*5-1"
),
10.180
,
delta
=
1e-3
)
self
.
assertAlmostEqual
(
calc
.
evaluator
({},
{},
"1+1/(1+1/(1+1/(1+1)))"
),
1.6
,
delta
=
1e-3
)
self
.
assertAlmostEqual
(
calc
.
evaluator
({},
{},
"10||sin(7+5)"
),
-
0.567
,
delta
=
0.01
)
def
test_calc
(
self
):
variables
=
{
'R1'
:
2.0
,
'R3'
:
4.0
}
functions
=
{
'sin'
:
numpy
.
sin
,
'cos'
:
numpy
.
cos
}
self
.
assertAlmostEqual
(
calc
.
evaluator
(
variables
,
functions
,
"10||sin(7+5)"
),
-
0.567
,
delta
=
0.01
)
self
.
assertEqual
(
calc
.
evaluator
({
'R1'
:
2.0
,
'R3'
:
4.0
},
{},
"13"
),
13
)
self
.
assertEqual
(
calc
.
evaluator
(
variables
,
functions
,
"13"
),
13
)
self
.
assertEqual
(
calc
.
evaluator
({
'a'
:
2.2997471478310274
,
'k'
:
9
,
'm'
:
8
,
'x'
:
0.66009498411213041
},
{},
"5"
),
5
)
self
.
assertEqual
(
calc
.
evaluator
(
variables
,
functions
,
"R1*R3"
),
8.0
)
self
.
assertAlmostEqual
(
calc
.
evaluator
(
variables
,
functions
,
"sin(e)"
),
0.41
,
delta
=
0.01
)
self
.
assertAlmostEqual
(
calc
.
evaluator
(
variables
,
functions
,
"k*T/q"
),
0.025
,
delta
=
1e-3
)
self
.
assertAlmostEqual
(
calc
.
evaluator
(
variables
,
functions
,
"e^(j*pi)"
),
-
1
,
delta
=
1e-5
)
variables
[
't'
]
=
1.0
self
.
assertAlmostEqual
(
calc
.
evaluator
(
variables
,
functions
,
"t"
),
1.0
,
delta
=
1e-5
)
self
.
assertAlmostEqual
(
calc
.
evaluator
(
variables
,
functions
,
"T"
),
1.0
,
delta
=
1e-5
)
self
.
assertAlmostEqual
(
calc
.
evaluator
(
variables
,
functions
,
"t"
,
cs
=
True
),
1.0
,
delta
=
1e-5
)
self
.
assertAlmostEqual
(
calc
.
evaluator
(
variables
,
functions
,
"T"
,
cs
=
True
),
298
,
delta
=
0.2
)
self
.
assertRaises
(
calc
.
UndefinedVariable
,
calc
.
evaluator
,
{},
{},
"5+7 QWSEKO"
)
self
.
assertRaises
(
calc
.
UndefinedVariable
,
calc
.
evaluator
,
{
'r1'
:
5
},
{},
"r1+r2"
)
self
.
assertEqual
(
calc
.
evaluator
(
variables
,
functions
,
"r1*r3"
),
8.0
)
self
.
assertRaises
(
calc
.
UndefinedVariable
,
calc
.
evaluator
,
variables
,
functions
,
"r1*r3"
,
cs
=
True
)
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