From 44c1f419c40141228be507bc00de927f7964c765 Mon Sep 17 00:00:00 2001 From: Serena Caraco <15524864+SybelBlue@users.noreply.github.com> Date: Tue, 22 Sep 2026 14:52:30 -0700 Subject: [PATCH 1/2] Implement suggested change --- sketchresponse/grader_lib/CurveFunction.py | 9 ++++++--- test_grader_lib/testSplineFunctionMethods.py | 21 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/sketchresponse/grader_lib/CurveFunction.py b/sketchresponse/grader_lib/CurveFunction.py index 3c4c034..d3c0083 100644 --- a/sketchresponse/grader_lib/CurveFunction.py +++ b/sketchresponse/grader_lib/CurveFunction.py @@ -172,10 +172,13 @@ def get_x_for_yval(self, yval: float) -> list[float]: p = np.poly1d(self.y) tvals = (p - yval).roots xvals = [self.get_x_for_t(t) for t in tvals] - xvals = [val for val in xvals if np.imag(val) == 0] - return xvals + return [ + float(np.real(value)) + for value in xvals + if abs(np.imag(value)) < self.tolerance["imag_threshold"] + ] - def get_x_for_t(self, t: float) -> float: + def get_x_for_t(self, t: complex) -> complex: x = ( (1 - t) ** 3 * self.p0[0] + 3 * (1 - t) ** 2 * t * self.p1[0] diff --git a/test_grader_lib/testSplineFunctionMethods.py b/test_grader_lib/testSplineFunctionMethods.py index 5457eb6..92e2519 100644 --- a/test_grader_lib/testSplineFunctionMethods.py +++ b/test_grader_lib/testSplineFunctionMethods.py @@ -2,6 +2,7 @@ from typing import cast from sketchresponse.grader_lib.Axis import Axis +from sketchresponse.grader_lib.CurveFunction import CurveFunction from sketchresponse.grader_lib.SplineFunction import SplineFunction from sketchresponse.types import SketchGrader @@ -29,5 +30,25 @@ def test_custom_tolerance_is_applied(self): self.assertEqual(len(sf.functions), 1) +class TestCurveFunction(unittest.TestCase): + def test_get_x_for_yval_returns_real_floats(self): + xaxis = Axis([0, 1], 100) + yaxis = Axis([1, 0], 100) + path_info: list[list[float]] = [ + [0, 100], + [100 / 3, 100], + [200 / 3, 100], + [100, 0], + ] + grader = cast(SketchGrader, {"tolerance": 10, "debug": False}) + curve = CurveFunction(xaxis, yaxis, path_info, grader, "test-tool") + + xvals = curve.get_x_for_yval(0.125) + + self.assertEqual(len(xvals), 1) + self.assertAlmostEqual(xvals[0], 0.5) + self.assertListEqual([float] * len(xvals), [type(x) for x in xvals]) + + if __name__ == "__main__": unittest.main() From 544f53c35ded49d6d29353636053849eff4b9cea Mon Sep 17 00:00:00 2001 From: Serena Caraco <15524864+SybelBlue@users.noreply.github.com> Date: Wed, 23 Sep 2026 09:58:06 -0700 Subject: [PATCH 2/2] Filter CurveFunction roots before scaling --- sketchresponse/grader_lib/CurveFunction.py | 7 +++---- test_grader_lib/testSplineFunctionMethods.py | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/sketchresponse/grader_lib/CurveFunction.py b/sketchresponse/grader_lib/CurveFunction.py index d3c0083..334ad78 100644 --- a/sketchresponse/grader_lib/CurveFunction.py +++ b/sketchresponse/grader_lib/CurveFunction.py @@ -171,11 +171,10 @@ def get_value_at(self, xval: float) -> float | None: def get_x_for_yval(self, yval: float) -> list[float]: p = np.poly1d(self.y) tvals = (p - yval).roots - xvals = [self.get_x_for_t(t) for t in tvals] return [ - float(np.real(value)) - for value in xvals - if abs(np.imag(value)) < self.tolerance["imag_threshold"] + float(np.real(self.get_x_for_t(t))) + for t in tvals + if abs(np.imag(t)) < self.tolerance["imag_threshold"] ] def get_x_for_t(self, t: complex) -> complex: diff --git a/test_grader_lib/testSplineFunctionMethods.py b/test_grader_lib/testSplineFunctionMethods.py index 92e2519..e0ca998 100644 --- a/test_grader_lib/testSplineFunctionMethods.py +++ b/test_grader_lib/testSplineFunctionMethods.py @@ -49,6 +49,23 @@ def test_get_x_for_yval_returns_real_floats(self): self.assertAlmostEqual(xvals[0], 0.5) self.assertListEqual([float] * len(xvals), [type(x) for x in xvals]) + def test_get_x_for_yval_filters_complex_roots_before_scaling(self): + xaxis = Axis([0, 1e-6], 100) + yaxis = Axis([1, 0], 100) + path_info: list[list[float]] = [ + [0, 100], + [100, 100], + [0, 100], + [100, 0], + ] + grader = cast(SketchGrader, {"tolerance": 10, "debug": False}) + curve = CurveFunction(xaxis, yaxis, path_info, grader, "test-tool") + + xvals = curve.get_x_for_yval(0.125) + + self.assertEqual(len(xvals), 1) + self.assertAlmostEqual(xvals[0], 5e-7) + if __name__ == "__main__": unittest.main()