ronantakizawa/codereview-bench huggingface dataset:
Repository: ManimCommunity/manim
File: manim/mobject/value_tracker.py (Python)

Code before:
    .. manim:: ComplexValueTrackerExample

        class ComplexValueTrackerExample(Scene):
            def construct(self):
                tracker = ComplexValueTracker(-2+1j)
                dot = Dot().add_updater(
                    lambda x: x.move_to(tracker.points)
                )

                self.add(NumberPlane(), dot)

                self.play(tracker.animate.set_value(3+2j))
                self.play(tracker.animate.set_value(tracker.get_value() * 1j))
                self.play(tracker.animate.set_value(tracker.get_value() - 2j))
                self.play(tracker.animate.set_value(tracker.get_value() / (-2 + 3j)))
    """

    def get_value(self) -> complex:  # type: ignore [override]
        """Get the current value of this ComplexValueTracker as a complex number."""
        return complex(*self.points[0, :2])

    def set_value(self, value: complex | float) -> Self:
        """Sets a new complex value to the ComplexValueTracker."""
        z = complex(value)
        self.points[0, :2] = (z.real, z.imag)
        return self


Review comment (suggestion):
Do not know how to resolve this. 
Between ``ValueTracker`` and ``ComplexValueTracker``, the latter makes more sense as the base class not the other way around, but that would be a large re-write.

Code after:

    The value is internally stored as a points array [a, b, 0]. This can be accessed directly
    to represent the value geometrically, see the usage example.
    When the value is set through :attr:`animate`, the value will take a straight path from the
    source point to the destination point.

    Examples
    --------
    .. manim:: ComplexValueTrackerExample

        class ComplexValueTrackerExample(Scene):
            def construct(self):
                tracker = ComplexValueTracker(-2+1j)
                dot = Dot().add_updater(
                    lambda x: x.move_to(tracker.points)
                )

                self.add(NumberPlane(), dot)

                self.play(tracker.animate.set_value(3+2j))
                self.play(tracker.animate.set_value(tracker.get_value() * 1j))
                self.play(tracker.animate.set_value(tracker.get_value() - 2j))
                self.play(tracker.animate.set_value(tracker.get_value() / (-2 + 3j)))
    """

    def get_value(self) -> complex:  # type: ignore [override]
        """Get the current value of this ComplexValueTracker as a complex number."""
        return complex(*self.points[0, :2])

    def set_value(self, value: complex | float) -> Self:
        """Sets a new complex value to the ComplexValueTracker."""
        z = complex(value)
        self.points[0, :2] = (z.real, z.imag)
        return self
Repository: ManimCommunity/manim
File: manim/mobject/mobject.py (Python)

Code before:
        vectors
            Vectors to shift by. If multiple vectors are given, they are added
            together.

        Returns
        -------
        :class:`Mobject`
            ``self``

        See also
        --------
        :meth:`move_to`
        """
        total_vector = reduce(op.add, vectors)
        for mob in self.family_members_with_points():
            mob.points = mob.points.astype("float")
            mob.points += total_vector

        return self

    def scale(
        self,
        scale_factor: float,
        *,
        about_point: Point3DLike | None = None,
        about_edge: Vector3D | None = None,
    ) -> Self:
        r"""Scale the size by a factor.

        Default behavior is to scale about the center of the mobject.

        Parameters
        ----------
        scale_factor
            The scaling factor :math:`\alpha`. If :math:`0 < |\alpha| < 1`, the mobject
            will shrink, and for :math:`|\alpha| > 1` it will grow. Furthermore,
            if :math:`\alpha < 0`, the mobject is also flipped.
        about_point
            The point about which to apply the scaling.
        about_edge
            The edge about which to apply the scaling.

        Returns
        -------
        :class:`Mobject`
            ``self``

        Examples
        --------

        .. manim:: MobjectScaleExample

Review comment (suggestion):
Since PR #4068 was merged, now we have the `Vector3DLike` alias. Could you please use that one for all these `about_edge` parameters?
```suggestion
        about_edge: Vector3DLike | None = None,
```

Code after:
        ----------
        vectors
            Vectors to shift by. If multiple vectors are given, they are added
            together.

        Returns
        -------
        :class:`Mobject`
            ``self``

        See also
        --------
        :meth:`move_to`
        """
        total_vector = reduce(op.add, vectors)
        for mob in self.family_members_with_points():
            mob.points = mob.points.astype("float")
            mob.points += total_vector

        return self

    def scale(
        self,
        scale_factor: float,
        *,
        about_point: Point3DLike | None = None,
        about_edge: Vector3DLike | None = None,
    ) -> Self:
        r"""Scale the size by a factor.

        Default behavior is to scale about the center of the mobject.

        Parameters
        ----------
        scale_factor
            The scaling factor :math:`\alpha`. If :math:`0 < |\alpha| < 1`, the mobject
            will shrink, and for :math:`|\alpha| > 1` it will grow. Furthermore,
            if :math:`\alpha < 0`, the mobject is also flipped.
        about_point
            The point about which to apply the scaling.
        about_edge
            The edge about which to apply the scaling.

        Returns
        -------
        :class:`Mobject`
            ``self``

        Examples
        --------
Repository: ManimCommunity/manim
File: manim/utils/images.py (Python)

Code before:
def get_full_raster_image_path(image_file_name: str | PurePath) -> Path:
    return seek_full_path_from_defaults(
        image_file_name,
        default_dir=config.get_dir("assets_dir"),
        extensions=[".jpg", ".jpeg", ".png", ".gif", ".ico"],
    )


def get_full_vector_image_path(image_file_name: str | PurePath) -> Path:
    return seek_full_path_from_defaults(
        image_file_name,
        default_dir=config.get_dir("assets_dir"),
        extensions=[".svg"],
    )


def drag_pixels(frames: list[np.ndarray]) -> list[np.ndarray]:
    curr = frames[0]
    new_frames: list[np.ndarray] = []
    for frame in frames:
        curr += (curr == 0) * np.array(frame)
        new_frames.append(np.array(curr))
    return new_frames


def invert_image(image: np.ndarray) -> Image.Image:
    arr = np.array(image)
    arr = (255 * np.ones(arr.shape)).astype(arr.dtype) - arr
    return Image.fromarray(arr)


def change_to_rgba_array(image: RGBPixelArray, dtype: str = "uint8") -> RGBPixelArray:
    """Converts an RGB array into RGBA with the alpha value opacity maxed."""
    pa = image
    if len(pa.shape) == 2:
        pa = pa.reshape(list(pa.shape) + [1])
    if pa.shape[2] == 1:
        pa = pa.repeat(3, axis=2)
    if pa.shape[2] == 3:
        alphas = 255 * np.ones(
            list(pa.shape[:2]) + [1],
            dtype=dtype,
        )
        pa = np.append(pa, alphas, axis=2)
    return pa


Review comment (suggestion):
```suggestion
def invert_image(image: PixelArray) -> Image.Image:
```

Code after:
def get_full_raster_image_path(image_file_name: str | PurePath) -> Path:
    return seek_full_path_from_defaults(
        image_file_name,
        default_dir=config.get_dir("assets_dir"),
        extensions=[".jpg", ".jpeg", ".png", ".gif", ".ico"],
    )


def get_full_vector_image_path(image_file_name: str | PurePath) -> Path:
    return seek_full_path_from_defaults(
        image_file_name,
        default_dir=config.get_dir("assets_dir"),
        extensions=[".svg"],
    )


def drag_pixels(frames: Sequence[PixelArray]) -> list[np.ndarray]:
    curr = frames[0]
    new_frames: list[np.ndarray] = []
    for frame in frames:
        curr += (curr == 0) * np.array(frame)
        new_frames.append(np.array(curr))
    return new_frames


def invert_image(image: PixelArray) -> Image:
    arr = np.array(image)
    arr = (255 * np.ones(arr.shape)).astype(arr.dtype) - arr
    return Image.fromarray(arr)


