#! /usr/bin/env python # -*- coding: utf-8 -*- # vim:fenc=utf-8 # # Copyright © 2017 lafrite # # Distributed under terms of the MIT license. from random import choice import math EVAL_FUN = {**math.__dict__} def complete_variable_configs( variables, global_config: dict = {}, configs: dict = {} ) -> dict: """Completes variables configurations with the global configuration :param variables: list of random variables to generate :param global_config: global parameters :param configs: global parameters :return: complete variable scope :example: >>> 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)} ... }) >>> 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_configs = configs.copy() for variable in variables: try: complete_configs[variable] except KeyError: complete_configs[variable] = global_config else: complete_configs[variable] = dict(global_config, **configs[variable]) return complete_configs def random_generator( variables: list[str], conditions: list[str] = [], global_config: dict = {}, configs: dict = {}, ) -> dict[str, int]: """Generate random variables :param variables: list of random variables to generate :param conditions: condition over variables :param global_config: global parameters :param configs: global parameters :return: dictionnary of generated variables In variables and configurations, you have access to all math module functions :example: >>> gene = random_generator(["a", "b"], ... ["a > 0"], ... {"rejected": [0], "min_max":(-10, 10)}, ... {"a": {"rejected": [0, 1]}, ... "b": {"min_max": (-5, 0)}, ... }) >>> gene["a"] > 0 True >>> gene["a"] != 0 True >>> gene["b"] < 0 True >>> gene = random_generator(["a", "b"], ... ["a % b == 0"], ... {"rejected": [0, 1], "min_max":(-10, 10)} ... ) >>> gene["a"] not in [0, 1] True >>> gene["b"] in list(range(-10, 11)) True >>> gene["a"] % gene["b"] 0 """ complete_scope = complete_variable_configs(variables, global_config, configs) choices_list = { v: list( set( range( complete_scope[v]["min_max"][0], complete_scope[v]["min_max"][1] + 1 ) ).difference(complete_scope[v]["rejected"]) ) 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 variables} while not all([eval(c, EVAL_FUN, generate_variable) for c in conditions]): generate_variable = {v: choice(choices_list[v]) for v in variables} return generate_variable