Commit 31d8fa15 by Peter Baratta

Change calc's API: `evaluator` to use `case_sensitive` rather than `cs`

Double check that this does not introduce any errors. Also, get rid of old tests in xmodule (they are replicated in calc/tests/test_calc.py).
parent 80befacb
...@@ -325,14 +325,13 @@ def add_defaults(variables, functions, case_sensitive): ...@@ -325,14 +325,13 @@ def add_defaults(variables, functions, case_sensitive):
return (all_variables, all_functions) return (all_variables, all_functions)
def evaluator(variables, functions, string, cs=False): def evaluator(variables, functions, string, case_sensitive=False):
""" """
Evaluate an expression; that is, take a string of math and return a float Evaluate an expression; that is, take a string of math and return a float
-Variables are passed as a dictionary from string to value. They must be -Variables are passed as a dictionary from string to value. They must be
python numbers python numbers
-Unary functions are passed as a dictionary from string to function. -Unary functions are passed as a dictionary from string to function.
-cs: Case sensitive
""" """
# No need to go further # No need to go further
if string.strip() == "": if string.strip() == "":
...@@ -342,13 +341,13 @@ def evaluator(variables, functions, string, cs=False): ...@@ -342,13 +341,13 @@ def evaluator(variables, functions, string, cs=False):
tree = parse_algebra(string) tree = parse_algebra(string)
# Get our variables together # Get our variables together
all_variables, all_functions = add_defaults(variables, functions, cs) all_variables, all_functions = add_defaults(variables, functions, case_sensitive)
# ...and check them # ...and check them
check_variables(tree, set(all_variables), set(all_functions), cs) check_variables(tree, set(all_variables), set(all_functions), case_sensitive)
# Create a recursion to evaluate the tree # Create a recursion to evaluate the tree
casify = lambda x: x if cs else x.lower() # Lowercase for case insens. casify = lambda x: x if case_sensitive else x.lower() # Lowercase for case insens.
evaluate_action = { evaluate_action = {
'number': eval_number, 'number': eval_number,
'variable': lambda x: all_variables[casify(x[0])], 'variable': lambda x: all_variables[casify(x[0])],
......
...@@ -470,10 +470,15 @@ class EvaluatorTest(unittest.TestCase): ...@@ -470,10 +470,15 @@ class EvaluatorTest(unittest.TestCase):
variables = {'t': 1.0} variables = {'t': 1.0}
self.assertEqual(calc.evaluator(variables, {}, "t"), 1.0) self.assertEqual(calc.evaluator(variables, {}, "t"), 1.0)
self.assertEqual(calc.evaluator(variables, {}, "T"), 1.0) self.assertEqual(calc.evaluator(variables, {}, "T"), 1.0)
self.assertEqual(calc.evaluator(variables, {}, "t", cs=True), 1.0) self.assertEqual(
calc.evaluator(variables, {}, "t", case_sensitive=True),
1.0
)
# Recall 'T' is a default constant, with value 298.15 # Recall 'T' is a default constant, with value 298.15
self.assertAlmostEqual(calc.evaluator(variables, {}, "T", cs=True), self.assertAlmostEqual(
298, delta=0.2) calc.evaluator(variables, {}, "T", case_sensitive=True),
298, delta=0.2
)
def test_simple_funcs(self): def test_simple_funcs(self):
""" """
...@@ -502,8 +507,10 @@ class EvaluatorTest(unittest.TestCase): ...@@ -502,8 +507,10 @@ class EvaluatorTest(unittest.TestCase):
self.assertEqual(calc.evaluator({}, functions, 'f(6)'), self.assertEqual(calc.evaluator({}, functions, 'f(6)'),
calc.evaluator({}, functions, 'F(6)')) calc.evaluator({}, functions, 'F(6)'))
# Test case sensitive evaluation # Test case sensitive evaluation
self.assertNotEqual(calc.evaluator({}, functions, 'f(6)', cs=True), self.assertNotEqual(
calc.evaluator({}, functions, 'F(6)', cs=True)) calc.evaluator({}, functions, 'f(6)', case_sensitive=True),
calc.evaluator({}, functions, 'F(6)', case_sensitive=True)
)
def test_undefined_vars(self): def test_undefined_vars(self):
""" """
...@@ -521,5 +528,5 @@ class EvaluatorTest(unittest.TestCase): ...@@ -521,5 +528,5 @@ class EvaluatorTest(unittest.TestCase):
) )
self.assertRaises( self.assertRaises(
calc.UndefinedVariable, calc.evaluator, calc.UndefinedVariable, calc.evaluator,
variables, {}, "r1*r3", cs=True variables, {}, "r1*r3", case_sensitive=True
) )
...@@ -1748,15 +1748,19 @@ class FormulaResponse(LoncapaResponse): ...@@ -1748,15 +1748,19 @@ class FormulaResponse(LoncapaResponse):
student_variables[str(var)] = value student_variables[str(var)] = value
# log.debug('formula: instructor_vars=%s, expected=%s' % # log.debug('formula: instructor_vars=%s, expected=%s' %
# (instructor_variables,expected)) # (instructor_variables,expected))
instructor_result = evaluator(instructor_variables, dict(), instructor_result = evaluator(
expected, cs=self.case_sensitive) instructor_variables, dict(),
expected, case_sensitive=self.case_sensitive
)
try: try:
# log.debug('formula: student_vars=%s, given=%s' % # log.debug('formula: student_vars=%s, given=%s' %
# (student_variables,given)) # (student_variables,given))
student_result = evaluator(student_variables, student_result = evaluator(
dict(), student_variables,
given, dict(),
cs=self.case_sensitive) given,
case_sensitive=self.case_sensitive
)
except UndefinedVariable as uv: except UndefinedVariable as uv:
log.debug( log.debug(
'formularesponse: undefined variable in given=%s' % given) 'formularesponse: undefined variable in given=%s' % given)
......
...@@ -71,51 +71,6 @@ class ModelsTest(unittest.TestCase): ...@@ -71,51 +71,6 @@ class ModelsTest(unittest.TestCase):
vc_str = "<class 'xmodule.video_module.VideoDescriptor'>" vc_str = "<class 'xmodule.video_module.VideoDescriptor'>"
self.assertEqual(str(vc), vc_str) self.assertEqual(str(vc), vc_str)
def test_calc(self):
variables = {'R1': 2.0, 'R3': 4.0}
functions = {'sin': numpy.sin, 'cos': numpy.cos}
self.assertTrue(abs(calc.evaluator(variables, functions, "10000||sin(7+5)+0.5356")) < 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({}, {}, "-1"), -1)
self.assertEqual(calc.evaluator({}, {}, "-0.33"), -.33)
self.assertEqual(calc.evaluator({}, {}, "-.33"), -.33)
self.assertEqual(calc.evaluator(variables, functions, "R1*R3"), 8.0)
self.assertTrue(abs(calc.evaluator(variables, functions, "sin(e)-0.41")) < 0.01)
self.assertTrue(abs(calc.evaluator(variables, functions, "k*T/q-0.025")) < 0.001)
self.assertTrue(abs(calc.evaluator(variables, functions, "e^(j*pi)") + 1) < 0.00001)
self.assertTrue(abs(calc.evaluator(variables, functions, "j||1") - 0.5 - 0.5j) < 0.00001)
variables['t'] = 1.0
# Use self.assertAlmostEqual here...
self.assertTrue(abs(calc.evaluator(variables, functions, "t") - 1.0) < 0.00001)
self.assertTrue(abs(calc.evaluator(variables, functions, "T") - 1.0) < 0.00001)
self.assertTrue(abs(calc.evaluator(variables, functions, "t", cs=True) - 1.0) < 0.00001)
self.assertTrue(abs(calc.evaluator(variables, functions, "T", cs=True) - 298) < 0.2)
# Use self.assertRaises here...
exception_happened = False
try:
calc.evaluator({}, {}, "5+7 QWSEKO")
except:
exception_happened = True
self.assertTrue(exception_happened)
try:
calc.evaluator({'r1': 5}, {}, "r1+r2")
except calc.UndefinedVariable:
pass
self.assertEqual(calc.evaluator(variables, functions, "r1*r3"), 8.0)
exception_happened = False
try:
calc.evaluator(variables, functions, "r1*r3", cs=True)
except:
exception_happened = True
self.assertTrue(exception_happened)
class PostData(object): class PostData(object):
"""Class which emulate postdata.""" """Class which emulate postdata."""
def __init__(self, dict_data): def __init__(self, dict_data):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment