Source code for mimesis.random
"""Implements various helpers which are used in the various data providers.
This module contains custom ``Random()`` class where implemented a lot of
methods which are not included in standard :py:class:`random.Random`,
but frequently used in this project.
"""
import random as random_module
import string
import typing as t
import uuid
from mimesis.types import MissingSeed, Seed
__all__ = ["Random", "random"]
#: Different plugins (like `pytest-randomly`)
#: can set custom values to a global seed,
#: which are going to be the new default.
global_seed: Seed = MissingSeed
[docs]class Random(random_module.Random):
"""A custom random class.
It is a subclass of the :py:class:`random.Random` class from the standard
library's random module. The class incorporates additional custom methods.
This class can be extended according to specific requirements.
"""
[docs] def randints(self, amount: int = 3, a: int = 1, b: int = 100) -> t.List[int]:
"""Generate list of random integers.
:param amount: Amount of elements.
:param a: Minimum value of range.
:param b: Maximum value of range.
:return: List of random integers.
:raises ValueError: if amount less or equal to zero.
"""
if amount <= 0:
raise ValueError("Amount out of range.")
return [int(self.random() * (b - a)) + a for _ in range(amount)]
def _generate_string(self, str_seq: str, length: int = 10) -> str:
"""Generate random string created from string sequence.
:param str_seq: String sequence of letters or digits.
:param length: Max value.
:return: Single string.
"""
return "".join(self.choices(str_seq, k=length))
[docs] def custom_code(self, mask: str = "@###", char: str = "@", digit: str = "#") -> str:
"""Generate custom code using ascii uppercase and random integers.
:param mask: Mask of code.
:param char: Placeholder for characters.
:param digit: Placeholder for digits.
:return: Custom code.
"""
char_code = ord(char)
digit_code = ord(digit)
if char_code == digit_code:
raise ValueError(
"The same placeholder cannot be "
"used for both numbers and characters."
)
def random_int(a: int, b: int) -> int:
b = b - a
return int(self.random() * b) + a
_mask = mask.encode()
code = bytearray(len(_mask))
for i, p in enumerate(_mask):
if p == char_code:
a = random_int(65, 91) # A-Z
elif p == digit_code:
a = random_int(48, 58) # 0-9
else:
a = p
code[i] = a
return code.decode()
def _randstr(self, unique: bool = False, length: t.Optional[int] = None) -> str:
"""Generate random string value.
This method can be especially useful when you need to generate
only unique values in your provider. Just pass parameter unique=True.
Basically, this method is just a simple wrapper around :py:class:`uuid.UUID`.
:param unique: Generate only unique values.
:param length: Length of string. Default range is [a, b].
:return: Random string.
"""
if unique:
return str(uuid.uuid4().hex)
if length is None:
length = self.randint(16, 128)
characters = string.ascii_letters + string.digits
return "".join(self.choices(characters, k=length))
[docs] def randbytes(self, n: int = 16) -> bytes:
"""Generate n random bytes."""
return self.getrandbits(n * 8).to_bytes(n, "little")
[docs] def weighted_choice(self, choices: t.Dict[t.Any, float]) -> t.Any:
"""Returns a random element according to the specified weights.
:param choices: A dictionary where keys are choices and values are weights.
:raises ValueError: if choices is empty.
:return: Random key from dictionary.
"""
if not choices:
raise ValueError("Choices cannot be empty.")
population = list(choices.keys())
weights = list(choices.values())
return self.choices(population, weights=weights, k=1)[0]
[docs] def choice_enum_item(self, enum: t.Any) -> t.Any:
"""Get random value of enum object.
:param enum: Enum object.
:return: Random value of enum.
"""
return self.choice(list(enum))
# Compat
# See: https://github.com/lk-geimfari/mimesis/issues/469
random = Random()