Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit af88adf

Browse files
committedJan 21, 2025·
Add typing to mobject/valuetracker.py
1 parent 6ca08fd commit af88adf

File tree

2 files changed

+69
-38
lines changed

2 files changed

+69
-38
lines changed
 

‎manim/mobject/value_tracker.py

+66-38
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,19 @@
44

55
__all__ = ["ValueTracker", "ComplexValueTracker"]
66

7+
from typing import TYPE_CHECKING, Any
78

89
import numpy as np
910

1011
from manim.mobject.mobject import Mobject
1112
from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL
1213
from manim.utils.paths import straight_path
1314

15+
if TYPE_CHECKING:
16+
from typing_extensions import Self
17+
18+
from manim.typing import PathFuncType
19+
1420

1521
class ValueTracker(Mobject, metaclass=ConvertToOpenGL):
1622
"""A mobject that can be used for tracking (real-valued) parameters.
@@ -69,76 +75,102 @@ def construct(self):
6975
7076
"""
7177

72-
def __init__(self, value=0, **kwargs):
78+
def __init__(self, value: float = 0, **kwargs: Any) -> None:
7379
super().__init__(**kwargs)
7480
self.set(points=np.zeros((1, 3)))
7581
self.set_value(value)
7682

7783
def get_value(self) -> float:
7884
"""Get the current value of this ValueTracker."""
79-
return self.points[0, 0]
85+
value: float = self.points[0, 0]
86+
return value
8087

81-
def set_value(self, value: float):
82-
"""Sets a new scalar value to the ValueTracker"""
88+
def set_value(self, value: float) -> Self:
89+
"""Sets a new scalar value to the ValueTracker."""
8390
self.points[0, 0] = value
8491
return self
8592

86-
def increment_value(self, d_value: float):
87-
"""Increments (adds) a scalar value to the ValueTracker"""
93+
def increment_value(self, d_value: float) -> Self:
94+
"""Increments (adds) a scalar value to the ValueTracker."""
8895
self.set_value(self.get_value() + d_value)
8996
return self
9097

91-
def __bool__(self):
92-
"""Return whether the value of this value tracker evaluates as true."""
98+
def __bool__(self) -> bool:
99+
"""Return whether the value of this ValueTracker evaluates as true."""
93100
return bool(self.get_value())
94101

95-
def __iadd__(self, d_value: float):
96-
"""adds ``+=`` syntax to increment the value of the ValueTracker"""
97-
self.increment_value(d_value)
102+
def __iadd__(self, d_value: float | Mobject) -> Self:
103+
"""adds ``+=`` syntax to increment the value of the ValueTracker."""
104+
if isinstance(d_value, Mobject):
105+
raise ValueError(
106+
"Cannot increment ValueTracker by a Mobject. Please provide a scalar value."
107+
)
108+
else:
109+
self.increment_value(d_value)
98110
return self
99111

