def normalize(paths: List[str]) -> List[Record]:
	stats = readRecords(paths)
	pairList = sorted(makeThemPair(stats))

	results = []

	for base, opt in pairList:
		rec = Record(base.name, base.traceConfig, opt.ssdConfig, "normalized", 0, [{}])

		rec.latency = opt.latency / base.latency

		baseLastStat = max(base.statistics, key=lambda x: x["host_time"])
		optLastStat = max(opt.statistics, key=lambda x: x["host_time"])

		for key in [
			"cum_bandwidth",
			"ftl.page_mapping.gc.reclaimed_blocks",
			"ftl.page_mapping.valid_pages",
		]:
			baseValue, optValue = map(lambda x: x[key],
			                          [baseLastStat, optLastStat])
			try:
				normalized = optValue / baseValue
			except:
				normalized = float("nan")
			rec.statistics[0][key] = normalized
		
		rec.statistics[0]["WA"] = WA(optLastStat) / WA(baseLastStat)

		results.append(rec)

	return results
def calculateAverages(records: List[Record]):
	keyFunc = lambda x: (x.name, x.ssdConfig, x.scheme)
	avgs = []
	for (name, ssd, scheme), group in groupby(sorted(records, key=keyFunc),
	                                  key=keyFunc):
		group = list(group)
		avg = Record(name, f"average", ssd, scheme, 0, [{}])
		avg.latency = mean(i.latency for i in group)
		for key in records[0].statistics[0].keys():
			values = [i.statistics[0][key] for i in group if not isnan(i.statistics[0][key]) ]
			avg.statistics[0][key] = mean(values)

		avgs.append(avg)
	def sort_order(x: Record):
		cfg = [float(i) for i in x.ssdConfig.split(',')]
		return (x.traceConfig, cfg, x.name)
	return sorted(records, key=sort_order) + sorted(avgs, key=sort_order)