Metadata-Version: 2.1
Name: mathdunders
Version: 0.3.15
Summary: Decorator that adds math dunders to a class derived from a numeric type.
Home-page: https://github.com/discretegames/mathdunders
Author: discretegames
Author-email: discretizedgames@gmail.com
License: MIT
Description: # mathdunders
        
        **A Python decorator that automatically adds math-related dunder methods to a class derived from a numeric type.**
        
        Useful when you want operations on that class to remain the same type but don't want to manually write all the dunders.
        
        Think of it in the same vein as [@functools.total_ordering](https://docs.python.org/3/library/functools.html#functools.total_ordering).
        
        ## Installation
        
        ```text
        pip install mathdunders
        ```
        
        [View on PyPI](https://pypi.org/project/mathdunders/) - [View on GitHub](https://github.com/discretegames/mathdunders)
        
        This package was built in Python 3.9.4 and tested to work in 3.6.8+.
        
        ## Usage
        
        Import and put `@mathdunders()` above your class:
        
        ```py
        from mathdunders import mathdunders
        
        @mathdunders()
        class RealNumber(float):
            pass
        
        a = RealNumber(3) + RealNumber(4)
        print(a, type(a))  # -> 7.0 <class '__main__.RealNumber'>
        
        b = RealNumber(3) * 4
        print(b, type(b))  # -> 12.0 <class '__main__.RealNumber'>
        
        c = 3 - RealNumber(4)
        print(c, type(c))  # -> -1.0 <class '__main__.RealNumber'>
        ```
        
        Now any math operation with `RealNumber` will result in another `RealNumber` rather than a float.
        
        In the above code block, `@mathdunders()` makes `RealNumber` behave as if it was written like:
        
        ```py
        class RealNumber(float):
            def __add__(self, other):
                return RealNumber(float(self) + other)
        
            def __mul__(self, other):
                return RealNumber(float(self) * other)
        
            def __rsub__(self, other):
                return RealNumber(other - float(self))
        
            # ... plus 20 other similar boilerplate dunder methods ...
        ```
        
        ## Supported Dunders
        
        `@mathdunders()` adds 23 "magic" double-underscore (dunder) methods to the class it decorates:
        
        ```text
        Dunder           Trigger
        __abs__          abs(x)
        __ceil__         math.ceil(x)
        __floor__        math.floor(x)
        __neg__          -x
        __pos__          +x
        __round__        round(x)
        __trunc__        math.trunc(x)
        __add__          x + 3
        __divmod__       divmod(x, 3)
        __floordiv__     x // 3
        __mod__          x % 3
        __mul__          x * 3
        __pow__          x ** 3
        __sub__          x - 3
        __truediv__      x / 3
        __radd__         3 + x
        __rdivmod__      divmod(3, x)
        __rfloordiv__    3 // x
        __rmod__         3 % x
        __rmul__         3 * x
        __rpow__         3 ** x
        __rsub__         3 - x
        __rtruediv__     3 / x
        ```
        
        `dunders` is a tuple of all supported dunder names:
        
        ```py
        from mathdunders import dunders
        print(dunders)  # -> ('__abs__', '__ceil__', '__floor__', '__neg__', ...
        ```
        
        Note: `__ceil__` and `__floor__` are unimplemented for floats in Python versions before 3.9.
        
        ## Advanced Usage
        
        If the numeric type such as `float`, `int`, or `Decimal` is not the first base class, use the optional `base` parameter to specify the numeric type.
        
        ```py
        from mathdunders import mathdunders
        
        class Parent:
            pass
        
        @mathdunders(base=int)
        class Int(Parent, int):
            pass
        
        print(Int(10) / Int(2))  # -> 5
        ```
        
        By default dunders are not inserted if the class already defines them. `force=True` can be used to override this.
        
        ```py
        from mathdunders import mathdunders
        
        @mathdunders(force=False)  # default behavior
        class A(float):
            def __abs__(self):
                return 1234
        
        a = abs(A(-1))
        print(a, type(a))  # -> 1234 <class 'int'>
        
        @mathdunders(force=True)  # forces dunders to be overwritten
        class B(float):
            def __abs__(self):
                return 1234
        
        b = abs(B(-1))
        print(b, type(b))  # -> 1.0 <class '__main__.B'>
        ```
        
Keywords: python,math,mathematics,dunder,double under,underscore,magic method,number
Platform: UNKNOWN
Description-Content-Type: text/markdown
