def _parseFormat(self): if self.filePath.endswith('.txt'): f = open(self.filePath) fileStr = f.read() f.close() else: return None # no other file types supported dataEval = [] # evaluated data, sorted by val, fq, other # for some reason radline got strange results on macos x # manually reading line types if fileStr.find('\r\n') >= 0: SEProw = '\r\n' # win elif '\r' in fileStr: SEProw = '\r' # macos elif '\n' in fileStr: SEProw = '\n' # unix else: return None # error, bad file fileLines = fileStr.split(SEProw) # skip first line, as is key for line in fileLines: if line == '': continue # need to figure seperator elif '\t' in line: SEPcol = '\t' else: return None # error, bad file spectData = line.split(SEPcol) #print _MOD, spectData # tabbed lists should have either 2 or 3 items spectChunk = len(spectData) if spectChunk < 2 or spectChunk > 3: continue if spectChunk == 2: # assume audacity spectrum # Frequency (Hz), Level (dB) # return amp, fq fmt = 'audacity.spectrum' fq = drawer.strToNum(spectData[0]) if fq == None: continue amp = drawer.strToNum(spectData[1]) if amp == None: continue dataEval.append((amp, fq)) elif spectChunk == 3: # assume audacity spectrum # Lag (seconds), Frequency (Hz), Level fmt = 'audacity.autocorrelation' fq = drawer.strToNum(spectData[1]) if fq == None: continue amp = drawer.strToNum(spectData[2]) if amp == None: continue s = drawer.strToNum(spectData[0]) if s == None: continue dataEval.append((amp, fq, s)) if len(dataEval) == 0: return None # sort so amps is ranked first dataEval.sort() dataEval.reverse() # largest on top return dataEval, fmt
def _parseWeightValue(self, pairWeight): """read a complete dictionary of transition keys and weights, and load weights as a list""" self._weightSrc = {} for key, value in pairWeight.items(): # make key into a list of symbol strings key = self._parseWeightKey(key) # make value into a list of pairs weights = value.split(self.ASSIGNDELIMIT) weightList = [] for assign in weights: if self.ASSIGN not in assign: continue if assign.count(self.ASSIGN) > 1: # bad syntax or other error raise error.TransitionSyntaxError, \ "incorrect weight specification: %s" % assign symbol, w = assign.split(self.ASSIGN) # convert to float or int, may not be less tn zero # will return None on error w = drawer.strToNum(w, 'num', 0, None) # it woudl be nice to accept zero weights but this causes many # side-effects; need to test in whole # not defining all weights is permitted if w in (None, 0): # no zero weights, or other errors raise error.TransitionSyntaxError, \ "bad weight value given: %s" % assign weightList.append((symbol, w)) # assign to weight src self._weightSrc[key] = weightList
def _parseWeightValue(self, pairWeight): """read a complete dictionary of transition keys and weights, and load weights as a list""" self._weightSrc = {} for key, value in list(pairWeight.items()): # make key into a list of symbol strings key = self._parseWeightKey(key) # make value into a list of pairs weights = value.split(self.ASSIGNDELIMIT) weightList = [] for assign in weights: if self.ASSIGN not in assign: continue if assign.count(self.ASSIGN) > 1: # bad syntax or other error raise error.TransitionSyntaxError("incorrect weight specification: %s" % assign) symbol, w = assign.split(self.ASSIGN) # convert to float or int, may not be less tn zero # will return None on error w = drawer.strToNum(w, 'num', 0, None) # it woudl be nice to accept zero weights but this causes many # side-effects; need to test in whole # not defining all weights is permitted if w in (None, 0): # no zero weights, or other errors raise error.TransitionSyntaxError("bad weight value given: %s" % assign) weightList.append((symbol, w)) # assign to weight src self._weightSrc[key] = weightList
def psNameToPs(psStr): """pitch names to ps numbers middle c == c4 == midi 60 == 0 should support negative octaves, like d-2 """ psStr = psStr.lower() # make sure lower case pcBase = REFdiaNameToPc[psStr[0]] # get first char flatScore = 0 sharpScore = 0 qScore = 0 octaveStr = '' # assume c4 octave for char in psStr: if char == SYMflat: flatScore = flatScore + 1 if char == SYMsharp: # or char == '+': sharpScore = sharpScore + 1 elif char == SYMqTone: qScore = qScore + 1 # oct may be negative elif char.isdigit() or char == '-': # get oct, negative if present octaveStr = octaveStr + char octaveInt = drawer.strToNum(octaveStr, 'int') # will return None on error if octaveInt == None: octaveInt = 4 # octave starting at middle c # adjust pitch pcBase = pcBase - flatScore pcBase = pcBase + sharpScore if qScore != 0: # add quarter tones pcBase = pcBase + (qScore * .5) # add octave: pcBase = pcBase + _octNameToPsShift(octaveInt) return pcBase
def __init__(self, usrStr): """usrStr may have a comma, and thus include data for the number of values to read; can also be set below w/ getPitch method""" if usrStr == None: raise ValueError, 'bad file path given' if usrStr.find(',') >= 0: filePath, maxCount = usrStr.split(',')[:2] maxCount = drawer.strToNum(maxCount, 'int') #print _MOD, 'got maxCount of', maxCount else: filePath = usrStr maxCount = None # default if maxCount != None: self.maxCount = maxCount else: self.maxCount = 10 # file path shuold always exists filePath = drawer.pathScrub(filePath) if not os.path.exists(filePath) or os.path.isdir(filePath): raise ValueError, 'bad file path given' self.filePath = filePath self.forms = ['audacity.spectrum', 'audacity.autocorrelation'] ok = self._parseFormat() if ok == None: raise ValueError, 'bad file path given' self.dataEval, self.fmt = ok
def _updateDefault(self, src): """make a ca dictionary rule and mutation are left out, as dynamic""" xMAX = 1000 yMAX = 10000 ref = { # these are the limits 'f' : ('s',), # must be first element of a list 'k' : (2, 0, 36), # def, min, max 'r' : (1, .5, 10), 'i' : ('center',), 'x' : (91, 1, xMAX), # should be odd value 'y' : (135, 1, yMAX), 'w' : (0, 0, yMAX), # will get value of 'c' : (0, -xMAX, xMAX), # center 's' : (0, 0, yMAX), # skip } # src keys have already been formated to single character refs for key in ref.keys(): if key not in src.keys(): src[key] = ref[key][0] else: # keu exists, eval numbers if necessary if drawer.isNum(ref[key][0]): # check numbers min = ref[key][1] max = ref[key][2] # permit r values w/ decimal .5 if key =='r' and '.' in src[key]: # double, round, and divide; will be either 0 or .5 value = drawer.strToNum(src[key], 'float', min, max) value = round(value*2) / 2 else: value = drawer.strToNum(src[key], 'int', min, max) if value != None: src[key] = value else: # cant resolve value, provide default src[key] = ref[key][0] if drawer.isStr(ref[key][0]): # check strings if key == 'f': value = caFormatParser(src[key]) elif key == 'i': value = caInitParser(src[key]) if value != None: src[key] = value else: src[key] = ref[key][0] return src
def _updateDefault(self, src): """make a ca dictionary rule and mutation are left out, as dynamic""" xMAX = 1000 yMAX = 10000 ref = { # these are the limits 'f': ('s', ), # must be first element of a list 'k': (2, 0, 36), # def, min, max 'r': (1, .5, 10), 'i': ('center', ), 'x': (91, 1, xMAX), # should be odd value 'y': (135, 1, yMAX), 'w': (0, 0, yMAX), # will get value of 'c': (0, -xMAX, xMAX), # center 's': (0, 0, yMAX), # skip } # src keys have already been formated to single character refs for key in ref.keys(): if key not in src.keys(): src[key] = ref[key][0] else: # keu exists, eval numbers if necessary if drawer.isNum(ref[key][0]): # check numbers min = ref[key][1] max = ref[key][2] # permit r values w/ decimal .5 if key == 'r' and '.' in src[key]: # double, round, and divide; will be either 0 or .5 value = drawer.strToNum(src[key], 'float', min, max) value = round(value * 2) / 2 else: value = drawer.strToNum(src[key], 'int', min, max) if value != None: src[key] = value else: # cant resolve value, provide default src[key] = ref[key][0] if drawer.isStr(ref[key][0]): # check strings if key == 'f': value = caFormatParser(src[key]) elif key == 'i': value = caInitParser(src[key]) if value != None: src[key] = value else: src[key] = ref[key][0] return src
def _parsePsReal(self, usrStr): """process a usr string entered as a list psReals""" usrList = drawer.strToListFlat(usrStr, 'L') psList = [] for elem in usrList: # may be int or float elem = drawer.strToNum(elem.strip(), 'num') if elem == None: continue else: psList.append(elem) return psList
def _parseFq(self, usrStr): """conver midi values to psInt values""" usrStr = drawer.strStripAlpha(usrStr) usrList = drawer.strToListFlat(usrStr, 'L') #usrList = usrStr.split(',') psList = [] for elem in usrList: # may be int or float elem = drawer.strToNum(elem.strip(), 'num') if elem == None: continue else: psList.append(pitchTools.fqToPs(elem)) return psList
def _getCount(self, termObj): """get number of pitches to read interactively""" query = 'number of pitches?' while 1: usrStr = dialog.askStr(query, termObj) if usrStr == None: return None num = drawer.strToNum(usrStr, 'int') if num != None and num != 0: return num else: dialog.msgOut(('%senter a positive or negative integer.\n' % lang.TAB), termObj)
def clear(self): """processes init value and replaces history with first generation will always add an init to the history, meaning that there will always be one more generation than expected in most cases """ stepInit = self._getTemplate() if drawer.isStr(self.init): numStr, junk = drawer.strExtractNum(self.init) if self.init == 'center': centerIndex = self._getCenter() if self.dstValues == None: # continuous case if self.DECIMAL: val = decimal.Decimal(1) else: val = 1.0 # should add one here, but need -1 for list position shift stepInit[self._getCenter()] = val else: # center value is dependent; must provude as variable stepInit[self._getCenter()] = self.dstValues[ self.dstIndexCenter] elif self.init == 'random': for x in range(self.size): if self.dstValues == None: # continuous case if self.DECIMAL: val = decimal.Decimal(str(random.random())) else: val = random.random() stepInit[x] = val else: # discrete stepInit[x] = random.choice(self.dstValues) # may be number as a string; treat as a list elif len(numStr) == len(self.init): for x in range(self.size): # must be integers, use force to limit at min / max if self.dstValues != None: min = self.dstValues[0] max = self.dstValues[-1] else: # continuous, unit interval min = 0 max = 1 val = drawer.strToNum(self.init[(x % len(self.init))], 'int', min, max, 1) stepInit[x] = val elif drawer.isNum(self.init): for x in range(self.size): stepInit[x] = self.init elif drawer.isList(self.init): for x in range(self.size): stepInit[x] = self.init[(x % len(self.init))] self.stepHistory = [stepInit] # a list of arrays
def clear(self): """processes init value and replaces history with first generation will always add an init to the history, meaning that there will always be one more generation than expected in most cases """ stepInit = self._getTemplate() if drawer.isStr(self.init): numStr, junk = drawer.strExtractNum(self.init) if self.init == 'center': centerIndex = self._getCenter() if self.dstValues == None: # continuous case if self.DECIMAL: val = decimal.Decimal(1) else: val = 1.0 # should add one here, but need -1 for list position shift stepInit[self._getCenter()] = val else: # center value is dependent; must provude as variable stepInit[self._getCenter()] = self.dstValues[self.dstIndexCenter] elif self.init == 'random': for x in range(self.size): if self.dstValues == None: # continuous case if self.DECIMAL: val = decimal.Decimal(str(random.random())) else: val = random.random() stepInit[x] = val else: # discrete stepInit[x] = random.choice(self.dstValues) # may be number as a string; treat as a list elif len(numStr) == len(self.init): for x in range(self.size): # must be integers, use force to limit at min / max if self.dstValues != None: min = self.dstValues[0] max = self.dstValues[-1] else: # continuous, unit interval min = 0 max = 1 val = drawer.strToNum(self.init[(x % len(self.init))], 'int', min, max, 1) stepInit[x] = val elif drawer.isNum(self.init): for x in range(self.size): stepInit[x] = self.init elif drawer.isList(self.init): for x in range(self.size): stepInit[x] = self.init[(x % len(self.init))] self.stepHistory = [stepInit] # a list of arrays
def _parseRuleValue(self, pairRule): """Read a preliminary dictionary of rules, and split into a list of rules based on having one or more probabilistic rule options >>> g = Grammar() >>> g._parseRuleValue({'a': 'ab'}) >>> g._rules {'a': [('ab', 1)]} >>> g._parseRuleValue({'a': 'ab|ac'}) >>> g._rules {'a': [('ab', 1), ('ac', 1)]} >>> g._parseRuleValue({'a': 'ab|ac|aa=3'}) >>> g._rules {'a': [('ab', 1), ('ac', 1), ('aa', 3)]} >>> g._parseRuleValue({'a': 'ab=3|c=12|aa=3'}) >>> g._rules {'a': [('ab', 3), ('c', 12), ('aa', 3)]} >>> g._parseRuleValue({'a': 'ab=3|c=12|aa=3', 'c': 'b=3|c=5|a'}) >>> g._rules {'a': [('ab', 3), ('c', 12), ('aa', 3)], 'c': [('b', 3), ('c', 5), ('a', 1)]} >>> g._parseRuleValue({'a': 'ab=3|c=12|aa=0'}) Traceback (most recent call last): TransitionSyntaxError: bad weight value given: aa=0 >>> g._parseRuleValue({'a': ''}) >>> g._rules {'a': [('', 1)]} >>> g._parseRuleValue({'a': 'ab=3|c=12|'}) >>> g._rules {'a': [('ab', 3), ('c', 12), ('', 1)]} >>> g._parseRuleValue({'*a': 'ab=3|c=12|a=3'}) >>> g._rules {'*a': [('ab', 3), ('c', 12), ('a', 3)]} """ self._rules = {} # this always clears the last rules for key, value in list(pairRule.items()): # make value into a src:dst pairs ruleList = [] weights = value.split(self.ASSIGNDELIMIT) # this is the | if len(weights) == 1: # if there is only one weight, add an assignment value of 1 # this is permitted if self.ASSIGN not in weights[0]: ruleList.append((weights[0], 1)) else: # remove weight, as it is not significant w = weights[0].split(self.ASSIGN)[0] ruleList.append((w, 1)) # if there are no assignments but more than one option # that is, no = sign assignments elif value.count(self.ASSIGN) == 0: for symbol in weights: ruleList.append((symbol, 1)) else: #environment.printDebug(['obtained weights', weights, value.count(self.ASSIGN)]) for assign in weights: # if not assignment, provide one as a string if self.ASSIGN not in assign: assign += '=1' # assume 1 symbol, w = assign.split(self.ASSIGN) # convert to float or int, may not be less tn zero # will return None on error w = drawer.strToNum(w, 'num', 0, None) if w in [None, 0]: # no zero weights, or other errors raise error.TransitionSyntaxError( "bad weight value given: %s" % assign) ruleList.append((symbol, w)) self._rules[key] = ruleList
def _parseRuleValue(self, pairRule): """Read a preliminary dictionary of rules, and split into a list of rules based on having one or more probabilistic rule options >>> g = Grammar() >>> g._parseRuleValue({'a': 'ab'}) >>> g._rules {'a': [('ab', 1)]} >>> g._parseRuleValue({'a': 'ab|ac'}) >>> g._rules {'a': [('ab', 1), ('ac', 1)]} >>> g._parseRuleValue({'a': 'ab|ac|aa=3'}) >>> g._rules {'a': [('ab', 1), ('ac', 1), ('aa', 3)]} >>> g._parseRuleValue({'a': 'ab=3|c=12|aa=3'}) >>> g._rules {'a': [('ab', 3), ('c', 12), ('aa', 3)]} >>> g._parseRuleValue({'a': 'ab=3|c=12|aa=3', 'c': 'b=3|c=5|a'}) >>> g._rules {'a': [('ab', 3), ('c', 12), ('aa', 3)], 'c': [('b', 3), ('c', 5), ('a', 1)]} >>> g._parseRuleValue({'a': 'ab=3|c=12|aa=0'}) Traceback (most recent call last): TransitionSyntaxError: bad weight value given: aa=0 >>> g._parseRuleValue({'a': ''}) >>> g._rules {'a': [('', 1)]} >>> g._parseRuleValue({'a': 'ab=3|c=12|'}) >>> g._rules {'a': [('ab', 3), ('c', 12), ('', 1)]} >>> g._parseRuleValue({'*a': 'ab=3|c=12|a=3'}) >>> g._rules {'*a': [('ab', 3), ('c', 12), ('a', 3)]} """ self._rules = {} # this always clears the last rules for key, value in pairRule.items(): # make value into a src:dst pairs ruleList = [] weights = value.split(self.ASSIGNDELIMIT) # this is the | if len(weights) == 1: # if there is only one weight, add an assignment value of 1 # this is permitted if self.ASSIGN not in weights[0]: ruleList.append((weights[0], 1)) else: # remove weight, as it is not significant w = weights[0].split(self.ASSIGN)[0] ruleList.append((w, 1)) # if there are no assignments but more than one option # that is, no = sign assignments elif value.count(self.ASSIGN) == 0: for symbol in weights: ruleList.append((symbol, 1)) else: #environment.printDebug(['obtained weights', weights, value.count(self.ASSIGN)]) for assign in weights: # if not assignment, provide one as a string if self.ASSIGN not in assign: assign += '=1' # assume 1 symbol, w = assign.split(self.ASSIGN) # convert to float or int, may not be less tn zero # will return None on error w = drawer.strToNum(w, 'num', 0, None) if w in [None, 0]: # no zero weights, or other errors raise error.TransitionSyntaxError( "bad weight value given: %s" % assign) ruleList.append((symbol, w)) self._rules[key] = ruleList