def combine_stations() -> Iterable[List[str]]: 'Combine the two railway station datasets by telecode.' stations = AttrDict() names = {} stations_95306 = hyfw.dfs() stations_12306 = kyfw.stations() for s in stations_95306: pinyin = s['PYM'].lower() if len(pinyin) > 3: pinyin = pinyin[:2] + pinyin[-1] elif len(pinyin) < 3: pinyin = '' name, telecode = s['ZMHZ'], s['DBM'] stations[telecode] = [pinyin, name, s['TMIS'], s['SSJC']] names[name] = telecode for s in stations_12306: old = stations.get(s.telecode) new = [s.pinyin_code, s.name, '', ''] if s.name in names and s.telecode != names[s.name]: conflict = '%s/%s -> %s/%s' % (names[s.name], new, s.telecode, old) if s.telecode in stations: conflict = 'Name conflict: %s -> ?' % conflict else: conflict = 'Solved conflict: %s' % conflict old = stations[s.telecode] = stations.pop(names[s.name]) old[:2] = new[:2] elif s.telecode in stations and s.name != stations[s.telecode][1]: new[-2] = tmis(s.name).get(s.name, '') conflict = '%s/(%s => %s)' % (s.telecode, old, new) if new[-2] and old[-2] != new[-2]: # TMIS codes conflict conflict = 'Ambiguous telecode: %s' % conflict else: conflict = 'Solved conflict: %s' % conflict old[:2] = new[:2] else: if s.telecode not in stations: stations[s.telecode] = [''] * 4 stations[s.telecode][:2] = new[:2] continue # resolve merge conflicts manually shell(dict(vars(), s=stations), '\n%s' % conflict) for k, v in stations.items(): # drop telecodes with spaces # so those can be used as temporary names in conflict solving v.insert(2, '' if ' ' in k else k) yield v
def explain(self, info: AttrDict) -> str: 'Convert the query result to a human-readable text message.' # remove trailing whitespace and null values for k, v in info.items(): info[k] = str(v).rstrip() if info[k] in ['0', '-1', '发货人']: info[k] = '' # rename some fields to fit into the template converters = { 'fz': 'cdyStation', 'dz': 'destStation', 'pm': 'cdyName', 'xh': 'carNo', 'xt': 'arrDepId', 'carType': 'carKind', 'tyrName': 'shpName', 'conName': 'shpName', 'wbID': 'wbNbr', } for k, v in converters.items(): info[k] = info.get(k, '') info[v] = info.get(v) or info[k] if info.conName == info.shpName: info.conName = '' elif info.conName: info.conName = ',发往' + info.conName if info.xh: info.carKind = '集装箱' info.carLE = 'L' if info.cdyName else 'E' elif info.carType.startswith(info.carKind): info.carKind = '车辆' if not info.cdyName: status = '' elif info.carLE == 'L': status = '负责运送{wbNbr[单号为 {} 的]}{cdyName}' if info.cdyName[-1:].isdigit(): info.cdyName += '型集装箱' else: status = '当前状态为{cdyName}{wbNbr[,运单号为 {}]}' if info.cdyName.endswith('空'): info.cdyName += '车' if info.get('trainId'): info.train = ' %s 次列车' % info.trainId info.arrDep = { 'A': '到达', 'D': '离开', '在站': '到达', '在途': '离开', }.get(info.arrDepId, '到达') explanation = ''' 截至 {eventDate} 时为止,您查询的{shpName[由{}托运{conName}的]} {carNo[ {} 号]}{carType[ {} 型]}{carKind} {cdyStation[已从{cdyAdm}{}站发出,]} {destStation[正前往{destAdm}{}站,]}%s{cdyName[。该车]} {train[现被编入{}]}{trainOrder[机后第 {} 位]}{train[,]} 目前已{arrDep}{eventProvince[位于{}{eventCity}的]} {eventAdm}{eventStation}站 {dzlc[,距离终点站{destStation}站还有 {} km]}。 ''' % status return self.format(strip_lines(explanation), **info)