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

Code before:
    .. manim:: ParaSurface
        :save_last_frame:

        class ParaSurface(ThreeDScene):
            def func(self, u, v):
                return np.array([np.cos(u) * np.cos(v), np.cos(u) * np.sin(v), u])

            def construct(self):
                axes = ThreeDAxes(x_range=[-4,4], x_length=8)
                surface = ParametricSurface(
                    lambda u, v: axes.c2p(*self.func(u, v)),
                    u_range=[-PI, PI],
                    v_range=[0, TAU]
                )
                self.set_camera_orientation(theta=70 * DEGREES, phi=75 * DEGREES)
                self.add(axes, surface)
    """

    def __init__(
        self,
        func,
        u_range=[0, 1],
        v_range=[0, 1],
        resolution=32,
        surface_piece_config={},
        fill_color=BLUE_D,
        fill_opacity=1.0,
        checkerboard_colors=[BLUE_D, BLUE_E],
        stroke_color=LIGHT_GREY,
        stroke_width=0.5,
        should_make_jagged=False,
        pre_function_handle_to_anchor_scale_factor=0.00001,
        **kwargs
    ):
        VGroup.__init__(self, **kwargs)
        self.u_min = u_range[0]
        self.u_max = u_range[1]
        self.v_min = v_range[0]
        self.v_max = v_range[1]
        self.resolution = resolution
        self.surface_piece_config = surface_piece_config
        self.fill_color = fill_color
        self.fill_opacity = fill_opacity
        self.checkerboard_colors = checkerboard_colors
        self.stroke_color = stroke_color
        self.stroke_width = stroke_width
        self.should_make_jagged = should_make_jagged
        self.pre_function_handle_to_anchor_scale_factor = (
            pre_function_handle_to_anchor_scale_factor
        )
        self.func = func

Review comment (suggestion):
Currently, these are breaking changes since inputting `u_min/u_max` would error out, which I'm generally okay with but would like to avoid when unecessary. Since we have @deprecated_params now, I think we should try to use it here to prevent old code from breaking. I used it in another PR to deprecate `size`, [see here](https://github.com/ManimCommunity/manim/blob/5320a6e8f12b0145582dfd9a42b03e617bf9c1a9/manim/mobject/svg/text_mobject.py#L396-L433). You could try to follow a similar approach.

Be sure to place the decorator before `__init__`, otherwise you won't be able to subclass the class.

Code after:
        super().__init__(shade_in_3d=shade_in_3d, **kwargs)


class ParametricSurface(VGroup):
    """Creates a Parametric Surface

    Parameters
    ----------
    func :
        The function that defines the surface.
    u_range :
        The range of the ``u`` variable: ``(u_min, u_max)``.
    v_range :
        The range of the ``v`` variable: ``(v_min, v_max)``.
    resolution :
        The number of samples taken of the surface. A tuple
        can be used to define different resolutions for ``u`` and
        ``v`` respectively.

    Examples
    --------
    .. manim:: ParaSurface
        :save_last_frame:

        class ParaSurface(ThreeDScene):
            def func(self, u, v):
                return np.array([np.cos(u) * np.cos(v), np.cos(u) * np.sin(v), u])

            def construct(self):
                axes = ThreeDAxes(x_range=[-4,4], x_length=8)
                surface = ParametricSurface(
                    lambda u, v: axes.c2p(*self.func(u, v)),
                    u_range=[-PI, PI],
                    v_range=[0, TAU]
                )
                self.set_camera_orientation(theta=70 * DEGREES, phi=75 * DEGREES)
                self.add(axes, surface)
    """

    @deprecated_params(
        params="u_min,u_max,v_min,v_max",
        since="v0.9.0",
        until="v0.10.0",
        message="Use u_range and v_range instead.",
    )
    def __init__(
        self,
        func: Callable[[float, float], np.ndarray],
        u_range: Sequence[float] = [0, 1],
        v_range: Sequence[float] = [0, 1],
        resolution: Sequence[int] = 32,