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.
|
# 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
|
fill new trees
|
||||||
|
|
||||||
Flow
|
Flow
|
||||||
@ -17,7 +17,7 @@ Tree with RdLeaf
|
|||||||
|
|
|
|
||||||
| Extract rdLeaf
|
| Extract rdLeaf
|
||||||
|
|
|
|
||||||
List of leafs to generate
|
List of leaves to generate
|
||||||
|
|
|
|
||||||
| extract_rv
|
| extract_rv
|
||||||
|
|
|
|
||||||
@ -27,9 +27,9 @@ List random variables to generate
|
|||||||
|
|
|
|
||||||
Dictionnary of generated random variables
|
Dictionnary of generated random variables
|
||||||
|
|
|
|
||||||
| Compute leafs
|
| Compute leaves
|
||||||
|
|
|
|
||||||
Dictionnary of computed leafs
|
Dictionnary of computed leaves
|
||||||
|
|
|
|
||||||
| Replace
|
| Replace
|
||||||
|
|
|
|
||||||
@ -46,15 +46,15 @@ Tree with RdLeaf replaced by generated values
|
|||||||
/
|
/
|
||||||
> {a}
|
> {a}
|
||||||
> {a*k}
|
> {a*k}
|
||||||
>>> leafs = rd_t.random_leaf
|
>>> leaves = rd_t.random_leaves
|
||||||
>>> leafs = ['a', 'a*k']
|
>>> leaves = ['a', 'a*k']
|
||||||
>>> rd_varia = extract_letters(leafs)
|
>>> rd_varia = extract_letters(leaves)
|
||||||
>>> sorted(list(rd_varia))
|
>>> sorted(list(rd_varia))
|
||||||
['a', 'k']
|
['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
|
>>> generated # doctest: +SKIP
|
||||||
{'a': 7, 'k': 4}
|
{'a': 7, 'k': 4}
|
||||||
>>> computed = eval_words(leafs, generated)
|
>>> computed = eval_words(leaves, generated)
|
||||||
>>> computed # doctest: +SKIP
|
>>> computed # doctest: +SKIP
|
||||||
{'a': 7, 'a*k': 28}
|
{'a': 7, 'a*k': 28}
|
||||||
>>> replaced = rd_t.eval_random_leaves(computed)
|
>>> replaced = rd_t.eval_random_leaves(computed)
|
||||||
|
@ -10,63 +10,60 @@
|
|||||||
from random import choice
|
from random import choice
|
||||||
|
|
||||||
|
|
||||||
def build_variable_scope(rd_variables, rejected, min_max, variables_scope):
|
def complete_variable_configs(variables, global_config:dict={}, configs:dict={})->dict:
|
||||||
""" Build variables scope from incomplete one
|
""" Completes variables configurations with the global configuration
|
||||||
|
|
||||||
:param rd_variables: list of random variables to generate
|
:param variables: list of random variables to generate
|
||||||
:param rejected: Rejected values for the generator
|
:param global_config: global parameters
|
||||||
:param min_max: (min, max) limits in between variables will be generated
|
:param configs: global parameters
|
||||||
:param variables_scope: rejected and min_max define for individual variables
|
|
||||||
:return: complete variable scope
|
:return: complete variable scope
|
||||||
|
|
||||||
:example:
|
:example:
|
||||||
>>> completed = build_variable_scope(["a", "b", "c", "d"], [0], (-10, 10),
|
>>> completed = complete_variable_configs(["a", "b", "c", "d"],
|
||||||
... {"a": {"rejected": [0, 1]},
|
... global_config={"rejected": [], "min_max": (-10, 10)},
|
||||||
|
... configs={
|
||||||
|
... "a": {"rejected": [0, 1]},
|
||||||
... "b": {"min_max": (-5, 0)},
|
... "b": {"min_max": (-5, 0)},
|
||||||
... "c": {"rejected": [2], "min_max": (0, 5)}})
|
... "c": {"rejected": [2], "min_max": (0, 5)}
|
||||||
>>> complete = {'a': {'rejected': [0, 1], 'min_max': (-10, 10)},
|
... })
|
||||||
... 'b': {'rejected': [0], 'min_max': (-5, 0)},
|
>>> completed["a"] == {'rejected': [0, 1], 'min_max': (-10, 10)}
|
||||||
... 'c': {'rejected': [2], 'min_max': (0, 5)},
|
True
|
||||||
... 'd': {'rejected': [0], 'min_max': (-10, 10)}}
|
>>> completed["b"] == {'rejected': [], 'min_max': (-5, 0)}
|
||||||
>>> completed == complete
|
True
|
||||||
|
>>> completed['c'] == {'rejected': [2], 'min_max': (0, 5)}
|
||||||
|
True
|
||||||
|
>>> completed['d'] == {'rejected': [], 'min_max': (-10, 10)}
|
||||||
True
|
True
|
||||||
"""
|
"""
|
||||||
complete_scope = variables_scope.copy()
|
complete_configs = configs.copy()
|
||||||
for v in rd_variables:
|
for variable in variables:
|
||||||
try:
|
try:
|
||||||
complete_scope[v]
|
complete_configs[variable]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
complete_scope[v] = {"rejected": rejected, "min_max": min_max}
|
complete_configs[variable] = global_config
|
||||||
else:
|
else:
|
||||||
try:
|
complete_configs[variable] = dict(global_config, **configs[variable])
|
||||||
complete_scope[v]["rejected"]
|
return complete_configs
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
def random_generator(
|
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
|
""" 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 conditions: condition over variables
|
||||||
:param rejected: Rejected values for the generator (default [0])
|
:param global_config: global parameters
|
||||||
:param min_max: (min, max) limits in between variables will be generated
|
:param configs: global parameters
|
||||||
:param variables_scope: rejected and min_max define for individual variables
|
|
||||||
:return: dictionnary of generated variables
|
:return: dictionnary of generated variables
|
||||||
|
|
||||||
:example:
|
:example:
|
||||||
>>> gene = random_generator(["a", "b"],
|
>>> gene = random_generator(["a", "b"],
|
||||||
... ["a > 0"],
|
... ["a > 0"],
|
||||||
... [0], (-10, 10),
|
... {"rejected": [0], "min_max":(-10, 10)},
|
||||||
... {"a": {"rejected": [0, 1]},
|
... {"a": {"rejected": [0, 1]},
|
||||||
... "b": {"min_max": (-5, 0)}})
|
... "b": {"min_max": (-5, 0)},
|
||||||
|
... })
|
||||||
>>> gene["a"] > 0
|
>>> gene["a"] > 0
|
||||||
True
|
True
|
||||||
>>> gene["a"] != 0
|
>>> gene["a"] != 0
|
||||||
@ -75,7 +72,8 @@ def random_generator(
|
|||||||
True
|
True
|
||||||
>>> gene = random_generator(["a", "b"],
|
>>> gene = random_generator(["a", "b"],
|
||||||
... ["a % b == 0"],
|
... ["a % b == 0"],
|
||||||
... [0, 1], (-10, 10))
|
... {"rejected": [0, 1], "min_max":(-10, 10)}
|
||||||
|
... )
|
||||||
>>> gene["a"] not in [0, 1]
|
>>> gene["a"] not in [0, 1]
|
||||||
True
|
True
|
||||||
>>> gene["b"] in list(range(-10, 11))
|
>>> gene["b"] in list(range(-10, 11))
|
||||||
@ -83,8 +81,8 @@ def random_generator(
|
|||||||
>>> gene["a"] % gene["b"]
|
>>> gene["a"] % gene["b"]
|
||||||
0
|
0
|
||||||
"""
|
"""
|
||||||
complete_scope = build_variable_scope(
|
complete_scope = complete_variable_configs(
|
||||||
rd_variables, rejected, min_max, variables_scope
|
variables, global_config, configs
|
||||||
)
|
)
|
||||||
choices_list = {
|
choices_list = {
|
||||||
v: list(
|
v: list(
|
||||||
@ -94,17 +92,17 @@ def random_generator(
|
|||||||
)
|
)
|
||||||
).difference(complete_scope[v]["rejected"])
|
).difference(complete_scope[v]["rejected"])
|
||||||
)
|
)
|
||||||
for v in rd_variables
|
for v in variables
|
||||||
}
|
}
|
||||||
|
|
||||||
# quantity_choices = reduce(lambda x,y : x*y,
|
# quantity_choices = reduce(lambda x,y : x*y,
|
||||||
# [len(choices_list[v]) for v in choices_list])
|
# [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
|
# 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]):
|
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
|
return generate_variable
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from ...core.tree import MutableTree, Tree
|
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
|
from .str2 import rdstr2
|
||||||
|
|
||||||
class RandomTree(MutableTree):
|
class RandomTree(MutableTree):
|
||||||
@ -36,22 +37,17 @@ class RandomTree(MutableTree):
|
|||||||
str_2_mut_tree = rdstr2(cls.sink)
|
str_2_mut_tree = rdstr2(cls.sink)
|
||||||
return str_2_mut_tree(expression)
|
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
|
@property
|
||||||
def random_leaf(self) -> list[str]:
|
def random_leaves(self) -> list[str]:
|
||||||
""" Get list of random leaves
|
""" Get list of random leaves
|
||||||
|
|
||||||
:example:
|
:example:
|
||||||
>>> from .leaf import RdLeaf
|
>>> from .leaf import RdLeaf
|
||||||
>>> random_tree = RandomTree("+", RdLeaf("a"), RdLeaf("a*k"))
|
>>> random_tree = RandomTree("+", RdLeaf("a"), RdLeaf("a*k"))
|
||||||
>>> random_tree.random_leaf
|
>>> random_tree.random_leaves
|
||||||
['a', 'a*k']
|
['a', 'a*k']
|
||||||
>>> random_tree = RandomTree("+", RdLeaf("a"), 2)
|
>>> random_tree = RandomTree("+", RdLeaf("a"), 2)
|
||||||
>>> random_tree.random_leaf
|
>>> random_tree.random_leaves
|
||||||
['a']
|
['a']
|
||||||
"""
|
"""
|
||||||
rd_leafs = []
|
rd_leafs = []
|
||||||
@ -78,7 +74,7 @@ class RandomTree(MutableTree):
|
|||||||
>>> random_tree.random_value
|
>>> random_tree.random_value
|
||||||
{'a'}
|
{'a'}
|
||||||
"""
|
"""
|
||||||
return extract_letters(self.random_leaf)
|
return extract_letters(self.random_leaves)
|
||||||
|
|
||||||
|
|
||||||
def eval_random_leaves(self, leaves_value:dict[str, int]):
|
def eval_random_leaves(self, leaves_value:dict[str, int]):
|
||||||
@ -102,3 +98,15 @@ class RandomTree(MutableTree):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
return leaf
|
return leaf
|
||||||
return self.map_on_leaf(replace)
|
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.generate import random_generator
|
||||||
from .core.grammar import extract_letters, eval_words
|
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
|
""" Generate random computed values from the list
|
||||||
|
|
||||||
:param rd_variables: list of random variables to generate (can be computed value - "a*b")
|
: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 rejected Rejected values for the generator (default [0])
|
||||||
:param min_max: (min, max) limits in between variables will be generated
|
: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_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
|
:return: dictionnary of generated variables
|
||||||
|
|
||||||
:example:
|
:example:
|
||||||
@ -33,12 +37,21 @@ def list_generator(var_list, conditions=[], rejected=[0], min_max=(-10, 10), var
|
|||||||
-20
|
-20
|
||||||
>>> a, b # doctest: +SKIP
|
>>> a, b # doctest: +SKIP
|
||||||
5, -4
|
5, -4
|
||||||
>>> list_generator(["a", "a*b", "b", "c"], dictionnary=True) # doctest: +SKIP
|
>>> a, ab, b, c = list_generator(["a", "a*b", "b", "c"], conditions=["a-b==0"])
|
||||||
{'a': -3, 'a*b': 18, 'b': -6, 'c': -4}
|
>>> 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 = 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)
|
generated = eval_words(var_list, rv_gen)
|
||||||
if dictionnary:
|
|
||||||
return generated
|
|
||||||
return [generated[v] for v in var_list]
|
return [generated[v] for v in var_list]
|
||||||
|
Loading…
Reference in New Issue
Block a user