| #!/usr/bin/python  | 
| # -*- coding: GBK -*-  | 
| #-------------------------------------------------------------------------------  | 
| #  | 
| ##@package   | 
| #  | 
| # @todo:¶ÁÈ¡PY±í  | 
| # @author hxp  | 
| # @date 2018-05-10  | 
| # @version 1.0  | 
| #  | 
| # ÏêϸÃèÊö: ¶ÁÈ¡PY±í  | 
| #  | 
| #-------------------------------------------------------------------------------  | 
| #"""Version = 2018-05-10 12:00"""  | 
| #-------------------------------------------------------------------------------  | 
|   | 
| import FormulaControl  | 
| import ChConfig  | 
| import LogUI  | 
|   | 
| import hashlib  | 
| import os  | 
|   | 
| '''±í½á¹¹¶¨Òå×Öµä  | 
| {  | 
|     ±íÃû:(  | 
|         (×Ö¶ÎÀàÐÍ, ×Ö¶ÎÃû, ÊÇ·ñ²éѯË÷Òý),   | 
|         ...  | 
|         ),  | 
|     ...  | 
| }  | 
| '''  | 
| Def_IpyTable = {  | 
|                 #<%Table_Def%>  | 
|                 }  | 
|   | 
| #<%Table_Class%>  | 
|   | 
|   | 
| def Log(msg, playerID=0, par=0):  | 
|     LogUI.Msg("%s\t%s\t%s" % (par, playerID, msg))  | 
|     return  | 
|       | 
| def ErrLog(msg, playerID=0, par=0):  | 
|     LogUI.Msg("%s\t%s\t###Error:%s" % (par, playerID, msg))  | 
|     return  | 
|       | 
| ## PY±íÊý¾Ý¹ÜÀíÀà  | 
| class IPY_DataMgr():  | 
|       | 
|     def __init__(self):  | 
|         self.fileMD5Dict = {} # Êý¾Ý±íÎļþmd5×Öµä, ÓÃÓÚ¶Ô±ÈÎļþ²îÒìÅжÏÊÇ·ñÖØ¶Á {dtName:md5, ...}  | 
|         self.ipyConfigEx = {} # ×Ô¶¨ÒåÊý¾Ý»º´æ {key:configData, ...}  | 
|         self.ipyDataIndexMap = {} # Êý¾Ý±íË÷Òý²éѯ»º´æ {dtName:{args:[index, ...], ...}, ...}  | 
|         self.ipyDataIndexMapEx = {} # Êý¾Ý±í×Ô¶¨Òå²éѯÌõ¼þ²éѯ»º´æ {dtName_(findKey,...):{(findKeyValue, ...):[index, ...], ...}, ...}  | 
|         self.ipyFuncConfigDict = {} # ¹¦ÄÜÅäÖÃ±í»º´æ {key:IPY_FuncConfig, ...}  | 
|         self.IpyDataClear()  | 
|         return  | 
|       | 
|     def IpyDataClear(self):  | 
|         Log("IPY_DataMgr Init...")  | 
|         self.ipyConfigEx = {}  | 
|         #<%Ipy_Cache_Init%>  | 
|         Log("IPY_FuncConfig count=%s" % len(self.ipyFuncConfigDict))  | 
|         Log("IPY_DataMgr InitOK!")  | 
|         return  | 
|       | 
|     def __LoadFileData(self, tableName, Class):  | 
|         curPath = "<%LoadStructPath%>" + "\\PySysDB\\tag" + tableName + ".txt"  | 
|         if not os.path.isfile(curPath):  | 
|             ErrLog("can not find file = %s,%s" % (tableName, curPath))  | 
|             raise Exception("can not find file = %s,%s" % (tableName, curPath))  | 
|           | 
|         fileObj = open(curPath, 'rb')  | 
|         content = fileObj.read()  | 
|         fileObj.close()  | 
|           | 
|         md5_obj = hashlib.md5()  | 
|         md5_obj.update(content)  | 
|         newMD5Code = md5_obj.hexdigest()  | 
|         if tableName in self.fileMD5Dict:  | 
|             oldMD5Code = self.fileMD5Dict[tableName]  | 
|             if newMD5Code == oldMD5Code:  | 
|                 return getattr(self, "ipy%sCache" % tableName)  | 
|               | 
|             if tableName in self.ipyDataIndexMap:  | 
|                 self.ipyDataIndexMap.pop(tableName)  | 
|             for dtName_Findkey in self.ipyDataIndexMapEx.keys():  | 
|                 findStr = "%s_" % tableName  | 
|                 if findStr in dtName_Findkey:  | 
|                     self.ipyDataIndexMapEx.pop(dtName_Findkey)  | 
|             if tableName == "FuncConfig":  | 
|                 self.ipyFuncConfigDict = {}  | 
|         self.fileMD5Dict[tableName] = newMD5Code  | 
|           | 
|         dataIndex = 0  | 
|         indexDict = {}  | 
|         cacheList = []  | 
|         fieldList = Def_IpyTable[tableName]  | 
|         infoList = content.split('\r\n')  | 
|         for line in xrange(len(infoList)):  | 
|             if line == 0:  | 
|                 continue  | 
|             if not infoList[line]:  | 
|                 #ErrLog("line not content! %s, line=%s" % (tableName, line))  | 
|                 continue  | 
|             rowList = infoList[line].split('\t')  | 
|             if len(fieldList) != len(rowList):  | 
|                 ErrLog("field count error!, %s, line=%s, len=%s,rowCount=%s" % (tableName, line, len(fieldList), len(rowList)))  | 
|                 raise Exception("field count error!, %s, line=%s, len=%s,rowCount=%s" % (tableName, line,len(fieldList), len(rowList)))  | 
|               | 
|             try:  | 
|                 indexKey = []  | 
|                 classObj = Class()  | 
|                 for j, value in enumerate(rowList):  | 
|                     fieldType, fieldName, isIndex = fieldList[j]  | 
|                     if fieldType == "char":  | 
|                         attrValue = value  | 
|                     elif fieldType == "dict":  | 
|                         attrValue = self.__StrToDict(value)  | 
|                     elif fieldType == "list":  | 
|                         attrValue = self.__StrToList(value)  | 
|                     elif fieldType == "eval":  | 
|                         attrValue = self.__StrToEval(value)  | 
|                     elif fieldType == "float":  | 
|                         attrValue = float(value)  | 
|                     else:  | 
|                         attrValue = 0 if not value.isdigit() else int(value)  | 
|                     setattr(classObj, "%s" % fieldName, attrValue)  | 
|                     if isIndex:  | 
|                         indexKey.append(attrValue)  | 
|                 cacheList.append(classObj)  | 
|                 indexKey = tuple(indexKey)  | 
|                 indexList = indexDict.get(indexKey, [])  | 
|                 indexList.append(dataIndex)  | 
|                 indexDict[indexKey] = indexList  | 
|                 dataIndex += 1  | 
|             except BaseException:  | 
|                 ErrLog("SetIpyDataError: tableName=%s,line=%s,fieldName=%s,fieldType=%s,value=%s" % (tableName, line, fieldName, fieldType, value))  | 
|                 raise  | 
|             if tableName == "FuncConfig":  | 
|                 self.__LoadFuncConfigData(fieldList, rowList)  | 
|         if tableName != "FuncConfig":  | 
|             self.ipyDataIndexMap[tableName] = indexDict  | 
|         Log("LoadIpydata: %s, content count=%s" % (tableName, len(cacheList)))  | 
|         return cacheList  | 
|       | 
|     def __LoadFuncConfigData(self, fieldList, rowList):  | 
|         funcConfigObj = IPY_FuncConfig()  | 
|         key = rowList[0]  | 
|         funcConfigObj.Key = key  | 
|         for i, strValue in enumerate(rowList):  | 
|             if i == 0:  | 
|                 continue  | 
|             try:  | 
|                 fieldName = fieldList[i][1]  | 
|                 strValue = strValue.lstrip().rstrip()  | 
|                 if strValue.isdigit():  | 
|                     configValue = int(strValue)  | 
|                 elif (strValue.startswith("{") and strValue.endswith("}")) \  | 
|                     or (strValue.startswith("[") and strValue.endswith("]")) \  | 
|                     or (strValue.startswith("(") and strValue.endswith(")")):  | 
|                     configValue = eval(strValue)  | 
|                 elif "_" in strValue and type(self.__StrToDict(strValue)) == dict:  | 
|                     configValue = self.__StrToDict(strValue)  | 
|                 elif ChConfig.Def_Str_Montant in strValue:  | 
|                     configValue = eval("(%s,)" % strValue.replace(ChConfig.Def_Str_Montant, ","))  | 
|                 elif strValue in ["-", ""]:  | 
|                     configValue = ""  | 
|                 else:  | 
|                     configValue = self.__ToFloat(strValue)  | 
|             except BaseException:  | 
|                 ErrLog("SetIpyDataError: tableName=%s,key=%s,i=%s,value=%s" % ("FuncConfig", key, i, strValue))  | 
|                 raise  | 
|             setattr(funcConfigObj, fieldName, configValue)  | 
|         self.ipyFuncConfigDict[key] = funcConfigObj  | 
|         return  | 
|       | 
|     def __ToFloat(self, strValue):  | 
|         try:  | 
|             value = float(strValue)  | 
|         except:  | 
|             return strValue  | 
|         return value  | 
|       | 
|     def __StrToEval(self, strValue):  | 
|         if not strValue or strValue in ["0", "-", ""]:  | 
|             return  | 
|         return eval(strValue)  | 
|       | 
|     def __StrToDict(self, strValue):  | 
|         setDict = {}  | 
|         if "{" in strValue and "}" in strValue:  | 
|             setDict = eval(strValue)  | 
|         elif strValue in ["0", "-", ""]:  | 
|             pass  | 
|         else:  | 
|             keyValueList = strValue.split(ChConfig.Def_Str_Montant)  | 
|             for keyValue in keyValueList:  | 
|                 if "_" not in keyValue:  | 
|                     continue  | 
|                 kv = keyValue.split("_")  | 
|                 if len(kv) != 2:  | 
|                     return  | 
|                 key, value = kv  | 
|                 if key.isdigit():  | 
|                     key = int(key)  | 
|                 if value.isdigit():  | 
|                     value = int(value)  | 
|                 setDict[key] = value  | 
|         return setDict  | 
|       | 
|     def __StrToList(self, strValue):  | 
|         setList = []  | 
|         if ("[" in strValue and "]" in strValue) or ("(" in strValue and ")" in strValue):  | 
|             setList = eval(strValue)  | 
|         elif strValue in ["0", "-", ""]:  | 
|             pass  | 
|         elif strValue.isdigit():  | 
|             setList = (int(strValue),)  | 
|         else:  | 
|             for value in strValue.split(ChConfig.Def_Str_Montant):  | 
|                 if value.isdigit():  | 
|                     value = int(value)  | 
|                 setList.append(value)  | 
|             if setList:  | 
|                 setList = tuple(setList)  | 
|         return setList  | 
|       | 
| #<%Ipy_Cache_Func%>  | 
|   | 
| IPYData = IPY_DataMgr()  | 
| def IPY_Data(): return IPYData  | 
|   | 
| def GetConfigEx(key):  | 
|     '''»ñÈ¡×Ô¶¨Òåkey»º´æÊý¾Ý  | 
|     '''  | 
|     if key in IPYData.ipyConfigEx:  | 
|         return IPYData.ipyConfigEx[key]  | 
|     return  | 
| def SetConfigEx(key, configData):  | 
|     '''ÉèÖÃ×Ô¶¨Òåkey»º´æÊý¾Ý  | 
|     ÓÐЩ±íµÄÅäÖÃÄÚÈÝ¿ÉÄÜÔÚʵ¼Ê¹¦ÄÜʹÓÃÖÐÖ±½ÓʹÓñíÊý¾ÝµÄ»°»á±È½ÏÂé·³£¬±ÈÈçÿ´Î¶¼Òª±éÀú»ñȡһЩ±íÊý¾Ý  | 
|     Èç¹û¾¹ýÒ»²ãÊý¾Ýת»»ºóÔÙÀ´Ê¹ÓøÃÊý¾ÝµÄ»°»á¼ò»¯¹¦ÄÜÂß¼»òÌá¸ßЧÂÊ£¬Ôò¿ÉÒÔͨ¹ýº¯Êý±£´æÒ»Ð©×Ô¶¨ÒåµÄ»º´æÄÚÈÝ£¬·½±ã¹¦ÄÜʹÓà  | 
|     Ò²¿ÉÒÔÊÊÓÃÓÚÆäËû×Ô¶¨Ò建´æ´æ´¢  | 
|     '''  | 
|     IPYData.ipyConfigEx[key] = configData  | 
|     return configData  | 
|   | 
| def GetIpyGameData(dtName, *args):  | 
|     '''»ñÈ¡±íÊý¾Ý£¬ÊÊÓÃÓÚÊý¾ÝΨһµÄ£¬·µ»Øµ¥ÌõÊý¾ÝʵÀý  | 
|     @param dtName: ±íÃû£¬²»º¬tag  | 
|     @param args: ½¨±íʱÉèÖõÄË÷Òý×Ö¶Î˳Ðò¶ÔÓ¦µÄ²éѯֵ  | 
|     @return: ¶ÔÓ¦²éѯÌõ¼þµÄ ipyData Êý¾ÝʵÀý£¬Ö»·µ»Øµ¥¸öʵÀý  | 
|     @ʹÓÃ˵Ã÷: IpyGameDataPY.GetIpyGameData(±íÃû, Ë÷Òý1²éѯֵ, Ë÷Òý2²éѯֵ, ¡ )  | 
|     '''  | 
|     if dtName not in IPYData.ipyDataIndexMap:  | 
|         ErrLog("Can not found ipyData dtName=%s" % (dtName))  | 
|         return  | 
|     indexDict = IPYData.ipyDataIndexMap[dtName]  | 
|     if args not in indexDict:  | 
|         ErrLog("Can not found ipyData dtName=%s,indexValue=%s" % (dtName, args))  | 
|         return  | 
|     indexList = indexDict[args]  | 
|     return getattr(IPYData, "ipy%sCache" % dtName)[indexList[0]]  | 
|   | 
| def GetIpyGameDataList(dtName, *args):  | 
|     '''»ñÈ¡±íÊý¾Ý£¬ÊÊÓÃÓÚ²éѯ½á¹ûÓжàÌõÊý¾ÝµÄ  | 
|     @param dtName: ±íÃû£¬²»º¬tag  | 
|     @param args: ½¨±íʱÉèÖõÄË÷Òý×Ö¶Î˳Ðò¶ÔÓ¦µÄ²éѯֵ  | 
|     @return: ¶ÔÓ¦²éѯÌõ¼þµÄ ipyData Êý¾ÝʵÀýÁÐ±í  | 
|     @ʹÓÃ˵Ã÷: Óë GetIpyGameData º¯ÊýÏàͬ  | 
|     '''  | 
|     if dtName not in IPYData.ipyDataIndexMap:  | 
|         ErrLog("Can not found ipyDataList dtName=%s" % (dtName))  | 
|         return  | 
|     indexDict = IPYData.ipyDataIndexMap[dtName]  | 
|     if args not in indexDict:  | 
|         ErrLog("Can not found ipyDataList dtName=%s,indexValue=%s" % (dtName, args))  | 
|         return  | 
|     indexList = indexDict[args]  | 
|     dataCache = getattr(IPYData, "ipy%sCache" % dtName)  | 
|     return [dataCache[i] for i in indexList]  | 
|   | 
| def GetIpyGameDataNotLog(dtName, *args):  | 
|     '''Óë GetIpyGameData º¯ÊýÏàͬ, Ö»ÊÇÕÒ²»µ½Êý¾Ýʱ²»»áÊä³öÈÕÖ¾  | 
|     '''  | 
|     if dtName not in IPYData.ipyDataIndexMap:  | 
|         #ErrLog("Can not found ipyData dtName=%s" % (dtName))  | 
|         return  | 
|     indexDict = IPYData.ipyDataIndexMap[dtName]  | 
|     if args not in indexDict:  | 
|         #ErrLog("Can not found ipyData dtName=%s,indexValue=%s" % (dtName, args))  | 
|         return  | 
|     indexList = indexDict[args]  | 
|     return getattr(IPYData, "ipy%sCache" % dtName)[indexList[0]]  | 
|   | 
| def GetIpyGameDataListNotLog(dtName, *args):  | 
|     '''Óë GetIpyGameDataList º¯ÊýÏàͬ, Ö»ÊÇÕÒ²»µ½Êý¾Ýʱ²»»áÊä³öÈÕÖ¾  | 
|     '''  | 
|     if dtName not in IPYData.ipyDataIndexMap:  | 
|         #ErrLog("Can not found ipyDataList dtName=%s" % (dtName))  | 
|         return  | 
|     indexDict = IPYData.ipyDataIndexMap[dtName]  | 
|     if args not in indexDict:  | 
|         #ErrLog("Can not found ipyDataList dtName=%s,indexValue=%s" % (dtName, args))  | 
|         return  | 
|     indexList = indexDict[args]  | 
|     dataCache = getattr(IPYData, "ipy%sCache" % dtName)  | 
|     return [dataCache[i] for i in indexList]  | 
|   | 
| def GetIpyGameDataByCondition(dtName, keyDict={}, returnList=False, isLogNone=True):  | 
|     '''¸ù¾Ý×Ô¶¨Òå²éѯÌõ¼þ²éѯ±íÊý¾Ý£¬ÓÉÓÚĿǰֻ֧³Ö½¨Á¢Ò»×é²éѯË÷Òý£¬ËùÒÔʹÓÃÆäËû²éѯÌõ¼þ²é±íʱֻÄÜͨ¹ý¸Ãº¯Êý²éÕÒ  | 
|     @param dtName: ±íÃû£¬²»º¬tag  | 
|     @param keyDict: ²éѯÌõ¼þ×Öµä {²éѯ×Ö¶ÎÃû:²éѯֵ, ...}  | 
|     @param returnList: ÊÇ·ñÒÔÁбíµÄÐÎʽ·µ»Ø²éѯÊý¾Ý£¬Ä¬ÈÏ·ñ  | 
|     @param isLogNone: ÕÒ²»µ½Êý¾ÝʱÊÇ·ñÊý¾ÝÈÕÖ¾£¬Ä¬ÈÏÊÇ  | 
|     @return: ÕÒ²»µ½Êý¾Ýʱ·µ»Ø None£¬ÓÐÊý¾Ýʱ¸ù¾Ý²ÎÊýÊÇ·ñ·µ»ØÁÐ±í·µ»Ø¶ÔÓ¦µÄÊý¾ÝʵÀý»òÊý¾ÝʵÀýÁÐ±í  | 
|     '''  | 
|     fieldList = keyDict.keys()  | 
|     valueList = keyDict.values()  | 
|     findFieldKey = "%s_%s" % (dtName, fieldList)  | 
|     findValueKey = tuple(valueList)  | 
|       | 
|     cacheList = getattr(IPYData, "ipy%sCache" % dtName)  | 
|     if findFieldKey not in IPYData.ipyDataIndexMapEx:  | 
|         indexMapDict = {}  | 
|         for index, iData in enumerate(cacheList):  | 
|             valuekey = tuple([getattr(iData, "%s" % field) for field in fieldList])  | 
|             indexList = indexMapDict.get(valuekey, [])  | 
|             indexList.append(index)  | 
|             indexMapDict[valuekey] = indexList          | 
|         IPYData.ipyDataIndexMapEx[findFieldKey] = indexMapDict  | 
|           | 
|     indexMapDict = IPYData.ipyDataIndexMapEx[findFieldKey]  | 
|     if findValueKey not in indexMapDict:  | 
|         if isLogNone:  | 
|             ErrLog("GetIpyGameDataByCondition can not found data! %s %s" % (dtName, keyDict))  | 
|         return  | 
|     indexList = indexMapDict[findValueKey]  | 
|     if not returnList:  | 
|         return cacheList[indexList[0]]  | 
|     return [cacheList[index] for index in indexList]  | 
|   | 
| def GetFuncCfgIpyData(key):  | 
|     '''¶Á¹¦ÄÜÅäÖñíÅäÖÃʵÀý  | 
|     @param key: ÅäÖÃkey  | 
|     @return: Ö±½Ó·µ»Ø¸ÃÅäÖÃkey¶ÔÓ¦µÄÅäÖÃipyDataʵÀý  | 
|     '''  | 
|     if key not in IPYData.ipyFuncConfigDict:  | 
|         ErrLog("Can not found ipyData FuncConfig key=%s!" % key)  | 
|         return ""  | 
|     return IPYData.ipyFuncConfigDict[key]  | 
|   | 
| def GetFuncCfg(key, index=1):  | 
|     '''¶Á¹¦ÄÜÅäÖñíÅäÖÃרÓú¯Êý  | 
|     @param key: ÅäÖÃkey  | 
|     @param index: µÚ¼¸¸öÅäÖÃÖµ£¬Ö§³Ö1~5  | 
|     @return: Ö±½Ó·µ»Ø¶ÔÓ¦µÄÊý¾ÝÀàÐÍ int¡¢str£¬²»ÓÃÔÙÊÖ¶¯×ªint  | 
|     '''  | 
|     if key not in IPYData.ipyFuncConfigDict:  | 
|         ErrLog("Can not found ipyData FuncConfig key=%s!" % key)  | 
|         return ""  | 
|     cfgObj = IPYData.ipyFuncConfigDict[key]  | 
|     if index == 1:  | 
|         return cfgObj.Numerical1  | 
|     if index == 2:  | 
|         return cfgObj.Numerical2  | 
|     if index == 3:  | 
|         return cfgObj.Numerical3  | 
|     if index == 4:  | 
|         return cfgObj.Numerical4  | 
|     if index == 5:  | 
|         return cfgObj.Numerical5  | 
|     ErrLog("Can not found ipyData FuncConfig key=%s,index=%s!" % (key, index))  | 
|     return ""  | 
|   | 
| def GetFuncEvalCfg(key, index=1, defaultValue=[]):  | 
|     '''¶ÁÈ¡¹¦ÄÜÅäÖñíÅäÖÃÁÐ±í¡¢×Öµä¸ñʽרÓú¯Êý  | 
|     @param key: ÅäÖÃkey  | 
|     @param index: µÚ¼¸¸öÅäÖÃÖµ£¬Ö§³Ö1~5  | 
|     @return: Ö±½Ó·µ»Ø¶ÔÓ¦µÄÊý¾ÝÀàÐÍ list¡¢dict¡¢tuple£¬²»ÓÃÔÙeval  | 
|       | 
|     ÓÉÓڲ߻®ÓÐ×Ô¶¨ÒåµÄÁбí½á¹¹ obj|¡ , µ±¸ÃÁбíÅäÖÃÖ»ÓÐÒ»¸öÔªËØÊ±£¬´ËʱÅäÖõÄÄÚÈÝΪµ¥¸öÊýÖµ£¬¼ÓÔØµÄÅäÖõÄʱºò´ËÌõÊý¾Ý»á±»×ªÎªintÐÍ  | 
|     ¹ÊʹÓøÃרÓú¯Êý·µ»ØÁбí½á¹¹£¬·½±ã¹¦ÄÜ¿ª·¢Ê±²»ÓÃÔÙ¿¼ÂÇÁбíΪintʱµÄÇé¿ö£»  | 
|     µ±È»Èç¹ûÅäÖõÄÄÚÈݱ¾Éí¾ÍΪpythonµÄÁÐ±í¡¢×Öµä½á¹¹µÄ»°¿ÉʹÓÃÉÏÃæµÄº¯Êý  | 
|     ²»¹ýΪÁËͳһ£¬½¨Ò鹦ÄÜÅäÖñí¶ÁÁÐ±í¡¢×Öµäʱ¶¼Ê¹Óøú¯Êý  | 
|     '''  | 
|     if key not in IPYData.ipyFuncConfigDict:  | 
|         ErrLog("Can not found ipyData FuncConfig key=%s!" % key)  | 
|         return defaultValue  | 
|     cfgObj = IPYData.ipyFuncConfigDict[key]  | 
|     if index == 1:  | 
|         curConfig = cfgObj.Numerical1  | 
|     elif index == 2:  | 
|         curConfig = cfgObj.Numerical2  | 
|     elif index == 3:  | 
|         curConfig = cfgObj.Numerical3  | 
|     elif index == 4:  | 
|         curConfig = cfgObj.Numerical4  | 
|     elif index == 5:  | 
|         curConfig = cfgObj.Numerical5  | 
|     else:  | 
|         ErrLog("Can not found ipyData FuncConfig key=%s,index=%s!" % (key, index))  | 
|         return defaultValue  | 
|     curType = type(curConfig)  | 
|     if curType in [list, tuple, dict]:  | 
|         return curConfig  | 
|     if curType == int:  | 
|         return [curConfig]  | 
|     return defaultValue  | 
|   | 
| def GetFuncCompileCfg(key, index=1):  | 
|     '''»ñÈ¡¹¦ÄÜÅäÖñíÒѱàÒë¹ýµÄ¹«Ê½  | 
|     @param key: ÅäÖÃkey  | 
|     @param index: µÚ¼¸¸öÅäÖÃÖµ£¬Ö§³Ö1~5  | 
|     @return: ·µ»ØÒѱàÒë¹ýµÄ¹«Ê½  | 
|     '''  | 
|     return FormulaControl.GetCompileFormula(key + str(index), str(GetFuncCfg(key, index)))  | 
|   | 
| def InterpolationSearch(dtName, keyName, keyValue, conditionDict={}):  | 
|     '''²éѯÌõ¼þÏÂÓë¶ÔÓ¦²éѯ×ֶβο¼ÖµÏà½üµÄÊý¾ÝʵÀý£»²Î¿¼ÖµÐ¡ÓÚÅäÖñí×îСֵʱ·µ»Ønone£¬´óÓÚ×î´óֵʱ·µ»Ø×î´óÖµ¶ÔÓ¦µÄʵÀý  | 
|     @param dtName: ±íÃû£¬²»º¬tag  | 
|     @param keyName: ²Î¿¼×Ö¶ÎÃû  | 
|     @param keyValue: ²Î¿¼×Ö¶ÎÖµ£¬´óÓÚµÈÓÚ×Ö¶Îֵʱ·µ»Ø¶ÔÓ¦Êý¾Ý  | 
|     @param conditionDict: ²éѯÌõ¼þ£¬{²éѯ×Ö¶ÎÃû:×Ö¶ÎÖµ, ...}  | 
|     @return: ÕÒ²»µ½Êý¾Ý·µ»Ø None £¬ ·ñÔò·µ»Ø¶ÔÓ¦µÄ ipyData Êý¾ÝʵÀý  | 
|     '''  | 
|     if not conditionDict:  | 
|         dataList = getattr(IPYData, "ipy%sCache" % dtName)  | 
|     else:  | 
|         dataList = GetIpyGameDataByCondition(dtName, conditionDict, True)  | 
|     if not dataList:  | 
|         return  | 
|       | 
|     low = 0  | 
|     lowData = dataList[0]  | 
|     lowValue = getattr(lowData, "%s" % keyName)  | 
|     if keyValue < lowValue:  | 
|         return  | 
|       | 
|     high = len(dataList) - 1  | 
|     highData = dataList[high]  | 
|     highValue = getattr(highData, "%s" % keyName)  | 
|     if keyValue >= highValue:  | 
|         return highData  | 
|       | 
|     near = low + int((high - low) * (keyValue - lowValue)/(highValue - lowValue))  | 
|       | 
|     nearData = dataList[near]  | 
|     nearValue = getattr(nearData, "%s" % keyName)  | 
|       | 
|     if keyValue < nearValue:  | 
|         for i in xrange(near - 1, low - 1, -1):  | 
|             nearData = dataList[i]  | 
|             nearValue = getattr(nearData, "%s" % keyName)  | 
|             if nearValue <= keyValue:  | 
|                 return nearData  | 
|               | 
|     elif keyValue > nearValue:  | 
|         for i in xrange(near + 1, high + 1):  | 
|             nearData = dataList[i]  | 
|             nearValue = getattr(nearData, "%s" % keyName)  | 
|             if nearValue > keyValue:  | 
|                 return dataList[i - 1]  | 
|               | 
|     return nearData  | 
|   |