#!/usr/bin/env python # encoding: utf-8 from random import randint import re import pyparsing from .generic import flatten_list # Below import are needed for conditions in varia generation. from .arithmetic import gcd def random_str(form, conditions=[], val_min=-10, val_max=10): """ Create a random string using RdExpression class """ random_str_generator = RdExpression(form, conditions) return random_str_generator(val_min, val_max) class RdExpression(object): """ A generator of random expression builder """ def __init__(self, form, conditions=[]): """Initiate the generator :param form: the form of the expression (/!\ variables need to be in brackets {}) :param conditions: condition on variables (/!\ variables need to be in brackets {}) """ self._form = self.mod_underscores(form) self._conditions = conditions self._letters = self.get_letters() self._gene_varia = {} self._gene_2replaced = {} def get_2replaced(self): """Get elements of self._form which will have to be replaced :returns: set for elements which have to be replaced """ # TODO: Bug with varia with spaces |dim. nov. 23 10:44:34 CET 2014 varia_form = flatten_list([eval(str(i[0])) for i in pyparsing.nestedExpr( '{', '}').searchString(self._form)]) varia_form = set(varia_form) varia_cond = set() for c in self._conditions: c_varia_cond = flatten_list( [eval(str(i[0])) for i in pyparsing.nestedExpr('{', '}').searchString(c)]) varia_cond = varia_cond | set(c_varia_cond) self._2replaced = varia_cond | varia_form return self._2replaced def get_letters(self): """Find letters in the form :returns: list of letters """ v2replaced = self.get_2replaced() varia = set() pattern = "([a-zA-Z]+)" for v in v2replaced: lvar = set(re.findall(pattern, v)) varia = varia | lvar return varia def mod_underscores(self, form): """ Transform underscores of string to {...} forme with capital letters :param form: the form string with _ to replace :returns: the string with _ replaced """ i = 64 new_form = form while "_" in new_form: i += 1 new_form = new_form.replace("_", "{" + chr(i) + "}", 1) return new_form def __call__(self, val_min=-10, val_max=10): """RdExpression once it is initiate act like a function which create random expressions. :param val_min: minimum value random generation :param val_max: maximum value random generation :returns: an formated random expression """ return self.raw_str(val_min, val_max) def raw_str(self, val_min=-10, val_max=10): """Return raw string (don't use Expression for rendering or parsing) :param val_min: minimum value random generation :param val_max: maximum value random generation :returns: an random Expression object """ self.gene_varia(val_min, val_max) while not(self.val_conditions()): self.gene_varia(val_min, val_max) exp = self._form.format(**self._gene_2replaced) return exp def gene_varia(self, val_min=-10, val_max=10): """Randomly generates variables/letters Varia can't be equal to 0 """ for l in self._letters: self._gene_varia[l] = randint(val_min, val_max) while self._gene_varia[l] == 0: self._gene_varia[l] = randint(val_min, val_max) for e in self._2replaced: self._gene_2replaced[e] = eval(e, globals(), self._gene_varia) def val_conditions(self): """Tells whether or not conditions are validates :returns: boolean """ if self._conditions != []: return eval( " and ".join( self._conditions).format( **self._gene_2replaced)) else: return True def desc_rdExp(rdExp): print("--------------------") print("form: ", rdExp._form) print("Conditions: ", rdExp._conditions) print("Letters: ", rdExp._letters) print("2replaced: ", rdExp._2replaced) print("Call : ", rdExp()) print("type: ", type(rdExp())) print("Gene varia: ", rdExp._gene_varia) print("Gene 2replaced: ", rdExp._gene_2replaced) print('') # ----------------------------- # Reglages pour 'vim' # vim:set autoindent expandtab tabstop=4 shiftwidth=4: # cursor: 16 del