CDash: Add comparison tables
[csit.git] / csit.infra.dash / app / cdash / utils / utils.py
index 461821d..6809998 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2022 Cisco and/or its affiliates.
+# Copyright (c) 2023 Cisco and/or its affiliates.
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at:
@@ -17,6 +17,7 @@
 import pandas as pd
 import dash_bootstrap_components as dbc
 
+from math import sqrt
 from numpy import isnan
 from dash import dcc
 from datetime import datetime
@@ -346,29 +347,73 @@ def set_job_params(df: pd.DataFrame, job: str) -> dict:
     }
 
 
-def get_list_group_items(tests: list) -> list:
-    """Generate list of ListGroupItems with checkboxes with selected tests.
-
-    :param tests: List of tests to be displayed in the ListGroup.
-    :type tests: list
-    :returns: List of ListGroupItems with checkboxes with selected tests.
+def get_list_group_items(
+        items: list,
+        type: str,
+        colorize: bool=True,
+        add_index: bool=False
+    ) -> list:
+    """Generate list of ListGroupItems with checkboxes with selected items.
+
+    :param items: List of items to be displayed in the ListGroup.
+    :param type: The type part of an element ID.
+    :param colorize: If True, the color of labels is set, otherwise the default
+        color is used.
+    :param add_index: Add index to the list items.
+    :type items: list
+    :type type: str
+    :type colorize: bool
+    :type add_index: bool
+    :returns: List of ListGroupItems with checkboxes with selected items.
     :rtype: list
     """
-    return [
-        dbc.ListGroupItem(
-            children=[
-                dbc.Checkbox(
-                    id={"type": "sel-cl", "index": i},
-                    label=l["id"],
-                    value=False,
-                    label_class_name="m-0 p-0",
-                    label_style={
-                        "font-size": ".875em",
-                        "color": get_color(i)
-                    },
-                    input_class_name="border-danger bg-danger"
-                )
-            ],
-            class_name="p-0"
-        ) for i, l in enumerate(tests)
-    ]
+
+    children = list()
+    for i, l in enumerate(items):
+        idx = f"{i + 1}. " if add_index else str()
+        label = f"{idx}{l['id']}" if isinstance(l, dict) else f"{idx}{l}"
+        children.append(
+            dbc.ListGroupItem(
+                children=[
+                    dbc.Checkbox(
+                        id={"type": type, "index": i},
+                        label=label,
+                        value=False,
+                        label_class_name="m-0 p-0",
+                        label_style={
+                            "font-size": ".875em",
+                            "color": get_color(i) if colorize else "#55595c"
+                        },
+                        class_name="info"
+                    )
+                ],
+                class_name="p-0"
+            )
+        )
+
+    return children
+
+def relative_change_stdev(mean1, mean2, std1, std2):
+    """Compute relative standard deviation of change of two values.
+
+    The "1" values are the base for comparison.
+    Results are returned as percentage (and percentual points for stdev).
+    Linearized theory is used, so results are wrong for relatively large stdev.
+
+    :param mean1: Mean of the first number.
+    :param mean2: Mean of the second number.
+    :param std1: Standard deviation estimate of the first number.
+    :param std2: Standard deviation estimate of the second number.
+    :type mean1: float
+    :type mean2: float
+    :type std1: float
+    :type std2: float
+    :returns: Relative change and its stdev.
+    :rtype: float
+    """
+    mean1, mean2 = float(mean1), float(mean2)
+    quotient = mean2 / mean1
+    first = std1 / mean1
+    second = std2 / mean2
+    std = quotient * sqrt(first * first + second * second)
+    return (quotient - 1) * 100, std * 100