Repository: ManimCommunity/manim
File: manim/mobject/types/vectorized_mobject.py (Python)

Code before:
        Raises
        ------
        :exc:`ValueError`
            If ``point`` does not lie on the curve.
        :exc:`Exception`
            If the :class:`VMobject` has no points.
        """
        self.throw_error_if_no_points()

        nc = self.get_num_curves()
        vmob_length = sum(self.get_nth_curve_length(i) for i in range(nc))
        total_length = 0
        for n in range(nc):
            control_points = self.get_nth_curve_points(n)
            length = self.get_nth_curve_length(n)
            if point_lies_on_bezier(point, control_points):
                t = max(bez_params_from_point(point, control_points))
                total_length += length * t
                break
            else:
                total_length += length
        else:
            raise ValueError(f"Point {point} does not lie on this curve.")
        alpha = total_length / vmob_length

        return alpha

    def get_anchors_and_handles(self) -> typing.Iterable[np.ndarray]:
        """Returns anchors1, handles1, handles2, anchors2,
        where (anchors1[i], handles1[i], handles2[i], anchors2[i])
        will be four points defining a cubic bezier curve
        for any i in range(0, len(anchors1))

        Returns
        -------
        typing.Iterable[np.ndarray]
            Iterable of the anchors and handles.
        """
        nppcc = self.n_points_per_cubic_curve
        return [self.points[i::nppcc] for i in range(nppcc)]

    def get_start_anchors(self) -> np.ndarray:
        """Returns the start anchors of the bezier curves.

        Returns
        -------
        np.ndarray
            Starting anchors
        """
        return self.points[0 :: self.n_points_per_cubic_curve]


Review comment (suggestion):
```suggestion

        alpha = total_length / vmob_length
        return alpha
```

Code after:
        Returns
        -------
        curve : typing.Callable[[float], np.ndarray]
            The function for the nth curve.
        length : :class:`float`
            The length of the nth curve.
        """

        if sample_points is None:
            sample_points = 10

        curve = self.get_nth_curve_function(n)

        points = np.array([curve(a) for a in np.linspace(0, 1, sample_points)])
        diffs = points[1:] - points[:-1]
        norms = np.apply_along_axis(np.linalg.norm, 1, diffs)

        length = np.sum(norms)

        return curve, length

    def get_num_curves(self) -> int:
        """Returns the number of curves of the vmobject.

        Returns
        -------
        int
            number of curves. of the vmobject.
        """
        nppcc = self.n_points_per_cubic_curve
        return len(self.points) // nppcc

    def get_curve_functions(
        self,
    ) -> typing.Iterable[typing.Callable[[float], np.ndarray]]:
        """Gets the functions for the curves of the mobject.

        Returns
        -------
        typing.Iterable[typing.Callable[[float], np.ndarray]]
            The functions for the curves.
        """

        num_curves = self.get_num_curves()

        for n in range(num_curves):
            yield self.get_nth_curve_function(n)

    def get_curve_functions_with_lengths(
        self, **kwargs
    ) -> typing.Iterable[typing.Tuple[typing.Callable[[float], np.ndarray], float]]: