ytdl-sub/src/ytdl_sub/script/functions/numeric_functions.py
Jesse Bannon c46de048ca
[FEATURE] %range function (#1405)
Add `%range` function, equivalent to Python's `range`.
2025-12-31 09:06:08 -08:00

115 lines
3.1 KiB
Python

import math
from typing import Optional
from ytdl_sub.script.types.array import Array
from ytdl_sub.script.types.resolvable import AnyArgument
from ytdl_sub.script.types.resolvable import Float
from ytdl_sub.script.types.resolvable import Integer
from ytdl_sub.script.types.resolvable import Numeric
def _to_numeric(value: int | float) -> Numeric:
if int(value) == value:
return Integer(value=value)
return Float(value=value)
class NumericFunctions:
@staticmethod
def float(value: AnyArgument) -> Float:
"""
:description:
Cast to Float.
"""
return Float(value=float(value.value))
@staticmethod
def int(value: AnyArgument) -> Integer:
"""
:description:
Cast to Integer.
"""
return Integer(value=int(value.value))
@staticmethod
def add(*values: Numeric) -> Numeric:
"""
:description:
``+`` operator. Returns the sum of all values.
"""
return _to_numeric(sum(val.value for val in values))
@staticmethod
def sub(*values: Numeric) -> Numeric:
"""
:description:
``-`` operator. Subtracts all values from left to right.
"""
output = values[0].value
for val in values[1:]:
output -= val.value
return _to_numeric(output)
@staticmethod
def mul(*values: Numeric) -> Numeric:
"""
:description:
``*`` operator. Returns the product of all values.
"""
return _to_numeric(math.prod([val.value for val in values]))
@staticmethod
def pow(base: Numeric, exponent: Numeric) -> Numeric:
"""
:description:
``**`` operator. Returns the exponential of the base and exponent value.
"""
return _to_numeric(math.pow(base.value, exponent.value))
@staticmethod
def div(left: Numeric, right: Numeric) -> Numeric:
"""
:description:
``/`` operator. Returns ``left / right``.
"""
return _to_numeric(left.value / right.value)
@staticmethod
def mod(left: Numeric, right: Numeric) -> Numeric:
"""
:description:
``%`` operator. Returns ``left % right``.
"""
return _to_numeric(value=left.value % right.value)
@staticmethod
def max(*values: Numeric) -> Numeric:
"""
:description:
Returns max of all values.
"""
return _to_numeric(max(val.value for val in values))
@staticmethod
def min(*values: Numeric) -> Numeric:
"""
:description:
Returns min of all values.
"""
return _to_numeric(min(val.value for val in values))
@staticmethod
def range(
end: Integer, start: Optional[Integer] = None, step: Optional[Integer] = None
) -> Array:
"""
:description:
Returns the desired range of Integers in the form of an Array.
"""
if start is None:
start = Integer(0)
if step is None:
step = Integer(1)
return Array(value=[Integer(idx) for idx in range(start.value, end.value, step.value)])