162 lines
5.3 KiB
Python
162 lines
5.3 KiB
Python
"""
|
||
一场比赛的数据
|
||
"""
|
||
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)
|