**''.join(list)**the list see below, rather than the simple += concatenation):-

""" grammar.py module by Martin Prout Supports the parsing of both stochastic and non-stochastic rules axiom/rules are evaluated by the produce function, which uses the __weightedRule function to return any stochastic rule according to the input dict, the repeat function is used to repeatedly iterate the rules in a recursive fashion. Example Rules: Non-Stochastic = { "A": "A+F", "G": "GG", "X" :"G-G"} Stochastic = {"A" : {"BCD": 5, "C+C+C":10, "ACA": 40}, "B" : {"DE-F": 5, "CCC":10, "A[C]A": 40}} The Stochastic rule may contain non stochastic elements, in the above example there are two stochastic, elements, with keys "A" and "B". The stochastic rule is detected by checking the 'value' type is dict. The dict needs to of the form "string substitution" as key with the weighting as value. A test function is included for the test conscious or skeptic. """importrandomdef__weightedRule(rules):""" A private method used to choose a substitution rule from a dict of rules, according to its weighted probality. 'rules' is expected to be a dict where the substition string is the 'key' and the 'value' is the rule weight """ rand=random.random()prob=0 tot=sum(rules.values())# sum probabilitiesforruleinrules.keys():# iterate over rule choices prob+=rules.get(rule)# add assigned probalitiesif((rand*tot)<prob):# compare running total with scaled random valuereturn(rule)defproduce(axiom, rules):""" The single rule substitution utility, that uses type to check for dict or str as key value, else declares 'Unrecognized grammar'. Does not throw exception!!! """ output=[]# is a list this is somewhat more efficient than string concatenationforiinaxiom:temp=rules.get(i, i)if(type(temp)isdict):output.append(__weightedRule(temp))elif(type(temp)isstr):output.append(temp)else:error="Unknown rule type %s\n"%type(temp)(error)return''.join(output)defrepeat(rpx, axiom, rules):""" Repeat rule substitution in a recursive fashion rpx times """ production=axiomforiinrange(0, rpx):production=produce(production, rules)returnproductiondef__testWeighting(rules, key, total):""" Private test function see module header for examples of rules format Takes a dict containing a stochastic rule with 'key' as key. Tests the weighted rule function a 'total' number of times. Frequency result is printed. """ wordList=[] # create a big test list of replacement rulesforzinrange(0, total):wordList.append(__weightedRule(rules.get(key)))# calculate each word frequency in generated list (NB: does not test the # randomness of order though) freqD2={}forword2inwordList:freqD2[word2]=freqD2.get(word2, 0)+1 keyList=freqD2.keys()keyList.sort()forkey2inkeyList:%(key2, freqD2[key2])deftoRuleString(axiom, rules):""" Creates a string representing the pythonic rules in a more conventional manner """ output="Axiom:\t%s\n"%axiom keys=rules.keys()forkeyinkeys:temp=rules.get(key)type_temp=type(temp)if(type_tempisdict):keys2=temp.keys()forkey2inkeys2:output+="Rule:\t%s => %s\t%d\n"%(key, key2, temp.get(key2))elif(type_tempisstr):output+="Rule:\t%s => %s\n"%(key, temp)else:output+="Key:\t%s => %s an unknown rule type\n"%(key, type_temp)returnoutput

## No comments:

## Post a Comment