in lib/report.py [0:0]
def createSummarySection(self):
t = get_template("summary.html")
control=self.data["branches"][0]
row_background="white";
segments = []
for segment in self.data["segments"]:
numerical_metrics = []
categorical_metrics = []
for metric_type in ["histograms", "pageload_event_metrics"]:
for metric in self.data[metric_type]:
# Alternate between white and #ececec for row backgound.
row_background = flip_row_background(row_background)
if metric_type == "pageload_event_metrics":
kind = "numerical"
metric_name = f"pageload event: {metric}"
else:
kind = self.data[metric_type][metric]["kind"]
metric = metric.split(".")[-1]
metric_name = metric
# Generate summary for categorical histograms here.
if kind == "categorical":
branches = []
for branch in self.data["branches"]:
if "uplift" in self.data[branch][segment][metric_type][metric]:
rows = []
n_labels = len(self.data[branch][segment][metric_type][metric]["labels"])
for i in range(n_labels):
label = self.data[branch][segment][metric_type][metric]["labels"][i]
uplift = self.data[branch][segment][metric_type][metric]["uplift"][i]
# Enumerated histograms have a lot of labels, so try and limit the ones
# we show.
if n_labels > 5 and abs(uplift)<0.05:
continue
weight="font-weight:normal;"
if abs(uplift) >= 10:
effect = "Large"
weight = "font-weight:bold;"
elif abs(uplift) >= 5:
effect = "Medium"
weight = "font-weight:bold;"
elif abs(uplift) >= 2:
effect = "Small"
else:
effect = "None"
if uplift > 0:
uplift = "+{0:.2f}".format(self.data[branch][segment][metric_type][metric]["uplift"][i])
else:
uplift = "{0:.2f}".format(self.data[branch][segment][metric_type][metric]["uplift"][i])
uplift_desc=f"{label:<15}: {uplift}%"
rows.append({
"uplift": uplift_desc,
"effect": effect,
"weight": weight,
"style": f"background:{row_background};",
})
rows[-1]["style"] = rows[-1]["style"] + "border-bottom-style: solid;"
branches.append({
"branch": branch,
"style": f"background:{row_background};",
"branch_rowspan": len(rows),
"rows": rows
})
branches[-1]["style"] = branches[-1]["style"] + "border-bottom-style: solid;"
total_rowspan = 0
for i in range(len(branches)):
total_rowspan = total_rowspan + branches[i]["branch_rowspan"]
categorical_metrics.append({
"name": metric_name,
"desc": self.data[branch][segment][metric_type][metric]["desc"],
"style": f"background:{row_background}; border-bottom-style: solid; border-right-style: solid;",
"name_rowspan": total_rowspan,
"branches": branches
})
continue
# Generate summary for numerical histograms here.
datasets = []
for branch in self.data["branches"]:
if branch == control:
continue
mean = "{0:.1f}".format(self.data[branch][segment][metric_type][metric]["mean"])
std = "{0:.1f}".format(self.data[branch][segment][metric_type][metric]["std"])
branch_mean = self.data[branch][segment][metric_type][metric]["mean"]
control_mean = self.data[control][segment][metric_type][metric]["mean"]
uplift = (branch_mean-control_mean)/control_mean*100.0
if uplift > 0:
uplift_str = "+{0:.1f}".format(uplift)
else:
uplift_str = "{0:.1f}".format(uplift)
pval = self.data[branch][segment][metric_type][metric]["tests"]["mwu"]["p-value"]
effect_size = self.data[branch][segment][metric_type][metric]["tests"]["mwu"]["effect"]
effect_meaning = get_rank_biserial_corr_meaning(effect_size)
effect_size = "{0:.2f}".format(effect_size)
effect = f"{effect_meaning} (r={effect_size})"
if pval >= 0.001:
pval = "{0:.2f}".format(pval)
effect = f"None (p={pval})"
effect_meaning = "None"
if effect_meaning == "None" or effect_meaning == "Small":
color="font-weight: normal"
else:
if uplift >= 1.5:
color="font-weight: bold; color: red"
elif uplift <= -1.5:
color="font-weight: bold; color: green"
else:
color="font-weight: normal"
dataset = {
"branch": branch,
"mean": mean,
"uplift": uplift_str,
"std": std,
"effect": effect,
"color": color,
"style": f"background:{row_background};"
}
datasets.append(dataset);
datasets[-1]["style"] = datasets[-1]["style"] + "border-bottom-style:solid;"
numerical_metrics.append({ "desc": metric_name,
"name": metric,
"desc": self.data[branch][segment][metric_type][metric]["desc"],
"style": f"background:{row_background}; border-bottom-style:solid; border-right-style:solid;",
"datasets": datasets,
"rowspan": len(datasets)})
segments.append({
"name": segment,
"numerical_metrics": numerical_metrics,
"categorical_metrics": categorical_metrics
})
slug = self.data['slug']
is_experiment = self.data['is_experiment']
if is_experiment:
startDate = self.data['startDate']
endDate = self.data['endDate']
channel = self.data['channel']
else:
startDate = None,
endDate = None
channel = None
branches=[]
for i in range(len(self.data['input']['branches'])):
if is_experiment:
branchInfo = {
"name": self.data['input']['branches'][i]['name']
}
else:
branchInfo = {
"name": self.data['input']['branches'][i]['name'],
"startDate": self.data['input']['branches'][i]['startDate'],
"endDate": self.data['input']['branches'][i]['endDate'],
"channel": self.data['input']['branches'][i]['channel']
}
branches.append(branchInfo)
context = {
"slug": slug,
"is_experiment": is_experiment,
"startDate": startDate,
"endDate": endDate,
"channel": channel,
"branches": branches,
"segments": segments,
"branchlen": len(branches)
}
self.doc(t.render(context))