def change_to_rgba_array(image: RGBPixelArray, dtype: str = "uint8") -> RGBAPixelArray:
    """Converts an RGB array into RGBA with the alpha value opacity maxed."""
    pa = image
    if len(pa.shape) == 2:
        pa = pa.reshape(list(pa.shape) + [1])
    if pa.shape[2] == 1:
        pa = pa.repeat(3, axis=2)
    if pa.shape[2] == 3:
        alphas = 255 * np.ones(
            list(pa.shape[:2]) + [1],
            dtype=dtype,
        )
        pa = np.append(pa, alphas, axis=2)
    return pa
Repository: ManimCommunity/manim
File: manim/mobject/graphing/scale.py (Python)

Code before:
        if condition:
            raise ValueError(
                "log(0) is undefined. Make sure the value is in the domain of the function"
            )
        value = func(value, self.base)
        return value

    def get_custom_labels(
        self,
        val_range: Iterable[float],
        unit_decimal_places: int = 0,
        **base_config: dict[str, Any],
    ) -> list[Mobject]:
        """Produces custom :class:`~.Integer` labels in the form of ``10^2``.

        Parameters
        ----------
        val_range
            The iterable of values used to create the labels. Determines the exponent.
        unit_decimal_places
            The number of decimal places to include in the exponent
        base_config
            Additional arguments to be passed to :class:`~.Integer`.
        """
        # uses `format` syntax to control the number of decimal places.
        tex_labels: list[Mobject] = [
            Integer(
                self.base,
                unit="^{%s}" % (f"{self.inverse_function(i):.{unit_decimal_places}f}"),  # noqa: UP031
                **base_config,  # type: ignore[arg-type]
            )
            for i in val_range
        ]
        return tex_labels


Review comment (suggestion):
Instead of typing `tex_labels` as `list[Mobject]`, I believe that changing the return type of the `.get_custom_labels()` method itself to `list[Integer]` would be better.

Code after:
        if condition:
            raise ValueError(
                "log(0) is undefined. Make sure the value is in the domain of the function"
            )
        value = func(value, self.base)
        return value

    def get_custom_labels(
        self,
        val_range: Iterable[float],
        unit_decimal_places: int = 0,
        **base_config: Any,
    ) -> list[Integer]:
        """Produces custom :class:`~.Integer` labels in the form of ``10^2``.

        Parameters
        ----------
        val_range
            The iterable of values used to create the labels. Determines the exponent.
        unit_decimal_places
            The number of decimal places to include in the exponent
        base_config
            Additional arguments to be passed to :class:`~.Integer`.
        """
        # uses `format` syntax to control the number of decimal places.
        tex_labels = [
            Integer(
                self.base,
                unit="^{%s}" % (f"{self.inverse_function(i):.{unit_decimal_places}f}"),  # noqa: UP031
                **base_config,
            )
            for i in val_range
        ]
        return tex_labels
Repository: ManimCommunity/manim
File: manim/mobject/graphing/scale.py (Python)

Code before:
        value = func(value, self.base)
        return value

    def get_custom_labels(
        self,
        val_range: Iterable[float],
        unit_decimal_places: int = 0,
        **base_config: dict[str, Any],
    ) -> list[Mobject]:
        """Produces custom :class:`~.Integer` labels in the form of ``10^2``.

        Parameters
        ----------
        val_range
            The iterable of values used to create the labels. Determines the exponent.
        unit_decimal_places
            The number of decimal places to include in the exponent
        base_config
            Additional arguments to be passed to :class:`~.Integer`.
        """
        # uses `format` syntax to control the number of decimal places.
        tex_labels: list[Mobject] = [
            Integer(
                self.base,
                unit="^{%s}" % (f"{self.inverse_function(i):.{unit_decimal_places}f}"),  # noqa: UP031
                **base_config,  # type: ignore[arg-type]
            )
            for i in val_range
        ]
        return tex_labels


Review comment (suggestion):
The reason why you're getting an error is because `**base_config` is typed as `dict[str, Any]`, when it should actually be typed as `Any`. In the same way an hypothetical `*mobjects` parameter should be typed as `Mobject` instead of `Iterable[Mobject]`, `**base_config`'s typehint should not be a `dict` itself, but rather the types of the values it contains (`Any`).

