def toColumns(strs, widths, columnSeparators=False): """ strs : [string] - text for each column width :[int] - each column width columnSeparators : bool - if True, then columns are separated by the character mud.format.column.COLUMN_SEPARATOR """ isList(strs) isList(widths) assert len(strs) == len(widths) if columnSeparators: assert SPACES_BETWEEN_COLUMNS % 2 > 0, "mud.format.column: separators are incompatible with even SPACES_BETWEEN_COLUMNS" rendered = "" columns = columnsFromStrings(strs, widths[:], columnSeparators) maxLength = getMaxLengthFromColumns(columns) #print maxLength renderFunctions = getColumnRenderFunctions(columns, widths[:], columnSeparators) rendered = renderFromFunctions(renderFunctions, maxLength, columnSeparators) rendered += "\r\n" return rendered
def toColumns( strs, widths, columnSeparators = False ): """ strs : [string] - text for each column width :[int] - each column width columnSeparators : bool - if True, then columns are separated by the character mud.format.column.COLUMN_SEPARATOR """ isList( strs ) isList( widths ) assert len(strs) == len(widths) if columnSeparators: assert SPACES_BETWEEN_COLUMNS % 2 > 0, "mud.format.column: separators are incompatible with even SPACES_BETWEEN_COLUMNS" rendered = "" columns = columnsFromStrings( strs, widths[:], columnSeparators ) maxLength = getMaxLengthFromColumns( columns ) #print maxLength renderFunctions = getColumnRenderFunctions( columns, widths[:], columnSeparators ) rendered = renderFromFunctions( renderFunctions, maxLength, columnSeparators ) rendered += "\r\n" return rendered
def __init__(self, menuPairs, finishedCallback, invalidSelectionCallback=None, alphabeticOptions=False): """ menuPairs: [], each element is string or (string, any type) finishedCallback: f( clientId, selectedValue ) invalidSelectionCallback: f( clientId, remaining ) """ isList(menuPairs) isFunc(finishedCallback) if invalidSelectionCallback: isFunc(invalidSelectionCallback) else: invalidSelectionCallback = lambda clientId, remaining: defaultInvalidSelectionCallback( clientId, self.menuStr) self.menuStr = "{!" self.menuMap = CmdMap(invalidSelectionCallback) menuIndex = 1 def finishMenuWithValue(value): return lambda clientId, remaining: finishMenu( clientId, finishedCallback, value) for item in menuPairs: if type(item) == str: self.menuStr += item + "\r\n" continue (menuItemDescription, menuItemValue) = item optionLabel = "" if alphabeticOptions: optionLabel = chr(96 + menuIndex) else: optionLabel = menuIndex isStr(menuItemDescription) self.menuStr = self.menuStr + " {FC%s{FG) - {FU%s\r\n" % ( optionLabel, menuItemDescription) self.menuMap.addCmd("%s" % optionLabel, finishMenuWithValue(menuItemValue)) menuIndex += 1 self.menuStr += "{@"
def _matches(self, markup, matchAgainst): #print "Matching %s against %s" % (markup, matchAgainst) result = False if matchAgainst == True and type(matchAgainst) == types.BooleanType: result = markup != None elif callable(matchAgainst): result = matchAgainst(markup) else: #Custom match methods take the tag as an argument, but all #other ways of matching match the tag name as a string. if isinstance(markup, Tag): markup = markup.name if markup is not None and not isinstance(markup, basestring): markup = unicode(markup) #Now we know that chunk is either a string, or None. if hasattr(matchAgainst, 'match'): # It's a regexp object. result = markup and matchAgainst.search(markup) elif (isList(matchAgainst) and (markup is not None or not isinstance(matchAgainst, basestring))): result = markup in matchAgainst elif hasattr(matchAgainst, 'items'): result = markup.has_key(matchAgainst) elif matchAgainst and isinstance(markup, basestring): if isinstance(markup, unicode): matchAgainst = unicode(matchAgainst) else: matchAgainst = str(matchAgainst) if not result: result = matchAgainst == markup return result
def search(self, markup): #print 'looking for %s in %s' % (self, markup) found = None # If given a list of items, scan it for a text element that # matches. if isList(markup) and not isinstance(markup, Tag): for element in markup: if isinstance(element, NavigableString) \ and self.search(element): found = element break # If it's a Tag, make sure its name or attributes match. # Don't bother with Tags if we're searching for text. elif isinstance(markup, Tag): if not self.text: found = self.searchTag(markup) # If it's text, make sure the text matches. elif isinstance(markup, NavigableString) or \ isinstance(markup, basestring): if self._matches(markup, self.text): found = markup else: raise Exception, "I don't know how to match against a %s" \ % markup.__class__ return found
def projectRawRec(rawRec, idxL): """ rawRec :: tuple([any]) idxL :: [int] return :: tuple([any]) """ assert isinstance(rawRec, tuple) assert util.isList(idxL, int) return tuple(map(lambda idx: rawRec[idx], idxL))
def __init__( self, menuItems, submitCallback, invalidSelectionCallback = "DEFAULT", alphabeticOptions = False ): """ creates a form menu widget, used to contain other menu widgets """ assert isList( menuItems ) assert isFunc( submitCallback ) assert isBool( alphabeticOptions ) # invalidSelectionCallback may be: # "DEFAULT" - an internal hack to bind to self.menu # None - meaning an invalid selection defers to a later cmdHandler # Func - a client-supplied invalidSelectionCallback if invalidSelectionCallback == "DEFAULT": invalidSelectionCallback = lambda clientId, remaining: defaultInvalidSelectionCallback( clientId, self.menu) if isDefined( invalidSelectionCallback ): assert isFunc( invalidSelectionCallback ) assert len(menuItems) > 0 self.menuItems = menuItems self.prompt = "{!{FB<options: " self.cmdMap = CmdMap( invalidSelectionCallback ) self.alphabeticOptions = alphabeticOptions menuIndex = 1 self.cmdMap.addCmd( "f", lambda clientId, remaining: submitCallback( clientId ) ) self.cmdMap.addCmd( "a", lambda clientId, remaining: submitCallback( clientId, abort=True ) ) for item in self.menuItems: if isString( item ): continue assert isTuple( item ) # item wasn't tuple or string assert len( item ) == 3 ( itemDesc, itemSelectedFunc, itemValueDescFunc ) = item assert isString( itemDesc ) assert isFunc( itemSelectedFunc) assert isFunc( itemValueDescFunc) itemLabel = menuIndex if self.alphabeticOptions: itemLabel = chr(96 + menuIndex ) self.cmdMap.addCmd( "%s" % itemLabel, lambda clientId, remaining: itemSelectedFunc( clientId ) ) self.prompt += "{FC%s{FB, " % itemLabel menuIndex += 1 self.prompt += "{FCa{FB, {FCf{FB> "
def __init__( self, menuPairs, finishedCallback, invalidSelectionCallback = None, alphabeticOptions = False ): """ menuPairs: [], each element is string or (string, any type) finishedCallback: f( clientId, selectedValue ) invalidSelectionCallback: f( clientId, remaining ) """ isList( menuPairs) isFunc( finishedCallback) if invalidSelectionCallback: isFunc( invalidSelectionCallback ) else: invalidSelectionCallback = lambda clientId, remaining: defaultInvalidSelectionCallback( clientId, self.menuStr ) self.menuStr = "{!" self.menuMap = CmdMap( invalidSelectionCallback ) menuIndex = 1 def finishMenuWithValue( value ): return lambda clientId, remaining: finishMenu( clientId, finishedCallback, value ) for item in menuPairs: if type(item) == str: self.menuStr += item + "\r\n" continue ( menuItemDescription, menuItemValue ) = item optionLabel = "" if alphabeticOptions: optionLabel = chr(96 + menuIndex) else: optionLabel = menuIndex isStr( menuItemDescription) self.menuStr = self.menuStr + " {FC%s{FG) - {FU%s\r\n" % ( optionLabel, menuItemDescription ) self.menuMap.addCmd( "%s" % optionLabel, finishMenuWithValue( menuItemValue ) ) menuIndex += 1 self.menuStr += "{@"
def parseValues(self, valueStrs): """ valueStrs :: [str] | tuple([str]) return :: tuple([any]) This must be the same type of rawRec. """ assert util.isList(valueStrs, str) or util.isTuple(valueStrs, str) if util.isTuple(valueStrs, str): valueStrs = list(valueStrs) assert self.size() == len(valueStrs) return tuple(map(lambda (e, s): e.type().parse(s), zip(self.__schemaEntryL, valueStrs)))
def project(self, cols, reuse=False): """ cols :: [str] return :: Relation """ assert util.isList(cols, str) schema, idxL = self.schema().project(cols) def mapper(rawRec): return projectRawRec(rawRec, idxL) g = itertools.imap(mapper, self.getG()) return Relation(schema, g, reuse)
def map(self, colsFrom, schemaTo, mapper, name=None, reuse=False): """ Map a relation to another. colsFrom :: [str] schemaTo :: Schema mapper :: rawRec -> rawRec """ assert util.isList(colsFrom, str) assert isinstance(schemaTo, Schema) def g(): for rec in self.getRecG(): yield mapper(rec[colsFrom]) return Relation(schemaTo, g(), name=name, reuse=reuse)
def __init__(self, menuItems, selectionCallback, invalidSelectionCallback="DEFAULT", alphabeticOptions=False): """ creates a menu widget, used to prompt the user to select a value from a set menuItems: [item] - the list of items to display in the menu. item: string - a line of text (e.g. header) to display in the menu or ( string, value ) - a description, value pair that the user can select selectionCallback: func - the function called with args ( clientId, selectedValue ) when the user selects a value invalidSelectionCallback: func - the function called with args ( clientId, clientInputRemaining ) when the user's input doesn't map to a valid choice alphabeticOptions: bool - if true, use alphabetic, i.e. a..z, instead of numeric indices for the menu """ assert isList(menuItems) assert isFunc(selectionCallback) assert isBool(alphabeticOptions) assert len(menuItems) > 0 self.menu = "{!" # invalidSelectionCallback may be: # "DEFAULT" - an internal hack to bind to self.menu # None - meaning an invalid selection defers to a later cmdHandler # Func - a client-supplied invalidSelectionCallback if invalidSelectionCallback == "DEFAULT": invalidSelectionCallback = lambda clientId, remaining: defaultInvalidSelectionCallback(clientId, self.menu) if isDefined(invalidSelectionCallback): assert isFunc(invalidSelectionCallback) self.prompt = "" self.cmdMap = CmdMap(invalidSelectionCallback) menuIndex = 1 for item in menuItems: if isString(item): self.menu += item + endl continue assert isTuple(item) # item wasn't string assert len(item) == 2 (itemDesc, itemValue) = item assert isString(itemDesc) itemLabel = menuIndex if alphabeticOptions: itemLabel = chr(96 + menuIndex) self.menu += " {FC%s{FG) - {FU%s" % (itemLabel, itemDesc) + endl def getItemSelectedFunction(selectedValue): return lambda clientId, remaining: selectionCallback(clientId, selectedValue) self.cmdMap.addCmd("%s" % itemLabel, getItemSelectedFunction(itemValue)) menuIndex += 1 self.menu += "{@"
def joinTwoRelations(keyCols, relCols0, relCols1, reuse=False): """ Join two relations. This will execute sort and merge join. keyCols :: tuple([str]) Name of key columns. The key columns must be unique in both rel0 and rel1. relCols0 :: (Relation, cols) relCols1 :: (Relation, cols) cols :: [str] Target columns. reuse :: bool return :: Relation joined relations. """ rel0, cols0 = relCols0 rel1, cols1 = relCols1 assert isinstance(rel0, Relation) assert isinstance(rel1, Relation) assert util.isList(cols0, str) assert util.isList(cols1, str) assert len(cols0) > 0 assert len(cols1) > 0 assert isinstance(keyCols, tuple) assert len(keyCols) > 0 # sorted records generator. schema0 = list(keyCols) + cols0 schema1 = list(keyCols) + cols1 g0 = iter(rel0.sort(cols=list(keyCols)).project(schema0).getG()) g1 = iter(rel1.sort(cols=list(keyCols)).project(schema1).getG()) # merged records generator. keySize = len(keyCols) def joinedRawRecG(): isEnd = False try: rawRec0 = g0.next() rawRec1 = g1.next() except StopIteration: isEnd = True for _ in []: yield while not isEnd: try: if rawRec0[:keySize] == rawRec1[:keySize]: yield rawRec0[:keySize] + rawRec0[keySize:] + rawRec1[keySize:] rawRec0 = g0.next() rawRec1 = g1.next() elif rawRec0[:keySize] < rawRec0[:keySize]: rawRec0 = g0.next() else: rawRec1 = g1.next() except StopIteration: isEnd = True retSchemaEntryL = [] for colName in list(keyCols) + cols0: retSchemaEntryL.append(rel0.schema().getEntry(colName)) for colName in cols1: retSchemaEntryL.append(rel1.schema().getEntry(colName)) return Relation(Schema(retSchemaEntryL), joinedRawRecG(), reuse=reuse)