""" 一场比赛的数据 """ import json class Match: """Match""" def __init__(self, raw, dtype='json'): """ :param json_string: string represents data in json format """ self.name = '' if dtype == 'json': self.raw_data = json.loads(raw) self.dtype = 'json' else: self.raw_data = raw self.dtype = 'mid' def query(self, cat, act): """ start a query eg. match.query('game', 'created') if cat or act is `None', the corresponding field matches anything :param cat: category :param act: action """ if self.dtype == 'mid': raise RuntimeError("Query on intermediate result.") result = [] for entry in self.raw_data: if (cat == None or entry['cat'] == cat) and (act == None or entry['act'] == act): result.append(entry) return Match(result, dtype='mid') def where(self, where_expr): """ add some condition eg. match.query('player', 'join').where(lambda i: i['pid']==9527) """ if self.dtype != 'mid': raise RuntimeError("Where query on raw data.") return Match([item for item in self.raw_data if where_expr(item)], dtype='mid') def orderby(self, key): """ sort it! eg. match.query('player', 'join').where(lambda i: i['pid']<9527).orderby('created_at') """ if self.dtype != 'mid': raise RuntimeError("Orderby query on raw data.") return Match(sorted(self.raw_data, key=lambda x: x[key]), dtype='mid') def select(self, key1, *args): """ select some columns eg. match.query('player', 'join') .select('pid', 'created_at') .where(lambda i: i['pid']<9527) .orderby('created_at') """ if self.dtype != 'mid': raise RuntimeError("select query on raw data.") result = [] keys = [key1] for k in args: keys.append(k) for entry in self.raw_data: dct = dict.fromkeys(keys) for k in keys: dct[k] = entry[k] result.append(dct) return Match(result, dtype='mid') def first(self): """ return the first result """ if self.dtype != 'mid': raise RuntimeError("first query on raw data.") rawl = len(self.raw_data) return self.raw_data[0] if rawl > 0 else None def count(self): """ return the amount of results """ if self.dtype != 'mid': raise RuntimeError("count query on raw data.") return len(self.raw_data) def get_tr(self, i, target, nb, sv): """ # 计算tau_f的方式是统计周围邻居剩余的tr # 本函数计算第i轮,所有有消耗tr的player,最后剩余的tr # 由于是计算剩余tr,所以不能计算和target之间的交互 # nb是target的邻居 # 2018/08/31 更新:即便是已经交互过的邻居,他的剩余时间资源依旧应该计算入tau_f中,使得公式完整。 # 2018/09/01 更新:不应该算在tau_P中,尝试单独列成一项,因为优化目标不同。 # 2018/09.01 更新:将tau_p更改为tau_f """ trs = {} req = self.query('action', 'request').where(lambda x: x['rno'] == i+1) app = self.query('action', 'approve').where(lambda x: x['rno'] == i+1).raw_data can = self.query('action', 'cancel').where(lambda x: x['rno'] == i+1).raw_data den = self.query('action', 'deny').where(lambda x: x['rno'] == i+1).raw_data fr = [] for r in self.query('action', 'done').where(lambda x: x['rno'] == i and (x['a'] == target or x['b'] == target)).raw_data: if r['a'] == target: fr.append(r['b']) elif r['b'] == target: fr.append(r['a']) truenb = [] for r in nb: if r not in fr and r in sv: truenb.append(r) trs[r] = 1440 for r in req.raw_data: if r['from'] in truenb and r['to'] != target : if r['from'] not in trs: trs[r['from']] = 1440 trs[r['from']] -= r['tr'] for r in app: if r['from'] in truenb and r['to'] != target: if r['from'] not in trs: trs[r['from']] = 1440 trs[r['from']] -= r['tr'] for r in can: if r['from'] in trs and r['to'] != target: trs[r['from']] += req.where(lambda x: x['from'] == r['from'] and x['to'] == r['to'] and x['log_id'] < r['log_id']).orderby('log_id').raw_data[-1]['tr'] for r in den: if r['to'] in trs and r['from'] != target: trs[r['to']] += req.where(lambda x: x['from'] == r['to'] and x['to'] == r['from'] and x['log_id'] < r['log_id']).orderby('log_id').raw_data[-1]['tr'] return trs @staticmethod def read_from_json(json_path): """ 从json_path读取json文件,并返回Match :param json_path: path to json file """ json_string = '' with open(json_path, 'r', encoding='utf-8') as file: json_string = file.read() return Match(json_string)