100-
def __ifloordiv__(self, d_value: float):
101-
"""Set the value of this value tracker to the floor division of the current value by ``d_value``."""
112+
def __ifloordiv__(self, d_value: float) -> Self:
113+
"""Set the value of this ValueTracker to the floor division of the current value by ``d_value``."""
102114
self.set_value(self.get_value() // d_value)
103115
return self
104116

105-
def __imod__(self, d_value: float):
106-
"""Set the value of this value tracker to the current value modulo ``d_value``."""
117+
def __imod__(self, d_value: float) -> Self:
118+
"""Set the value of this ValueTracker to the current value modulo ``d_value``."""
107119
self.set_value(self.get_value() % d_value)
108120
return self
109121

110-
def __imul__(self, d_value: float):
111-
"""Set the value of this value tracker to the product of the current value and ``d_value``."""
122+
def __imul__(self, d_value: float) -> Self:
123+
"""Set the value of this ValueTracker to the product of the current value and ``d_value``."""
112124
self.set_value(self.get_value() * d_value)
113125
return self
114126

115-
def __ipow__(self, d_value: float):
116-
"""Set the value of this value tracker to the current value raised to the power of ``d_value``."""
127+
def __ipow__(self, d_value: float) -> Self:
128+
"""Set the value of this ValueTracker to the current value raised to the power of ``d_value``."""
117129
self.set_value(self.get_value() ** d_value)
118130
return self
119131

120-
def __isub__(self, d_value: float):
121-
"""adds ``-=`` syntax to decrement the value of the ValueTracker"""
122-
self.increment_value(-d_value)
132+
def __sub__(self, d_value: float | Mobject) -> Self:
133+
"""Decrements the ValueTracker by ``d_value``."""
134+
if isinstance(d_value, Mobject):
135+
raise ValueError(
136+
"Cannot decrement ValueTracker by a Mobject. Please provide a scalar value."
137+
)
138+
else:
139+
self.increment_value(-d_value)
123140
return self
124141

125-
def __itruediv__(self, d_value: float):
126-
"""Sets the value of this value tracker to the current value divided by ``d_value``."""
142+
def __isub__(self, d_value: float | Mobject) -> Self:
143+
"""Adds ``-=`` syntax to decrement the value of the ValueTracker."""
144+
if isinstance(d_value, Mobject):
145+
raise ValueError(
146+
"Cannot decrement ValueTracker by a Mobject. Please provide a scalar value."
147+
)
148+
else:
149+
self.increment_value(-d_value)
150+
return self
151+
152+
def __itruediv__(self, d_value: float) -> Self:
153+
"""Sets the value of this ValueTracker to the current value divided by ``d_value``."""
127154
self.set_value(self.get_value() / d_value)
128155
return self
129156

130-
def interpolate(self, mobject1, mobject2, alpha, path_func=straight_path()):
131-
"""
132-
Turns self into an interpolation between mobject1
133-
and mobject2.
134-
"""
157+
def interpolate(
158+
self,
159+
mobject1: Mobject,
160+
mobject2: Mobject,
161+
alpha: float,
162+
path_func: PathFuncType = straight_path(),
163+
) -> Self:
164+
"""Turns ``self`` into an interpolation between ``mobject1`` and ``mobject2``."""
135165
self.set(points=path_func(mobject1.points, mobject2.points, alpha))
136166
return self
137167

138168

139169
class ComplexValueTracker(ValueTracker):
140170
"""Tracks a complex-valued parameter.
141171
172+
The value is internally stored as a points array [a, b, 0]. This can be accessed directly
173+
to represent the value geometrically, see the usage example.
142174
When the value is set through :attr:`animate`, the value will take a straight path from the
143175
source point to the destination point.
144176
@@ -161,16 +193,12 @@ def construct(self):
161193
self.play(tracker.animate.set_value(tracker.get_value() / (-2 + 3j)))
162194
"""
163195

164-
def get_value(self):
165-
"""Get the current value of this value tracker as a complex number.
166-
167-
The value is internally stored as a points array [a, b, 0]. This can be accessed directly
168-
to represent the value geometrically, see the usage example.
169-
"""
196+
def get_value(self) -> complex: # type: ignore [override]
197+
"""Get the current value of this ComplexValueTracker as a complex number."""
170198
return complex(*self.points[0, :2])
171199

172-
def set_value(self, z):
173-
"""Sets a new complex value to the ComplexValueTracker"""
174-
z = complex(z)
200+
def set_value(self, value: complex | float) -> Self:
201+
"""Sets a new complex value to the ComplexValueTracker."""
202+
z = complex(value)
175203
self.points[0, :2] = (z.real, z.imag)
176204
return self

‎mypy.ini

+3
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ ignore_errors = False
7676
[mypy-manim.mobject.geometry.*]
7777
ignore_errors = True
7878

79+
[mypy-manim.mobject.value_tracker]
80+
ignore_errors = False
81+
7982
[mypy-manim.renderer.*]
8083
ignore_errors = True
8184

0 commit comments

Comments
 (0)
Please sign in to comment.