diff --git a/common/lib/calc/calc/calc.py b/common/lib/calc/calc/calc.py
index 225edb495508c3427db1f43d0d3b5f62e0780561..397e1bdc671fd06c037b3ef433e592d64c798dda 100644
--- a/common/lib/calc/calc/calc.py
+++ b/common/lib/calc/calc/calc.py
@@ -458,11 +458,45 @@ class ParseAugmenter(object):
         else:
             casify = lambda x: x.lower()  # Lowercase for case insens.
 
-        # Test if casify(X) is valid, but return the actual bad input (i.e. X)
         bad_vars = set(var for var in self.variables_used
                        if casify(var) not in valid_variables)
-        bad_vars.update(func for func in self.functions_used
-                        if casify(func) not in valid_functions)
 
         if bad_vars:
-            raise UndefinedVariable(' '.join(sorted(bad_vars)))
+            varnames = ", ".join(sorted(bad_vars))
+            message = "Invalid Input: {} not permitted in answer as a variable".format(varnames)
+
+            # Check to see if there is a different case version of the variables
+            caselist = set()
+            if self.case_sensitive:
+                for var2 in bad_vars:
+                    for var1 in valid_variables:
+                        if var2.lower() == var1.lower():
+                            caselist.add(var1)
+                if len(caselist) > 0:
+                    betternames = ', '.join(sorted(caselist))
+                    message += " (did you mean " + betternames + "?)"
+
+            raise UndefinedVariable(message)
+
+        bad_funcs = set(func for func in self.functions_used
+                        if casify(func) not in valid_functions)
+        if bad_funcs:
+            funcnames = ', '.join(sorted(bad_funcs))
+            message = "Invalid Input: {} not permitted in answer as a function".format(funcnames)
+
+            # Check to see if there is a corresponding variable name
+            if any(casify(func) in valid_variables for func in bad_funcs):
+                message += " (did you forget to use * for multiplication?)"
+
+            # Check to see if there is a different case version of the function
+            caselist = set()
+            if self.case_sensitive:
+                for func2 in bad_funcs:
+                    for func1 in valid_functions:
+                        if func2.lower() == func1.lower():
+                            caselist.add(func1)
+                if len(caselist) > 0:
+                    betternames = ', '.join(sorted(caselist))
+                    message += " (did you mean " + betternames + "?)"
+
+            raise UndefinedVariable(message)
diff --git a/common/lib/calc/calc/tests/test_calc.py b/common/lib/calc/calc/tests/test_calc.py
index 73f130049b074529a07738ecbc50d15eed590d7f..c5235c253cd0a79c71f1a69c2151b3e3939db3e7 100644
--- a/common/lib/calc/calc/tests/test_calc.py
+++ b/common/lib/calc/calc/tests/test_calc.py
@@ -541,8 +541,10 @@ class EvaluatorTest(unittest.TestCase):
             calc.evaluator({}, {}, "5+7*QWSEKO")
         with self.assertRaisesRegexp(calc.UndefinedVariable, 'r2'):
             calc.evaluator({'r1': 5}, {}, "r1+r2")
-        with self.assertRaisesRegexp(calc.UndefinedVariable, 'r1 r3'):
+        with self.assertRaisesRegexp(calc.UndefinedVariable, 'r1, r3'):
             calc.evaluator(variables, {}, "r1*r3", case_sensitive=True)
+        with self.assertRaisesRegexp(calc.UndefinedVariable, 'did you forget to use \*'):
+            calc.evaluator(variables, {}, "R1(R3 + 1)")
 
     def test_mismatched_parens(self):
         """
diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py
index 4a5ce19692d9a168d1c98f4916928beb505436e2..cc549104d5d903f69628f59164c188a1302c5a67 100644
--- a/common/lib/capa/capa/responsetypes.py
+++ b/common/lib/capa/capa/responsetypes.py
@@ -1598,11 +1598,9 @@ class NumericalResponse(LoncapaResponse):
         # Catch a bunch of exceptions and give nicer messages to the student.
         try:
             student_float = evaluator({}, {}, student_answer)
-        except UndefinedVariable as undef_var:
+        except UndefinedVariable as err:
             raise StudentInputError(
-                _(u"You may not use variables ({bad_variables}) in numerical problems.").format(
-                    bad_variables=text_type(undef_var),
-                )
+                err.args[0]
             )
         except UnmatchedParenthesis as err:
             raise StudentInputError(
@@ -3110,7 +3108,7 @@ class FormulaResponse(LoncapaResponse):
                     cgi.escape(answer)
                 )
                 raise StudentInputError(
-                    _("Invalid input: {bad_input} not permitted in answer.").format(bad_input=text_type(err))
+                    err.args[0]
                 )
             except UnmatchedParenthesis as err:
                 log.debug(
diff --git a/common/lib/capa/capa/tests/test_responsetypes.py b/common/lib/capa/capa/tests/test_responsetypes.py
index b4779d6cf4c92518d2d13651548c5b95b2aab398..63c9b367efbf83d581a6b707e66f4dd3770f6834 100644
--- a/common/lib/capa/capa/tests/test_responsetypes.py
+++ b/common/lib/capa/capa/tests/test_responsetypes.py
@@ -1625,7 +1625,8 @@ class NumericalResponseTest(ResponseTest):  # pylint: disable=missing-docstring
         problem = self.build_problem(answer=4)
 
         errors = [  # (exception raised, message to student)
-            (calc.UndefinedVariable("x"), r"You may not use variables \(x\) in numerical problems"),
+            (calc.UndefinedVariable("Invalid Input: x not permitted in answer as a variable"),
+             r"Invalid Input: x not permitted in answer as a variable"),
             (ValueError("factorial() mess-up"), "Factorial function evaluated outside its domain"),
             (ValueError(), "Could not interpret '.*' as a number"),
             (pyparsing.ParseException("oopsie"), "Invalid math syntax"),