Repository: ManimCommunity/manim

Issue:
Need a `Variable` class for intuitively using continuously updated values 
### Feature request
Right now, creating a continuously updating variable say `x = ...` is very cumbersome. First you have to create the label `x =` as Tex(t)Mobject, then a `ValueTracker` object for tracking the value and then finally a `DecimalNumber` object for displaying the value of the variable, An example is [here](https://github.com/Elteoremadebeethoven/AnimationsWithManim/blob/32271a83b8a87c310b72292b301040c227683d00/English/update_successions/value_tracker_examples.py#L9). 

It would be nice to wrap this functionality together so that user has to take care of just updating the value and rest of the things are done automatically in the background. 



Discussion:
Would love to see a PR that implements this!

Resolving patch:
diff --git a/example_scenes/basic.py b/example_scenes/basic.py
--- a/example_scenes/basic.py
+++ b/example_scenes/basic.py
@@ -178,4 +178,44 @@ def construct(self):
         self.wait()
 
 
-# See old_projects folder for many, many more
+class VariableExample(Scene):
+    def construct(self):
+        var = 0.5
+        on_screen_var = Variable(var, Text("var"), num_decimal_places=3)
+
+        # You can also change the colours for the label and value
+        on_screen_var.label.set_color(RED)
+        on_screen_var.value.set_color(GREEN)
+
+        self.play(Write(on_screen_var))
+        # The above line will just display the variable with
+        # its initial value on the screen. If you also wish to
+        # update it, you can do so by accessing the `tracker` attribute
+        self.wait()
+        var_tracker = on_screen_var.tracker
+        var = 10.5
+        self.play(var_tracker.set_value, var)
+        self.wait()
+
+        int_var = 0
+        on_screen_int_var = Variable(int_var, Text("int_var"), var_type=Integer).next_to(
+            on_screen_var, DOWN
+        )
+        on_screen_int_var.label.set_color(RED)
+        on_screen_int_var.value.set_color(GREEN)
+
+        self.play(Write(on_screen_int_var))
+        self.wait()
+        var_tracker = on_screen_int_var.tracker
+        var = 10.5
+        self.play(var_tracker.set_value, var)
+        self.wait()
+
+        # If you wish to have a somewhat more complicated label for your
+        # variable with subscripts, superscripts, etc. the default class
+        # for the label is MathTex
+        subscript_label_var = 10
+        on_screen_subscript_var = Variable(subscript_label_var, "{a}_{i}").next_to(on_screen_int_var, DOWN)
+        self.play(Write(on_screen_subscript_var))
+        self.wait()
+
diff --git a/manim/mobject/numbers.py b/manim/mobject/numbers.py
--- a/manim/mobject/numbers.py
+++ b/manim/mobject/numbers.py
@@ -1,9 +1,11 @@
-__all__ = ["DecimalNumber", "Integer"]
+__all__ = ["DecimalNumber", "Integer", "Variable"]
 
 
 from ..constants import *
-from ..mobject.svg.tex_mobject import SingleStringMathTex
-from ..mobject.types.vectorized_mobject import VMobject
+from ..mobject.svg.tex_mobject import MathTex, SingleStringMathTex, Tex
+from ..mobject.svg.text_mobject import Text
+from ..mobject.types.vectorized_mobject import VDict, VMobject
+from ..mobject.value_tracker import ValueTracker
 
 
 class DecimalNumber(VMobject):
@@ -143,3 +145,71 @@ class Integer(DecimalNumber):
 
     def get_value(self):
         return int(np.round(super().get_value()))
+
+
+class Variable(VMobject):
+    """A class for displaying text that continuously updates to reflect the value of a python variable.
+
+    Automatically adds the text for the label and the value when instantiated and added to the screen.
+
+    Parameters
+    ----------
+    var : Union[:class:`int`, :class:`float`]
+        The python variable you need to keep track of and display.
+    label : Union[:class:`str`, :class:`~.Tex`, :class:`~.MathTex`, :class:`Text`]
+        The label for your variable, for example `x = ...`. To use math mode, for e.g.
+        subscripts, superscripts, etc. simply pass in a raw string.
+    var_type : Union[:class:`DecimalNumber`, :class:`Integer`], optional
+        The class used for displaying the number. Defaults to :class:`DecimalNumber`.
+    num_decimal_places : :class:`int`, optional
+        The number of decimal places to display in your variable. Defaults to 2.
+        If `var_type` is an :class:`Integer`, this parameter is ignored.
+    kwargs : Any
+            Other arguments to be passed to `~.Mobject`.
+
+    Attributes
+    ----------
+    label : Union[:class:`str`, :class:`~.Tex`, :class:`~.MathTex`, :class:`Text`]
+        The label for your variable, for example `x = ...`.
+    tracker : :class:`~.ValueTracker`
+        Useful in updating the value of your variable on-screen.
+    value : Union[:class:`DecimalNumber`, :class:`Integer`]
+        The tex for the value of your variable.
+
+    Examples
+    --------
+    Normal usage::
+        # DecimalNumber type
+        var = 0.5
+        on_screen_var = Variable(var, "var", num_decimal_places=3)
+        # Integer type
+        int_var = 0
+        on_screen_int_var = Variable(int_var, "int_var", var_type=Integer)
+        # Using math mode for the label
+        on_screen_int_var = Variable(int_var, "${a}_{i}$", var_type=Integer)
+
+    """
+
+    def __init__(
+        self, var, label, var_type=DecimalNumber, num_decimal_places=2, **kwargs
+    ):
+
+        self.label = MathTex(label) if isinstance(label,str) else label
+        equals = MathTex("=").next_to(self.label, RIGHT)
+        self.label.add(equals)
+
+        self.tracker = ValueTracker(var)
+
+        if var_type == DecimalNumber:
+            self.value = DecimalNumber(
+                self.tracker.get_value(), num_decimal_places=num_decimal_places
+            )
+        elif var_type == Integer:
+            self.value = Integer(self.tracker.get_value())
+
+        self.value.add_updater(lambda v: v.set_value(self.tracker.get_value())).next_to(
+            self.label, RIGHT
+        )
+
+        VMobject.__init__(self, **kwargs)
+        self.add(self.label, self.value)


Test patch: