aboutsummaryrefslogtreecommitdiff
path: root/.venv/lib/python3.12/site-packages/pydash/numerical.py
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/pydash/numerical.py
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-4a52a71956a8d46fcb7294ac71734504bb09bcc2.tar.gz
two version of R2R are hereHEADmaster
Diffstat (limited to '.venv/lib/python3.12/site-packages/pydash/numerical.py')
-rw-r--r--.venv/lib/python3.12/site-packages/pydash/numerical.py1252
1 files changed, 1252 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/pydash/numerical.py b/.venv/lib/python3.12/site-packages/pydash/numerical.py
new file mode 100644
index 00000000..711cab0c
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/pydash/numerical.py
@@ -0,0 +1,1252 @@
+"""
+Numerical/mathematical related functions.
+
+.. versionadded:: 2.1.0
+"""
+
+from __future__ import annotations
+
+import math
+import operator
+import typing as t
+
+import pydash as pyd
+
+from .helpers import UNSET, Unset, iterator, iterator_with_default, iteriteratee
+from .types import IterateeObjT, NumberNoDecimalT, NumberT, SupportsMul, SupportsRound
+
+
+if t.TYPE_CHECKING:
+ from decimal import Decimal # pragma: no cover
+
+ from _typeshed import SupportsAdd, SupportsRichComparisonT, SupportsSub # pragma: no cover
+
+
+__all__ = (
+ "add",
+ "ceil",
+ "clamp",
+ "divide",
+ "floor",
+ "max_",
+ "max_by",
+ "mean",
+ "mean_by",
+ "median",
+ "min_",
+ "min_by",
+ "moving_mean",
+ "multiply",
+ "power",
+ "round_",
+ "scale",
+ "slope",
+ "std_deviation",
+ "sum_",
+ "sum_by",
+ "subtract",
+ "transpose",
+ "variance",
+ "zscore",
+)
+
+T = t.TypeVar("T")
+T2 = t.TypeVar("T2")
+T3 = t.TypeVar("T3")
+
+
+INFINITY = float("inf")
+
+
+@t.overload
+def add(a: "SupportsAdd[T, T2]", b: T) -> T2: ...
+
+
+@t.overload
+def add(a: T, b: "SupportsAdd[T, T2]") -> T2: ...
+
+
+def add(a, b):
+ """
+ Adds two numbers.
+
+ Args:
+ a: First number to add.
+ b: Second number to add.
+
+ Returns:
+ number
+
+ Example:
+
+ >>> add(10, 5)
+ 15
+
+ .. versionadded:: 2.1.0
+
+ .. versionchanged:: 3.3.0
+ Support adding two numbers when passed as positional arguments.
+
+ .. versionchanged:: 4.0.0
+ Only support two argument addition.
+ """
+ return a + b
+
+
+@t.overload
+def sum_(collection: t.Mapping[t.Any, "SupportsAdd[int, T]"]) -> T: ...
+
+
+@t.overload
+def sum_(collection: t.Iterable["SupportsAdd[int, T]"]) -> T: ...
+
+
+def sum_(collection):
+ """
+ Sum each element in `collection`.
+
+ Args:
+ collection: Collection to process or first number to add.
+
+ Returns:
+ Result of summation.
+
+ Example:
+
+ >>> sum_([1, 2, 3, 4])
+ 10
+
+ .. versionadded:: 2.1.0
+
+ .. versionchanged:: 3.3.0
+ Support adding two numbers when passed as positional arguments.
+
+ .. versionchanged:: 4.0.0
+ Move iteratee support to :func:`sum_by`. Move two argument addition to
+ :func:`add`.
+ """
+ return sum_by(collection)
+
+
+@t.overload
+def sum_by(
+ collection: t.Mapping[T, T2],
+ iteratee: t.Callable[[T2, T, t.Dict[T, T2]], "SupportsAdd[int, T3]"],
+) -> T3: ...
+
+
+@t.overload
+def sum_by(
+ collection: t.Mapping[T, T2], iteratee: t.Callable[[T2, T], "SupportsAdd[int, T3]"]
+) -> T3: ...
+
+
+@t.overload
+def sum_by(
+ collection: t.Mapping[t.Any, T2], iteratee: t.Callable[[T2], "SupportsAdd[int, T3]"]
+) -> T3: ...
+
+
+@t.overload
+def sum_by(
+ collection: t.Iterable[T], iteratee: t.Callable[[T, int, t.List[T]], "SupportsAdd[int, T2]"]
+) -> T2: ...
+
+
+@t.overload
+def sum_by(
+ collection: t.Iterable[T], iteratee: t.Callable[[T, int], "SupportsAdd[int, T2]"]
+) -> T2: ...
+
+
+@t.overload
+def sum_by(collection: t.Iterable[T], iteratee: t.Callable[[T], "SupportsAdd[int, T2]"]) -> T2: ...
+
+
+@t.overload
+def sum_by(collection: t.Mapping[t.Any, "SupportsAdd[int, T]"], iteratee: None = None) -> T: ...
+
+
+@t.overload
+def sum_by(collection: t.Iterable["SupportsAdd[int, T]"], iteratee: None = None) -> T: ...
+
+
+def sum_by(collection, iteratee=None):
+ """
+ Sum each element in `collection`. If iteratee is passed, each element of `collection` is passed
+ through an iteratee before the summation is computed.
+
+ Args:
+ collection: Collection to process or first number to add.
+ iteratee: Iteratee applied per iteration or second number to add.
+
+ Returns:
+ Result of summation.
+
+ Example:
+
+ >>> sum_by([1, 2, 3, 4], lambda x: x**2)
+ 30
+
+ .. versionadded:: 4.0.0
+ """
+ return sum(result[0] for result in iteriteratee(collection, iteratee))
+
+
+@t.overload
+def mean(collection: t.Mapping[t.Any, "SupportsAdd[int, t.Any]"]) -> float: ...
+
+
+@t.overload
+def mean(collection: t.Iterable["SupportsAdd[int, t.Any]"]) -> float: ...
+
+
+def mean(collection):
+ """
+ Calculate arithmetic mean of each element in `collection`.
+
+ Args:
+ collection: Collection to process.
+
+ Returns:
+ Result of mean.
+
+ Example:
+
+ >>> mean([1, 2, 3, 4])
+ 2.5
+
+ .. versionadded:: 2.1.0
+
+ .. versionchanged:: 4.0.0
+
+ - Removed ``average`` and ``avg`` aliases.
+ - Moved iteratee functionality to :func:`mean_by`.
+ """
+ return mean_by(collection)
+
+
+@t.overload
+def mean_by(
+ collection: t.Mapping[T, T2],
+ iteratee: t.Callable[[T2, T, t.Dict[T, T2]], "SupportsAdd[int, t.Any]"],
+) -> float: ...
+
+
+@t.overload
+def mean_by(
+ collection: t.Mapping[T, T2], iteratee: t.Callable[[T2, T], "SupportsAdd[int, t.Any]"]
+) -> float: ...
+
+
+@t.overload
+def mean_by(
+ collection: t.Mapping[t.Any, T2], iteratee: t.Callable[[T2], "SupportsAdd[int, t.Any]"]
+) -> float: ...
+
+
+@t.overload
+def mean_by(
+ collection: t.Iterable[T], iteratee: t.Callable[[T, int, t.List[T]], "SupportsAdd[int, t.Any]"]
+) -> float: ...
+
+
+@t.overload
+def mean_by(
+ collection: t.Iterable[T], iteratee: t.Callable[[T, int], "SupportsAdd[int, t.Any]"]
+) -> float: ...
+
+
+@t.overload
+def mean_by(
+ collection: t.Iterable[T], iteratee: t.Callable[[T], "SupportsAdd[int, t.Any]"]
+) -> float: ...
+
+
+@t.overload
+def mean_by(
+ collection: t.Mapping[t.Any, "SupportsAdd[int, t.Any]"], iteratee: None = None
+) -> float: ...
+
+
+@t.overload
+def mean_by(collection: t.Iterable["SupportsAdd[int, t.Any]"], iteratee: None = None) -> float: ...
+
+
+def mean_by(collection, iteratee=None):
+ """
+ Calculate arithmetic mean of each element in `collection`. If iteratee is passed, each element
+ of `collection` is passed through an iteratee before the mean is computed.
+
+ Args:
+ collection: Collection to process.
+ iteratee: Iteratee applied per iteration.
+
+ Returns:
+ Result of mean.
+
+ Example:
+
+ >>> mean_by([1, 2, 3, 4], lambda x: x**2)
+ 7.5
+
+ .. versionadded:: 4.0.0
+ """
+ return sum_by(collection, iteratee) / len(collection)
+
+
+def ceil(x: NumberT, precision: int = 0) -> float:
+ """
+ Round number up to precision.
+
+ Args:
+ x: Number to round up.
+ precision: Rounding precision. Defaults to ``0``.
+
+ Returns:
+ Number rounded up.
+
+ Example:
+
+ >>> ceil(3.275) == 4.0
+ True
+ >>> ceil(3.215, 1) == 3.3
+ True
+ >>> ceil(6.004, 2) == 6.01
+ True
+
+ .. versionadded:: 3.3.0
+ """
+ return rounder(math.ceil, x, precision)
+
+
+NumT = t.TypeVar("NumT", int, float, "Decimal")
+NumT2 = t.TypeVar("NumT2", int, float, "Decimal")
+NumT3 = t.TypeVar("NumT3", int, float, "Decimal")
+
+
+def clamp(x: NumT, lower: NumT2, upper: t.Union[NumT3, None] = None) -> t.Union[NumT, NumT2, NumT3]:
+ """
+ Clamps number within the inclusive lower and upper bounds.
+
+ Args:
+ x: Number to clamp.
+ lower: Lower bound.
+ upper: Upper bound
+
+ Returns:
+ number
+
+ Example:
+
+ >>> clamp(-10, -5, 5)
+ -5
+ >>> clamp(10, -5, 5)
+ 5
+ >>> clamp(10, 5)
+ 5
+ >>> clamp(-10, 5)
+ -10
+
+ .. versionadded:: 4.0.0
+ """
+ if upper is None:
+ upper = lower # type: ignore
+ lower = x # type: ignore
+
+ if x < lower:
+ x = lower # type: ignore
+ elif x > upper: # type: ignore
+ x = upper # type: ignore
+
+ return x
+
+
+def divide(dividend: t.Union[NumberT, None], divisor: t.Union[NumberT, None]) -> float:
+ """
+ Divide two numbers.
+
+ Args:
+ dividend: The first number in a division.
+ divisor: The second number in a division.
+
+ Returns:
+ Returns the quotient.
+
+ Example:
+
+ >>> divide(20, 5)
+ 4.0
+ >>> divide(1.5, 3)
+ 0.5
+ >>> divide(None, None)
+ 1.0
+ >>> divide(5, None)
+ 5.0
+
+ .. versionadded:: 4.0.0
+ """
+ return call_math_operator(dividend, divisor, operator.truediv, 1)
+
+
+def floor(x: NumberT, precision: int = 0) -> float:
+ """
+ Round number down to precision.
+
+ Args:
+ x: Number to round down.
+ precision: Rounding precision. Defaults to ``0``.
+
+ Returns:
+ Number rounded down.
+
+ Example:
+
+ >>> floor(3.75) == 3.0
+ True
+ >>> floor(3.215, 1) == 3.2
+ True
+ >>> floor(0.046, 2) == 0.04
+ True
+
+ .. versionadded:: 3.3.0
+ """
+ return rounder(math.floor, x, precision)
+
+
+@t.overload
+def max_(
+ collection: t.Mapping[t.Any, "SupportsRichComparisonT"], default: Unset = UNSET
+) -> "SupportsRichComparisonT": ...
+
+
+@t.overload
+def max_(
+ collection: t.Mapping[t.Any, "SupportsRichComparisonT"], default: T
+) -> t.Union["SupportsRichComparisonT", T]: ...
+
+
+@t.overload
+def max_(
+ collection: t.Iterable["SupportsRichComparisonT"], default: Unset = UNSET
+) -> "SupportsRichComparisonT": ...
+
+
+@t.overload
+def max_(
+ collection: t.Iterable["SupportsRichComparisonT"], default: T
+) -> t.Union["SupportsRichComparisonT", T]: ...
+
+
+def max_(collection, default=UNSET):
+ """
+ Retrieves the maximum value of a `collection`.
+
+ Args:
+ collection: Collection to iterate over.
+ default: Value to return if `collection` is empty.
+
+ Returns:
+ Maximum value.
+
+ Example:
+
+ >>> max_([1, 2, 3, 4])
+ 4
+ >>> max_([], default=-1)
+ -1
+
+ .. versionadded:: 1.0.0
+
+ .. versionchanged:: 4.0.0
+ Moved iteratee iteratee support to :func:`max_by`.
+ """
+ return max_by(collection, default=default)
+
+
+@t.overload
+def max_by(
+ collection: t.Mapping[t.Any, "SupportsRichComparisonT"],
+ iteratee: None = None,
+ default: Unset = UNSET,
+) -> "SupportsRichComparisonT": ...
+
+
+@t.overload
+def max_by(
+ collection: t.Mapping[t.Any, T2],
+ iteratee: t.Callable[[T2], "SupportsRichComparisonT"],
+ default: Unset = UNSET,
+) -> T2: ...
+
+
+@t.overload
+def max_by(
+ collection: t.Mapping[t.Any, T2],
+ iteratee: t.Callable[[T2], "SupportsRichComparisonT"],
+ *,
+ default: T,
+) -> t.Union[T2, T]: ...
+
+
+@t.overload
+def max_by(
+ collection: t.Mapping[t.Any, "SupportsRichComparisonT"], iteratee: None = None, *, default: T
+) -> t.Union["SupportsRichComparisonT", T]: ...
+
+
+@t.overload
+def max_by(
+ collection: t.Iterable["SupportsRichComparisonT"], iteratee: None = None, default: Unset = UNSET
+) -> "SupportsRichComparisonT": ...
+
+
+@t.overload
+def max_by(
+ collection: t.Iterable[T2],
+ iteratee: t.Callable[[T2], "SupportsRichComparisonT"],
+ default: Unset = UNSET,
+) -> T2: ...
+
+
+@t.overload
+def max_by(
+ collection: t.Iterable[T2], iteratee: t.Callable[[T2], "SupportsRichComparisonT"], *, default: T
+) -> t.Union[T2, T]: ...
+
+
+@t.overload
+def max_by(
+ collection: t.Iterable["SupportsRichComparisonT"], iteratee: None = None, *, default: T
+) -> t.Union["SupportsRichComparisonT", T]: ...
+
+
+@t.overload
+def max_by(collection: t.Iterable[T], iteratee: IterateeObjT, default: Unset = UNSET) -> T: ...
+
+
+@t.overload
+def max_by(collection: t.Iterable[T], iteratee: IterateeObjT, default: T2) -> t.Union[T, T2]: ...
+
+
+def max_by(collection, iteratee=None, default=UNSET):
+ """
+ Retrieves the maximum value of a `collection`.
+
+ Args:
+ collection: Collection to iterate over.
+ iteratee: Iteratee applied per iteration.
+ default: Value to return if `collection` is empty.
+
+ Returns:
+ Maximum value.
+
+ Example:
+
+ >>> max_by([1.0, 1.5, 1.8], math.floor)
+ 1.0
+ >>> max_by([{"a": 1}, {"a": 2}, {"a": 3}], "a")
+ {'a': 3}
+ >>> max_by([], default=-1)
+ -1
+
+ .. versionadded:: 4.0.0
+ """
+ if isinstance(collection, dict):
+ collection = collection.values()
+
+ return max(iterator_with_default(collection, default), key=pyd.iteratee(iteratee))
+
+
+@t.overload
+def median(
+ collection: t.Mapping[T, T2], iteratee: t.Callable[[T2, T, t.Dict[T, T2]], NumberT]
+) -> t.Union[float, int]: ...
+
+
+@t.overload
+def median(
+ collection: t.Mapping[T, T2], iteratee: t.Callable[[T2, T], NumberT]
+) -> t.Union[float, int]: ...
+
+
+@t.overload
+def median(
+ collection: t.Mapping[t.Any, T2], iteratee: t.Callable[[T2], NumberT]
+) -> t.Union[float, int]: ...
+
+
+@t.overload
+def median(
+ collection: t.Iterable[T], iteratee: t.Callable[[T, int, t.List[T]], NumberT]
+) -> t.Union[float, int]: ...
+
+
+@t.overload
+def median(
+ collection: t.Iterable[T], iteratee: t.Callable[[T, int], NumberT]
+) -> t.Union[float, int]: ...
+
+
+@t.overload
+def median(
+ collection: t.Iterable[T], iteratee: t.Callable[[T], NumberT]
+) -> t.Union[float, int]: ...
+
+
+@t.overload
+def median(collection: t.Iterable[NumberT], iteratee: None = None) -> t.Union[float, int]: ...
+
+
+def median(collection, iteratee=None):
+ """
+ Calculate median of each element in `collection`. If iteratee is passed, each element of
+ `collection` is passed through an iteratee before the median is computed.
+
+ Args:
+ collection: Collection to process.
+ iteratee: Iteratee applied per iteration.
+
+ Returns:
+ Result of median.
+
+ Example:
+
+ >>> median([1, 2, 3, 4, 5])
+ 3
+ >>> median([1, 2, 3, 4])
+ 2.5
+
+ .. versionadded:: 2.1.0
+ """
+ length = len(collection)
+ middle = (length + 1) / 2
+ collection = sorted(ret[0] for ret in iteriteratee(collection, iteratee))
+
+ if pyd.is_odd(length):
+ result = collection[int(middle - 1)]
+ else:
+ left = int(middle - 1.5)
+ right = int(middle - 0.5)
+ result = (collection[left] + collection[right]) / 2
+
+ return result
+
+
+@t.overload
+def min_(
+ collection: t.Mapping[t.Any, "SupportsRichComparisonT"], default: Unset = UNSET
+) -> "SupportsRichComparisonT": ...
+
+
+@t.overload
+def min_(
+ collection: t.Mapping[t.Any, "SupportsRichComparisonT"], default: T
+) -> t.Union["SupportsRichComparisonT", T]: ...
+
+
+@t.overload
+def min_(
+ collection: t.Iterable["SupportsRichComparisonT"], default: Unset = UNSET
+) -> "SupportsRichComparisonT": ...
+
+
+@t.overload
+def min_(
+ collection: t.Iterable["SupportsRichComparisonT"], default: T
+) -> t.Union["SupportsRichComparisonT", T]: ...
+
+
+def min_(collection, default=UNSET):
+ """
+ Retrieves the minimum value of a `collection`.
+
+ Args:
+ collection: Collection to iterate over.
+ default: Value to return if `collection` is empty.
+
+ Returns:
+ Minimum value.
+
+ Example:
+
+ >>> min_([1, 2, 3, 4])
+ 1
+ >>> min_([], default=100)
+ 100
+
+ .. versionadded:: 1.0.0
+
+ .. versionchanged:: 4.0.0
+ Moved iteratee iteratee support to :func:`min_by`.
+ """
+ return min_by(collection, default=default)
+
+
+@t.overload
+def min_by(
+ collection: t.Mapping[t.Any, "SupportsRichComparisonT"],
+ iteratee: None = None,
+ default: Unset = UNSET,
+) -> "SupportsRichComparisonT": ...
+
+
+@t.overload
+def min_by(
+ collection: t.Mapping[t.Any, T2],
+ iteratee: t.Callable[[T2], "SupportsRichComparisonT"],
+ default: Unset = UNSET,
+) -> T2: ...
+
+
+@t.overload
+def min_by(
+ collection: t.Mapping[t.Any, T2],
+ iteratee: t.Callable[[T2], "SupportsRichComparisonT"],
+ *,
+ default: T,
+) -> t.Union[T2, T]: ...
+
+
+@t.overload
+def min_by(
+ collection: t.Mapping[t.Any, "SupportsRichComparisonT"], iteratee: None = None, *, default: T
+) -> t.Union["SupportsRichComparisonT", T]: ...
+
+
+@t.overload
+def min_by(
+ collection: t.Iterable["SupportsRichComparisonT"], iteratee: None = None, default: Unset = UNSET
+) -> "SupportsRichComparisonT": ...
+
+
+@t.overload
+def min_by(
+ collection: t.Iterable[T2],
+ iteratee: t.Callable[[T2], "SupportsRichComparisonT"],
+ default: Unset = UNSET,
+) -> T2: ...
+
+
+@t.overload
+def min_by(
+ collection: t.Iterable[T2], iteratee: t.Callable[[T2], "SupportsRichComparisonT"], *, default: T
+) -> t.Union[T2, T]: ...
+
+
+@t.overload
+def min_by(
+ collection: t.Iterable["SupportsRichComparisonT"], iteratee: None = None, *, default: T
+) -> t.Union["SupportsRichComparisonT", T]: ...
+
+
+@t.overload
+def min_by(collection: t.Iterable[T], iteratee: IterateeObjT, default: Unset = UNSET) -> T: ...
+
+
+@t.overload
+def min_by(collection: t.Iterable[T], iteratee: IterateeObjT, default: T2) -> t.Union[T, T2]: ...
+
+
+def min_by(collection, iteratee=None, default=UNSET):
+ """
+ Retrieves the minimum value of a `collection`.
+
+ Args:
+ collection: Collection to iterate over.
+ iteratee: Iteratee applied per iteration.
+ default: Value to return if `collection` is empty.
+
+ Returns:
+ Minimum value.
+
+ Example:
+
+ >>> min_by([1.8, 1.5, 1.0], math.floor)
+ 1.8
+ >>> min_by([{"a": 1}, {"a": 2}, {"a": 3}], "a")
+ {'a': 1}
+ >>> min_by([], default=100)
+ 100
+
+ .. versionadded:: 4.0.0
+ """
+ if isinstance(collection, dict):
+ collection = collection.values()
+ return min(iterator_with_default(collection, default), key=pyd.iteratee(iteratee))
+
+
+def moving_mean(array: t.Sequence["SupportsAdd[int, t.Any]"], size: t.SupportsInt) -> t.List[float]:
+ """
+ Calculate moving mean of each element of `array`.
+
+ Args:
+ array: List to process.
+ size: Window size.
+
+ Returns:
+ Result of moving average.
+
+ Example:
+
+ >>> moving_mean(range(10), 1)
+ [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
+ >>> moving_mean(range(10), 5)
+ [2.0, 3.0, 4.0, 5.0, 6.0, 7.0]
+ >>> moving_mean(range(10), 10)
+ [4.5]
+
+ .. versionadded:: 2.1.0
+
+ .. versionchanged:: 4.0.0
+ Rename to ``moving_mean`` and remove ``moving_average`` and ``moving_avg`` aliases.
+ """
+ result = []
+ size = int(size)
+
+ for i in range(size - 1, len(array) + 1):
+ window = array[i - size : i]
+
+ if len(window) == size:
+ result.append(mean(window))
+
+ return result
+
+
+@t.overload
+def multiply(multiplier: SupportsMul[int, T2], multiplicand: None) -> T2: ...
+
+
+@t.overload
+def multiply(multiplier: None, multiplicand: SupportsMul[int, T2]) -> T2: ...
+
+
+@t.overload
+def multiply(multiplier: None, multiplicand: None) -> int: ...
+
+
+@t.overload
+def multiply(multiplier: SupportsMul[T, T2], multiplicand: T) -> T2: ...
+
+
+@t.overload
+def multiply(multiplier: T, multiplicand: SupportsMul[T, T2]) -> T2: ...
+
+
+def multiply(multiplier, multiplicand):
+ """
+ Multiply two numbers.
+
+ Args:
+ multiplier: The first number in a multiplication.
+ multiplicand: The second number in a multiplication.
+
+ Returns:
+ Returns the product.
+
+ Example:
+
+ >>> multiply(4, 5)
+ 20
+ >>> multiply(10, 4)
+ 40
+ >>> multiply(None, 10)
+ 10
+ >>> multiply(None, None)
+ 1
+
+ .. versionadded:: 4.0.0
+ """
+ return call_math_operator(multiplier, multiplicand, operator.mul, 1)
+
+
+@t.overload
+def power(x: int, n: int) -> t.Union[int, float]: ...
+
+
+@t.overload
+def power(x: float, n: t.Union[int, float]) -> float: ...
+
+
+@t.overload
+def power(x: t.List[int], n: int) -> t.List[t.Union[int, float]]: ...
+
+
+@t.overload
+def power(x: t.List[float], n: t.List[t.Union[int, float]]) -> t.List[float]: ...
+
+
+def power(x, n):
+ """
+ Calculate exponentiation of `x` raised to the `n` power.
+
+ Args:
+ x: Base number.
+ n: Exponent.
+
+ Returns:
+ Result of calculation.
+
+ Example:
+
+ >>> power(5, 2)
+ 25
+ >>> power(12.5, 3)
+ 1953.125
+
+ .. versionadded:: 2.1.0
+
+ .. versionchanged:: 4.0.0
+ Removed alias ``pow_``.
+ """
+ if pyd.is_number(x):
+ result = pow(x, n)
+ elif pyd.is_list(x):
+ result = [pow(item, n) for item in x]
+ else:
+ result = None
+
+ return result
+
+
+@t.overload
+def round_(x: t.List[SupportsRound[NumberT]], precision: int = 0) -> t.List[float]: ...
+
+
+@t.overload
+def round_(x: SupportsRound[NumberT], precision: int = 0) -> float: ...
+
+
+def round_(x, precision=0):
+ """
+ Round number to precision.
+
+ Args:
+ x: Number to round.
+ precision: Rounding precision. Defaults to ``0``.
+
+ Returns:
+ Rounded number.
+
+ Example:
+
+ >>> round_(3.275) == 3.0
+ True
+ >>> round_(3.275, 1) == 3.3
+ True
+
+ .. versionadded:: 2.1.0
+
+ .. versionchanged:: 4.0.0
+ Remove alias ``curve``.
+ """
+ return rounder(round, x, precision)
+
+
+@t.overload
+def scale(array: t.Iterable["Decimal"], maximum: "Decimal") -> t.List["Decimal"]: ...
+
+
+@t.overload
+def scale(array: t.Iterable[NumberNoDecimalT], maximum: NumberNoDecimalT) -> t.List[float]: ...
+
+
+@t.overload
+def scale(array: t.Iterable[NumberT], maximum: int = 1) -> t.List[float]: ...
+
+
+def scale(array, maximum: NumberT = 1):
+ """
+ Scale list of value to a maximum number.
+
+ Args:
+ array: Numbers to scale.
+ maximum: Maximum scale value.
+
+ Returns:
+ Scaled numbers.
+
+ Example:
+
+ >>> scale([1, 2, 3, 4])
+ [0.25, 0.5, 0.75, 1.0]
+ >>> scale([1, 2, 3, 4], 1)
+ [0.25, 0.5, 0.75, 1.0]
+ >>> scale([1, 2, 3, 4], 4)
+ [1.0, 2.0, 3.0, 4.0]
+ >>> scale([1, 2, 3, 4], 2)
+ [0.5, 1.0, 1.5, 2.0]
+
+ .. versionadded:: 2.1.0
+ """
+ array_max = max(array)
+ factor = maximum / array_max
+ return [item * factor for item in array]
+
+
+@t.overload
+def slope(
+ point1: t.Union[t.Tuple["Decimal", "Decimal"], t.List["Decimal"]],
+ point2: t.Union[t.Tuple["Decimal", "Decimal"], t.List["Decimal"]],
+) -> "Decimal": ...
+
+
+@t.overload
+def slope(
+ point1: t.Union[t.Tuple[NumberNoDecimalT, NumberNoDecimalT], t.List[NumberNoDecimalT]],
+ point2: t.Union[t.Tuple[NumberNoDecimalT, NumberNoDecimalT], t.List[NumberNoDecimalT]],
+) -> float: ...
+
+
+def slope(point1, point2):
+ """
+ Calculate the slope between two points.
+
+ Args:
+ point1: X and Y coordinates of first point.
+ point2: X and Y cooredinates of second point.
+
+ Returns:
+ Calculated slope.
+
+ Example:
+
+ >>> slope((1, 2), (4, 8))
+ 2.0
+
+ .. versionadded:: 2.1.0
+ """
+ x1, y1 = point1[0], point1[1]
+ x2, y2 = point2[0], point2[1]
+
+ if x1 == x2:
+ result = INFINITY
+ else:
+ result = (y2 - y1) / (x2 - x1)
+
+ return result
+
+
+def std_deviation(array: t.List[NumberT]) -> float:
+ """
+ Calculate standard deviation of list of numbers.
+
+ Args:
+ array: List to process.
+
+ Returns:
+ Calculated standard deviation.
+
+ Example:
+
+ >>> round(std_deviation([1, 18, 20, 4]), 2) == 8.35
+ True
+
+ .. versionadded:: 2.1.0
+
+ .. versionchanged:: 4.0.0
+ Remove alias ``sigma``.
+ """
+ return math.sqrt(variance(array))
+
+
+@t.overload
+def subtract(minuend: "SupportsSub[T, T2]", subtrahend: T) -> T2: ...
+
+
+@t.overload
+def subtract(minuend: T, subtrahend: "SupportsSub[T, T2]") -> T2: ...
+
+
+def subtract(minuend, subtrahend):
+ """
+ Subtracts two numbers.
+
+ Args:
+ minuend: Value passed in by the user.
+ subtrahend: Value passed in by the user.
+
+ Returns:
+ Result of the difference from the given values.
+
+ Example:
+
+ >>> subtract(10, 5)
+ 5
+ >>> subtract(-10, 4)
+ -14
+ >>> subtract(2, 0.5)
+ 1.5
+
+ .. versionadded:: 4.0.0
+ """
+ return call_math_operator(minuend, subtrahend, operator.sub, 0)
+
+
+def transpose(array: t.Iterable[t.Iterable[T]]) -> t.List[t.List[T]]:
+ """
+ Transpose the elements of `array`.
+
+ Args:
+ array: List to process.
+
+ Returns:
+ Transposed list.
+
+ Example:
+
+ >>> transpose([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
+ [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
+
+ .. versionadded:: 2.1.0
+ """
+ trans: t.List[t.List[T]] = []
+
+ for y, row in iterator(array):
+ for x, col in iterator(row):
+ trans = pyd.set_(trans, [x, y], col)
+
+ return trans
+
+
+@t.overload
+def variance(array: t.Mapping[t.Any, "SupportsAdd[int, t.Any]"]) -> float: ...
+
+
+@t.overload
+def variance(array: t.Iterable["SupportsAdd[int, t.Any]"]) -> float: ...
+
+
+def variance(array):
+ """
+ Calculate the variance of the elements in `array`.
+
+ Args:
+ array: List to process.
+
+ Returns:
+ Calculated variance.
+
+ Example:
+
+ >>> variance([1, 18, 20, 4])
+ 69.6875
+
+ .. versionadded:: 2.1.0
+ """
+ avg = mean(array)
+
+ def var(x):
+ return power(x - avg, 2)
+
+ return pyd._(array).map_(var).mean().value()
+
+
+@t.overload
+def zscore(
+ collection: t.Mapping[T, T2], iteratee: t.Callable[[T2, T, t.Dict[T, T2]], NumberT]
+) -> t.List[float]: ...
+
+
+@t.overload
+def zscore(
+ collection: t.Mapping[T, T2], iteratee: t.Callable[[T2, T], NumberT]
+) -> t.List[float]: ...
+
+
+@t.overload
+def zscore(
+ collection: t.Mapping[t.Any, T2], iteratee: t.Callable[[T2], NumberT]
+) -> t.List[float]: ...
+
+
+@t.overload
+def zscore(
+ collection: t.Iterable[T], iteratee: t.Callable[[T, int, t.List[T]], NumberT]
+) -> t.List[float]: ...
+
+
+@t.overload
+def zscore(collection: t.Iterable[T], iteratee: t.Callable[[T, int], NumberT]) -> t.List[float]: ...
+
+
+@t.overload
+def zscore(collection: t.Iterable[T], iteratee: t.Callable[[T], NumberT]) -> t.List[float]: ...
+
+
+@t.overload
+def zscore(collection: t.Iterable[NumberT], iteratee: None = None) -> t.List[float]: ...
+
+
+def zscore(collection, iteratee=None):
+ """
+ Calculate the standard score assuming normal distribution. If iteratee is passed, each element
+ of `collection` is passed through an iteratee before the standard score is computed.
+
+ Args:
+ collection: Collection to process.
+ iteratee: Iteratee applied per iteration.
+
+ Returns:
+ Calculated standard score.
+
+ Example:
+
+ >>> results = zscore([1, 2, 3])
+
+ # [-1.224744871391589, 0.0, 1.224744871391589]
+
+ .. versionadded:: 2.1.0
+ """
+ array = pyd.map_(collection, iteratee)
+ avg = mean(array)
+ sig = std_deviation(array)
+
+ return [(item - avg) / sig for item in array]
+
+
+#
+# Utility methods not a part of the main API
+#
+
+
+def call_math_operator(value1, value2, op, default):
+ """Return the result of the math operation on the given values."""
+ if value1 is None:
+ value1 = default
+
+ if value2 is None:
+ value2 = default
+
+ if not pyd.is_number(value1):
+ try:
+ value1 = float(value1)
+ except Exception:
+ pass
+
+ if not pyd.is_number(value2):
+ try:
+ value2 = float(value2)
+ except Exception:
+ pass
+
+ return op(value1, value2)
+
+
+def rounder(func, x, precision):
+ precision = pow(10, precision)
+
+ def rounder_func(item):
+ return func(item * precision) / precision
+
+ result = None
+
+ if pyd.is_number(x):
+ result = rounder_func(x)
+ elif pyd.is_iterable(x):
+ try:
+ result = [rounder_func(item) for item in x]
+ except TypeError:
+ pass
+
+ return result