Code after:
        value = func(value, self.base)
        return value

    def get_custom_labels(
        self,
        val_range: Iterable[float],
        unit_decimal_places: int = 0,
        **base_config: Any,
    ) -> list[Integer]:
        """Produces custom :class:`~.Integer` labels in the form of ``10^2``.

        Parameters
        ----------
        val_range
            The iterable of values used to create the labels. Determines the exponent.
        unit_decimal_places
            The number of decimal places to include in the exponent
        base_config
            Additional arguments to be passed to :class:`~.Integer`.
        """
        # uses `format` syntax to control the number of decimal places.
        tex_labels = [
            Integer(
                self.base,
                unit="^{%s}" % (f"{self.inverse_function(i):.{unit_decimal_places}f}"),  # noqa: UP031
                **base_config,
            )
            for i in val_range
        ]
        return tex_labels
Repository: ManimCommunity/manim
File: manim/scene/moving_camera_scene.py (Python)

Code before:

    Note: Examples are included in the moving_camera_scene module
    documentation, see below in the 'see also' section.

    .. SEEALSO::

        :mod:`.moving_camera_scene`
        :class:`.MovingCamera`
    """

    def __init__(
        self, camera_class: type[MovingCamera] = MovingCamera, **kwargs: Any
    ) -> None:
        super().__init__(camera_class=camera_class, **kwargs)

    def get_moving_mobjects(self, *animations: Animation) -> list[Mobject]:
        """
        This method returns a list of all of the Mobjects in the Scene that
        are moving, that are also in the animations passed.

        Parameters
        ----------
        *animations
            The Animations whose mobjects will be checked.
        """
        moving_mobjects: list[Mobject] = super().get_moving_mobjects(*animations)
        all_moving_mobjects = extract_mobject_family_members(moving_mobjects)
        movement_indicators = self.renderer.camera.get_mobjects_indicating_movement()
        for movement_indicator in movement_indicators:
            if movement_indicator in all_moving_mobjects:
                # When one of these is moving, the camera should
                # consider all mobjects to be moving
                return list_update(self.mobjects, moving_mobjects)
        return moving_mobjects


Review comment (suggestion):
I think it would be better to add the corresponding typehint to the parent class' method `Scene.get_moving_mobjects()` instead.

Code after:

    Note: Examples are included in the moving_camera_scene module
    documentation, see below in the 'see also' section.

    .. SEEALSO::

        :mod:`.moving_camera_scene`
        :class:`.MovingCamera`
    """

    def __init__(
        self, camera_class: type[MovingCamera] = MovingCamera, **kwargs: Any
    ) -> None:
        super().__init__(camera_class=camera_class, **kwargs)

    def get_moving_mobjects(self, *animations: Animation) -> list[Mobject]:
        """
        This method returns a list of all of the Mobjects in the Scene that
        are moving, that are also in the animations passed.

        Parameters
        ----------
        *animations
            The Animations whose mobjects will be checked.
        """
        moving_mobjects = super().get_moving_mobjects(*animations)
        all_moving_mobjects = extract_mobject_family_members(moving_mobjects)
        movement_indicators = self.renderer.camera.get_mobjects_indicating_movement()
        for movement_indicator in movement_indicators:
            if movement_indicator in all_moving_mobjects:
                # When one of these is moving, the camera should
                # consider all mobjects to be moving
                return list_update(self.mobjects, moving_mobjects)
        return moving_mobjects
Repository: ManimCommunity/manim
File: manim/animation/changing.py (Python)

