class UserSimulation(object): def __init__(self): self.config = GetConfig() assert (not self.config==None), 'Config file required' assert (self.config.has_option('LGus','LOGIN_PAGE')),'LGus section missing field LOGIN_PAGE' self.login_page = self.config.get('LGus','LOGIN_PAGE') assert (self.config.has_option('LGus','URL')),'LGus section missing field URL' self.url = self.config.get('LGus','URL') assert (self.config.has_option('LGus','ID')),'LGus section missing field ID' self.id = {'username':self.config.get('LGus','ID')} assert (self.config.has_option('LGus','PASSWD')),'LGus section missing field PASSWD' self.id['password'] = self.config.get('LGus','PASSWD') try: data = urllib.urlencode(self.id) req = urllib2.Request(self.login_page, data) cj = cookielib.CookieJar() self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj)) response = self.opener.open(req) the_page = response.read() # print the_page except Exception, detail: print "Err ", detail
class tokenizer(object): MY_ID = 'TOKENIZER' def __init__(self,mode=None): self.config = GetConfig() if mode: self.mode = mode else: if self.config.has_option(self.MY_ID,'mode'): self.mode = self.config.get(self.MY_ID,'mode') else: self.mode = 'NLTK' if self.mode == 'STANFORD': from nltk.tokenize.stanford import StanfordTokenizer as Tokenizer self.tokenizer = Tokenizer() elif self.mode == 'NLTK': pass elif self.mode == 'MINE': self.spacePunct = re.compile(ur'[`~!@#\$%\^&\*\(\)\[\]{}_\+\-=\|\\:;\"\'<>,\?/]') self.removePunct = re.compile(ur'\.') else: raise Exception('Error: tokenizer, Unknown mode %s!' %(self.mode)) def tokenize(self, sent): if sent.endswith('-') or sent.endswith('~'): sent += ' ' sent = sent.replace('~ ', ' ~ ') sent = sent.replace('- ', ' - ') if self.mode == 'STANFORD': tokens = self.tokenizer.tokenize(sent.strip()) elif self.mode == 'NLTK': tokens = nltk.word_tokenize(sent.strip()) elif self.mode == 'MINE': new_sent = sent.strip() new_sent = self.spacePunct.sub(' ', new_sent) new_sent = self.removePunct.sub('', new_sent) tokens = new_sent.split() p_sent = ' '.join(tokens) p_sent = p_sent.replace('% ', '%') p_sent = p_sent.replace('``', '\"') p_sent = p_sent.replace('\'\'', '\"') p_tokens = p_sent.split(' ') return p_tokens
class Partition(object): ''' Tracks a partition of listings. This class tracks a partition of listings. ''' def __init__(self,existingPartition=None,fieldToSplit=None,value=None): ''' Constructor, and copy constructor. If called as Partition(), returns a new root partition. If called as Partition(existingPartition,fieldToSplit,value), this creates a new child partition of existingPartition, split on fieldToSplit=value. Does not modify existingPartition. This constructor is not meant to be called directly by application code. Application code should use the BeliefState wrapper. ''' self.appLogger = logging.getLogger('Learning') # self.appLogger.info('Partition init') self.config = GetConfig() self.useLearnedUserModel = self.config.getboolean(MY_ID,'useLearnedUserModel') self.confirmUnlikelyDiscountFactor = self.config.getfloat(MY_ID,'confirmUnlikelyDiscountFactor') self.ignoreNonunderstandingFactor = self.config.getboolean(MY_ID,'ignoreNonunderstandingFactor') self.num_route = self.config.getint(MY_ID,'numberOfRoute') self.num_place = self.config.getint(MY_ID,'numberOfPlace') self.num_time = self.config.getint(MY_ID,'numberOfTime') self.offListBeliefUpdateMethod = self.config.get('PartitionDistribution','offListBeliefUpdateMethod') db = GetDB() # self.appLogger.info('Partition 1') if (existingPartition == None): #self.fieldList = db.GetFields() self.fieldList = ['route','departure_place','arrival_place','travel_time'] self.fieldCount = len(self.fieldList) #self.totalCount = db.GetListingCount({}) self.totalCount = self.num_route * self.num_place * self.num_place * self.num_time self.fields = {} # self.appLogger.info('Partition 2') for field in self.fieldList: self.fields[field] = _FieldEntry() self.count = self.totalCount self.prior = 1.0 self.priorOfField = {'route':1.0,'departure_place':1.0,'arrival_place':1.0,'travel_time':1.0} self.countOfField = {'route':self.num_route,'departure_place':self.num_place,'arrival_place':self.num_place,'travel_time':self.num_time} # self.appLogger.info('Partition 3') if not self.useLearnedUserModel: umFields = ['request_nonUnderstandingProb', 'request_directAnswerProb', 'request_allOverCompleteProb', 'request_oogProb', 'request_irrelevantAnswerProb', 'confirm_directAnswerProb', 'confirm_nonUnderstandingProb', 'confirm_oogProb'] assert (not self.config == None), 'Config file required (UserModel parameters)' self.umParams = {} for key in umFields: assert (self.config.has_option('UserModel', key)),'UserModel section missing field %s' % (key) self.umParams[key] = self.config.getfloat('UserModel',key) overCompleteActionCount = 0 for i in range(1,self.fieldCount): overCompleteActionCount += Combination(self.fieldCount-1,i) self.appLogger.info('fieldCount = %d; overCompleteActionCount = %d' % (self.fieldCount,overCompleteActionCount)) self.umParams['request_overCompleteProb'] = \ 1.0 * self.umParams['request_allOverCompleteProb'] / overCompleteActionCount self.umParams['open_answerProb'] = \ (1.0 - self.umParams['request_nonUnderstandingProb'] - self.umParams['request_oogProb']) / \ overCompleteActionCount else: modelPath = self.config.get('Global','modelPath') # self.appLogger.info('Partition 4') self.userModelPath = self.config.get(MY_ID,'userModelPath') # self.appLogger.info('Partition 5') self.userModel = pickle.load(open(os.path.join(modelPath,self.userModelPath),'rb')) # self.appLogger.info('Partition 6') if self.offListBeliefUpdateMethod == 'heuristicUsingPrior': self.irrelevantUserActProb = self.config.getfloat(MY_ID,'irrelevantUserActProb_HeuristicUsingPrior') self.minRelevantUserActProb = self.config.getfloat(MY_ID,'minRelevantUserActProb_HeuristicUsingPrior') elif self.offListBeliefUpdateMethod in ['plain','heuristicPossibleActions']: self.irrelevantUserActProb = self.config.getfloat(MY_ID,'irrelevantUserActProb') self.minRelevantUserActProb = self.config.getfloat(MY_ID,'minRelevantUserActProb') else: raise RuntimeError,'Unknown offListBeliefUpdateMethod = %s'%self.offListBeliefUpdateMethod # self.appLogger.info('Partition 7') else: assert not fieldToSplit == None,'arg not defined' assert not value == None,'arg not defined' self.fieldList = existingPartition.fieldList self.fieldCount = existingPartition.fieldCount if not self.useLearnedUserModel: self.umParams = existingPartition.umParams else: self.userModel = existingPartition.userModel self.irrelevantUserActProb = existingPartition.irrelevantUserActProb self.minRelevantUserActProb = existingPartition.minRelevantUserActProb self.totalCount = existingPartition.totalCount self.countOfField = existingPartition.countOfField self.priorOfField = {} self.fields = {} self.count = 1 for field in self.fieldList: if (field == fieldToSplit): self.fields[field] = _FieldEntry(type='equals', equals=value) else: self.fields[field] = existingPartition.fields[field].Copy() if self.fields[field].type == 'equals': self.count *= 1 self.priorOfField[field] = 1.0/self.countOfField[field] # elif field == 'route': # self.count *= (self.num_route - len(self.fields[field].excludes.keys())) # elif field in ['departure_place','arrival_place']: # self.count *= (self.num_place - len(self.fields[field].excludes.keys())) # elif field == 'travel_time': # self.count *= (self.num_time - len(self.fields[field].excludes.keys())) # else: # raise RuntimeError,'Invalid field %s'%field else: self.count *= (self.countOfField[field] - len(self.fields[field].excludes.keys())) self.priorOfField[field] = 1.0 - 1.0 * len(self.fields[field].excludes.keys())/self.countOfField[field] #self.count = db.GetListingCount(self.fields) self.prior = 1.0 * self.count / self.totalCount def Split(self,userAction): ''' Attempts to split the partition on userAction. Returns a list of zero or more child partitions, modifying this partition as appropriate. ''' newPartitions = [] if (userAction.type == 'non-understanding'): # silent doesn't split pass else: for field in userAction.content.keys(): if (field == 'confirm'): continue val = userAction.content[field] if (self.fields[field].type == 'equals'): # Cant split this partition -- field already equals something pass elif (val in self.fields[field].excludes): # Cant split this partition -- field exludes this value already pass else: newPartition = Partition(existingPartition=self,fieldToSplit=field,value=val) if (newPartition.count > 0): self.fields[field].excludes[val] = True self.count -= newPartition.count self.prior = 1.0 * self.count / self.totalCount self.priorOfField[field] = 1.0 - 1.0 * len(self.fields[field].excludes.keys())/self.countOfField[field] newPartitions.append(newPartition) return newPartitions # This will only be called on a child with no children def Recombine(self,child): ''' Attempts to recombine child partition with this (parent) partition. If possible, does the recombination and returns True. If not possible, makes no changes and returns False. ''' fieldsToRecombine = [] for field in self.fields: if (self.fields[field].type == 'excludes'): if (child.fields[field].type == 'equals'): # parent excludes, child equals value = child.fields[field].equals if (value in self.fields[field].excludes): fieldsToRecombine.append((field,value)) else: raise RuntimeError, 'Error: field %s: child equals %s but parent doesnt exclude it' % (field,value) else: # parent excludes, child excludes # ensure they exclude the same things if (not len(self.fields[field].excludes) == len(child.fields[field].excludes)): return False for val in self.fields[field].excludes: if (val not in child.fields[field].excludes): return False pass else: if (child.fields[field].type == 'equals'): # parent equals, child equals (must be equal) pass else: raise RuntimeError,'Error: field %s: parent equals %s but child excludes this field' % (field,value) if (len(fieldsToRecombine) == 0): raise RuntimeError,'Error: parent and child are identical' if (len(fieldsToRecombine) > 1): raise RuntimeError,'Error: parent and child differ by more than 1 field: %s' % (fieldsToRecombine) self.count += child.count self.prior = 1.0 * self.count / self.totalCount del self.fields[fieldsToRecombine[0][0]].excludes[ fieldsToRecombine[0][1] ] return True def __str__(self): ''' Renders this partition as a string. Example: city x();state x();last x(WILLIAMS);first=JASON;count=386 This is the partition of 386 listings which have first name JASON, and do NOT have last name WILLIAMS (located in any city and any state). ''' s = '' if (len(self.fields) > 0): elems = [] for conceptName in self.fieldList: if (self.fields[conceptName].type == 'equals') : elems.append('%s=%s' % (conceptName,self.fields[conceptName].equals)) elif (len(self.fields[conceptName].excludes) <= 2): elems.append('%s x(%s)' % (conceptName,','.join(self.fields[conceptName].excludes.keys()))) else: elems.append('%s x([%d entries])' % (conceptName,len(self.fields[conceptName].excludes))) elems.append('count=%d' % (self.count)) s = ';'.join(elems) else: s = "(all)" return s def _getClosestUserAct(self,userAction): if userAction.type == 'non-understanding': return 'non-understanding' acts = [['I:ap','I:bn','I:dp','I:tt'],\ ['I:ap','I:bn','I:dp'],\ ['I:ap','I:dp','I:tt'],\ ['I:bn','I:dp','I:tt'],\ ['I:ap','I:dp'],\ ['I:bn','I:tt'],\ ['I:bn'],\ ['I:dp'],\ ['I:ap'],\ ['I:tt'],\ ['yes'],\ ['no']] ua = [] for field in userAction.content: if field == 'confirm': ua.append('yes' if userAction.content[field] == 'YES' else 'no') elif field == 'route': ua.append('I:bn') elif field == 'departure_place': ua.append('I:dp') elif field == 'arrival_place': ua.append('I:ap') elif field == 'travel_time': ua.append('I:tt') score = [float(len(set(act).intersection(set(ua))))/len(set(act).union(set(ua))) for act in acts] closestUserAct = ','.join(acts[score.index(max(score))]) # self.appLogger.info('Closest user action %s'%closestUserAct) return closestUserAct def UserActionLikelihood(self, userAction, history, sysAction): ''' Returns the probability of the user taking userAction given dialog history, sysAction, and that their goal is within this partition. ''' # if (sysAction.type == 'ask'): # if (sysAction.force == 'request'): # if (userAction.type == 'non-understanding'): # result = self.umParams['request_nonUnderstandingProb'] # else: # targetFieldIncludedFlag = False # overCompleteFlag = False # allFieldsMatchGoalFlag = True # askedField = sysAction.content # for field in userAction.content: # if field == 'confirm': # allFieldsMatchGoalFlag = False # continue # val = userAction.content[field] # if (self.fields[field].type == 'equals' and self.fields[field].equals == val): # if (field == askedField): # targetFieldIncludedFlag = True # else: # overCompleteFlag = True # else: # allFieldsMatchGoalFlag = False # if (not allFieldsMatchGoalFlag): # # This action doesn't agree with this partition # result = 0.0 # elif (askedField == 'all'): # # A response to the open question # result = self.umParams['open_answerProb'] # elif (not targetFieldIncludedFlag): # # This action doesn't include the information that was asked for # # This user model doesn't ever do this # result = 0.0 # elif (overCompleteFlag): # # This action include extra information - this happens # # request_overCompleteProb amount of the time # result = self.umParams['request_overCompleteProb'] # else: # # This action just answers the question that was asked # result = self.umParams['request_directAnswerProb'] # elif (sysAction.force == 'confirm'): # if (userAction.type == 'non-understanding'): # result = self.umParams['confirm_nonUnderstandingProb'] # else: # allFieldsMatchGoalFlag = True # for field in sysAction.content: # val = sysAction.content[field] # if (self.fields[field].type == 'excludes' or not self.fields[field].equals == val): # allFieldsMatchGoalFlag = False # if (allFieldsMatchGoalFlag): # if (userAction.content['confirm'] == 'YES'): # result = self.umParams['confirm_directAnswerProb'] # else: # result = 0.0 # else: # if (userAction.content['confirm'] == 'NO'): # result = self.umParams['confirm_directAnswerProb'] # else: # result = 0.0 # else: # raise RuntimeError, 'Dont know sysAction.force = %s' % (sysAction.force) if not self.useLearnedUserModel: result = 0.0 if (sysAction.type == 'ask'): if (userAction.type == 'non-understanding'): if (sysAction.force == 'confirm'): result = self.umParams['confirm_nonUnderstandingProb'] else: result = self.umParams['request_nonUnderstandingProb'] else: targetFieldIncludedFlag = False overCompleteFlag = False allFieldsMatchGoalFlag = True askedField = sysAction.content for field in userAction.content: if field == 'confirm': if sysAction.force == 'request': allFieldsMatchGoalFlag = False continue for field in sysAction.content: val = sysAction.content[field] if (self.fields[field].type == 'excludes' or not self.fields[field].equals == val): allFieldsMatchGoalFlag = False if (allFieldsMatchGoalFlag): if (userAction.content['confirm'] == 'YES'): result = self.umParams['confirm_directAnswerProb'] targetFieldIncludedFlag = True else: result = self.umParams['request_irrelevantAnswerProb'] else: if (userAction.content['confirm'] == 'NO'): result = self.umParams['confirm_directAnswerProb'] targetFieldIncludedFlag = True else: result = self.umParams['request_irrelevantAnswerProb'] else: val = userAction.content[field] if (self.fields[field].type == 'equals' and self.fields[field].equals == val): if (field == askedField): targetFieldIncludedFlag = True else: overCompleteFlag = True else: allFieldsMatchGoalFlag = False if (not allFieldsMatchGoalFlag): # This action doesn't agree with this partition result = self.umParams['request_irrelevantAnswerProb'] elif (askedField == 'all'): # A response to the open question result = self.umParams['open_answerProb'] elif (not targetFieldIncludedFlag): # This action doesn't include the information that was asked for # This user model doesn't ever do this result = self.umParams['request_irrelevantAnswerProb'] elif (overCompleteFlag): # This action include extra information - this happens # request_overCompleteProb amount of the time result = self.umParams['request_overCompleteProb'] else: # This action just answers the question that was asked result = result if result > 0 else self.umParams['request_directAnswerProb'] else: raise RuntimeError, 'Dont know sysAction.type = %s' % (sysAction.type) else: # self.appLogger.info('Apply learned user model') if sysAction.type != 'ask': raise RuntimeError, 'Cannot handle sysAction %s'%str(sysAction) result = self.irrelevantUserActProb allFieldsMatchGoalFlag = True directAnswer = False if sysAction.force == 'confirm': askedField = sysAction.content.keys()[0] if userAction.type != 'non-understanding': for ua_field in userAction.content: self.appLogger.info('User action field: %s:%s'%(ua_field,userAction.content[ua_field])) if ua_field == 'confirm' and userAction.content[ua_field] == 'YES': val = sysAction.content[askedField] if self.fields[askedField].type == 'excludes' or not self.fields[askedField].equals == val: self.appLogger.info('Mismatched YES') allFieldsMatchGoalFlag = False elif ua_field == 'confirm' and userAction.content[ua_field] == 'NO': val = sysAction.content[askedField] if (self.fields[askedField].type == 'equals' and self.fields[askedField].equals == val) or\ (self.fields[askedField].type == 'excludes' and val not in self.fields[askedField].excludes): self.appLogger.info('Mismatched NO') allFieldsMatchGoalFlag = False elif askedField == ua_field: directAnswer = True # val = sysAction.content[askedField] # if self.fields[askedField].type != 'excludes' and \ # self.fields[askedField].equals == userAction.content[askedField]: # self.appLogger.info('Matched %s'%userAction.content[askedField]) # allFieldsMatchGoalFlag = True if self.fields[askedField].type == 'excludes' or \ self.fields[askedField].equals != userAction.content[askedField]: self.appLogger.info('Mismatched %s'%userAction.content[askedField]) allFieldsMatchGoalFlag = False else: val = userAction.content[ua_field] if self.fields[ua_field].type == 'excludes' or not self.fields[ua_field].equals == val: if not ((ua_field == 'arrival_place' and 'departure_place' in userAction.content and \ userAction.content['departure_place'] == userAction.content['arrival_place'] and \ self.fields['departure_place'].type == 'equals' and \ self.fields['departure_place'].equals == userAction.content['departure_place']) or\ (ua_field == 'departure_place' and 'arrival_place' in userAction.content and \ userAction.content['departure_place'] == userAction.content['arrival_place'] and \ self.fields['arrival_place'].type == 'equals' and \ self.fields['arrival_place'].equals == userAction.content['arrival_place'])): self.appLogger.info('Mismatched %s in field %s'%(val,ua_field)) allFieldsMatchGoalFlag = False elif self.ignoreNonunderstandingFactor: allFieldsMatchGoalFlag = False if allFieldsMatchGoalFlag: self.appLogger.info('All fields matched') if (userAction.type != 'non-understanding' and 'confirm' in userAction.content and userAction.content['confirm'] == 'YES') or\ directAnswer: result = self.userModel['C-o'][self._getClosestUserAct(userAction)] else: if userAction.type != 'non-understanding' and 'confirm' in userAction.content and directAnswer: del userAction.content['confirm'] if 'departure_place' in userAction.content and 'arrival_place' in userAction.content and \ userAction.content['departure_place'] == userAction.content['arrival_place']: tempUserAction = deepcopy(userAction) del tempUserAction.content['arrival_place'] result = self.userModel['C-x'][self._getClosestUserAct(tempUserAction)] else: result = self.userModel['C-x'][self._getClosestUserAct(userAction)] self.appLogger.info('User action likelihood %g'%result) result = self.minRelevantUserActProb if result < self.minRelevantUserActProb else result self.appLogger.info('Set minimum user action likelihood %g'%result) elif sysAction.force == 'request': askedField = sysAction.content if userAction.type != 'non-understanding': for ua_field in userAction.content: if ua_field != 'confirm': val = userAction.content[ua_field] if self.fields[ua_field].type == 'excludes' or not self.fields[ua_field].equals == val: if not ((ua_field == 'arrival_place' and 'departure_place' in userAction.content and \ userAction.content['departure_place'] == userAction.content['arrival_place'] and \ self.fields['departure_place'].type == 'equals' and \ self.fields['departure_place'].equals == userAction.content['departure_place']) or\ (ua_field == 'departure_place' and 'arrival_place' in userAction.content and \ userAction.content['departure_place'] == userAction.content['arrival_place'] and \ self.fields['arrival_place'].type == 'equals' and \ self.fields['arrival_place'].equals == userAction.content['arrival_place'])): self.appLogger.info('Mismatched %s in field %s'%(val,ua_field)) allFieldsMatchGoalFlag = False elif self.ignoreNonunderstandingFactor: allFieldsMatchGoalFlag = False if allFieldsMatchGoalFlag: if askedField == 'route': # print self.userModel['R-bn'] result = self.userModel['R-bn'][self._getClosestUserAct(userAction)] elif askedField == 'departure_place': # print self.userModel['R-dp'] result = self.userModel['R-dp'][self._getClosestUserAct(userAction)] elif askedField == 'arrival_place': # print self.userModel['R-ap'] result = self.userModel['R-ap'][self._getClosestUserAct(userAction)] elif askedField == 'travel_time': # print self.userModel['R-tt'] if 'departure_place' in userAction.content and 'arrival_place' in userAction.content and \ userAction.content['departure_place'] == userAction.content['arrival_place']: tempUserAction = deepcopy(userAction) del tempUserAction.content['arrival_place'] result = self.userModel['R-tt'][self._getClosestUserAct(tempUserAction)] else: result = self.userModel['R-tt'][self._getClosestUserAct(userAction)] elif askedField == 'all': # print self.userModel['R-open'] if 'departure_place' in userAction.content and 'arrival_place' in userAction.content and \ userAction.content['departure_place'] == userAction.content['arrival_place']: tempUserAction = deepcopy(userAction) del tempUserAction.content['arrival_place'] result = self.userModel['R-open'][self._getClosestUserAct(tempUserAction)] else: result = self.userModel['R-open'][self._getClosestUserAct(userAction)] self.appLogger.info('User action likelihood %g'%result) result = self.minRelevantUserActProb if result < self.minRelevantUserActProb else result self.appLogger.info('Set minimum user action likelihood %g'%result) return result def UserActionUnlikelihood(self, userAction, history, sysAction): ''' Returns the probability of the user not taking userAction given dialog history, sysAction, and that their goal is within this partition. ''' if sysAction.type != 'ask': raise RuntimeError, 'Dont know sysAction.type = %s' % (sysAction.type) # self.appLogger.info('Apply confirmUnlikelyDiscountFactor %f'%self.confirmUnlikelyDiscountFactor) if sysAction.force == 'request': result = self.prior reason = 'request' elif sysAction.force == 'confirm': result = self.confirmUnlikelyDiscountFactor * self.prior reason = 'confirm' # self.appLogger.info('UserActionUnlikelihood by (%s): %g'%(reason,result)) return result
class Grammar(): ''' Class representing a grammar. The cardinality of a grammar (i.e., how many distinct utterances it can recognize) is available in grammar.cardinality Configuration option: [Grammar] useSharedGrammars: only relevant when using an interactive dialog manager with ASR on the AT&T Speech Mashup platform. If 'true', then Grammar.GetFullName returns the public, shared versions of the grammars (e.g., 'asdt-demo-shared.db100k.all'). If 'false', Grammar.GetFullName returns the private versions of the grammars (e.g., 'db100k.all'). If you have not generated and built your own grammars, set this to 'false'. ''' MY_ID = 'Grammar' def __init__(self,name): ''' The "name" of the grammar is either: - a field name from the DB - "confirm" (which accepts "yes" and "no") only - "all" (which accepts any ordered subset of any listing, like "JASON" or "JASON WILLIAMS" or "JASON NEW YORK" ''' self.config = GetConfig() db = GetDB() # assert (name in db.GetFields() or name in ['all','confirm']),'Unknown Grammar name: %s' % (name) assert (name in ['route','departure_place','arrival_place','travel_time'] or name in ['all','confirm']),'Unknown Grammar name: %s' % (name) self.name = name if (self.name == 'confirm'): self.fullName = 'confirm' else: stem = db.GetDBStem() self.fullName = '%s.%s' % (stem,self.name) if (self.config.has_option(self.MY_ID,'useSharedGrammars') and self.config.getboolean(self.MY_ID,'useSharedGrammars')): if (self.name == 'all'): self.fullName = 'asdt-demo-shared.%s.loc' % (self.fullName) else: self.fullName = 'asdt-demo-shared.%s' % (self.fullName) if (name == 'confirm'): self.cardinality = 2 elif (name == 'all'): fields = ['route','departure_place','arrival_place','travel_time']#db.GetFields() fieldCount = len(fields) fieldCombos = 0 for r in range(fieldCount): fieldCombos += Combination(fieldCount,r) self.cardinality = db.GetListingCount({}) * fieldCombos else: self.cardinality = db.GetFieldSize(self.name) def GetFullName(self): ''' Returns the "fullName" of a grammar, i.e., fullName.grxml For example, the "name" might be "first", but the "fullName" is "db-100k.first" ''' return self.fullName def __str__(self): return '%s:%d' % (self.name,self.cardinality)