Feat: move to global_config, configs for generator
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
b2b204c17b
commit
87b6b3ca27
@ -7,7 +7,7 @@
|
||||
# Distributed under terms of the MIT license.
|
||||
|
||||
"""
|
||||
Tools to extract random leafs, random variables, generate random values and
|
||||
Tools to extract random leaves, random variables, generate random values and
|
||||
fill new trees
|
||||
|
||||
Flow
|
||||
@ -17,7 +17,7 @@ Tree with RdLeaf
|
||||
|
|
||||
| Extract rdLeaf
|
||||
|
|
||||
List of leafs to generate
|
||||
List of leaves to generate
|
||||
|
|
||||
| extract_rv
|
||||
|
|
||||
@ -27,9 +27,9 @@ List random variables to generate
|
||||
|
|
||||
Dictionnary of generated random variables
|
||||
|
|
||||
| Compute leafs
|
||||
| Compute leaves
|
||||
|
|
||||
Dictionnary of computed leafs
|
||||
Dictionnary of computed leaves
|
||||
|
|
||||
| Replace
|
||||
|
|
||||
@ -46,15 +46,15 @@ Tree with RdLeaf replaced by generated values
|
||||
/
|
||||
> {a}
|
||||
> {a*k}
|
||||
>>> leafs = rd_t.random_leaf
|
||||
>>> leafs = ['a', 'a*k']
|
||||
>>> rd_varia = extract_letters(leafs)
|
||||
>>> leaves = rd_t.random_leaves
|
||||
>>> leaves = ['a', 'a*k']
|
||||
>>> rd_varia = extract_letters(leaves)
|
||||
>>> sorted(list(rd_varia))
|
||||
['a', 'k']
|
||||
>>> generated = random_generator(rd_varia, conditions=['a%2+1'])
|
||||
>>> generated = random_generator(rd_varia, conditions=['a%2+1'], global_config={"min_max": (-10, 10), "rejected":[0, 1]})
|
||||
>>> generated # doctest: +SKIP
|
||||
{'a': 7, 'k': 4}
|
||||
>>> computed = eval_words(leafs, generated)
|
||||
>>> computed = eval_words(leaves, generated)
|
||||
>>> computed # doctest: +SKIP
|
||||
{'a': 7, 'a*k': 28}
|
||||
>>> replaced = rd_t.eval_random_leaves(computed)
|
||||
|
@ -10,63 +10,60 @@
|
||||
from random import choice
|
||||
|
||||
|
||||
def build_variable_scope(rd_variables, rejected, min_max, variables_scope):
|
||||
""" Build variables scope from incomplete one
|
||||
def complete_variable_configs(variables, global_config:dict={}, configs:dict={})->dict:
|
||||
""" Completes variables configurations with the global configuration
|
||||
|
||||
:param rd_variables: list of random variables to generate
|
||||
:param rejected: Rejected values for the generator
|
||||
:param min_max: (min, max) limits in between variables will be generated
|
||||
:param variables_scope: rejected and min_max define for individual variables
|
||||
:param variables: list of random variables to generate
|
||||
:param global_config: global parameters
|
||||
:param configs: global parameters
|
||||
:return: complete variable scope
|
||||
|
||||
:example:
|
||||
>>> completed = build_variable_scope(["a", "b", "c", "d"], [0], (-10, 10),
|
||||
... {"a": {"rejected": [0, 1]},
|
||||
>>> completed = complete_variable_configs(["a", "b", "c", "d"],
|
||||
... global_config={"rejected": [], "min_max": (-10, 10)},
|
||||
... configs={
|
||||
... "a": {"rejected": [0, 1]},
|
||||
... "b": {"min_max": (-5, 0)},
|
||||
... "c": {"rejected": [2], "min_max": (0, 5)}})
|
||||
>>> complete = {'a': {'rejected': [0, 1], 'min_max': (-10, 10)},
|
||||
... 'b': {'rejected': [0], 'min_max': (-5, 0)},
|
||||
... 'c': {'rejected': [2], 'min_max': (0, 5)},
|
||||
... 'd': {'rejected': [0], 'min_max': (-10, 10)}}
|
||||
>>> completed == complete
|
||||
... "c": {"rejected": [2], "min_max": (0, 5)}
|
||||
... })
|
||||
>>> completed["a"] == {'rejected': [0, 1], 'min_max': (-10, 10)}
|
||||
True
|
||||
>>> completed["b"] == {'rejected': [], 'min_max': (-5, 0)}
|
||||
True
|
||||
>>> completed['c'] == {'rejected': [2], 'min_max': (0, 5)}
|
||||
True
|
||||
>>> completed['d'] == {'rejected': [], 'min_max': (-10, 10)}
|
||||
True
|
||||
"""
|
||||
complete_scope = variables_scope.copy()
|
||||
for v in rd_variables:
|
||||
complete_configs = configs.copy()
|
||||
for variable in variables:
|
||||
try:
|
||||
complete_scope[v]
|
||||
complete_configs[variable]
|
||||
except KeyError:
|
||||
complete_scope[v] = {"rejected": rejected, "min_max": min_max}
|
||||
complete_configs[variable] = global_config
|
||||
else:
|
||||
try:
|
||||
complete_scope[v]["rejected"]
|
||||
except KeyError:
|
||||
complete_scope[v]["rejected"] = rejected
|
||||
try:
|
||||
complete_scope[v]["min_max"]
|
||||
except KeyError:
|
||||
complete_scope[v]["min_max"] = min_max
|
||||
return complete_scope
|
||||
complete_configs[variable] = dict(global_config, **configs[variable])
|
||||
return complete_configs
|
||||
|
||||
|
||||
def random_generator(
|
||||
rd_variables, conditions=[], rejected=[0], min_max=(-10, 10), variables_scope={}
|
||||
):
|
||||
variables:list[str], conditions:list[str]=[], global_config:dict={}, configs:dict={},
|
||||
)-> dict[str, int]:
|
||||
""" Generate random variables
|
||||
|
||||
:param rd_variables: list of random variables to generate
|
||||
:param variables: list of random variables to generate
|
||||
:param conditions: condition over variables
|
||||
:param rejected: Rejected values for the generator (default [0])
|
||||
:param min_max: (min, max) limits in between variables will be generated
|
||||
:param variables_scope: rejected and min_max define for individual variables
|
||||
:param global_config: global parameters
|
||||
:param configs: global parameters
|
||||
:return: dictionnary of generated variables
|
||||
|
||||
:example:
|
||||
>>> gene = random_generator(["a", "b"],
|
||||
... ["a > 0"],
|
||||
... [0], (-10, 10),
|
||||
... {"rejected": [0], "min_max":(-10, 10)},
|
||||
... {"a": {"rejected": [0, 1]},
|
||||
... "b": {"min_max": (-5, 0)}})
|
||||
... "b": {"min_max": (-5, 0)},
|
||||
... })
|
||||
>>> gene["a"] > 0
|
||||
True
|
||||
>>> gene["a"] != 0
|
||||
@ -75,7 +72,8 @@ def random_generator(
|
||||
True
|
||||
>>> gene = random_generator(["a", "b"],
|
||||
... ["a % b == 0"],
|
||||
... [0, 1], (-10, 10))
|
||||
... {"rejected": [0, 1], "min_max":(-10, 10)}
|
||||
... )
|
||||
>>> gene["a"] not in [0, 1]
|
||||
True
|
||||
>>> gene["b"] in list(range(-10, 11))
|
||||
@ -83,8 +81,8 @@ def random_generator(
|
||||
>>> gene["a"] % gene["b"]
|
||||
0
|
||||
"""
|
||||
complete_scope = build_variable_scope(
|
||||
rd_variables, rejected, min_max, variables_scope
|
||||
complete_scope = complete_variable_configs(
|
||||
variables, global_config, configs
|
||||
)
|
||||
choices_list = {
|
||||
v: list(
|
||||
@ -94,17 +92,17 @@ def random_generator(
|
||||
)
|
||||
).difference(complete_scope[v]["rejected"])
|
||||
)
|
||||
for v in rd_variables
|
||||
for v in variables
|
||||
}
|
||||
|
||||
# quantity_choices = reduce(lambda x,y : x*y,
|
||||
# [len(choices_list[v]) for v in choices_list])
|
||||
# TODO: améliorer la méthode de rejet avec un cache |dim. mai 12 17:04:11 CEST 2019
|
||||
|
||||
generate_variable = {v: choice(choices_list[v]) for v in rd_variables}
|
||||
generate_variable = {v: choice(choices_list[v]) for v in variables}
|
||||
|
||||
while not all([eval(c, __builtins__, generate_variable) for c in conditions]):
|
||||
generate_variable = {v: choice(choices_list[v]) for v in rd_variables}
|
||||
generate_variable = {v: choice(choices_list[v]) for v in variables}
|
||||
|
||||
return generate_variable
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
from ...core.tree import MutableTree, Tree
|
||||
from .grammar import extract_letters
|
||||
from .grammar import extract_letters, eval_words
|
||||
from .generate import random_generator
|
||||
from .str2 import rdstr2
|
||||
|
||||
class RandomTree(MutableTree):
|
||||
@ -35,23 +36,18 @@ class RandomTree(MutableTree):
|
||||
"""
|
||||
str_2_mut_tree = rdstr2(cls.sink)
|
||||
return str_2_mut_tree(expression)
|
||||
|
||||
def generate(self, conditions:list[str]=[], rejected:list[int]=[0, 1], min_max:tuple[int]=(-10, 10),scopes:dict={}) -> Tree:
|
||||
""" Generate a random version of self """
|
||||
|
||||
pass
|
||||
|
||||
@property
|
||||
def random_leaf(self) -> list[str]:
|
||||
def random_leaves(self) -> list[str]:
|
||||
""" Get list of random leaves
|
||||
|
||||
:example:
|
||||
>>> from .leaf import RdLeaf
|
||||
>>> random_tree = RandomTree("+", RdLeaf("a"), RdLeaf("a*k"))
|
||||
>>> random_tree.random_leaf
|
||||
>>> random_tree.random_leaves
|
||||
['a', 'a*k']
|
||||
>>> random_tree = RandomTree("+", RdLeaf("a"), 2)
|
||||
>>> random_tree.random_leaf
|
||||
>>> random_tree.random_leaves
|
||||
['a']
|
||||
"""
|
||||
rd_leafs = []
|
||||
@ -78,7 +74,7 @@ class RandomTree(MutableTree):
|
||||
>>> random_tree.random_value
|
||||
{'a'}
|
||||
"""
|
||||
return extract_letters(self.random_leaf)
|
||||
return extract_letters(self.random_leaves)
|
||||
|
||||
|
||||
def eval_random_leaves(self, leaves_value:dict[str, int]):
|
||||
@ -102,3 +98,15 @@ class RandomTree(MutableTree):
|
||||
except AttributeError:
|
||||
return leaf
|
||||
return self.map_on_leaf(replace)
|
||||
|
||||
def generate(self, conditions:list[str]=[], config:dict={} , configs:dict={}) -> Tree:
|
||||
""" Generate a random version of self
|
||||
|
||||
:param conditions: list of conditions
|
||||
:param config: global configuration for generated values
|
||||
:param configs: specific configuration for each generated values
|
||||
|
||||
"""
|
||||
generated_values = random_generator(self.random_values, config, configs)
|
||||
leaves = eval_words(self.random_leaves, generated_values)
|
||||
return self.eval_random_leaves(leaves)
|
||||
|
@ -12,7 +12,12 @@ This function ignores tree structure and works with lists
|
||||
from .core.generate import random_generator
|
||||
from .core.grammar import extract_letters, eval_words
|
||||
|
||||
def list_generator(var_list, conditions=[], rejected=[0], min_max=(-10, 10), variables_scope={}, dictionnary=False):
|
||||
DEFAUTL_CONFIG = {
|
||||
"rejected": [0],
|
||||
"min_max": (-10, 10),
|
||||
}
|
||||
|
||||
def list_generator(var_list:list[str], conditions:list[str]=[], global_config:dict={}, configs:dict={})->list[int]:
|
||||
""" Generate random computed values from the list
|
||||
|
||||
:param rd_variables: list of random variables to generate (can be computed value - "a*b")
|
||||
@ -20,7 +25,6 @@ def list_generator(var_list, conditions=[], rejected=[0], min_max=(-10, 10), var
|
||||
:param rejected Rejected values for the generator (default [0])
|
||||
:param min_max: (min, max) limits in between variables will be generated
|
||||
:param variables_scope: rejected and min_max define for individual variables
|
||||
:param dictionnary: the return value will be a dictionnary with var_list as keys (default False)
|
||||
:return: dictionnary of generated variables
|
||||
|
||||
:example:
|
||||
@ -33,12 +37,21 @@ def list_generator(var_list, conditions=[], rejected=[0], min_max=(-10, 10), var
|
||||
-20
|
||||
>>> a, b # doctest: +SKIP
|
||||
5, -4
|
||||
>>> list_generator(["a", "a*b", "b", "c"], dictionnary=True) # doctest: +SKIP
|
||||
{'a': -3, 'a*b': 18, 'b': -6, 'c': -4}
|
||||
>>> a, ab, b, c = list_generator(["a", "a*b", "b", "c"], conditions=["a-b==0"])
|
||||
>>> a - b == 0
|
||||
True
|
||||
>>> a, ab, b, c = list_generator(["a", "a*b", "b", "c"], global_config={"rejected": [2, 3, 5, 7]})
|
||||
>>> a not in [2, 3, 5, 7]
|
||||
True
|
||||
>>> b not in [2, 3, 5, 7]
|
||||
True
|
||||
>>> c not in [2, 3, 5, 7]
|
||||
True
|
||||
>>> a, ab, b, c = list_generator(["a", "a*b", "b", "c"], configs={"a": {"rejected": [2, 3, 5, 7]})
|
||||
>>> a not in [2, 3, 5, 7]
|
||||
True
|
||||
"""
|
||||
rv = extract_letters(var_list)
|
||||
rv_gen = random_generator(rv, conditions, rejected, min_max, variables_scope)
|
||||
rv_gen = random_generator(rv, conditions, dict(DEFAUTL_CONFIG, **global_config), variables_scope)
|
||||
generated = eval_words(var_list, rv_gen)
|
||||
if dictionnary:
|
||||
return generated
|
||||
return [generated[v] for v in var_list]
|
||||
|
Loading…
Reference in New Issue
Block a user