Code before:
                self.play(a.animate(path_arc=-PI / 4).shift(LEFT * 2))
                self.wait()

    """

    def __init__(
        self,
        traced_point_func: Callable,
        stroke_width: float = 2,
        stroke_color: ParsableManimColor | None = WHITE,
        dissipating_time: float | None = None,
        **kwargs: Any,
    ) -> None:
        super().__init__(stroke_color=stroke_color, stroke_width=stroke_width, **kwargs)
        self.traced_point_func = traced_point_func
        self.dissipating_time = dissipating_time
        self.time: float | None = 1 if self.dissipating_time else None
        self.add_updater(self.update_path)

    def update_path(self, mob: Any, dt: float) -> None:
        new_point = self.traced_point_func()
        if not self.has_points():
            self.start_new_path(new_point)
        self.add_line_to(new_point)
        if self.dissipating_time:
            assert isinstance(self.time, float)
            self.time += dt
            if self.time - 1 > self.dissipating_time:
                nppcc = self.n_points_per_curve
                self.set_points(self.points[nppcc:])


Review comment (bug):
This line is causing an `AssertionError` when passing a float to `dissipating_time` in `TracedPath`, because the initial value assigned to `self.time` is `1`, which is an `int`, not a `float`. This is the reason why the docs are failing to build: the `DissipatingPathExample` errors out, because it uses a `TracedPath` with `dissipating_time=0.5`.

Changing the initial assignation to `self.time` from `1` to `1.0`, as I suggested above, works. However, it's best to change this assertion to directly make sure that `self.time` is not `None`.
```suggestion
            assert self.time is not None
```

Code after:
                self.add(a, b)
                self.play(a.animate(path_arc=PI / 4).shift(LEFT * 2))
                self.play(a.animate(path_arc=-PI / 4).shift(LEFT * 2))
                self.wait()

    """

    def __init__(
        self,
        traced_point_func: Callable,
        stroke_width: float = 2,
        stroke_color: ParsableManimColor | None = WHITE,
        dissipating_time: float | None = None,
        **kwargs: Any,
    ) -> None:
        super().__init__(stroke_color=stroke_color, stroke_width=stroke_width, **kwargs)
        self.traced_point_func = traced_point_func
        self.dissipating_time = dissipating_time
        self.time = 1.0 if self.dissipating_time else None
        self.add_updater(self.update_path)

    def update_path(self, mob: Mobject, dt: float) -> None:
        new_point = self.traced_point_func()
        if not self.has_points():
            self.start_new_path(new_point)
        self.add_line_to(new_point)
        if self.dissipating_time:
            assert self.time is not None
            self.time += dt
            if self.time - 1 > self.dissipating_time:
                nppcc = self.n_points_per_curve
                self.set_points(self.points[nppcc:])
Repository: ManimCommunity/manim
File: manim/__init__.py (Python)

Code before:
#!/usr/bin/env python
from __future__ import annotations

from importlib.metadata import PackageNotFoundError, version

# Use installed distribution version if available; otherwise fall back to a
# sensible default so that importing from a source checkout works without an
# editable install (pip install -e .).
try:
    __version__ = version(__name__)
except PackageNotFoundError:
    # Package is not installed; provide a fallback version string.
    __version__ = "0.0.0+dev"


# isort: off

# Importing the config module should be the first thing we do, since other
# modules depend on the global config dict for initialization.
from ._config import *

# many scripts depend on this -> has to be loaded first
from .utils.commands import *

# isort: on
import numpy as np

from .animation.animation import *
from .animation.changing import *
from .animation.composition import *
from .animation.creation import *
from .animation.fading import *
from .animation.growing import *
from .animation.indication import *
from .animation.movement import *
from .animation.numbers import *
from .animation.rotation import *
from .animation.specialized import *

Review comment (suggestion):
I'd go for something that is semantically somewhat more correct (it is unclear whether the version in this case is a development version, or whether someone has just forgotten to install the package). What about this:

```suggestion
    __version__ = "0.0.0+unknown"
```

Code after:
#!/usr/bin/env python
from __future__ import annotations

from importlib.metadata import PackageNotFoundError, version

# Use installed distribution version if available; otherwise fall back to a
# sensible default so that importing from a source checkout works without an
# editable install (pip install -e .).
try:
    __version__ = version(__name__)
except PackageNotFoundError:
    # Package is not installed; provide a fallback version string.
    __version__ = "0.0.0+unknown"


# isort: off

# Importing the config module should be the first thing we do, since other
# modules depend on the global config dict for initialization.
from ._config import *

# many scripts depend on this -> has to be loaded first
from .utils.commands import *

# isort: on
import numpy as np

from .animation.animation import *
from .animation.changing import *
from .animation.composition import *
from .animation.creation import *
from .animation.fading import *
from .animation.growing import *
from .animation.indication import *
from .animation.movement import *
from .animation.numbers import *
from .animation.rotation import *
from .animation.specialized import *