Random Structure Generator
Project description
RSG - Random Struct Generator
Rsg is a tool that helps creating randomly generated nested data structures, from simple built-in structures as lists, dictionaries and tuples, to custom composite class hierarchies.
In its current state, this library is merely a toy project with a few basic utilities, created with the intent of experimenting with python decorators and language inspection. It was originally a function that generated random yaml files for testing purposes, that quickly grew to become a generic subpackage that had no dependencies and could be exported as a separate python package.
Basics
Generators are subclasses of Rsg with special "generator" methods:
class RsgFooBar(Rsg):
@generator("foo")
def generate_foo(self):
return "foo"
@generator("bar")
def generate_bar(self):
return "bar"
This class genertes either "foo" or "bar" with equal chance:
rsg = RsgFooBar()
[print(next(rsg)) for _ in range(10)]
# bar foo foo bar foo foo bar bar foo foo
You can set a custom chance for each generator method, by setting the keyword agument
named <METHOD_NAME>_chance in the object constructor. Probabilities are normalized
automatically, so you don't need to ensure they sum up to one.
rsg = RsgFooBar(foo_chance=0.8, bar_chance=0.2)
[print(next(rsg)) for _ in range(10)]
# foo foo bar foo foo foo foo foo foo bar
Chances values all default to 1.0, you can set a custom default value when decorating a generator method. Default values are used only when a chance value is not specified in the object constructor.
@generator("foo", default_chance=0.2)
Parameters
What if a generator method needs parameters? In this example we want to make a generator of random powers of a number (a parameter), with the maximum exponent bounded by anohter parameter.
To do so, just add any amount of parameters to a generator method, you can use both positional and keyword arguments, without the need to implement a custom constructor for your class.
class RsgPowers(Rsg):
@generator("power")
def generate_power(self, base: int, max_exp: int = 5):
exp = randint(0, max_exp)
return base**exp
To set the declared parameters, just pass them to the class constructor, as if you had actually implemented it!
rsg = RsgPowers(base=2, max_exp=10)
[print(next(rsg)) for _ in range(10)]
# 512 1024 16 128 32 1024 64 8 8 1
In the previous example, the parameter max_exp has a default value of 5, this means
that you don't have to explicitly set it in the object constructor. On the other hand,
the base parameter doesn't have a default value, and so it must be set explicitly.
Composite Structures
A generator method can be of two types:
- Leaf - Objects with no children, like the ones used so far.
- Composite - Objects with randomly generated children, which in turn can have children recursively.
Let's make a generator of lists-of-lists-of-lists-of-l...
class RsgList(Rsg):
@generator("list")
def generate_list(self, children: Iterable[Any]) -> list:
return list(children)
To make it recursive, you just need to add an argument named children to the method.
This argument will contain an iterable of N randomly generated children objects.
The children objects are generated with the same generator used for the parent object.
Recusion is governed by the following parameters:
min_depth- The minimum number of recursions before a leaf object can be generated. Ignored if no composite generators are available.max_depth- The maximum number of recursions. Must be >=min_depth.min_breadth- The minimum number of children per recursion step. If no leaf generators are available, on the last recursion stepmin_breadthis forced to 0.max_breadth- The maximum number of children per recursion step.
rsg = RsgList(min_depth=1, max_depth=3, min_breadth=2, max_breadth=4)
print(next(rsg))
# [[[[], []], [[], []], [[], []], [[], []]], [[[], [], [], []], [[], []], [[], []], [[], []]]]
Mixin
You can combine any Rsg by simply inheriting from them:
class RsgMixed(RsgFooBar, RsgList, RsgPowers):
pass
You can still set all parameters of the base classes, remember to set the required ones,
or otherwise you will get an AttributeError!
rsg = RsgMixed(
base=3,
foo_chance=0.1,
bar_chance=0.1,
power_chance=0.4,
list_chance=0.4,
min_depth=2,
max_depth=3,
min_breadth=2,
max_breadth=4,
)
print(next(rsg))
# [[[9, 243, 'foo', 'bar'], 27, ['foo', 3]], ['foo', [243, 81, 243]], ['foo', 243]]
Built-in Generators
Rsg provides generators for the following built-in types:
int-rsg.core.RsgIntgenerates uniform integer values.float-rsg.core.RsgFloatgenerates uniform float values.str-rsg.core.RsgStrgenerates random strings containing a uniform random number of letters, digits and punctuations.list-rsg.core.RsgListgenerates nested lists.tuple-rsg.core.RsgTuplegenerates nested tuples.dict-rsg.core.RsgDictgenerates nested dicts with valid python identifiers as keys.
In addition, rsg.core.RsgBase combines all previous generators into one:
from rsg.core import RsgBase
rsg = RsgBase(min_depth=1, max_depth=4, min_breadth=1, max_breadth=3)
print(next(rsg))
# [
# ((0.73354,), (0.12835, '[^U`zq')),
# [643, ["QiX0@'", [0.95934, 0.27090, 0.66838]]],
# [{'N_dHLJUZA': 0.00379, 'D0N0uK1_eH': [667, 0.29715], 'SjWKcs_D': {'IMUUZH': 630}}]
# ]
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rsg-0.1.1.tar.gz.
File metadata
- Download URL: rsg-0.1.1.tar.gz
- Upload date:
- Size: 22.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/33.0 requests/2.27.1 requests-toolbelt/0.9.1 urllib3/1.26.8 tqdm/4.63.0 importlib-metadata/4.11.2 keyring/23.5.0 rfc3986/2.0.0 colorama/0.4.4 CPython/3.9.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2557aaed368396955844e5238a70074fd3806ea1bad34cc206f47f53a0de449a
|
|
| MD5 |
5f05d6c0f006381533f6a9c8bab0011e
|
|
| BLAKE2b-256 |
97c4118c900e28d37c0edbc3c99455427075a50183277068e0fad796bd004a2f
|
File details
Details for the file rsg-0.1.1-py2.py3-none-any.whl.
File metadata
- Download URL: rsg-0.1.1-py2.py3-none-any.whl
- Upload date:
- Size: 21.0 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/33.0 requests/2.27.1 requests-toolbelt/0.9.1 urllib3/1.26.8 tqdm/4.63.0 importlib-metadata/4.11.2 keyring/23.5.0 rfc3986/2.0.0 colorama/0.4.4 CPython/3.9.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7b624ced2779f662b990d5cd13d4e100c46bf345455edccf8176f52554057105
|
|
| MD5 |
5a55221a41c62fa8f3531adf8285f072
|
|
| BLAKE2b-256 |
81e8b2df1ec5b5b4c4a8e72a940701e48937680eb89718a31b4d2fb3fa183340
|