From 0a56652050deacbbc18c16bfd6ab45620fa9bdb9 Mon Sep 17 00:00:00 2001 From: MadScientistBR Date: Sat, 25 Jul 2026 11:53:31 -0400 Subject: [PATCH] Fixed function exponentiation not being parsed correctly (e.g. sec**2(x) -> sec(x)**2) --- app/tests/symbolic_evaluation_test.py | 52 +++++++++++++++++++++++++++ app/utility/expression_utilities.py | 4 +-- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/app/tests/symbolic_evaluation_test.py b/app/tests/symbolic_evaluation_test.py index 248db37..7ada94b 100644 --- a/app/tests/symbolic_evaluation_test.py +++ b/app/tests/symbolic_evaluation_test.py @@ -242,6 +242,58 @@ def test_recp_trig_correct(self, response, answer): result = evaluation_function(response, answer, params) assert result["is_correct"] is True + @pytest.mark.parametrize( + "response, answer", + [ + ("sec(x)^4", "sec(x)**4"), + ("sec**12(x)", "sec(x)**12"), + ("sec^3(x)", "sec(x)**3"), + ("sec**2(x)", "sec(x)^2"), + ("sec^2(x)", "sec(x)^2"), + # testing all 24 supported trig functions + ("sin**235(x)", "sin(x)**235"), + ("cos**123(x)", "cos(x)**123"), + ("tan**54(x)", "tan(x)**54"), + ("sinc**2(x)", "sinc(x)**2"), + ("csc**3(x)", "csc(x)**3"), + ("sec**6(x)", "sec(x)**6"), + ("cot**5(x)", "cot(x)**5"), + ("asin**75(x)", "asin(x)**75"), + ("acos**3(x)", "acos(x)**3"), + ("atan**2(x)", "atan(x)**2"), + ("acsc**9(x)", "acsc(x)**9"), + ("asec**7(x)", "asec(x)**7"), + ("acot**9(x)", "acot(x)**9"), + ("atan2**2(x,y)", "atan2(x,y)**2"), + ("sinh**4(x)", "sinh(x)**4"), + ("cosh**11(x)", "cosh(x)**11"), + ("tanh**8(x)", "tanh(x)**8"), + ("csch**5(x)", "csch(x)**5"), + ("sech**6(x)", "sech(x)**6"), + ("asinh**13(x)", "asinh(x)**13"), + ("acosh**4(x)", "acosh(x)**4"), + ("atanh**9(x)", "atanh(x)**9"), + ("acsch**7(x)", "acsch(x)**7"), + ("asech**5(x)", "asech(x)**5"), + ] + ) + def test_trig_expt_correct(self, response, answer): + params = {"strict_syntax": False} + result = evaluation_function(response, answer, params) + assert result["is_correct"] is True + + @pytest.mark.parametrize( + "response, answer", + [ + ("2sec**2(x)", "2*sec(x)**2"), + ("Bsec**2(x)", "B*sec(x)**2"), + ] + ) + def test_trig_expt_with_adjacent_implicit_multiplication_correct(self, response, answer): + params = {"strict_syntax": False, "elementary_functions": True} + result = evaluation_function(response, answer, params) + assert result["is_correct"] is True + @pytest.mark.parametrize( "response,answer", generate_input_variations( diff --git a/app/utility/expression_utilities.py b/app/utility/expression_utilities.py index b915bc5..0cb688a 100644 --- a/app/utility/expression_utilities.py +++ b/app/utility/expression_utilities.py @@ -810,9 +810,9 @@ def parse_expression(expr_string, parsing_params): can_split = lambda x: False if x in unsplittable_symbols else _token_splittable(x) if strict_syntax is True: - transformations = parser_transformations[0:4] + extra_transformations + transformations = parser_transformations[0:4, 10] + extra_transformations else: - transformations = (parser_transformations[0:5, 6] + extra_transformations + + transformations = (parser_transformations[0:5, 6, 10] + extra_transformations + (split_symbols_custom(can_split),) + parser_transformations[8, 9]) if parsing_params.get("rationalise", False):