def fracture(self, numerator, denominator): """denominatoride a pulse into two pulses that sum to the same dur provide a fraction that is returned as first half of a pulse triple if 4, 5 is provided, denominatorided into 4/5 adn 1/5, return 4/5 first""" if not drawer.isInt(numerator): raise ValueError, 'numerator must be an integer' if not drawer.isInt(denominator): raise ValueError, 'denominator must be an integer' if numerator > denominator: raise ValueError, 'fraction must be less than 1' a = self.copy() b = self.copy() # scale denominatorisor by uniform amount dSource = self.triple[0] a.triple[0] = dSource * denominator b.triple[0] = dSource * denominator mSource = self.triple[1] a.triple[1] = mSource * numerator b.triple[1] = mSource * (denominator - numerator) return a, b
def scToStr(rawForte): """raw fortte is a tuple with either 2 or 3 elements, needing to be checked >>> scToStr([4,3]) '4-3' """ if drawer.isInt(rawForte): return '1-1' elif rawForte[0] == 1: return '1-1' scTuple = tupleToSc(rawForte) if len(scTuple) != 3: raise ValueError # should never happen card = str(scTuple[0]) indx = str(scTuple[1]) if scTuple[2] == 0: inv = '' elif scTuple[2] == 1: inv = 'A' elif scTuple[2] == -1: inv = 'B' else: inv = 'error' return card + '-' + indx + inv
def unitNormRangeTable(table, fixRange=None): """read all values from a a list normalize values wihtin min and maximum of series >>> unitNormRangeTable([[4,-2],[234,0],[3,7]]) [[0.025423728813559324, 0.0], [1.0, 0.0084745762711864406], [0.021186440677966101, 0.038135593220338986]] """ if fixRange != None: fixRange.sort() min = fixRange[0] max = fixRange[-1] else: # find max and min from values min, max = tableMinMax(table) span = max - min unit = [] i = 0 for row in table: unit.append([]) for val in row: dif = val - min if drawer.isInt(dif): dif = float(dif) if span != 0: unit[i].append(dif / span) else: # fill value if span is zero unit[i].append(0) i = i + 1 return unit
def discreteBinaryPad(series, fixRange=None): """take an integer series of values fill all spaces with zeros that are not occupied the result will always be sorted >>> discreteBinaryPad([3,4,5]) [1, 1, 1] >>> discreteBinaryPad([3,20,22]) [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1] """ # make sure these are ints for x in series: if not drawer.isInt(x): raise UnitException('non integer value found') discrete = [] if fixRange != None: fixRange.sort() # make sure sorted min = fixRange[0] max = fixRange[-1] else: # find max and min from values seriesAlt = list(copy.deepcopy(series)) seriesAlt.sort() min = seriesAlt[0] max = seriesAlt[-1] for x in range(min, max+1): if x in series: discrete.append(1) else: # not in series discrete.append(0) return discrete
def sigDigMeasure(num): """for a number, suggest a quantity of significant digits >>> sigDigMeasure(3.2345) 2 """ if drawer.isInt(num): return 0 num = float(num) junk, floatPart = divmod((num), 1) # float will split into int, dec if floatPart == 0: sigDig = 0 elif floatPart < .0000001: sigDig = 8 elif floatPart < .000001: sigDig = 7 elif floatPart < .00001: sigDig = 6 elif floatPart < .0001: sigDig = 5 elif floatPart < .001: sigDig = 4 elif floatPart < .01: sigDig = 3 else: # this sets a minimum value for all floats sigDig = 2 return sigDig
def _guessType(self): """try to determine what kind of pitch data is being provided psReal is default for any integer midi values must be marked some other way (w/ an m?) """ data = copy.copy(self.srcData) if drawer.isStr(data): data = drawer.strScrub(data, 'L') if len(data) == 0: return None # no data found if data[0] in REFdiaNameToPc: return 'psName' elif data.find('m') >= 0 or data.find('midi') >= 0: # an m designates a midi note number return 'midi' elif data.find('pch') >= 0: # a pch designates a pch value return 'pch' elif data.find('hz') >= 0 or data.find('fq') >= 0: return 'fq' else: # assume other strings are psInts return 'psReal' if drawer.isInt(data): # midi int, or ps int return 'psReal' if drawer.isFloat(data): # assume it is a psReal value return 'psReal'
def getAllScTriples(cardRange='all', tniTog=0): """gets all scTriples within a variety of ranges card range can be specified as string 'all', as an int (getting just the values of that int or as a range from 1 to 12; if range, last values is inclusif""" if cardRange == 'all': gatherCards = range(1,13) elif drawer.isInt(cardRange): gatherCards = [cardRange,] # only get one card elif drawer.isList(cardRange): if cardRange[1] < cardRange[0]: raise ValueError, 'bad cardinality range given' elif cardRange[0] == cardRange[1]: gatherCards = [cardRange[0],] # only get one card else: gatherCards = range(cardRange[0], cardRange[1]+1) found = [] for scTriple in TNREF.keys(): card = scTriple[0] inv = scTriple[2] if card in gatherCards: if tniTog and inv == -1: pass # leave out inversions else: found.append(scTriple) found.sort() return found
def unitNormRange(series, fixRange=None): """read all values from a list normalize values within min and maximum of series >>> unitNormRange([0,3,4]) [0.0, 0.75, 1.0] """ if fixRange != None: fixRange.sort() min = fixRange[0] max = fixRange[-1] else: # find max and min from values min, max = seriesMinMax(series) span = max - min unit = [] if len(series) > 1: for val in series: dif = val - min if drawer.isInt(dif): dif = float(dif) if span != 0: unit.append(dif / span) else: # fill value if span is zero unit.append(0) else: # if one element, return 0 (could be 1, or .5) unit.append(0) return unit
def getAllScTriples(cardRange='all', tniTog=0): """gets all scTriples within a variety of ranges card range can be specified as string 'all', as an int (getting just the values of that int or as a range from 1 to 12; if range, last values is inclusif""" if cardRange == 'all': gatherCards = list(range(1, 13)) elif drawer.isInt(cardRange): gatherCards = [ cardRange, ] # only get one card elif drawer.isList(cardRange): if cardRange[1] < cardRange[0]: raise ValueError('bad cardinality range given') elif cardRange[0] == cardRange[1]: gatherCards = [ cardRange[0], ] # only get one card else: gatherCards = list(range(cardRange[0], cardRange[1] + 1)) found = [] for scTriple in list(TNREF.keys()): card = scTriple[0] inv = scTriple[2] if card in gatherCards: if tniTog and inv == -1: pass # leave out inversions else: found.append(scTriple) found.sort() return found
def discreteBinaryPad(series, fixRange=None): """take an integer series of values fill all spaces with zeros that are not occupied the result will always be sorted >>> discreteBinaryPad([3,4,5]) [1, 1, 1] >>> discreteBinaryPad([3,20,22]) [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1] """ # make sure these are ints for x in series: if not drawer.isInt(x): raise UnitException('non integer value found') discrete = [] if fixRange != None: fixRange.sort() # make sure sorted min = fixRange[0] max = fixRange[-1] else: # find max and min from values seriesAlt = list(copy.deepcopy(series)) seriesAlt.sort() min = seriesAlt[0] max = seriesAlt[-1] for x in range(min, max + 1): if x in series: discrete.append(1) else: # not in series discrete.append(0) return discrete
def scale(self, value): """scale the multiplier by an integer this can be used to increase or decrease duration; divisor is not altered """ if not drawer.isInt(value): raise ValueError, 'value must be an integer' self.triple[1] = self.triple[1] * value
def ratioRaise(self, value): """increasing divider and multipler; opposite of reducing raising ot a higher terms duratin remains the same""" if not drawer.isInt(value): raise ValueError, 'value must be an integer' self.triple[0] = self.triple[0] * value self.triple[1] = self.triple[1] * value
def _processType(self): """process raw data into appropriate primative format""" data = copy.copy(self.srcData) if self.format == 'psName': if drawer.isStr(data): return data else: return None elif self.format == 'psReal': # psReal values should not be rounded if drawer.isStr(data): try: return float(data) except ValueError: return None else: return data elif self.format == 'midi': #midi values should always be rounded if drawer.isStr(data): data = drawer.strStripAlpha(data) try: return float(data) # dont convert to int except ValueError: return None elif drawer.isInt(data): return data else: # its a float, round return data elif self.format == 'pch': # floating point values if drawer.isStr(data): data = drawer.strStripAlpha(data) try: return _normalizePch(float(data)) except ValueError: return None if drawer.isFloat(data): return _normalizePch(data) else: # something is wrong return None elif self.format == 'fq': # floating point values if drawer.isStr(data): data = drawer.strStripAlpha(data) try: return float(data) except ValueError: return None if drawer.isNum(data): return float(data) # convert to float else: # something is wrong return None else: # error return None
def ratioTarget(self, div): """given a goal divisor, provide appropriate multiples to div and mult must be sure that value is alreaduy a proper multiple""" if not drawer.isInt(div): raise ValueError, 'value must be an integer' if float(div) / self.triple[0] != float(div) // self.triple[0]: raise ValueError, 'target divisor does not divide evenly into pulse triple divisor' # divide goal divisor by current divisor to get necessary mutltiple m = div // self.triple[0] self.ratioRaise(m)
def cut(self, multiplier): """given a value for a multipler, return to pulses where the multipliers sum to the current multiplier""" if not drawer.isInt(multiplier): raise ValueError, 'multiplier must be an integer' if multiplier > self.triple[1]: raise ValueError, 'new multiplier must be less than current' a = self.copy() b = self.copy() mSource = self.triple[1] a.triple[1] = multiplier b.triple[1] = mSource - multiplier return a, b
def anyDataToStr(usrData, sigDig=None, seqBrace='tuple'): """convert any data to a proper string, taking type into account lists are recursive examined with the same function note: this will convert a list [] into a tuple representation depending on optional arg will automatically remove space between comma-separated lists >>> anyDataToStr('test') 'test' >>> anyDataToStr([3, 'mixed', [3,4,5]]) '(3,mixed,(3,4,5))' >>> anyDataToStr([2.35, ('a', (234, 34))]) '(2.35,(a,(234,34)))' """ if drawer.isStr(usrData): return usrData elif drawer.isInt(usrData): return '%i' % usrData elif drawer.isFloat(usrData): if sigDig != None: # force a certain length return '%s' % str(round(usrData, sigDig)) else: # adaptive by size: sigDig = sigDigMeasure(usrData) return '%s' % str(round(usrData, sigDig)) elif drawer.isBool(usrData): # does not work, evaluates as string? return boolAsStr(usrData) elif usrData == None: return 'none' elif drawer.isList(usrData): newData = [] for q in usrData: # recursively apply to each element in list newData.append(anyDataToStr(q, sigDig, seqBrace)) if seqBrace == 'tuple': return '(%s)' % ','.join(newData) elif seqBrace == 'list': return '[%s]' % ','.join(newData) else: return repr(usrData)
def unitNorm(value, valueRange): '''Normalize value within the unit interval. >>> unitNorm(3, (3,10)) 0.0 >>> unitNorm(1, (3,10)) # values are not limited here -0.285714... >>> unitNorm(6.5, (3,10)) 0.5 >>> unitNorm(10, (3,10)) 1.0 >>> unitNorm(17, (3,10)) 2.0 ''' min, max = seriesMinMax(valueRange) span = max - min dif = value - min if drawer.isInt(dif): dif = float(dif) if span != 0: return dif / span else: # fill value if span is zero return 0
def instNoValid(self, iNo): """test if an instrument number is valid""" return drawer.isInt(iNo)
def __call__(self, name): """simply treturn the data can access as numbered steps in arg list, starting at 0""" if drawer.isInt(name): # if number, make into string name name = self.argNames[name] return self.switch(name)
def strongType(usrArgs, argTypes, defaultArgs=[], argCountOffset=0): """Argument checking tool. checks raw arg type and number, one level deep (does not recurse into list) will supply defaults if missing args after last given and self.defaultArgs defined two arguments required, both lists: args = a list of arguments, of proper python data types argTypes = list of one-level deap types, specified w/ strings 'list', 'num', 'float', 'int', 'str'; see drawer.py one optional args defaultArgs = list of default args to substitute returns: newArgs, ok, msg >>> strongType([[1,2,3]], ['list']) ([[1, 2, 3]], 1, '') >>> strongType([.5, 3, 'three'], ['float', 'int', 'str']) ([0.5, 3, 'three'], 1, '') >>> strongType([3.2], ['num', 'num']) ([3.2000...], 0, 'incorrect number of arguments; enter 2 arguments.') >>> strongType([3.2, 5, 6], ['num', 'num']) ([3.2000..., 5, 6], 0, 'too many arguments; enter 2 arguments.') """ argCount = len(argTypes) if len(usrArgs) < argCount: # try to get from defaults if len(defaultArgs) == argCount: # defaults exits (default is 0) for retrieve in defaultArgs[len(usrArgs):]: usrArgs.append(retrieve) # add missing to end #print 'argTools.py: adding default', retrieve, defaultArgs else: # nothing we can do: failure msg = ('incorrect number of arguments; enter %i arguments.' % (argCount + argCountOffset)) # add incase if name offset return usrArgs, 0, msg elif len(usrArgs) > argCount: #print _MOD, len(usrArgs), argCount msg = 'too many arguments; enter %i arguments.' % (argCount + argCountOffset) return usrArgs, 0, msg for pos in range(0, argCount): argTest = usrArgs[pos] # can be [list, num, float, int, str] typeCandidates = argTypes[pos] if not drawer.isList(typeCandidates): typeCandidates = [typeCandidates,] # add to list for type in typeCandidates: if type == 'list' and drawer.isList(argTest): match = 1 break elif type == 'num' and drawer.isNum(argTest): match = 1 break elif type == 'float' and drawer.isFloat(argTest): match = 1 break elif type == 'int' and drawer.isInt(argTest): match = 1 break elif type == 'str' and drawer.isStr(argTest): match = 1 break else: # dont break; need to through other possbilities match = 0 # should covnert types to better strings if match == 0: msg = ('wrong type of data used as an argument. replace %s with a %s argument type.' % (repr(typeset.anyDataToStr(argTest)), # provide 'or' to show that any type in candidate is good drawer.typeListAsStr(typeCandidates, 'or'))) return usrArgs, 0, msg # all good return usrArgs, 1, ''
def extract(self, fmt='table', norm=1, rowStart=None, rowEnd=None, centerOffset=0, width=None): """ tage a segmetn from the 2d table datas width should not be negative norm: turn normalizing on or off; will change into list, even if an array >>> a = Table([[1,2,3], [4,5,6]]) >>> a.extract('table', 1, 0, 1, 2) [[1.0, 0.0, 0.5]] """ fmt = fmt.lower() # lower for reading values if rowStart == None: rowStart = 0 if rowEnd == None: rowEnd = len(self.data) if centerOffset == None: centerOffset = 0 if width == None: width = self.colCount elif width <= 0: width = 1 # never less than == 0 # provide modulus of start rowStart = rowStart % self.rowCount rowEnd = rowEnd % (self.rowCount+1) data = self.data[rowStart:rowEnd] c = self._getCenter() + centerOffset # shift index value lOffset, rOffset = drawer.intHalf(width) # note: these values may exceed index values: # will be wraped with the drawer util lSlice = (c - lOffset) rSlice = (c + rOffset) # this will force that a copy is made and og data is not altered dataFilter = [] if 'pair' in fmt: fmtCellExtract = 'pair' elif 'indexactive' in fmt: fmtCellExtract = 'indexactive' elif 'indexpassive' in fmt: fmtCellExtract = 'indexpassive' # these must follow searches above elif 'index' in fmt: fmtCellExtract = 'index' elif 'active' in fmt: fmtCellExtract = 'valueactive' elif 'passive' in fmt: fmtCellExtract = 'valuepassive' else: fmtCellExtract = 'value' # default for step in data: dataFilter.append(drawer.listSliceWrap(step, lSlice, rSlice, fmtCellExtract)) # tabular output if fmt == 'table': # should these range be provided? # cannot provide values to getMinMax; will return None if both # min and max not set, and unit proc will find automatically if norm: return unit.unitNormRangeTable(dataFilter, self._getMinMax()) else: return dataFilter # read tabel and concat into one list elif 'flat' in fmt: # if 'column' in fmt: # must rotate to read columns dataFilter = self._rotate(dataFilter) # 'row' or default dataFlat = [] for row in dataFilter: if 'reflect' in fmt or 'flip' in fmt: row.reverse() for val in row: dataFlat.append(val) if norm: # minMax may be None dataFlat = unit.unitNormRange(dataFlat, self._getMinMax(dataFlat)) return dataFlat # lists of data based on row/col operations; # one value per row/col; min is always 0, max may be much greater else: if 'column' in fmt: # must rotate to read columns dataFilter = self._rotate(dataFilter) # 'row' or default dataFlat = [] if 'sum' in fmt: for row in dataFilter: x = 0 for val in row: x = x + val dataFlat.append(x) elif 'average' in fmt: rowWidth = len(dataFilter[0]) # all rows must be the same for row in dataFilter: x = 0 for val in row: x = x + val # only change integers, as other number types may be here, # such as floats and decimals if drawer.isInt(x): x = float(x) dataFlat.append(x/rowWidth) elif 'product' in fmt: # multiply each value for row in dataFilter: x = 1 # init value here is 1 for val in row: x = x * val dataFlat.append(x) # noramlization for all but binary if norm: dataFlat = unit.unitNormRange(dataFlat, self._getMinMax(dataFlat)) return dataFlat
def strongType(usrArgs, argTypes, defaultArgs=[], argCountOffset=0): """Argument checking tool. checks raw arg type and number, one level deep (does not recurse into list) will supply defaults if missing args after last given and self.defaultArgs defined two arguments required, both lists: args = a list of arguments, of proper python data types argTypes = list of one-level deap types, specified w/ strings 'list', 'num', 'float', 'int', 'str'; see drawer.py one optional args defaultArgs = list of default args to substitute returns: newArgs, ok, msg >>> strongType([[1,2,3]], ['list']) ([[1, 2, 3]], 1, '') >>> strongType([.5, 3, 'three'], ['float', 'int', 'str']) ([0.5, 3, 'three'], 1, '') >>> strongType([3.2], ['num', 'num']) ([3.2000...], 0, 'incorrect number of arguments; enter 2 arguments.') >>> strongType([3.2, 5, 6], ['num', 'num']) ([3.2000..., 5, 6], 0, 'too many arguments; enter 2 arguments.') """ argCount = len(argTypes) if len(usrArgs) < argCount: # try to get from defaults if len(defaultArgs) == argCount: # defaults exits (default is 0) for retrieve in defaultArgs[len(usrArgs):]: usrArgs.append(retrieve) # add missing to end #print 'argTools.py: adding default', retrieve, defaultArgs else: # nothing we can do: failure msg = ('incorrect number of arguments; enter %i arguments.' % (argCount + argCountOffset)) # add incase if name offset return usrArgs, 0, msg elif len(usrArgs) > argCount: #print _MOD, len(usrArgs), argCount msg = 'too many arguments; enter %i arguments.' % (argCount + argCountOffset) return usrArgs, 0, msg for pos in range(0, argCount): argTest = usrArgs[pos] # can be [list, num, float, int, str] typeCandidates = argTypes[pos] if not drawer.isList(typeCandidates): typeCandidates = [ typeCandidates, ] # add to list for type in typeCandidates: if type == 'list' and drawer.isList(argTest): match = 1 break elif type == 'num' and drawer.isNum(argTest): match = 1 break elif type == 'float' and drawer.isFloat(argTest): match = 1 break elif type == 'int' and drawer.isInt(argTest): match = 1 break elif type == 'str' and drawer.isStr(argTest): match = 1 break else: # dont break; need to through other possbilities match = 0 # should covnert types to better strings if match == 0: msg = ( 'wrong type of data used as an argument. replace %s with a %s argument type.' % ( repr(typeset.anyDataToStr(argTest)), # provide 'or' to show that any type in candidate is good drawer.typeListAsStr(typeCandidates, 'or'))) return usrArgs, 0, msg # all good return usrArgs, 1, ''
def instNoValid(self, iNo): """test if an instrument number is valid""" if drawer.isInt(iNo) and iNo in self._instrNumbers: return 1 else: return 0