"""Provides data related to numbers."""
import typing as t
from collections import defaultdict
from decimal import Decimal
from mimesis.enums import NumType
from mimesis.providers.base import BaseProvider
from mimesis.types import Matrix
__all__ = ["Numeric"]
[docs]
class Numeric(BaseProvider):
"""A provider for generating numeric data."""
[docs]
def __init__(self, *args: t.Any, **kwargs: t.Any) -> None:
super().__init__(*args, **kwargs)
self.__increment_dict: t.DefaultDict[str, int] = defaultdict(int)
self.__default_accumulator_value: t.Final[str] = "default"
class Meta:
name = "numeric"
[docs]
def increment(self, accumulator: str | None = None) -> int:
"""Generates an incrementing number.
Each call of this method returns an incrementing number (with the step of +1).
If **accumulator** passed then increments number associated with it.
Example:
>>> self.increment()
1
>>> self.increment(accumulator="a")
1
>>> self.increment()
2
>>> self.increment(accumulator="a")
2
>>> self.increment(accumulator="b")
1
>>> self.increment(accumulator="a")
3
:param accumulator: Accumulator (used to create associative incrementation).
:return: Integer.
"""
if not accumulator:
accumulator = self.__default_accumulator_value
self.__increment_dict[accumulator] += 1
return self.__increment_dict[accumulator]
[docs]
def float_number(
self, start: float = -1000.0, end: float = 1000.0, precision: int = 15
) -> float:
"""Generates a random float number in range [start, end].
:param start: Start range.
:param end: End range.
:param precision: Round a number to a given
precision in decimal digits, default is 15.
:return: Float.
"""
return self.random.uniform(start, end, precision)
[docs]
def floats(
self, start: float = 0, end: float = 1, n: int = 10, precision: int = 15
) -> list[float]:
"""Generates a list of random float numbers.
:param start: Start range.
:param end: End range.
:param n: Length of the list.
:param precision: Round a number to a given
precision in decimal digits, default is 15.
:return: The list of floating-point numbers.
"""
return [self.float_number(start, end, precision) for _ in range(n)]
[docs]
def integer_number(self, start: int = -1000, end: int = 1000) -> int:
"""Generates a random integer from start to end.
:param start: Start range.
:param end: End range.
:return: Integer.
"""
return self.random.randint(start, end)
[docs]
def integers(self, start: int = 0, end: int = 10, n: int = 10) -> list[int]:
"""Generates a list of random integers.
:param start: Start.
:param end: End.
:param n: Length of the list.
:return: List of integers.
:Example:
[-20, -19, -18, -17]
"""
return self.random.randints(n, start, end)
[docs]
def complex_number(
self,
start_real: float = 0.0,
end_real: float = 1.0,
start_imag: float = 0.0,
end_imag: float = 1.0,
precision_real: int = 15,
precision_imag: int = 15,
) -> complex:
"""Generates a random complex number.
:param start_real: Start real range.
:param end_real: End real range.
:param start_imag: Start imaginary range.
:param end_imag: End imaginary range.
:param precision_real: Round a real part of
number to a given precision.
:param precision_imag: Round the imaginary part of
number to a given precision.
:return: Complex numbers.
"""
real_part = self.random.uniform(start_real, end_real, precision_real)
imag_part = self.random.uniform(start_imag, end_imag, precision_imag)
return complex(real_part, imag_part)
[docs]
def complexes(
self,
start_real: float = 0,
end_real: float = 1,
start_imag: float = 0,
end_imag: float = 1,
precision_real: int = 15,
precision_imag: int = 15,
n: int = 10,
) -> list[complex]:
"""Generates a list of random complex numbers.
:param start_real: Start real range.
:param end_real: End real range.
:param start_imag: Start imaginary range.
:param end_imag: End imaginary range.
:param precision_real: Round a real part of
number to a given precision.
:param precision_imag: Round the imaginary part of
number to a given precision.
:param n: Length of the list.
:return: A list of random complex numbers.
"""
numbers = []
for _ in range(n):
numbers.append(
self.complex_number(
start_real=start_real,
end_real=end_real,
start_imag=start_imag,
end_imag=end_imag,
precision_real=precision_real,
precision_imag=precision_imag,
),
)
return numbers
[docs]
def decimal_number(self, start: float = -1000.0, end: float = 1000.0) -> Decimal:
"""Generates a random decimal number.
:param start: Start range.
:param end: End range.
:return: :py:class:`decimal.Decimal` object.
"""
return Decimal.from_float(self.float_number(start, end))
[docs]
def decimals(
self, start: float = 0.0, end: float = 1000.0, n: int = 10
) -> list[Decimal]:
"""Generates a list of decimal numbers.
:param start: Start range.
:param end: End range.
:param n: Length of the list.
:return: A list of :py:class:`decimal.Decimal` objects.
"""
return [self.decimal_number(start, end) for _ in range(n)]
[docs]
def matrix(
self,
m: int = 10,
n: int = 10,
num_type: NumType = NumType.FLOAT,
**kwargs: t.Any,
) -> Matrix:
"""Generates m x n matrix with a random numbers.
This method works with a variety of types,
so you can pass method-specific `**kwargs`.
:param m: Number of rows.
:param n: Number of columns.
:param num_type: NumType enum object.
:param kwargs: Other method-specific arguments.
:return: A matrix of random numbers.
"""
key = self.validate_enum(num_type, NumType)
kwargs.update({"n": n})
method = getattr(self, key)
return [method(**kwargs) for _ in range(m)]