def createSummarySection()

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))