whylabs/whylogs-python

View on GitHub
python/examples/basic/Constraints_Suite.ipynb

Summary

Maintainability
Test Coverage
{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    ">### 🚩 *Create a free WhyLabs account to get more value out of whylogs!*<br> \n",
    ">*Did you know you can store, visualize, and monitor whylogs profiles with the [WhyLabs Observability Platform](https://whylabs.ai/whylogs-free-signup?utm_source=whylogs-Github&utm_medium=whylogs-example&utm_campaign=Constraints_Suite)? Sign up for a [free WhyLabs account](https://whylabs.ai/whylogs-free-signup?utm_source=whylogs-Github&utm_medium=whylogs-example&utm_campaign=Constraints_Suite) to leverage the power of whylogs and WhyLabs together!*"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Simple Constraints - Examples and Usage"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/whylabs/whylogs/blob/mainline/python/examples/basic/Constraints_Suite.ipynb)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> This is a `whylogs v1` example. For the analog feature in `v0`, please refer to [this example](https://github.com/whylabs/whylogs/blob/maintenance/0.7.x/examples/Constraints_Suite.ipynb)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this example, we'll show how to define a number of simple constraints and examples on how to use them. For the basics on how to build your own set of constraints, see the example - [Data Validation with Metric Constraints](https://whylogs.readthedocs.io/en/stable/examples/advanced/Metric_Constraints.html).\n",
    "\n",
    "The constraints are listed according to the metric namespace used when defining them. For each category, we will create helper functions for simple and popular constraints. Each helper function has a brief explanation in its docstring. After defining the helper functions, we'll show a simple example on how to build the constraints out of the functions and visualize them as a report with the visualization module."
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> Note: The constraints shown here are still experimental and subject to further changes. Stay tuned for upgrades!"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Completeness Constraints\n",
    "\n",
    "| constraint                   | parameters          | semantic                                              | metric |\n",
    "|------------------------------|---------------------|-------------------------------------------------------|--------|\n",
    "| no_missing_values            | column name         | Checks that are no missing values in the column       | Counts |\n",
    "| null_values_below_number     | column name, number | Number of null values must be below given number.     | Counts |\n",
    "| null_percentage_below_number | column name, number | Percentage of null values must be below given number. | Counts |"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Consistency Constraints\n",
    "\n",
    "| constraint                        | parameters                 | semantic                                                                               | metric         |\n",
    "|-----------------------------------|----------------------------|----------------------------------------------------------------------------------------|----------------|\n",
    "| greater_than_number               | column name                | Minimum value of given column must be above defined number.                            | Distribution   |\n",
    "| smaller_than_number               | column name, number        | Maximum value of given column must be below defined number.                            | Distribution   |\n",
    "| is_in_range                       | column name, lower, upper  | Checks that all of column's values are in defined range (inclusive).                   | Distribution   |\n",
    "| is_non_negative                   | column name                | Checks if a column is non negative.                                                    | Distribution   |\n",
    "| n_most_common_items_in_set        | column name, reference set | Checks if the top n most common items appear in the dataset.                           | Frequent Items |\n",
    "| frequent_strings_in_reference_set | column name, reference set | Checks if a set of variables appear in the frequent strings for a string column.       | Frequent Items |\n",
    "| count_below_number                | column name, number        | Checks if elements in a column are below given number.                                 | Counts         |\n",
    "| distinct_number_in_range          | column name, lower, upper  | Checks if number of distinct categories is between lower and upper values (inclusive). | Cardinality    |\n",
    "| column_is_nullable_integral       | column name                | Check if column contains only records of specific datatype.                            | Types          |\n",
    "| column_is_nullable_boolean        | column name                | Check if column contains only records of specific datatype.                            | Types          |\n",
    "| column_is_nullable_fractional     | column name                | Check if column contains only records of specific datatype.                            | Types          |\n",
    "| column_is_nullable_object         | column name                | Check if column contains only records of specific datatype.                            | Types          |\n",
    "| column_is_nullable_string         | column name                | Check if column contains only records of specific datatype.                            | Types          |"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Condition Count Constraints\n",
    "\n",
    "Please refer to the example [Metric Constraints with Condition Count Metrics](https://github.com/whylabs/whylogs/blob/mainline/python/examples/advanced/Metric_Constraints_with_Condition_Count_Metrics.ipynb) for examples on how to use these constraints.\n",
    "\n",
    "| constraint             | parameters                          | semantic                                                                             | metric       |\n",
    "|------------------------|-------------------------------------|--------------------------------------------------------------------------------------|--------------|\n",
    "| condition_meets     | column name, condition_name           | Fails if condition not met at least once.                        | Condition Count |\n",
    "| condition_never_meets   | column name, condition_name           | Fails if condition is met at least once          | Condition Count |\n",
    "| condition_count_below | column name, condition_name, max_count | Fails if condition is met more than max count | Condition Count |\n",
    "\n",
    "## Statistics Constraints\n",
    "\n",
    "| constraint             | parameters                          | semantic                                                                             | metric       |\n",
    "|------------------------|-------------------------------------|--------------------------------------------------------------------------------------|--------------|\n",
    "| mean_between_range     | column name, lower, upper           | Mean must be between range defined by lower and upper bounds.                        | Distribution |\n",
    "| stddev_between_range   | column name, lower, upper           | Standard deviarion must be between range defined by lower and upper bounds.          | Distribution |\n",
    "| quantile_between_range | column name, quantile, lower, upper | Q-th quantile value must be withing the range defined by lower and upper boundaries. | Distribution |"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Table of Contents\n",
    "\n",
    "- [Installing and Importing Modules](#pre)\n",
    "- [Distribution Metrics Constraints](#distribution)\n",
    "- [Frequent Items/Frequent Strings Metrics Constraints](#frequent)\n",
    "- [Counters Constraints](#counts)\n",
    "- [Cardinality Constraints](#card)\n",
    "- [Types Constraints](#types)\n",
    "- [Combined Metrics Constraints](#comb)\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Installing whylogs and importing modules <a class=\"anchor\" id=\"pre\"></a>\n",
    "\n",
    "If you haven't already, install whylogs:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Note: you may need to restart the kernel to use updated packages.\n",
    "%pip install 'whylogs[viz]'"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Then, let's import the helper functions needed to define the constraints:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from whylogs.core.constraints import ConstraintsBuilder\n",
    "from whylogs.core.constraints.factories import (\n",
    "    greater_than_number,\n",
    "    is_in_range,\n",
    "    is_non_negative,\n",
    "    mean_between_range,\n",
    "    smaller_than_number,\n",
    "    stddev_between_range,\n",
    "    quantile_between_range\n",
    ")"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Examples - Distribution Metrics Constraints"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import whylogs as why\n",
    "import pandas as pd\n",
    "data = {\n",
    "    \"animal\": [\"cat\", \"hawk\", \"snake\", \"cat\", \"mosquito\"],\n",
    "    \"legs\": [4, 2, 0, 4, 6],\n",
    "    \"weight\": [4.3, 1.8, 1.3, 4.1, 5.5e-6],\n",
    "}\n",
    "\n",
    "results = why.log(pd.DataFrame(data))\n",
    "profile_view = results.view()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div></div><iframe srcdoc=\"&lt;!DOCTYPE html&gt;\n",
       "&lt;html lang=&quot;en&quot;&gt;\n",
       "  &lt;head&gt;\n",
       "    &lt;meta charset=&quot;UTF-8&quot; /&gt;\n",
       "    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot; /&gt;\n",
       "    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;\n",
       "    &lt;meta name=&quot;description&quot; content=&quot;&quot; /&gt;\n",
       "    &lt;meta name=&quot;author&quot; content=&quot;&quot; /&gt;\n",
       "\n",
       "    &lt;title&gt;Profile Visualizer | whylogs&lt;/title&gt;\n",
       "\n",
       "    &lt;link rel=&quot;icon&quot; href=&quot;images/whylabs-favicon.png&quot; type=&quot;image/png&quot; sizes=&quot;16x16&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.googleapis.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; crossorigin /&gt;\n",
       "    &lt;link href=&quot;https://fonts.googleapis.com/css2?family=Asap:wght@400;500;600;700&amp;display=swap&quot; rel=&quot;stylesheet&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css&quot; /&gt;\n",
       "\n",
       "    &lt;script\n",
       "      src=&quot;https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js&quot;\n",
       "      integrity=&quot;sha512-RNLkV3d+aLtfcpEyFG8jRbnWHxUqVZozacROI4J2F1sTaDqo1dPQYs01OMi1t1w9Y2FdbSCDSQ2ZVdAC8bzgAg==&quot;\n",
       "      crossorigin=&quot;anonymous&quot;\n",
       "      referrerpolicy=&quot;no-referrer&quot;\n",
       "    &gt;&lt;/script&gt;\n",
       "\n",
       "    &lt;style type=&quot;text/css&quot;&gt;\n",
       "\n",
       "      /* Screen on smaller screens */\n",
       "      .no-responsive {\n",
       "        display: none;\n",
       "        position: fixed;\n",
       "        top: 0;\n",
       "        left: 0;\n",
       "        z-index: 1031;\n",
       "        width: 100vw;\n",
       "        height: 100vh;\n",
       "        background-color: var(--tealBackground);\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      @media screen and (min-width: 1000px) {\n",
       "        .desktop-content {\n",
       "          display: block;\n",
       "        }\n",
       "        .no-responsive {\n",
       "          display: none;\n",
       "        }\n",
       "      }\n",
       "\n",
       "      .no-responsive__content {\n",
       "        max-width: 600px;\n",
       "        width: 100%;\n",
       "        padding: 0 24px;\n",
       "      }\n",
       "\n",
       "      .no-responsive__title {\n",
       "        font-size: 96px;\n",
       "        font-weight: 300;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.167;\n",
       "      }\n",
       "\n",
       "      .no-responsive__text {\n",
       "        margin: 0;\n",
       "        font-size: 16px;\n",
       "        font-weight: 400;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.5;\n",
       "      }\n",
       "\n",
       "      .header-title {\n",
       "        font-size: 26px;\n",
       "        font-weight: 700;\n",
       "        color: #444444;\n",
       "      }\n",
       "\n",
       "      .tooltip-full-number {\n",
       "        position: relative;\n",
       "        display: inline-block;\n",
       "      }\n",
       "\n",
       "      .tooltip-full-number .tooltiptext {\n",
       "        visibility: hidden;\n",
       "        background: black;\n",
       "        color: white;\n",
       "        border: 1px solid black;\n",
       "        text-align: start;\n",
       "        padding: 3px;\n",
       "        position: absolute;\n",
       "        z-index: 1;\n",
       "        top: 0;\n",
       "        left: 100%;\n",
       "        margin-left: 5px;\n",
       "        opacity: 0;\n",
       "        transition: opacity 0.5s;\n",
       "        font-size: 13px;\n",
       "        font-weight: normal;\n",
       "        line-height: 100%;\n",
       "      }\n",
       "\n",
       "      .tooltip-full-number:hover .tooltiptext {\n",
       "        visibility: visible;\n",
       "        opacity: 1;\n",
       "      }\n",
       "\n",
       "\n",
       "      .wl-compare-profile {\n",
       "        position: relative;\n",
       "        left: 0;\n",
       "        padding: 30px;\n",
       "        margin-bottom: 20px;\n",
       "        background: var(--white);;\n",
       "        border-bottom: 1px solid #CED4DA;\n",
       "      }\n",
       "\n",
       "      .alert-list {\n",
       "        padding: 30px;\n",
       "        padding-top: 0;\n",
       "      }\n",
       "\n",
       "    .drift-detection {\n",
       "       justify-content: space-between;\n",
       "       align-items: center;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-circle {\n",
       "       width: 15px;\n",
       "       height: 15px;\n",
       "       border-radius: 50px;\n",
       "       display: inline-block;\n",
       "       margin-right: 8px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-drifts-item {\n",
       "         padding-right: 20px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-title {\n",
       "       font-family: Arial;\n",
       "       font-weight: bold;\n",
       "       font-size: 22px;\n",
       "       line-height: 130%;\n",
       "       color: #313B3D;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-drifts-item-count {\n",
       "       font-family: Arial;\n",
       "       font-weight: bold;\n",
       "       font-size: 14px;\n",
       "       line-height: 16px;\n",
       "       color: #000000;\n",
       "       padding-right: 8px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-drifts-item-name {\n",
       "       font-family: Arial;\n",
       "       font-style: normal;\n",
       "       font-weight: normal;\n",
       "       font-size: 12px;\n",
       "       line-height: 14px;\n",
       "       color: #000000;\n",
       "     }\n",
       "\n",
       "     .drift-detection-search-input {\n",
       "       display: flex;\n",
       "       align-items: center;\n",
       "       background: rgba(255, 255, 255, 0.7);\n",
       "       border: 1px solid #DBE5E7;\n",
       "       box-sizing: border-box;\n",
       "       border-radius: 4px;\n",
       "       width: 170px;\n",
       "       padding-left: 10px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-search-input img{\n",
       "       margin-right: 5px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-search-input input::placeholder {\n",
       "       font-family: Arial;\n",
       "       font-weight: normal;\n",
       "       font-size: 13px;\n",
       "       line-height: 16px;\n",
       "       color: #313B3D;\n",
       "     }\n",
       "\n",
       "     .dropdown-container {\n",
       "       position: absolute;\n",
       "       right: 30px;\n",
       "       top: 80px;\n",
       "       z-index: 999;\n",
       "       background: #FFFFFF;\n",
       "       border: 1px solid #DBE5E7;\n",
       "       box-sizing: border-box;\n",
       "       box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.05);\n",
       "       border-radius: 4px;\n",
       "       padding: 10px !important;\n",
       "       border: none !important;\n",
       "     }\n",
       "\n",
       "     .filter-options-title {\n",
       "       width: 240px;\n",
       "     }\n",
       "\n",
       "     .filter-options-title p {\n",
       "       margin: 0;\n",
       "     }\n",
       "\n",
       "     .form-check-input:checked {\n",
       "       background-color: #0E7384;\n",
       "       border-color: #0E7384;\n",
       "     }\n",
       "\n",
       "     .form-check-input[type=checkbox] {\n",
       "       border-radius: 2px;\n",
       "     }\n",
       "\n",
       "     .search-input{\n",
       "       padding-top: 0 !important;\n",
       "       padding-bottom: 0 !important;\n",
       "     }\n",
       "\n",
       "     .search-input input{\n",
       "       border: none;\n",
       "       background: none;\n",
       "       outline: none;\n",
       "       height: 40px;\n",
       "       width: 100%;\n",
       "       font-size: 14px;\n",
       "     }\n",
       "\n",
       "     .search-input img{\n",
       "       height: 19px;\n",
       "       pointer-events: none;\n",
       "     }\n",
       "\n",
       "     input::placeholder {\n",
       "       color: var(--secondaryLight1000);\n",
       "     }\n",
       "\n",
       "      .statistics {\n",
       "        width: 100%;\n",
       "      }\n",
       "\n",
       "     .close-filter-button {\n",
       "       display: flex;\n",
       "       justify-content: center;\n",
       "       align-items: center;\n",
       "       background: rgba(255, 255, 255, 0.7);\n",
       "       border: 1px solid #369BAC;\n",
       "       box-sizing: border-box;\n",
       "       border-radius: 4px;\n",
       "       width: 40px;\n",
       "       height: 40px;\n",
       "       cursor: pointer;\n",
       "       margin-left: 10px;\n",
       "     }\n",
       "\n",
       "      .statistic-number-title {\n",
       "        font-family: Arial;\n",
       "        font-weight: normal;\n",
       "        font-size: 14px;\n",
       "        line-height: 20px;\n",
       "        color: #6C757D;\n",
       "      }\n",
       "\n",
       "      .statistic-number {\n",
       "        font-family: Arial;\n",
       "        font-weight: bold;\n",
       "        font-size: 20px;\n",
       "        line-height: 140%;\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "        color: #4F595B;\n",
       "      }\n",
       "\n",
       "      .full-summary-statistics-wrap {\n",
       "        padding: 20px;\n",
       "      }\n",
       "\n",
       "      .statistics {\n",
       "        width: 100%;\n",
       "      }\n",
       "\n",
       "      .statistics-list {\n",
       "        width: 100% ;\n",
       "      }\n",
       "\n",
       "      mark {\n",
       "        padding: 5px;\n",
       "        border-radius: 4px;\n",
       "        font-family: Arial;\n",
       "        font-weight: normal;\n",
       "        font-size: 14px;\n",
       "        line-height: 140%;\n",
       "      }\n",
       "\n",
       "      .blue-mark {\n",
       "        background-color:  #369BAC1A;\n",
       "        color: #369BAC;\n",
       "      }\n",
       "\n",
       "      .red-mark {\n",
       "        background-color: #FFEFEE;\n",
       "        color: #F5473C;\n",
       "      }\n",
       "\n",
       "      .alert-tag {\n",
       "        height: 27px;\n",
       "        padding: 5px;\n",
       "        border-radius: 4px;\n",
       "        font-family: Arial;\n",
       "        font-weight: bold;\n",
       "        font-size: 12px;\n",
       "        line-height: 140%;\n",
       "        color: #FFFFFF;\n",
       "      }\n",
       "\n",
       "      .turquoise-background-color {\n",
       "        background-color: #1DBB42;\n",
       "      }\n",
       "\n",
       "      .bordeaux-background-color {\n",
       "        background-color: #C6462A;\n",
       "      }\n",
       "\n",
       "      .border-solid-gray {\n",
       "        border: 1px solid #CED4DA;\n",
       "        border-radius: 4px;\n",
       "      }\n",
       "\n",
       "      .display-flex {\n",
       "        display: flex;\n",
       "      }\n",
       "\n",
       "      .justify-content-space-between {\n",
       "        justify-content: space-between;\n",
       "      }\n",
       "\n",
       "      .justify-content-center {\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      .align-items-center {\n",
       "        align-items: center;\n",
       "      }\n",
       "\n",
       "      .align-items-flex-start {\n",
       "        align-items: flex-start;\n",
       "      }\n",
       "\n",
       "      .padding-right-30 {\n",
       "        padding-right: 30px;\n",
       "      }\n",
       "\n",
       "      .notif-circle-container{\n",
       "        position: absolute;\n",
       "        top: 25px;\n",
       "        right: 25px;\n",
       "        padding: 5.3px;\n",
       "        border-radius: 50%;\n",
       "        background-color: white;\n",
       "        cursor: pointer;\n",
       "      }\n",
       "\n",
       "      .notif-circle {\n",
       "        position: absolute;\n",
       "        top: 2px;\n",
       "        right: 2px;\n",
       "        padding: 3.3px;\n",
       "        border-radius: 50%;\n",
       "        background-color: #F2994A;\n",
       "      }\n",
       "\n",
       "      .alert-list-text {\n",
       "        width: 70%\n",
       "      }\n",
       "\n",
       "     @media screen and (min-width: 500px) {\n",
       "       .desktop-content {\n",
       "         display: block;\n",
       "       }\n",
       "       .no-responsive {\n",
       "         display: none;\n",
       "       }\n",
       "     }\n",
       "    &lt;/style&gt;\n",
       "  &lt;/head&gt;\n",
       "\n",
       "  &lt;body id=&quot;generated-html&quot;&gt;&lt;/body&gt;\n",
       "\n",
       "  &lt;script id=&quot;entry-template&quot; type=&quot;text/x-handlebars-template&quot;&gt;\n",
       "    \n",
       "      &lt;div class=&quot;desktop-content&quot;&gt;\n",
       "        &lt;div class=&quot;full-summary-statistics-wrap&quot;&gt;\n",
       "          &lt;div class=&quot;full-summary-statistics&quot;&gt;\n",
       "            &lt;div&gt;\n",
       "              &lt;div class=&quot;display-flex justify-content-center&quot;&gt;\n",
       "                &lt;div class=&quot;statistics-list border-solid-gray&quot;&gt;\n",
       "                  &lt;div&gt;\n",
       "                    &lt;div class=&quot;wl-compare-profile&quot; id=&quot;compare-profile&quot;&gt;\n",
       "                        &lt;div class=&quot;drift-detection-wrap&quot;&gt;\n",
       "                          &lt;div class=&quot;drift-detection display-flex align-items-flex-start&quot;&gt;\n",
       "                            &lt;div class=&quot;drift-detection-info flex-direction-colum&quot;&gt;\n",
       "                              &lt;div class=&quot;drift-detection-info-title-wrap display-flex&quot;&gt;\n",
       "                                &lt;p class=&quot;drift-detection-info-title&quot;&gt;\n",
       "                                  Constraints Report\n",
       "                                &lt;/p&gt;\n",
       "                              &lt;/div&gt;\n",
       "\n",
       "                              &lt;!-- &lt;/div&gt; --&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;div class=&quot;drift-detection-search-input-wrap display-flex&quot;&gt;\n",
       "                              &lt;div class=&quot;drift-detection-search-input search-input&quot;&gt;\n",
       "                                &lt;input type=&quot;text&quot; id=&quot;wl__feature-search&quot; placeholder=&quot;Quick search...&quot;/&gt;\n",
       "                                &lt;img src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAGdSURBVHgBpZK7TkJBEIZnZoVocdTYyQNALxpNKPQBMEaNJsbCRMKhl8ISWwt6AaksCF5iTHgAGhJD4AHkAaAzGiwUsjvOQnO4SYh/cXbPzO43OxcEj9Zy92EiFSXNIfvPyE1kKFfdoxJMENpP6DrvLC0vJoEwCgwto7DWcxoIIHBYbA3NmKwnDltjAeuZhyul1DaTTlfPB6Nt5Z53DOgky4P875+nlctY2+unjZviLklkJhi5bPUa3y/7qJuQUM7PinMy7CdQc1Gh16vnBxPzrMROmlKQEgKNASAHLQCmSIGpS75O+O5pdQAgVXaIqTkNwDDXHmcnW3VmHZoGMLoTsOt88+NrAMCIZdu+iLTyTwKRa1Md6YKfOgXbzO7K8sWku5u5RxcRV5EpPezrzcHGbXEXWaUkgkweZ/UC9YrK3zqggFw5FBZfm8EUavHj7AjAKpIvBDrGn+pNnlcyhYgqbcC41idr1gvB4SdZkDbzQa21gwv0Vj07aPTtL07XdDOyDXohCDNoHIRmAVRie20f+RKybRDQDvxHkXy/7b/DrayncLbMwQAAAABJRU5ErkJggg==&quot;/&gt;\n",
       "                              &lt;/div&gt;\n",
       "                              &lt;div class=&quot;wl__dropdown_arrow-icon&quot;&gt;\n",
       "                                &lt;div onclick=&quot;openFilter()&quot; class=&quot;close-filter-button&quot;&gt;\n",
       "                                &lt;div class=&quot;display-flex close-filter-icon d-none&quot;&gt;\n",
       "                                  &lt;img src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAADFSURBVHgBfY+xDcIwEEXvnLQBZQkYAEhDwwKpEEK0CCZgAEjJCEmgjYSAygxAHTZgFRSOsyUjY5mcZFnn/+78PwBXf3+MoKWUPuYjVBPFnTwpr9t/oNJfcTfXsAhRAlDqDhhQIPYgpAqNMDqcUqSAYZT1epr9gAHt6uXshvYme4DYHQJNDKh0dD0m5WXB10Y3Fqjtuh7fROn3oREDWxfeMLyRsMnc0OgDzdduaA0Pi3Plgr7Q2kaAePeBqh6rueSNBVt6fgCwBV1JLF3rlAAAAABJRU5ErkJggg==&quot;/&gt;\n",
       "                                &lt;/div&gt;\n",
       "                                &lt;div class=&quot;display-flex filter-icon&quot;&gt;\n",
       "                                  &lt;img src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACSSURBVHgBrZLBCYAwDEWTUjw7igcdwI1cxkNXUJzBEVzFAbSVKoKmaVrEB6GHJv/w+AACtRk7P9IONv1QOYUl96k0zv61m2tjARoLtSDI3EFsgIJ4uoXrMLazO72CRG2mzg/8BSdVlEjhpGZJjAWdAZJECpWalEhJSs1pHuUlMad5FFai1Lwg4Ckx1TxKIPFL8w55mEWd8VjPGAAAAABJRU5ErkJggg==&quot;/&gt;\n",
       "                                &lt;/div&gt;\n",
       "                                &lt;/div&gt;\n",
       "                              &lt;span class=&quot;notif-circle-container&quot;&gt;\n",
       "                                &lt;span class=&quot;notif-circle&quot;&gt;&lt;/span&gt;\n",
       "                              &lt;/span&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;/div&gt;\n",
       "                          &lt;/div&gt;\n",
       "                        &lt;/div&gt;\n",
       "                        &lt;div class=&quot;dropdown-container flex-direction-colum mb-2 d-none&quot; id=&quot;dropdown-container&quot;&gt;\n",
       "                          &lt;div class=&quot;filter-options&quot;&gt;\n",
       "                            &lt;div class=&quot;filter-options-title space-between dropdown&quot;&gt;\n",
       "                              &lt;p&gt;Select a view:&lt;/p&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;div class=&quot;form-check mb-1 mt-2&quot;&gt;\n",
       "                              &lt;input\n",
       "                                class=&quot;form-check-input wl__feature-filter-input&quot;\n",
       "                                type=&quot;checkbox&quot;\n",
       "                                name=&quot;checkbox&quot;\n",
       "                                value=&quot;Discrete&quot;\n",
       "                                id=&quot;inferredDiscrete&quot;\n",
       "                                checked\n",
       "                              /&gt;\n",
       "                              &lt;label class=&quot;form-check-label&quot; for=&quot;inferredDiscrete&quot;&gt;\n",
       "                                Failed constraints (&lt;span class=&quot;wl__feature-count--discrete&quot;&gt;&lt;/span&gt;)\n",
       "                              &lt;/label&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;div class=&quot;form-check mb-1&quot;&gt;\n",
       "                              &lt;input\n",
       "                                class=&quot;form-check-input wl__feature-filter-input&quot;\n",
       "                                type=&quot;checkbox&quot;\n",
       "                                name=&quot;checkbox&quot;\n",
       "                                value=&quot;Non-discrete&quot;\n",
       "                                id=&quot;inferredNonDiscrete&quot;\n",
       "                                checked\n",
       "                              /&gt;\n",
       "                              &lt;label class=&quot;form-check-label&quot; for=&quot;inferredNonDiscrete&quot;&gt;\n",
       "                                Passed constraints (&lt;span\n",
       "                                  class=&quot;wl__feature-count--non-discrete&quot;\n",
       "                                &gt;&lt;/span&gt;)\n",
       "                              &lt;/label&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;div class=&quot;form-check mb-1&quot;&gt;\n",
       "                              &lt;input\n",
       "                                class=&quot;form-check-input wl__feature-filter-input&quot;\n",
       "                                type=&quot;checkbox&quot;\n",
       "                                name=&quot;checkbox&quot;\n",
       "                                value=&quot;Unknown&quot;\n",
       "                                id=&quot;inferredUnknown&quot;\n",
       "                                checked\n",
       "                              /&gt;\n",
       "                              &lt;label class=&quot;form-check-label&quot; for=&quot;inferredUnknown&quot;&gt;\n",
       "                                All constraints (&lt;span class=&quot;wl__feature-count--unknown&quot;&gt;&lt;/span&gt;)\n",
       "                              &lt;/label&gt;\n",
       "                            &lt;/div&gt;\n",
       "                          &lt;/div&gt;\n",
       "                        &lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                    &lt;div class=&quot;alert-list&quot; id=&quot;alert-list&quot;&gt;\n",
       "                      {{{alertLIst this}}}\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                &lt;/div&gt;\n",
       "              &lt;/div&gt;\n",
       "            &lt;/div&gt;\n",
       "          &lt;/div&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "      &lt;div class=&quot;no-responsive&quot;&gt;\n",
       "        &lt;div class=&quot;no-responsive__content&quot;&gt;\n",
       "          &lt;h1 class=&quot;no-responsive__title&quot;&gt;Hold on! :)&lt;/h1&gt;\n",
       "          &lt;p class=&quot;no-responsive__text&quot;&gt;\n",
       "            It looks like your current screen size or device is not yet supported by the WhyLabs Sandbox. The Sandbox is\n",
       "            best experienced on a desktop computer. Please try maximizing this window or switching to another device. We\n",
       "            are working on adding support for a larger variety of devices.\n",
       "          &lt;/p&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "    \n",
       "  &lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://code.jquery.com/jquery-3.6.0.min.js&quot; integrity=&quot;sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js&quot; integrity=&quot;sha512-cd6CHE+XWDQ33ElJqsi0MdNte3S+bQY819f7p3NUHgwQQLXSKjE4cPZTeGNI+vaxZynk1wVU3hoHmow3m089wA==&quot; crossorigin=&quot;anonymous&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script&gt;\n",
       "    function registerHandlebarHelperFunctions() {\n",
       "      //helper fun\n",
       "      function formatLabelDate(timestamp) {\n",
       "        const date = new Date(timestamp);\n",
       "        const format = d3.timeFormat(&quot;%Y-%m-%d %I:%M:%S %p %Z&quot;);\n",
       "        return format(date);\n",
       "      }\n",
       "\n",
       "      function fixNumberTo(number, decimals = 3) {\n",
       "        return parseFloat(number).toFixed(decimals);\n",
       "      }\n",
       "\n",
       "      const randomNumbers = (range) =&gt; Math.floor(Math.random() * range)\n",
       "\n",
       "      const findFetureWithNumberSummary = (column) =&gt; {\n",
       "        const fetureIndex = Object.values(column.columns)\n",
       "              .findIndex((feture) =&gt; feture.numberSummary)\n",
       "\n",
       "        return Object.keys(column.columns)[fetureIndex]\n",
       "      }\n",
       "\n",
       "      const alertListItemStatus = (status, passedItem, failedItem) =&gt; {\n",
       "        if (status) {\n",
       "          return passedItem\n",
       "        } else {\n",
       "          return failedItem\n",
       "        }\n",
       "      }\n",
       "\n",
       "      const alertListElement = (name, text, status, summary) =&gt; {\n",
       "        if (summary == null){\n",
       "          return (\n",
       "          `&lt;div\n",
       "             data-inferred-type=${alertListItemStatus(status, &quot;passed&quot;, &quot;failed&quot;)}\n",
       "             class=&quot;alert-list-item display-flex justify-content-space-between align-items-center mb-2&quot;\n",
       "           &gt;\n",
       "            &lt;div class=&quot;alert-list-text&quot;&gt;\n",
       "              ${\n",
       "                name &amp;&amp;\n",
       "                alertListItemStatus(\n",
       "                  status,\n",
       "                  `&lt;mark class=&quot;blue-mark&quot;&gt;${name}&lt;/mark&gt;`,\n",
       "                  `&lt;mark class=&quot;red-mark&quot;&gt;${name}&lt;/mark&gt;`\n",
       "                )\n",
       "              }\n",
       "              ${text}\n",
       "            &lt;/div&gt;\n",
       "              ${\n",
       "                alertListItemStatus(\n",
       "                  status,\n",
       "                  `\n",
       "                  &lt;div class=&quot;turquoise-background-color alert-tag&quot;&gt;Passed&lt;/div&gt;\n",
       "                  `\n",
       "                  ,\n",
       "                  `\n",
       "                  &lt;div class=&quot;bordeaux-background-color alert-tag&quot;&gt;Failed&lt;/div&gt;\n",
       "                  `\n",
       "                )\n",
       "              }\n",
       "              &lt;/div&gt;`\n",
       "        )\n",
       "\n",
       "        }\n",
       "        return (\n",
       "          `&lt;div\n",
       "             data-inferred-type=${alertListItemStatus(status, &quot;passed&quot;, &quot;failed&quot;)}\n",
       "             class=&quot;alert-list-item display-flex justify-content-space-between align-items-center mb-2&quot;\n",
       "           &gt;\n",
       "            &lt;div class=&quot;alert-list-text&quot;&gt;\n",
       "              ${\n",
       "                name &amp;&amp;\n",
       "                alertListItemStatus(\n",
       "                  status,\n",
       "                  `&lt;mark class=&quot;blue-mark&quot;&gt;${name}&lt;/mark&gt;`,\n",
       "                  `&lt;mark class=&quot;red-mark&quot;&gt;${name}&lt;/mark&gt;`\n",
       "                )\n",
       "              }\n",
       "              ${text}\n",
       "            &lt;/div&gt;\n",
       "              ${\n",
       "                alertListItemStatus(\n",
       "                  status,\n",
       "                  `\n",
       "                  &lt;div class=&quot;tooltip-full-number&quot;&gt;\n",
       "                    &lt;div class=&quot;turquoise-background-color alert-tag&quot;&gt;Passed\n",
       "                      &lt;span class=&quot;tooltiptext&quot;&gt;\n",
       "                          &lt;pre class=&quot;mb-1&quot;&gt; ${JSON.stringify(summary, null, 2)} &lt;/pre&gt;\n",
       "                        &lt;/span&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;`\n",
       "\n",
       "                  ,\n",
       "                  `\n",
       "                  &lt;div class=&quot;tooltip-full-number&quot;&gt;\n",
       "                    &lt;div class=&quot;bordeaux-background-color alert-tag&quot;&gt;Failed\n",
       "                      &lt;span class=&quot;tooltiptext&quot;&gt;\n",
       "                        &lt;pre class=&quot;mb-1&quot;&gt; ${JSON.stringify(summary, null, 2)} &lt;/pre&gt;\n",
       "                        &lt;/span&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;`\n",
       "                )\n",
       "              }\n",
       "              &lt;/div&gt;`\n",
       "        )\n",
       "      }\n",
       "\n",
       "      let failedConstraints = 0;\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getProfileTimeStamp&quot;, function (column) {\n",
       "        return formatLabelDate(+column.properties.dataTimestamp)\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getProfileName&quot;, function (column) {\n",
       "        return column.properties.tags.name\n",
       "      });\n",
       "\n",
       "\n",
       "      Handlebars.registerHelper(&quot;alertLIst&quot;, function (column) {\n",
       "        let alertListItem = column.map((value) =&gt; {\n",
       "          if (value[1][0]) {\n",
       "            let alertListValue = value[1].map((cstr)=&gt;{\n",
       "              return alertListElement(value[0],cstr[0],cstr[cstr.length - 1] === 0 || (failedConstraints++, false), value[3])\n",
       "            })\n",
       "            return alertListValue.join(&#x27; &#x27;)\n",
       "          } else {\n",
       "            return alertListElement(&#x27;&#x27;, value[0], value[2] === 0 ||  (failedConstraints++, false), value[3])\n",
       "          }\n",
       "        })\n",
       "         $(document).ready(() =&gt; {\n",
       "           $(&quot;.wl__feature-count--discrete&quot;).append(failedConstraints)\n",
       "           $(&quot;.wl__feature-count--non-discrete&quot;).append(column.length - failedConstraints)\n",
       "           $(&quot;.wl__feature-count--unknown&quot;).append(column.length)\n",
       "         })\n",
       "        return alertListItem.join(&#x27; &#x27;)\n",
       "      });\n",
       "\n",
       "    }\n",
       "\n",
       "    function openFilter() {\n",
       "      const $filterOptions = $(&quot;.dropdown-container&quot;);\n",
       "      const filterClass = $filterOptions.attr(&quot;class&quot;);\n",
       "\n",
       "      if (filterClass.indexOf(&quot;d-none&quot;) &gt; 0) {\n",
       "        $filterOptions.removeClass(&quot;d-none&quot;);\n",
       "        $(&quot;.filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.close-filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "      } else {\n",
       "        $filterOptions.addClass(&quot;d-none&quot;);\n",
       "        $(&quot;.close-filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "      }\n",
       "    }\n",
       "\n",
       "    function initHandlebarsTemplate() {\n",
       "      // Replace this context with JSON from .py file\n",
       "      const context = [[&quot;weight greater than number 0.14&quot;, 0, 1, {&quot;metric&quot;: &quot;distribution&quot;, &quot;mean&quot;: 2.3000011000000002, &quot;stddev&quot;: 1.8560694154600064, &quot;n&quot;: 5, &quot;max&quot;: 4.3, &quot;min&quot;: 5.5e-06, &quot;q_01&quot;: 5.5e-06, &quot;q_05&quot;: 5.5e-06, &quot;q_10&quot;: 5.5e-06, &quot;q_25&quot;: 1.3, &quot;median&quot;: 1.8, &quot;q_75&quot;: 4.1, &quot;q_90&quot;: 4.3, &quot;q_95&quot;: 4.3, &quot;q_99&quot;: 4.3}], [&quot;weight mean between 2 and 3 (inclusive)&quot;, 1, 0, {&quot;metric&quot;: &quot;distribution&quot;, &quot;mean&quot;: 2.3000011000000002, &quot;stddev&quot;: 1.8560694154600064, &quot;n&quot;: 5, &quot;max&quot;: 4.3, &quot;min&quot;: 5.5e-06, &quot;q_01&quot;: 5.5e-06, &quot;q_05&quot;: 5.5e-06, &quot;q_10&quot;: 5.5e-06, &quot;q_25&quot;: 1.3, &quot;median&quot;: 1.8, &quot;q_75&quot;: 4.1, &quot;q_90&quot;: 4.3, &quot;q_95&quot;: 4.3, &quot;q_99&quot;: 4.3}], [&quot;weight smaller than number 20.5&quot;, 1, 0, {&quot;metric&quot;: &quot;distribution&quot;, &quot;mean&quot;: 2.3000011000000002, &quot;stddev&quot;: 1.8560694154600064, &quot;n&quot;: 5, &quot;max&quot;: 4.3, &quot;min&quot;: 5.5e-06, &quot;q_01&quot;: 5.5e-06, &quot;q_05&quot;: 5.5e-06, &quot;q_10&quot;: 5.5e-06, &quot;q_25&quot;: 1.3, &quot;median&quot;: 1.8, &quot;q_75&quot;: 4.1, &quot;q_90&quot;: 4.3, &quot;q_95&quot;: 4.3, &quot;q_99&quot;: 4.3}], [&quot;weight standard deviation between 1 and 3 (inclusive)&quot;, 1, 0, {&quot;metric&quot;: &quot;distribution&quot;, &quot;mean&quot;: 2.3000011000000002, &quot;stddev&quot;: 1.8560694154600064, &quot;n&quot;: 5, &quot;max&quot;: 4.3, &quot;min&quot;: 5.5e-06, &quot;q_01&quot;: 5.5e-06, &quot;q_05&quot;: 5.5e-06, &quot;q_10&quot;: 5.5e-06, &quot;q_25&quot;: 1.3, &quot;median&quot;: 1.8, &quot;q_75&quot;: 4.1, &quot;q_90&quot;: 4.3, &quot;q_95&quot;: 4.3, &quot;q_99&quot;: 4.3}], [&quot;weight 0.5-th quantile value between 1.5 and 2.0 (inclusive)&quot;, 1, 0, {&quot;metric&quot;: &quot;distribution&quot;, &quot;mean&quot;: 2.3000011000000002, &quot;stddev&quot;: 1.8560694154600064, &quot;n&quot;: 5, &quot;max&quot;: 4.3, &quot;min&quot;: 5.5e-06, &quot;q_01&quot;: 5.5e-06, &quot;q_05&quot;: 5.5e-06, &quot;q_10&quot;: 5.5e-06, &quot;q_25&quot;: 1.3, &quot;median&quot;: 1.8, &quot;q_75&quot;: 4.1, &quot;q_90&quot;: 4.3, &quot;q_95&quot;: 4.3, &quot;q_99&quot;: 4.3}], [&quot;weight is in range [1.1,3.2]&quot;, 0, 1, {&quot;metric&quot;: &quot;distribution&quot;, &quot;mean&quot;: 2.3000011000000002, &quot;stddev&quot;: 1.8560694154600064, &quot;n&quot;: 5, &quot;max&quot;: 4.3, &quot;min&quot;: 5.5e-06, &quot;q_01&quot;: 5.5e-06, &quot;q_05&quot;: 5.5e-06, &quot;q_10&quot;: 5.5e-06, &quot;q_25&quot;: 1.3, &quot;median&quot;: 1.8, &quot;q_75&quot;: 4.1, &quot;q_90&quot;: 4.3, &quot;q_95&quot;: 4.3, &quot;q_99&quot;: 4.3}], [&quot;legs is in range [0,6]&quot;, 1, 0, {&quot;metric&quot;: &quot;distribution&quot;, &quot;mean&quot;: 3.2, &quot;stddev&quot;: 2.280350850198276, &quot;n&quot;: 5, &quot;max&quot;: 6.0, &quot;min&quot;: 0.0, &quot;q_01&quot;: 0.0, &quot;q_05&quot;: 0.0, &quot;q_10&quot;: 0.0, &quot;q_25&quot;: 2.0, &quot;median&quot;: 4.0, &quot;q_75&quot;: 4.0, &quot;q_90&quot;: 6.0, &quot;q_95&quot;: 6.0, &quot;q_99&quot;: 6.0}], [&quot;legs is non negative&quot;, 1, 0, {&quot;metric&quot;: &quot;distribution&quot;, &quot;mean&quot;: 3.2, &quot;stddev&quot;: 2.280350850198276, &quot;n&quot;: 5, &quot;max&quot;: 6.0, &quot;min&quot;: 0.0, &quot;q_01&quot;: 0.0, &quot;q_05&quot;: 0.0, &quot;q_10&quot;: 0.0, &quot;q_25&quot;: 2.0, &quot;median&quot;: 4.0, &quot;q_75&quot;: 4.0, &quot;q_90&quot;: 6.0, &quot;q_95&quot;: 6.0, &quot;q_99&quot;: 6.0}], [&quot;animal 0.5-th quantile value between 1.5 and 2.0 (inclusive)&quot;, 0, 1, null]];\n",
       "      // Config handlebars and pass data to HBS template\n",
       "      const source = document.getElementById(&quot;entry-template&quot;).innerHTML;\n",
       "      const template = Handlebars.compile(source);\n",
       "      const html = template(context);\n",
       "      const target = document.getElementById(&quot;generated-html&quot;);\n",
       "      target.innerHTML = html;\n",
       "    }\n",
       "\n",
       "    function initWebsiteScripts() {\n",
       "      const $featureSearch = document.getElementById(&quot;wl__feature-search&quot;);\n",
       "      const $alertList = document.getElementById(&quot;alert-list&quot;);\n",
       "      const $discrete = document.getElementById(&quot;inferredDiscrete&quot;);\n",
       "      const $nonDiscrete = document.getElementById(&quot;inferredNonDiscrete&quot;);\n",
       "      const $unknown = document.getElementById(&quot;inferredUnknown&quot;);\n",
       "\n",
       "      const activeTypes = {\n",
       "        passed: true,\n",
       "        failed: true\n",
       "      };\n",
       "\n",
       "      let searchString = &quot;&quot;;\n",
       "\n",
       "      function debounce(func, wait, immediate) {\n",
       "        let timeout;\n",
       "\n",
       "        return function () {\n",
       "          const context = this;\n",
       "          const args = arguments;\n",
       "          const later = function () {\n",
       "            timeout = null;\n",
       "            if (!immediate) func.apply(context, args);\n",
       "          };\n",
       "\n",
       "          const callNow = immediate &amp;&amp; !timeout;\n",
       "          clearTimeout(timeout);\n",
       "          timeout = setTimeout(later, wait);\n",
       "          if (callNow) func.apply(context, args);\n",
       "        };\n",
       "      }\n",
       "\n",
       "      function filterNotification() {\n",
       "        const $notifCircleContainer = $(&quot;.notif-circle-container&quot;)\n",
       "        const $boxes = $(&#x27;.wl_filter-options&gt;.form-check&gt;input[name=checkbox]:checked&#x27;);\n",
       "        const item = Object.values($boxes).find(function(value) { return $(value)[0] === undefined});\n",
       "        if (item === undefined) {\n",
       "          $notifCircleContainer.removeClass(&quot;d-none&quot;)\n",
       "        } else {\n",
       "          $notifCircleContainer.addClass(&quot;d-none&quot;)\n",
       "        }\n",
       "      }\n",
       "\n",
       "      function handleSearch() {\n",
       "        const tableBodyChildren = $alertList.children;\n",
       "\n",
       "        for (let i = 0; i &lt; tableBodyChildren.length; i++) {\n",
       "          const type = tableBodyChildren[i].dataset.inferredType.toLowerCase();\n",
       "          const name = $(tableBodyChildren[i].children[0]).html().toLowerCase();\n",
       "          if (activeTypes[type] &amp;&amp; name.includes(searchString)) {\n",
       "            tableBodyChildren[i].style.display = &quot;&quot;;\n",
       "          } else {\n",
       "            tableBodyChildren[i].style.display = &quot;none&quot;;\n",
       "          }\n",
       "        }\n",
       "      }\n",
       "\n",
       "      const checkedBoxes = () =&gt; {\n",
       "        if ($(&#x27;.form-check-input:checked&#x27;).length === $(&quot;.form-check-input&quot;).length - 1) {\n",
       "          $($(&quot;.form-check-input&quot;)[$(&quot;.form-check-input&quot;).length - 1]).prop( &quot;checked&quot;, true );\n",
       "        }\n",
       "      }\n",
       "\n",
       "      $featureSearch.addEventListener(\n",
       "        &quot;keyup&quot;,\n",
       "        debounce((event) =&gt; {\n",
       "          searchString = event.target.value.toLowerCase();\n",
       "          handleSearch();\n",
       "        }, 100),\n",
       "      );\n",
       "\n",
       "      $discrete.addEventListener(&quot;change&quot;, (event) =&gt; {\n",
       "        const currentCheckbox = $(event.currentTarget);\n",
       "\n",
       "        if (event.currentTarget.checked) {\n",
       "          activeTypes[&quot;failed&quot;] = true;\n",
       "          checkedBoxes();\n",
       "        } else {\n",
       "          activeTypes[&quot;failed&quot;] = false;\n",
       "          $($(&quot;.form-check-input&quot;)[$(&quot;.form-check-input&quot;).length - 1]).prop( &quot;checked&quot;, false );\n",
       "        }\n",
       "        handleSearch();\n",
       "      });\n",
       "\n",
       "      $nonDiscrete.addEventListener(&quot;change&quot;, (event) =&gt; {\n",
       "        const currentCheckbox = $(event.currentTarget);\n",
       "\n",
       "        if (event.currentTarget.checked) {\n",
       "          activeTypes[&quot;passed&quot;] = true;\n",
       "          checkedBoxes();\n",
       "        } else {\n",
       "          activeTypes[&quot;passed&quot;] = false;\n",
       "          $($(&quot;.form-check-input&quot;)[$(&quot;.form-check-input&quot;).length - 1]).prop( &quot;checked&quot;, false );\n",
       "        }\n",
       "        handleSearch();\n",
       "      });\n",
       "\n",
       "      $unknown.addEventListener(&quot;change&quot;, (event) =&gt; {\n",
       "        const currentCheckbox = $(event.currentTarget);\n",
       "\n",
       "        if (event.currentTarget.checked) {\n",
       "          $(&quot;.form-check-input&quot;).prop( &quot;checked&quot;, true );\n",
       "          activeTypes[&quot;passed&quot;] = true;\n",
       "          activeTypes[&quot;failed&quot;] = true;\n",
       "          checkedBoxes();\n",
       "        } else {\n",
       "          $(&quot;.form-check-input&quot;).prop( &quot;checked&quot;, false );\n",
       "          activeTypes[&quot;passed&quot;] = false;\n",
       "          activeTypes[&quot;failed&quot;] = false;\n",
       "        }\n",
       "        handleSearch();\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function checkedBoxes() {\n",
       "      const $boxes = $(&#x27;input[name=checkbox]:checked&#x27;);\n",
       "      const $notifCircleContainer = $(&quot;.notif-circle-container&quot;)\n",
       "\n",
       "      if ($boxes.length) {\n",
       "        $notifCircleContainer.removeClass(&quot;d-none&quot;)\n",
       "      }\n",
       "    }\n",
       "\n",
       "    function openFilter() {\n",
       "      const $filterOptions = $(&quot;.dropdown-container&quot;);\n",
       "      const $notifCircleContainer = $(&quot;.notif-circle-container&quot;)\n",
       "      const filterClass = $filterOptions.attr(&quot;class&quot;);\n",
       "\n",
       "      if (filterClass.indexOf(&quot;d-none&quot;) &gt; 0) {\n",
       "        $notifCircleContainer.addClass(&quot;d-none&quot;)\n",
       "        $filterOptions.removeClass(&quot;d-none&quot;);\n",
       "        $(&quot;.filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.close-filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "      } else {\n",
       "        $filterOptions.addClass(&quot;d-none&quot;);\n",
       "        $(&quot;.close-filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "        checkedBoxes()\n",
       "      }\n",
       "    }\n",
       "\n",
       "    // Invoke functions -- keep in mind invokation order\n",
       "    registerHandlebarHelperFunctions();\n",
       "    initHandlebarsTemplate();\n",
       "    initWebsiteScripts();\n",
       "  &lt;/script&gt;\n",
       "&lt;/html&gt;\n",
       "\" width=100% height=300\n",
       "        frameBorder=0></iframe>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "builder = ConstraintsBuilder(dataset_profile_view=profile_view)\n",
    "builder.add_constraint(greater_than_number(column_name=\"weight\", number=0.14))\n",
    "builder.add_constraint(mean_between_range(column_name=\"weight\", lower=2, upper=3))\n",
    "builder.add_constraint(smaller_than_number(column_name=\"weight\", number=20.5))\n",
    "builder.add_constraint(stddev_between_range(column_name=\"weight\", lower=1, upper=3))\n",
    "builder.add_constraint(quantile_between_range(column_name=\"weight\", quantile=0.5, lower=1.5, upper=2.0))\n",
    "builder.add_constraint(is_in_range(column_name=\"weight\", lower=1.1, upper=3.2))\n",
    "builder.add_constraint(is_in_range(column_name=\"legs\", lower=0, upper=6))\n",
    "builder.add_constraint(is_non_negative(column_name=\"legs\"))\n",
    "\n",
    "# animal has missing distribution metrics. this will pass if skip_missing = True and fail otherwise.\n",
    "builder.add_constraint(\n",
    "    quantile_between_range(\n",
    "        column_name=\"animal\", \n",
    "        quantile=0.5, \n",
    "        lower=1.5, \n",
    "        upper=2.0, \n",
    "        skip_missing=False\n",
    "    )\n",
    ")\n",
    "\n",
    "constraints = builder.build()\n",
    "\n",
    "from whylogs.viz import NotebookProfileVisualizer\n",
    "\n",
    "visualization = NotebookProfileVisualizer()\n",
    "visualization.constraints_report(constraints, cell_height=300)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Frequent Items/Frequent Strings Constraints <a class=\"anchor\" id=\"frequent\"></a>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "from whylogs.core.constraints.factories import n_most_common_items_in_set, frequent_strings_in_reference_set"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Examples - Frequent Items/Frequent Strings Constraints"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "import whylogs as why\n",
    "import pandas as pd\n",
    "data = {\n",
    "    \"animal\": [\"cat\", \"snake\", \"snake\", \"cat\", \"mosquito\"],\n",
    "    \"legs\": [0, 1, 2, 3, 4],\n",
    "    \"weight\": [4.3, 1.8, 1.3, 4.1, 5.5e-6],\n",
    "}\n",
    "\n",
    "results = why.log(pd.DataFrame(data))\n",
    "profile_view = results.view()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div></div><iframe srcdoc=\"&lt;!DOCTYPE html&gt;\n",
       "&lt;html lang=&quot;en&quot;&gt;\n",
       "  &lt;head&gt;\n",
       "    &lt;meta charset=&quot;UTF-8&quot; /&gt;\n",
       "    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot; /&gt;\n",
       "    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;\n",
       "    &lt;meta name=&quot;description&quot; content=&quot;&quot; /&gt;\n",
       "    &lt;meta name=&quot;author&quot; content=&quot;&quot; /&gt;\n",
       "\n",
       "    &lt;title&gt;Profile Visualizer | whylogs&lt;/title&gt;\n",
       "\n",
       "    &lt;link rel=&quot;icon&quot; href=&quot;images/whylabs-favicon.png&quot; type=&quot;image/png&quot; sizes=&quot;16x16&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.googleapis.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; crossorigin /&gt;\n",
       "    &lt;link href=&quot;https://fonts.googleapis.com/css2?family=Asap:wght@400;500;600;700&amp;display=swap&quot; rel=&quot;stylesheet&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css&quot; /&gt;\n",
       "\n",
       "    &lt;script\n",
       "      src=&quot;https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js&quot;\n",
       "      integrity=&quot;sha512-RNLkV3d+aLtfcpEyFG8jRbnWHxUqVZozacROI4J2F1sTaDqo1dPQYs01OMi1t1w9Y2FdbSCDSQ2ZVdAC8bzgAg==&quot;\n",
       "      crossorigin=&quot;anonymous&quot;\n",
       "      referrerpolicy=&quot;no-referrer&quot;\n",
       "    &gt;&lt;/script&gt;\n",
       "\n",
       "    &lt;style type=&quot;text/css&quot;&gt;\n",
       "\n",
       "      /* Screen on smaller screens */\n",
       "      .no-responsive {\n",
       "        display: none;\n",
       "        position: fixed;\n",
       "        top: 0;\n",
       "        left: 0;\n",
       "        z-index: 1031;\n",
       "        width: 100vw;\n",
       "        height: 100vh;\n",
       "        background-color: var(--tealBackground);\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      @media screen and (min-width: 1000px) {\n",
       "        .desktop-content {\n",
       "          display: block;\n",
       "        }\n",
       "        .no-responsive {\n",
       "          display: none;\n",
       "        }\n",
       "      }\n",
       "\n",
       "      .no-responsive__content {\n",
       "        max-width: 600px;\n",
       "        width: 100%;\n",
       "        padding: 0 24px;\n",
       "      }\n",
       "\n",
       "      .no-responsive__title {\n",
       "        font-size: 96px;\n",
       "        font-weight: 300;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.167;\n",
       "      }\n",
       "\n",
       "      .no-responsive__text {\n",
       "        margin: 0;\n",
       "        font-size: 16px;\n",
       "        font-weight: 400;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.5;\n",
       "      }\n",
       "\n",
       "      .header-title {\n",
       "        font-size: 26px;\n",
       "        font-weight: 700;\n",
       "        color: #444444;\n",
       "      }\n",
       "\n",
       "      .tooltip-full-number {\n",
       "        position: relative;\n",
       "        display: inline-block;\n",
       "      }\n",
       "\n",
       "      .tooltip-full-number .tooltiptext {\n",
       "        visibility: hidden;\n",
       "        background: black;\n",
       "        color: white;\n",
       "        border: 1px solid black;\n",
       "        text-align: start;\n",
       "        padding: 3px;\n",
       "        position: absolute;\n",
       "        z-index: 1;\n",
       "        top: 0;\n",
       "        left: 100%;\n",
       "        margin-left: 5px;\n",
       "        opacity: 0;\n",
       "        transition: opacity 0.5s;\n",
       "        font-size: 13px;\n",
       "        font-weight: normal;\n",
       "        line-height: 100%;\n",
       "      }\n",
       "\n",
       "      .tooltip-full-number:hover .tooltiptext {\n",
       "        visibility: visible;\n",
       "        opacity: 1;\n",
       "      }\n",
       "\n",
       "\n",
       "      .wl-compare-profile {\n",
       "        position: relative;\n",
       "        left: 0;\n",
       "        padding: 30px;\n",
       "        margin-bottom: 20px;\n",
       "        background: var(--white);;\n",
       "        border-bottom: 1px solid #CED4DA;\n",
       "      }\n",
       "\n",
       "      .alert-list {\n",
       "        padding: 30px;\n",
       "        padding-top: 0;\n",
       "      }\n",
       "\n",
       "    .drift-detection {\n",
       "       justify-content: space-between;\n",
       "       align-items: center;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-circle {\n",
       "       width: 15px;\n",
       "       height: 15px;\n",
       "       border-radius: 50px;\n",
       "       display: inline-block;\n",
       "       margin-right: 8px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-drifts-item {\n",
       "         padding-right: 20px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-title {\n",
       "       font-family: Arial;\n",
       "       font-weight: bold;\n",
       "       font-size: 22px;\n",
       "       line-height: 130%;\n",
       "       color: #313B3D;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-drifts-item-count {\n",
       "       font-family: Arial;\n",
       "       font-weight: bold;\n",
       "       font-size: 14px;\n",
       "       line-height: 16px;\n",
       "       color: #000000;\n",
       "       padding-right: 8px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-drifts-item-name {\n",
       "       font-family: Arial;\n",
       "       font-style: normal;\n",
       "       font-weight: normal;\n",
       "       font-size: 12px;\n",
       "       line-height: 14px;\n",
       "       color: #000000;\n",
       "     }\n",
       "\n",
       "     .drift-detection-search-input {\n",
       "       display: flex;\n",
       "       align-items: center;\n",
       "       background: rgba(255, 255, 255, 0.7);\n",
       "       border: 1px solid #DBE5E7;\n",
       "       box-sizing: border-box;\n",
       "       border-radius: 4px;\n",
       "       width: 170px;\n",
       "       padding-left: 10px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-search-input img{\n",
       "       margin-right: 5px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-search-input input::placeholder {\n",
       "       font-family: Arial;\n",
       "       font-weight: normal;\n",
       "       font-size: 13px;\n",
       "       line-height: 16px;\n",
       "       color: #313B3D;\n",
       "     }\n",
       "\n",
       "     .dropdown-container {\n",
       "       position: absolute;\n",
       "       right: 30px;\n",
       "       top: 80px;\n",
       "       z-index: 999;\n",
       "       background: #FFFFFF;\n",
       "       border: 1px solid #DBE5E7;\n",
       "       box-sizing: border-box;\n",
       "       box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.05);\n",
       "       border-radius: 4px;\n",
       "       padding: 10px !important;\n",
       "       border: none !important;\n",
       "     }\n",
       "\n",
       "     .filter-options-title {\n",
       "       width: 240px;\n",
       "     }\n",
       "\n",
       "     .filter-options-title p {\n",
       "       margin: 0;\n",
       "     }\n",
       "\n",
       "     .form-check-input:checked {\n",
       "       background-color: #0E7384;\n",
       "       border-color: #0E7384;\n",
       "     }\n",
       "\n",
       "     .form-check-input[type=checkbox] {\n",
       "       border-radius: 2px;\n",
       "     }\n",
       "\n",
       "     .search-input{\n",
       "       padding-top: 0 !important;\n",
       "       padding-bottom: 0 !important;\n",
       "     }\n",
       "\n",
       "     .search-input input{\n",
       "       border: none;\n",
       "       background: none;\n",
       "       outline: none;\n",
       "       height: 40px;\n",
       "       width: 100%;\n",
       "       font-size: 14px;\n",
       "     }\n",
       "\n",
       "     .search-input img{\n",
       "       height: 19px;\n",
       "       pointer-events: none;\n",
       "     }\n",
       "\n",
       "     input::placeholder {\n",
       "       color: var(--secondaryLight1000);\n",
       "     }\n",
       "\n",
       "      .statistics {\n",
       "        width: 100%;\n",
       "      }\n",
       "\n",
       "     .close-filter-button {\n",
       "       display: flex;\n",
       "       justify-content: center;\n",
       "       align-items: center;\n",
       "       background: rgba(255, 255, 255, 0.7);\n",
       "       border: 1px solid #369BAC;\n",
       "       box-sizing: border-box;\n",
       "       border-radius: 4px;\n",
       "       width: 40px;\n",
       "       height: 40px;\n",
       "       cursor: pointer;\n",
       "       margin-left: 10px;\n",
       "     }\n",
       "\n",
       "      .statistic-number-title {\n",
       "        font-family: Arial;\n",
       "        font-weight: normal;\n",
       "        font-size: 14px;\n",
       "        line-height: 20px;\n",
       "        color: #6C757D;\n",
       "      }\n",
       "\n",
       "      .statistic-number {\n",
       "        font-family: Arial;\n",
       "        font-weight: bold;\n",
       "        font-size: 20px;\n",
       "        line-height: 140%;\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "        color: #4F595B;\n",
       "      }\n",
       "\n",
       "      .full-summary-statistics-wrap {\n",
       "        padding: 20px;\n",
       "      }\n",
       "\n",
       "      .statistics {\n",
       "        width: 100%;\n",
       "      }\n",
       "\n",
       "      .statistics-list {\n",
       "        width: 100% ;\n",
       "      }\n",
       "\n",
       "      mark {\n",
       "        padding: 5px;\n",
       "        border-radius: 4px;\n",
       "        font-family: Arial;\n",
       "        font-weight: normal;\n",
       "        font-size: 14px;\n",
       "        line-height: 140%;\n",
       "      }\n",
       "\n",
       "      .blue-mark {\n",
       "        background-color:  #369BAC1A;\n",
       "        color: #369BAC;\n",
       "      }\n",
       "\n",
       "      .red-mark {\n",
       "        background-color: #FFEFEE;\n",
       "        color: #F5473C;\n",
       "      }\n",
       "\n",
       "      .alert-tag {\n",
       "        height: 27px;\n",
       "        padding: 5px;\n",
       "        border-radius: 4px;\n",
       "        font-family: Arial;\n",
       "        font-weight: bold;\n",
       "        font-size: 12px;\n",
       "        line-height: 140%;\n",
       "        color: #FFFFFF;\n",
       "      }\n",
       "\n",
       "      .turquoise-background-color {\n",
       "        background-color: #1DBB42;\n",
       "      }\n",
       "\n",
       "      .bordeaux-background-color {\n",
       "        background-color: #C6462A;\n",
       "      }\n",
       "\n",
       "      .border-solid-gray {\n",
       "        border: 1px solid #CED4DA;\n",
       "        border-radius: 4px;\n",
       "      }\n",
       "\n",
       "      .display-flex {\n",
       "        display: flex;\n",
       "      }\n",
       "\n",
       "      .justify-content-space-between {\n",
       "        justify-content: space-between;\n",
       "      }\n",
       "\n",
       "      .justify-content-center {\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      .align-items-center {\n",
       "        align-items: center;\n",
       "      }\n",
       "\n",
       "      .align-items-flex-start {\n",
       "        align-items: flex-start;\n",
       "      }\n",
       "\n",
       "      .padding-right-30 {\n",
       "        padding-right: 30px;\n",
       "      }\n",
       "\n",
       "      .notif-circle-container{\n",
       "        position: absolute;\n",
       "        top: 25px;\n",
       "        right: 25px;\n",
       "        padding: 5.3px;\n",
       "        border-radius: 50%;\n",
       "        background-color: white;\n",
       "        cursor: pointer;\n",
       "      }\n",
       "\n",
       "      .notif-circle {\n",
       "        position: absolute;\n",
       "        top: 2px;\n",
       "        right: 2px;\n",
       "        padding: 3.3px;\n",
       "        border-radius: 50%;\n",
       "        background-color: #F2994A;\n",
       "      }\n",
       "\n",
       "      .alert-list-text {\n",
       "        width: 70%\n",
       "      }\n",
       "\n",
       "     @media screen and (min-width: 500px) {\n",
       "       .desktop-content {\n",
       "         display: block;\n",
       "       }\n",
       "       .no-responsive {\n",
       "         display: none;\n",
       "       }\n",
       "     }\n",
       "    &lt;/style&gt;\n",
       "  &lt;/head&gt;\n",
       "\n",
       "  &lt;body id=&quot;generated-html&quot;&gt;&lt;/body&gt;\n",
       "\n",
       "  &lt;script id=&quot;entry-template&quot; type=&quot;text/x-handlebars-template&quot;&gt;\n",
       "    \n",
       "      &lt;div class=&quot;desktop-content&quot;&gt;\n",
       "        &lt;div class=&quot;full-summary-statistics-wrap&quot;&gt;\n",
       "          &lt;div class=&quot;full-summary-statistics&quot;&gt;\n",
       "            &lt;div&gt;\n",
       "              &lt;div class=&quot;display-flex justify-content-center&quot;&gt;\n",
       "                &lt;div class=&quot;statistics-list border-solid-gray&quot;&gt;\n",
       "                  &lt;div&gt;\n",
       "                    &lt;div class=&quot;wl-compare-profile&quot; id=&quot;compare-profile&quot;&gt;\n",
       "                        &lt;div class=&quot;drift-detection-wrap&quot;&gt;\n",
       "                          &lt;div class=&quot;drift-detection display-flex align-items-flex-start&quot;&gt;\n",
       "                            &lt;div class=&quot;drift-detection-info flex-direction-colum&quot;&gt;\n",
       "                              &lt;div class=&quot;drift-detection-info-title-wrap display-flex&quot;&gt;\n",
       "                                &lt;p class=&quot;drift-detection-info-title&quot;&gt;\n",
       "                                  Constraints Report\n",
       "                                &lt;/p&gt;\n",
       "                              &lt;/div&gt;\n",
       "\n",
       "                              &lt;!-- &lt;/div&gt; --&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;div class=&quot;drift-detection-search-input-wrap display-flex&quot;&gt;\n",
       "                              &lt;div class=&quot;drift-detection-search-input search-input&quot;&gt;\n",
       "                                &lt;input type=&quot;text&quot; id=&quot;wl__feature-search&quot; placeholder=&quot;Quick search...&quot;/&gt;\n",
       "                                &lt;img src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAGdSURBVHgBpZK7TkJBEIZnZoVocdTYyQNALxpNKPQBMEaNJsbCRMKhl8ISWwt6AaksCF5iTHgAGhJD4AHkAaAzGiwUsjvOQnO4SYh/cXbPzO43OxcEj9Zy92EiFSXNIfvPyE1kKFfdoxJMENpP6DrvLC0vJoEwCgwto7DWcxoIIHBYbA3NmKwnDltjAeuZhyul1DaTTlfPB6Nt5Z53DOgky4P875+nlctY2+unjZviLklkJhi5bPUa3y/7qJuQUM7PinMy7CdQc1Gh16vnBxPzrMROmlKQEgKNASAHLQCmSIGpS75O+O5pdQAgVXaIqTkNwDDXHmcnW3VmHZoGMLoTsOt88+NrAMCIZdu+iLTyTwKRa1Md6YKfOgXbzO7K8sWku5u5RxcRV5EpPezrzcHGbXEXWaUkgkweZ/UC9YrK3zqggFw5FBZfm8EUavHj7AjAKpIvBDrGn+pNnlcyhYgqbcC41idr1gvB4SdZkDbzQa21gwv0Vj07aPTtL07XdDOyDXohCDNoHIRmAVRie20f+RKybRDQDvxHkXy/7b/DrayncLbMwQAAAABJRU5ErkJggg==&quot;/&gt;\n",
       "                              &lt;/div&gt;\n",
       "                              &lt;div class=&quot;wl__dropdown_arrow-icon&quot;&gt;\n",
       "                                &lt;div onclick=&quot;openFilter()&quot; class=&quot;close-filter-button&quot;&gt;\n",
       "                                &lt;div class=&quot;display-flex close-filter-icon d-none&quot;&gt;\n",
       "                                  &lt;img src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAADFSURBVHgBfY+xDcIwEEXvnLQBZQkYAEhDwwKpEEK0CCZgAEjJCEmgjYSAygxAHTZgFRSOsyUjY5mcZFnn/+78PwBXf3+MoKWUPuYjVBPFnTwpr9t/oNJfcTfXsAhRAlDqDhhQIPYgpAqNMDqcUqSAYZT1epr9gAHt6uXshvYme4DYHQJNDKh0dD0m5WXB10Y3Fqjtuh7fROn3oREDWxfeMLyRsMnc0OgDzdduaA0Pi3Plgr7Q2kaAePeBqh6rueSNBVt6fgCwBV1JLF3rlAAAAABJRU5ErkJggg==&quot;/&gt;\n",
       "                                &lt;/div&gt;\n",
       "                                &lt;div class=&quot;display-flex filter-icon&quot;&gt;\n",
       "                                  &lt;img src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACSSURBVHgBrZLBCYAwDEWTUjw7igcdwI1cxkNXUJzBEVzFAbSVKoKmaVrEB6GHJv/w+AACtRk7P9IONv1QOYUl96k0zv61m2tjARoLtSDI3EFsgIJ4uoXrMLazO72CRG2mzg/8BSdVlEjhpGZJjAWdAZJECpWalEhJSs1pHuUlMad5FFai1Lwg4Ckx1TxKIPFL8w55mEWd8VjPGAAAAABJRU5ErkJggg==&quot;/&gt;\n",
       "                                &lt;/div&gt;\n",
       "                                &lt;/div&gt;\n",
       "                              &lt;span class=&quot;notif-circle-container&quot;&gt;\n",
       "                                &lt;span class=&quot;notif-circle&quot;&gt;&lt;/span&gt;\n",
       "                              &lt;/span&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;/div&gt;\n",
       "                          &lt;/div&gt;\n",
       "                        &lt;/div&gt;\n",
       "                        &lt;div class=&quot;dropdown-container flex-direction-colum mb-2 d-none&quot; id=&quot;dropdown-container&quot;&gt;\n",
       "                          &lt;div class=&quot;filter-options&quot;&gt;\n",
       "                            &lt;div class=&quot;filter-options-title space-between dropdown&quot;&gt;\n",
       "                              &lt;p&gt;Select a view:&lt;/p&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;div class=&quot;form-check mb-1 mt-2&quot;&gt;\n",
       "                              &lt;input\n",
       "                                class=&quot;form-check-input wl__feature-filter-input&quot;\n",
       "                                type=&quot;checkbox&quot;\n",
       "                                name=&quot;checkbox&quot;\n",
       "                                value=&quot;Discrete&quot;\n",
       "                                id=&quot;inferredDiscrete&quot;\n",
       "                                checked\n",
       "                              /&gt;\n",
       "                              &lt;label class=&quot;form-check-label&quot; for=&quot;inferredDiscrete&quot;&gt;\n",
       "                                Failed constraints (&lt;span class=&quot;wl__feature-count--discrete&quot;&gt;&lt;/span&gt;)\n",
       "                              &lt;/label&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;div class=&quot;form-check mb-1&quot;&gt;\n",
       "                              &lt;input\n",
       "                                class=&quot;form-check-input wl__feature-filter-input&quot;\n",
       "                                type=&quot;checkbox&quot;\n",
       "                                name=&quot;checkbox&quot;\n",
       "                                value=&quot;Non-discrete&quot;\n",
       "                                id=&quot;inferredNonDiscrete&quot;\n",
       "                                checked\n",
       "                              /&gt;\n",
       "                              &lt;label class=&quot;form-check-label&quot; for=&quot;inferredNonDiscrete&quot;&gt;\n",
       "                                Passed constraints (&lt;span\n",
       "                                  class=&quot;wl__feature-count--non-discrete&quot;\n",
       "                                &gt;&lt;/span&gt;)\n",
       "                              &lt;/label&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;div class=&quot;form-check mb-1&quot;&gt;\n",
       "                              &lt;input\n",
       "                                class=&quot;form-check-input wl__feature-filter-input&quot;\n",
       "                                type=&quot;checkbox&quot;\n",
       "                                name=&quot;checkbox&quot;\n",
       "                                value=&quot;Unknown&quot;\n",
       "                                id=&quot;inferredUnknown&quot;\n",
       "                                checked\n",
       "                              /&gt;\n",
       "                              &lt;label class=&quot;form-check-label&quot; for=&quot;inferredUnknown&quot;&gt;\n",
       "                                All constraints (&lt;span class=&quot;wl__feature-count--unknown&quot;&gt;&lt;/span&gt;)\n",
       "                              &lt;/label&gt;\n",
       "                            &lt;/div&gt;\n",
       "                          &lt;/div&gt;\n",
       "                        &lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                    &lt;div class=&quot;alert-list&quot; id=&quot;alert-list&quot;&gt;\n",
       "                      {{{alertLIst this}}}\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                &lt;/div&gt;\n",
       "              &lt;/div&gt;\n",
       "            &lt;/div&gt;\n",
       "          &lt;/div&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "      &lt;div class=&quot;no-responsive&quot;&gt;\n",
       "        &lt;div class=&quot;no-responsive__content&quot;&gt;\n",
       "          &lt;h1 class=&quot;no-responsive__title&quot;&gt;Hold on! :)&lt;/h1&gt;\n",
       "          &lt;p class=&quot;no-responsive__text&quot;&gt;\n",
       "            It looks like your current screen size or device is not yet supported by the WhyLabs Sandbox. The Sandbox is\n",
       "            best experienced on a desktop computer. Please try maximizing this window or switching to another device. We\n",
       "            are working on adding support for a larger variety of devices.\n",
       "          &lt;/p&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "    \n",
       "  &lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://code.jquery.com/jquery-3.6.0.min.js&quot; integrity=&quot;sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js&quot; integrity=&quot;sha512-cd6CHE+XWDQ33ElJqsi0MdNte3S+bQY819f7p3NUHgwQQLXSKjE4cPZTeGNI+vaxZynk1wVU3hoHmow3m089wA==&quot; crossorigin=&quot;anonymous&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script&gt;\n",
       "    function registerHandlebarHelperFunctions() {\n",
       "      //helper fun\n",
       "      function formatLabelDate(timestamp) {\n",
       "        const date = new Date(timestamp);\n",
       "        const format = d3.timeFormat(&quot;%Y-%m-%d %I:%M:%S %p %Z&quot;);\n",
       "        return format(date);\n",
       "      }\n",
       "\n",
       "      function fixNumberTo(number, decimals = 3) {\n",
       "        return parseFloat(number).toFixed(decimals);\n",
       "      }\n",
       "\n",
       "      const randomNumbers = (range) =&gt; Math.floor(Math.random() * range)\n",
       "\n",
       "      const findFetureWithNumberSummary = (column) =&gt; {\n",
       "        const fetureIndex = Object.values(column.columns)\n",
       "              .findIndex((feture) =&gt; feture.numberSummary)\n",
       "\n",
       "        return Object.keys(column.columns)[fetureIndex]\n",
       "      }\n",
       "\n",
       "      const alertListItemStatus = (status, passedItem, failedItem) =&gt; {\n",
       "        if (status) {\n",
       "          return passedItem\n",
       "        } else {\n",
       "          return failedItem\n",
       "        }\n",
       "      }\n",
       "\n",
       "      const alertListElement = (name, text, status, summary) =&gt; {\n",
       "        if (summary == null){\n",
       "          return (\n",
       "          `&lt;div\n",
       "             data-inferred-type=${alertListItemStatus(status, &quot;passed&quot;, &quot;failed&quot;)}\n",
       "             class=&quot;alert-list-item display-flex justify-content-space-between align-items-center mb-2&quot;\n",
       "           &gt;\n",
       "            &lt;div class=&quot;alert-list-text&quot;&gt;\n",
       "              ${\n",
       "                name &amp;&amp;\n",
       "                alertListItemStatus(\n",
       "                  status,\n",
       "                  `&lt;mark class=&quot;blue-mark&quot;&gt;${name}&lt;/mark&gt;`,\n",
       "                  `&lt;mark class=&quot;red-mark&quot;&gt;${name}&lt;/mark&gt;`\n",
       "                )\n",
       "              }\n",
       "              ${text}\n",
       "            &lt;/div&gt;\n",
       "              ${\n",
       "                alertListItemStatus(\n",
       "                  status,\n",
       "                  `\n",
       "                  &lt;div class=&quot;turquoise-background-color alert-tag&quot;&gt;Passed&lt;/div&gt;\n",
       "                  `\n",
       "                  ,\n",
       "                  `\n",
       "                  &lt;div class=&quot;bordeaux-background-color alert-tag&quot;&gt;Failed&lt;/div&gt;\n",
       "                  `\n",
       "                )\n",
       "              }\n",
       "              &lt;/div&gt;`\n",
       "        )\n",
       "\n",
       "        }\n",
       "        return (\n",
       "          `&lt;div\n",
       "             data-inferred-type=${alertListItemStatus(status, &quot;passed&quot;, &quot;failed&quot;)}\n",
       "             class=&quot;alert-list-item display-flex justify-content-space-between align-items-center mb-2&quot;\n",
       "           &gt;\n",
       "            &lt;div class=&quot;alert-list-text&quot;&gt;\n",
       "              ${\n",
       "                name &amp;&amp;\n",
       "                alertListItemStatus(\n",
       "                  status,\n",
       "                  `&lt;mark class=&quot;blue-mark&quot;&gt;${name}&lt;/mark&gt;`,\n",
       "                  `&lt;mark class=&quot;red-mark&quot;&gt;${name}&lt;/mark&gt;`\n",
       "                )\n",
       "              }\n",
       "              ${text}\n",
       "            &lt;/div&gt;\n",
       "              ${\n",
       "                alertListItemStatus(\n",
       "                  status,\n",
       "                  `\n",
       "                  &lt;div class=&quot;tooltip-full-number&quot;&gt;\n",
       "                    &lt;div class=&quot;turquoise-background-color alert-tag&quot;&gt;Passed\n",
       "                      &lt;span class=&quot;tooltiptext&quot;&gt;\n",
       "                          &lt;pre class=&quot;mb-1&quot;&gt; ${JSON.stringify(summary, null, 2)} &lt;/pre&gt;\n",
       "                        &lt;/span&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;`\n",
       "\n",
       "                  ,\n",
       "                  `\n",
       "                  &lt;div class=&quot;tooltip-full-number&quot;&gt;\n",
       "                    &lt;div class=&quot;bordeaux-background-color alert-tag&quot;&gt;Failed\n",
       "                      &lt;span class=&quot;tooltiptext&quot;&gt;\n",
       "                        &lt;pre class=&quot;mb-1&quot;&gt; ${JSON.stringify(summary, null, 2)} &lt;/pre&gt;\n",
       "                        &lt;/span&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;`\n",
       "                )\n",
       "              }\n",
       "              &lt;/div&gt;`\n",
       "        )\n",
       "      }\n",
       "\n",
       "      let failedConstraints = 0;\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getProfileTimeStamp&quot;, function (column) {\n",
       "        return formatLabelDate(+column.properties.dataTimestamp)\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getProfileName&quot;, function (column) {\n",
       "        return column.properties.tags.name\n",
       "      });\n",
       "\n",
       "\n",
       "      Handlebars.registerHelper(&quot;alertLIst&quot;, function (column) {\n",
       "        let alertListItem = column.map((value) =&gt; {\n",
       "          if (value[1][0]) {\n",
       "            let alertListValue = value[1].map((cstr)=&gt;{\n",
       "              return alertListElement(value[0],cstr[0],cstr[cstr.length - 1] === 0 || (failedConstraints++, false), value[3])\n",
       "            })\n",
       "            return alertListValue.join(&#x27; &#x27;)\n",
       "          } else {\n",
       "            return alertListElement(&#x27;&#x27;, value[0], value[2] === 0 ||  (failedConstraints++, false), value[3])\n",
       "          }\n",
       "        })\n",
       "         $(document).ready(() =&gt; {\n",
       "           $(&quot;.wl__feature-count--discrete&quot;).append(failedConstraints)\n",
       "           $(&quot;.wl__feature-count--non-discrete&quot;).append(column.length - failedConstraints)\n",
       "           $(&quot;.wl__feature-count--unknown&quot;).append(column.length)\n",
       "         })\n",
       "        return alertListItem.join(&#x27; &#x27;)\n",
       "      });\n",
       "\n",
       "    }\n",
       "\n",
       "    function openFilter() {\n",
       "      const $filterOptions = $(&quot;.dropdown-container&quot;);\n",
       "      const filterClass = $filterOptions.attr(&quot;class&quot;);\n",
       "\n",
       "      if (filterClass.indexOf(&quot;d-none&quot;) &gt; 0) {\n",
       "        $filterOptions.removeClass(&quot;d-none&quot;);\n",
       "        $(&quot;.filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.close-filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "      } else {\n",
       "        $filterOptions.addClass(&quot;d-none&quot;);\n",
       "        $(&quot;.close-filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "      }\n",
       "    }\n",
       "\n",
       "    function initHandlebarsTemplate() {\n",
       "      // Replace this context with JSON from .py file\n",
       "      const context = [[&quot;animal values in set {&#x27;snake&#x27;, &#x27;cat&#x27;}&quot;, 0, 1, {&quot;metric&quot;: &quot;frequent_items&quot;, &quot;frequent_strings_top_10&quot;: [&quot;cat:2&quot;, &quot;snake:2&quot;, &quot;mosquito:1&quot;]}], [&quot;animal 2-most common items in set {&#x27;snake&#x27;, &#x27;cat&#x27;}&quot;, 1, 0, {&quot;metric&quot;: &quot;frequent_items&quot;, &quot;frequent_strings_top_10&quot;: [&quot;cat:2&quot;, &quot;snake:2&quot;, &quot;mosquito:1&quot;]}]];\n",
       "      // Config handlebars and pass data to HBS template\n",
       "      const source = document.getElementById(&quot;entry-template&quot;).innerHTML;\n",
       "      const template = Handlebars.compile(source);\n",
       "      const html = template(context);\n",
       "      const target = document.getElementById(&quot;generated-html&quot;);\n",
       "      target.innerHTML = html;\n",
       "    }\n",
       "\n",
       "    function initWebsiteScripts() {\n",
       "      const $featureSearch = document.getElementById(&quot;wl__feature-search&quot;);\n",
       "      const $alertList = document.getElementById(&quot;alert-list&quot;);\n",
       "      const $discrete = document.getElementById(&quot;inferredDiscrete&quot;);\n",
       "      const $nonDiscrete = document.getElementById(&quot;inferredNonDiscrete&quot;);\n",
       "      const $unknown = document.getElementById(&quot;inferredUnknown&quot;);\n",
       "\n",
       "      const activeTypes = {\n",
       "        passed: true,\n",
       "        failed: true\n",
       "      };\n",
       "\n",
       "      let searchString = &quot;&quot;;\n",
       "\n",
       "      function debounce(func, wait, immediate) {\n",
       "        let timeout;\n",
       "\n",
       "        return function () {\n",
       "          const context = this;\n",
       "          const args = arguments;\n",
       "          const later = function () {\n",
       "            timeout = null;\n",
       "            if (!immediate) func.apply(context, args);\n",
       "          };\n",
       "\n",
       "          const callNow = immediate &amp;&amp; !timeout;\n",
       "          clearTimeout(timeout);\n",
       "          timeout = setTimeout(later, wait);\n",
       "          if (callNow) func.apply(context, args);\n",
       "        };\n",
       "      }\n",
       "\n",
       "      function filterNotification() {\n",
       "        const $notifCircleContainer = $(&quot;.notif-circle-container&quot;)\n",
       "        const $boxes = $(&#x27;.wl_filter-options&gt;.form-check&gt;input[name=checkbox]:checked&#x27;);\n",
       "        const item = Object.values($boxes).find(function(value) { return $(value)[0] === undefined});\n",
       "        if (item === undefined) {\n",
       "          $notifCircleContainer.removeClass(&quot;d-none&quot;)\n",
       "        } else {\n",
       "          $notifCircleContainer.addClass(&quot;d-none&quot;)\n",
       "        }\n",
       "      }\n",
       "\n",
       "      function handleSearch() {\n",
       "        const tableBodyChildren = $alertList.children;\n",
       "\n",
       "        for (let i = 0; i &lt; tableBodyChildren.length; i++) {\n",
       "          const type = tableBodyChildren[i].dataset.inferredType.toLowerCase();\n",
       "          const name = $(tableBodyChildren[i].children[0]).html().toLowerCase();\n",
       "          if (activeTypes[type] &amp;&amp; name.includes(searchString)) {\n",
       "            tableBodyChildren[i].style.display = &quot;&quot;;\n",
       "          } else {\n",
       "            tableBodyChildren[i].style.display = &quot;none&quot;;\n",
       "          }\n",
       "        }\n",
       "      }\n",
       "\n",
       "      const checkedBoxes = () =&gt; {\n",
       "        if ($(&#x27;.form-check-input:checked&#x27;).length === $(&quot;.form-check-input&quot;).length - 1) {\n",
       "          $($(&quot;.form-check-input&quot;)[$(&quot;.form-check-input&quot;).length - 1]).prop( &quot;checked&quot;, true );\n",
       "        }\n",
       "      }\n",
       "\n",
       "      $featureSearch.addEventListener(\n",
       "        &quot;keyup&quot;,\n",
       "        debounce((event) =&gt; {\n",
       "          searchString = event.target.value.toLowerCase();\n",
       "          handleSearch();\n",
       "        }, 100),\n",
       "      );\n",
       "\n",
       "      $discrete.addEventListener(&quot;change&quot;, (event) =&gt; {\n",
       "        const currentCheckbox = $(event.currentTarget);\n",
       "\n",
       "        if (event.currentTarget.checked) {\n",
       "          activeTypes[&quot;failed&quot;] = true;\n",
       "          checkedBoxes();\n",
       "        } else {\n",
       "          activeTypes[&quot;failed&quot;] = false;\n",
       "          $($(&quot;.form-check-input&quot;)[$(&quot;.form-check-input&quot;).length - 1]).prop( &quot;checked&quot;, false );\n",
       "        }\n",
       "        handleSearch();\n",
       "      });\n",
       "\n",
       "      $nonDiscrete.addEventListener(&quot;change&quot;, (event) =&gt; {\n",
       "        const currentCheckbox = $(event.currentTarget);\n",
       "\n",
       "        if (event.currentTarget.checked) {\n",
       "          activeTypes[&quot;passed&quot;] = true;\n",
       "          checkedBoxes();\n",
       "        } else {\n",
       "          activeTypes[&quot;passed&quot;] = false;\n",
       "          $($(&quot;.form-check-input&quot;)[$(&quot;.form-check-input&quot;).length - 1]).prop( &quot;checked&quot;, false );\n",
       "        }\n",
       "        handleSearch();\n",
       "      });\n",
       "\n",
       "      $unknown.addEventListener(&quot;change&quot;, (event) =&gt; {\n",
       "        const currentCheckbox = $(event.currentTarget);\n",
       "\n",
       "        if (event.currentTarget.checked) {\n",
       "          $(&quot;.form-check-input&quot;).prop( &quot;checked&quot;, true );\n",
       "          activeTypes[&quot;passed&quot;] = true;\n",
       "          activeTypes[&quot;failed&quot;] = true;\n",
       "          checkedBoxes();\n",
       "        } else {\n",
       "          $(&quot;.form-check-input&quot;).prop( &quot;checked&quot;, false );\n",
       "          activeTypes[&quot;passed&quot;] = false;\n",
       "          activeTypes[&quot;failed&quot;] = false;\n",
       "        }\n",
       "        handleSearch();\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function checkedBoxes() {\n",
       "      const $boxes = $(&#x27;input[name=checkbox]:checked&#x27;);\n",
       "      const $notifCircleContainer = $(&quot;.notif-circle-container&quot;)\n",
       "\n",
       "      if ($boxes.length) {\n",
       "        $notifCircleContainer.removeClass(&quot;d-none&quot;)\n",
       "      }\n",
       "    }\n",
       "\n",
       "    function openFilter() {\n",
       "      const $filterOptions = $(&quot;.dropdown-container&quot;);\n",
       "      const $notifCircleContainer = $(&quot;.notif-circle-container&quot;)\n",
       "      const filterClass = $filterOptions.attr(&quot;class&quot;);\n",
       "\n",
       "      if (filterClass.indexOf(&quot;d-none&quot;) &gt; 0) {\n",
       "        $notifCircleContainer.addClass(&quot;d-none&quot;)\n",
       "        $filterOptions.removeClass(&quot;d-none&quot;);\n",
       "        $(&quot;.filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.close-filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "      } else {\n",
       "        $filterOptions.addClass(&quot;d-none&quot;);\n",
       "        $(&quot;.close-filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "        checkedBoxes()\n",
       "      }\n",
       "    }\n",
       "\n",
       "    // Invoke functions -- keep in mind invokation order\n",
       "    registerHandlebarHelperFunctions();\n",
       "    initHandlebarsTemplate();\n",
       "    initWebsiteScripts();\n",
       "  &lt;/script&gt;\n",
       "&lt;/html&gt;\n",
       "\" width=100% height=300\n",
       "        frameBorder=0></iframe>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "builder = ConstraintsBuilder(dataset_profile_view=profile_view)\n",
    "reference_set = {\"cat\",\"snake\"}\n",
    "builder.add_constraint(frequent_strings_in_reference_set(column_name=\"animal\", reference_set=reference_set))\n",
    "builder.add_constraint(n_most_common_items_in_set(column_name=\"animal\",n=2,reference_set=reference_set))\n",
    "\n",
    "constraints = builder.build()\n",
    "\n",
    "from whylogs.viz import NotebookProfileVisualizer\n",
    "\n",
    "visualization = NotebookProfileVisualizer()\n",
    "visualization.constraints_report(constraints, cell_height=300)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Counters Constraints <a class=\"anchor\" id=\"counts\"></a>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "from whylogs.core.constraints.factories import no_missing_values, count_below_number, null_percentage_below_number, null_values_below_number"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Examples - Counters Constraints"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "import whylogs as why\n",
    "import pandas as pd\n",
    "data = {\n",
    "    \"animal\": [\"cat\", \"snake\", \"snake\", \"cat\", \"mosquito\"],\n",
    "    \"legs\": [4, 2, 0, None, 6],\n",
    "    \"weight\": [4.3, 1.8, 1.3, 4.1, 5.5e-6],\n",
    "}\n",
    "\n",
    "results = why.log(pd.DataFrame(data))\n",
    "profile_view = results.view()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div></div><iframe srcdoc=\"&lt;!DOCTYPE html&gt;\n",
       "&lt;html lang=&quot;en&quot;&gt;\n",
       "  &lt;head&gt;\n",
       "    &lt;meta charset=&quot;UTF-8&quot; /&gt;\n",
       "    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot; /&gt;\n",
       "    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;\n",
       "    &lt;meta name=&quot;description&quot; content=&quot;&quot; /&gt;\n",
       "    &lt;meta name=&quot;author&quot; content=&quot;&quot; /&gt;\n",
       "\n",
       "    &lt;title&gt;Profile Visualizer | whylogs&lt;/title&gt;\n",
       "\n",
       "    &lt;link rel=&quot;icon&quot; href=&quot;images/whylabs-favicon.png&quot; type=&quot;image/png&quot; sizes=&quot;16x16&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.googleapis.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; crossorigin /&gt;\n",
       "    &lt;link href=&quot;https://fonts.googleapis.com/css2?family=Asap:wght@400;500;600;700&amp;display=swap&quot; rel=&quot;stylesheet&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css&quot; /&gt;\n",
       "\n",
       "    &lt;script\n",
       "      src=&quot;https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js&quot;\n",
       "      integrity=&quot;sha512-RNLkV3d+aLtfcpEyFG8jRbnWHxUqVZozacROI4J2F1sTaDqo1dPQYs01OMi1t1w9Y2FdbSCDSQ2ZVdAC8bzgAg==&quot;\n",
       "      crossorigin=&quot;anonymous&quot;\n",
       "      referrerpolicy=&quot;no-referrer&quot;\n",
       "    &gt;&lt;/script&gt;\n",
       "\n",
       "    &lt;style type=&quot;text/css&quot;&gt;\n",
       "\n",
       "      /* Screen on smaller screens */\n",
       "      .no-responsive {\n",
       "        display: none;\n",
       "        position: fixed;\n",
       "        top: 0;\n",
       "        left: 0;\n",
       "        z-index: 1031;\n",
       "        width: 100vw;\n",
       "        height: 100vh;\n",
       "        background-color: var(--tealBackground);\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      @media screen and (min-width: 1000px) {\n",
       "        .desktop-content {\n",
       "          display: block;\n",
       "        }\n",
       "        .no-responsive {\n",
       "          display: none;\n",
       "        }\n",
       "      }\n",
       "\n",
       "      .no-responsive__content {\n",
       "        max-width: 600px;\n",
       "        width: 100%;\n",
       "        padding: 0 24px;\n",
       "      }\n",
       "\n",
       "      .no-responsive__title {\n",
       "        font-size: 96px;\n",
       "        font-weight: 300;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.167;\n",
       "      }\n",
       "\n",
       "      .no-responsive__text {\n",
       "        margin: 0;\n",
       "        font-size: 16px;\n",
       "        font-weight: 400;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.5;\n",
       "      }\n",
       "\n",
       "      .header-title {\n",
       "        font-size: 26px;\n",
       "        font-weight: 700;\n",
       "        color: #444444;\n",
       "      }\n",
       "\n",
       "      .tooltip-full-number {\n",
       "        position: relative;\n",
       "        display: inline-block;\n",
       "      }\n",
       "\n",
       "      .tooltip-full-number .tooltiptext {\n",
       "        visibility: hidden;\n",
       "        background: black;\n",
       "        color: white;\n",
       "        border: 1px solid black;\n",
       "        text-align: start;\n",
       "        padding: 3px;\n",
       "        position: absolute;\n",
       "        z-index: 1;\n",
       "        top: 0;\n",
       "        left: 100%;\n",
       "        margin-left: 5px;\n",
       "        opacity: 0;\n",
       "        transition: opacity 0.5s;\n",
       "        font-size: 13px;\n",
       "        font-weight: normal;\n",
       "        line-height: 100%;\n",
       "      }\n",
       "\n",
       "      .tooltip-full-number:hover .tooltiptext {\n",
       "        visibility: visible;\n",
       "        opacity: 1;\n",
       "      }\n",
       "\n",
       "\n",
       "      .wl-compare-profile {\n",
       "        position: relative;\n",
       "        left: 0;\n",
       "        padding: 30px;\n",
       "        margin-bottom: 20px;\n",
       "        background: var(--white);;\n",
       "        border-bottom: 1px solid #CED4DA;\n",
       "      }\n",
       "\n",
       "      .alert-list {\n",
       "        padding: 30px;\n",
       "        padding-top: 0;\n",
       "      }\n",
       "\n",
       "    .drift-detection {\n",
       "       justify-content: space-between;\n",
       "       align-items: center;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-circle {\n",
       "       width: 15px;\n",
       "       height: 15px;\n",
       "       border-radius: 50px;\n",
       "       display: inline-block;\n",
       "       margin-right: 8px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-drifts-item {\n",
       "         padding-right: 20px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-title {\n",
       "       font-family: Arial;\n",
       "       font-weight: bold;\n",
       "       font-size: 22px;\n",
       "       line-height: 130%;\n",
       "       color: #313B3D;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-drifts-item-count {\n",
       "       font-family: Arial;\n",
       "       font-weight: bold;\n",
       "       font-size: 14px;\n",
       "       line-height: 16px;\n",
       "       color: #000000;\n",
       "       padding-right: 8px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-drifts-item-name {\n",
       "       font-family: Arial;\n",
       "       font-style: normal;\n",
       "       font-weight: normal;\n",
       "       font-size: 12px;\n",
       "       line-height: 14px;\n",
       "       color: #000000;\n",
       "     }\n",
       "\n",
       "     .drift-detection-search-input {\n",
       "       display: flex;\n",
       "       align-items: center;\n",
       "       background: rgba(255, 255, 255, 0.7);\n",
       "       border: 1px solid #DBE5E7;\n",
       "       box-sizing: border-box;\n",
       "       border-radius: 4px;\n",
       "       width: 170px;\n",
       "       padding-left: 10px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-search-input img{\n",
       "       margin-right: 5px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-search-input input::placeholder {\n",
       "       font-family: Arial;\n",
       "       font-weight: normal;\n",
       "       font-size: 13px;\n",
       "       line-height: 16px;\n",
       "       color: #313B3D;\n",
       "     }\n",
       "\n",
       "     .dropdown-container {\n",
       "       position: absolute;\n",
       "       right: 30px;\n",
       "       top: 80px;\n",
       "       z-index: 999;\n",
       "       background: #FFFFFF;\n",
       "       border: 1px solid #DBE5E7;\n",
       "       box-sizing: border-box;\n",
       "       box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.05);\n",
       "       border-radius: 4px;\n",
       "       padding: 10px !important;\n",
       "       border: none !important;\n",
       "     }\n",
       "\n",
       "     .filter-options-title {\n",
       "       width: 240px;\n",
       "     }\n",
       "\n",
       "     .filter-options-title p {\n",
       "       margin: 0;\n",
       "     }\n",
       "\n",
       "     .form-check-input:checked {\n",
       "       background-color: #0E7384;\n",
       "       border-color: #0E7384;\n",
       "     }\n",
       "\n",
       "     .form-check-input[type=checkbox] {\n",
       "       border-radius: 2px;\n",
       "     }\n",
       "\n",
       "     .search-input{\n",
       "       padding-top: 0 !important;\n",
       "       padding-bottom: 0 !important;\n",
       "     }\n",
       "\n",
       "     .search-input input{\n",
       "       border: none;\n",
       "       background: none;\n",
       "       outline: none;\n",
       "       height: 40px;\n",
       "       width: 100%;\n",
       "       font-size: 14px;\n",
       "     }\n",
       "\n",
       "     .search-input img{\n",
       "       height: 19px;\n",
       "       pointer-events: none;\n",
       "     }\n",
       "\n",
       "     input::placeholder {\n",
       "       color: var(--secondaryLight1000);\n",
       "     }\n",
       "\n",
       "      .statistics {\n",
       "        width: 100%;\n",
       "      }\n",
       "\n",
       "     .close-filter-button {\n",
       "       display: flex;\n",
       "       justify-content: center;\n",
       "       align-items: center;\n",
       "       background: rgba(255, 255, 255, 0.7);\n",
       "       border: 1px solid #369BAC;\n",
       "       box-sizing: border-box;\n",
       "       border-radius: 4px;\n",
       "       width: 40px;\n",
       "       height: 40px;\n",
       "       cursor: pointer;\n",
       "       margin-left: 10px;\n",
       "     }\n",
       "\n",
       "      .statistic-number-title {\n",
       "        font-family: Arial;\n",
       "        font-weight: normal;\n",
       "        font-size: 14px;\n",
       "        line-height: 20px;\n",
       "        color: #6C757D;\n",
       "      }\n",
       "\n",
       "      .statistic-number {\n",
       "        font-family: Arial;\n",
       "        font-weight: bold;\n",
       "        font-size: 20px;\n",
       "        line-height: 140%;\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "        color: #4F595B;\n",
       "      }\n",
       "\n",
       "      .full-summary-statistics-wrap {\n",
       "        padding: 20px;\n",
       "      }\n",
       "\n",
       "      .statistics {\n",
       "        width: 100%;\n",
       "      }\n",
       "\n",
       "      .statistics-list {\n",
       "        width: 100% ;\n",
       "      }\n",
       "\n",
       "      mark {\n",
       "        padding: 5px;\n",
       "        border-radius: 4px;\n",
       "        font-family: Arial;\n",
       "        font-weight: normal;\n",
       "        font-size: 14px;\n",
       "        line-height: 140%;\n",
       "      }\n",
       "\n",
       "      .blue-mark {\n",
       "        background-color:  #369BAC1A;\n",
       "        color: #369BAC;\n",
       "      }\n",
       "\n",
       "      .red-mark {\n",
       "        background-color: #FFEFEE;\n",
       "        color: #F5473C;\n",
       "      }\n",
       "\n",
       "      .alert-tag {\n",
       "        height: 27px;\n",
       "        padding: 5px;\n",
       "        border-radius: 4px;\n",
       "        font-family: Arial;\n",
       "        font-weight: bold;\n",
       "        font-size: 12px;\n",
       "        line-height: 140%;\n",
       "        color: #FFFFFF;\n",
       "      }\n",
       "\n",
       "      .turquoise-background-color {\n",
       "        background-color: #1DBB42;\n",
       "      }\n",
       "\n",
       "      .bordeaux-background-color {\n",
       "        background-color: #C6462A;\n",
       "      }\n",
       "\n",
       "      .border-solid-gray {\n",
       "        border: 1px solid #CED4DA;\n",
       "        border-radius: 4px;\n",
       "      }\n",
       "\n",
       "      .display-flex {\n",
       "        display: flex;\n",
       "      }\n",
       "\n",
       "      .justify-content-space-between {\n",
       "        justify-content: space-between;\n",
       "      }\n",
       "\n",
       "      .justify-content-center {\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      .align-items-center {\n",
       "        align-items: center;\n",
       "      }\n",
       "\n",
       "      .align-items-flex-start {\n",
       "        align-items: flex-start;\n",
       "      }\n",
       "\n",
       "      .padding-right-30 {\n",
       "        padding-right: 30px;\n",
       "      }\n",
       "\n",
       "      .notif-circle-container{\n",
       "        position: absolute;\n",
       "        top: 25px;\n",
       "        right: 25px;\n",
       "        padding: 5.3px;\n",
       "        border-radius: 50%;\n",
       "        background-color: white;\n",
       "        cursor: pointer;\n",
       "      }\n",
       "\n",
       "      .notif-circle {\n",
       "        position: absolute;\n",
       "        top: 2px;\n",
       "        right: 2px;\n",
       "        padding: 3.3px;\n",
       "        border-radius: 50%;\n",
       "        background-color: #F2994A;\n",
       "      }\n",
       "\n",
       "      .alert-list-text {\n",
       "        width: 70%\n",
       "      }\n",
       "\n",
       "     @media screen and (min-width: 500px) {\n",
       "       .desktop-content {\n",
       "         display: block;\n",
       "       }\n",
       "       .no-responsive {\n",
       "         display: none;\n",
       "       }\n",
       "     }\n",
       "    &lt;/style&gt;\n",
       "  &lt;/head&gt;\n",
       "\n",
       "  &lt;body id=&quot;generated-html&quot;&gt;&lt;/body&gt;\n",
       "\n",
       "  &lt;script id=&quot;entry-template&quot; type=&quot;text/x-handlebars-template&quot;&gt;\n",
       "    \n",
       "      &lt;div class=&quot;desktop-content&quot;&gt;\n",
       "        &lt;div class=&quot;full-summary-statistics-wrap&quot;&gt;\n",
       "          &lt;div class=&quot;full-summary-statistics&quot;&gt;\n",
       "            &lt;div&gt;\n",
       "              &lt;div class=&quot;display-flex justify-content-center&quot;&gt;\n",
       "                &lt;div class=&quot;statistics-list border-solid-gray&quot;&gt;\n",
       "                  &lt;div&gt;\n",
       "                    &lt;div class=&quot;wl-compare-profile&quot; id=&quot;compare-profile&quot;&gt;\n",
       "                        &lt;div class=&quot;drift-detection-wrap&quot;&gt;\n",
       "                          &lt;div class=&quot;drift-detection display-flex align-items-flex-start&quot;&gt;\n",
       "                            &lt;div class=&quot;drift-detection-info flex-direction-colum&quot;&gt;\n",
       "                              &lt;div class=&quot;drift-detection-info-title-wrap display-flex&quot;&gt;\n",
       "                                &lt;p class=&quot;drift-detection-info-title&quot;&gt;\n",
       "                                  Constraints Report\n",
       "                                &lt;/p&gt;\n",
       "                              &lt;/div&gt;\n",
       "\n",
       "                              &lt;!-- &lt;/div&gt; --&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;div class=&quot;drift-detection-search-input-wrap display-flex&quot;&gt;\n",
       "                              &lt;div class=&quot;drift-detection-search-input search-input&quot;&gt;\n",
       "                                &lt;input type=&quot;text&quot; id=&quot;wl__feature-search&quot; placeholder=&quot;Quick search...&quot;/&gt;\n",
       "                                &lt;img src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAGdSURBVHgBpZK7TkJBEIZnZoVocdTYyQNALxpNKPQBMEaNJsbCRMKhl8ISWwt6AaksCF5iTHgAGhJD4AHkAaAzGiwUsjvOQnO4SYh/cXbPzO43OxcEj9Zy92EiFSXNIfvPyE1kKFfdoxJMENpP6DrvLC0vJoEwCgwto7DWcxoIIHBYbA3NmKwnDltjAeuZhyul1DaTTlfPB6Nt5Z53DOgky4P875+nlctY2+unjZviLklkJhi5bPUa3y/7qJuQUM7PinMy7CdQc1Gh16vnBxPzrMROmlKQEgKNASAHLQCmSIGpS75O+O5pdQAgVXaIqTkNwDDXHmcnW3VmHZoGMLoTsOt88+NrAMCIZdu+iLTyTwKRa1Md6YKfOgXbzO7K8sWku5u5RxcRV5EpPezrzcHGbXEXWaUkgkweZ/UC9YrK3zqggFw5FBZfm8EUavHj7AjAKpIvBDrGn+pNnlcyhYgqbcC41idr1gvB4SdZkDbzQa21gwv0Vj07aPTtL07XdDOyDXohCDNoHIRmAVRie20f+RKybRDQDvxHkXy/7b/DrayncLbMwQAAAABJRU5ErkJggg==&quot;/&gt;\n",
       "                              &lt;/div&gt;\n",
       "                              &lt;div class=&quot;wl__dropdown_arrow-icon&quot;&gt;\n",
       "                                &lt;div onclick=&quot;openFilter()&quot; class=&quot;close-filter-button&quot;&gt;\n",
       "                                &lt;div class=&quot;display-flex close-filter-icon d-none&quot;&gt;\n",
       "                                  &lt;img src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAADFSURBVHgBfY+xDcIwEEXvnLQBZQkYAEhDwwKpEEK0CCZgAEjJCEmgjYSAygxAHTZgFRSOsyUjY5mcZFnn/+78PwBXf3+MoKWUPuYjVBPFnTwpr9t/oNJfcTfXsAhRAlDqDhhQIPYgpAqNMDqcUqSAYZT1epr9gAHt6uXshvYme4DYHQJNDKh0dD0m5WXB10Y3Fqjtuh7fROn3oREDWxfeMLyRsMnc0OgDzdduaA0Pi3Plgr7Q2kaAePeBqh6rueSNBVt6fgCwBV1JLF3rlAAAAABJRU5ErkJggg==&quot;/&gt;\n",
       "                                &lt;/div&gt;\n",
       "                                &lt;div class=&quot;display-flex filter-icon&quot;&gt;\n",
       "                                  &lt;img src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACSSURBVHgBrZLBCYAwDEWTUjw7igcdwI1cxkNXUJzBEVzFAbSVKoKmaVrEB6GHJv/w+AACtRk7P9IONv1QOYUl96k0zv61m2tjARoLtSDI3EFsgIJ4uoXrMLazO72CRG2mzg/8BSdVlEjhpGZJjAWdAZJECpWalEhJSs1pHuUlMad5FFai1Lwg4Ckx1TxKIPFL8w55mEWd8VjPGAAAAABJRU5ErkJggg==&quot;/&gt;\n",
       "                                &lt;/div&gt;\n",
       "                                &lt;/div&gt;\n",
       "                              &lt;span class=&quot;notif-circle-container&quot;&gt;\n",
       "                                &lt;span class=&quot;notif-circle&quot;&gt;&lt;/span&gt;\n",
       "                              &lt;/span&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;/div&gt;\n",
       "                          &lt;/div&gt;\n",
       "                        &lt;/div&gt;\n",
       "                        &lt;div class=&quot;dropdown-container flex-direction-colum mb-2 d-none&quot; id=&quot;dropdown-container&quot;&gt;\n",
       "                          &lt;div class=&quot;filter-options&quot;&gt;\n",
       "                            &lt;div class=&quot;filter-options-title space-between dropdown&quot;&gt;\n",
       "                              &lt;p&gt;Select a view:&lt;/p&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;div class=&quot;form-check mb-1 mt-2&quot;&gt;\n",
       "                              &lt;input\n",
       "                                class=&quot;form-check-input wl__feature-filter-input&quot;\n",
       "                                type=&quot;checkbox&quot;\n",
       "                                name=&quot;checkbox&quot;\n",
       "                                value=&quot;Discrete&quot;\n",
       "                                id=&quot;inferredDiscrete&quot;\n",
       "                                checked\n",
       "                              /&gt;\n",
       "                              &lt;label class=&quot;form-check-label&quot; for=&quot;inferredDiscrete&quot;&gt;\n",
       "                                Failed constraints (&lt;span class=&quot;wl__feature-count--discrete&quot;&gt;&lt;/span&gt;)\n",
       "                              &lt;/label&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;div class=&quot;form-check mb-1&quot;&gt;\n",
       "                              &lt;input\n",
       "                                class=&quot;form-check-input wl__feature-filter-input&quot;\n",
       "                                type=&quot;checkbox&quot;\n",
       "                                name=&quot;checkbox&quot;\n",
       "                                value=&quot;Non-discrete&quot;\n",
       "                                id=&quot;inferredNonDiscrete&quot;\n",
       "                                checked\n",
       "                              /&gt;\n",
       "                              &lt;label class=&quot;form-check-label&quot; for=&quot;inferredNonDiscrete&quot;&gt;\n",
       "                                Passed constraints (&lt;span\n",
       "                                  class=&quot;wl__feature-count--non-discrete&quot;\n",
       "                                &gt;&lt;/span&gt;)\n",
       "                              &lt;/label&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;div class=&quot;form-check mb-1&quot;&gt;\n",
       "                              &lt;input\n",
       "                                class=&quot;form-check-input wl__feature-filter-input&quot;\n",
       "                                type=&quot;checkbox&quot;\n",
       "                                name=&quot;checkbox&quot;\n",
       "                                value=&quot;Unknown&quot;\n",
       "                                id=&quot;inferredUnknown&quot;\n",
       "                                checked\n",
       "                              /&gt;\n",
       "                              &lt;label class=&quot;form-check-label&quot; for=&quot;inferredUnknown&quot;&gt;\n",
       "                                All constraints (&lt;span class=&quot;wl__feature-count--unknown&quot;&gt;&lt;/span&gt;)\n",
       "                              &lt;/label&gt;\n",
       "                            &lt;/div&gt;\n",
       "                          &lt;/div&gt;\n",
       "                        &lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                    &lt;div class=&quot;alert-list&quot; id=&quot;alert-list&quot;&gt;\n",
       "                      {{{alertLIst this}}}\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                &lt;/div&gt;\n",
       "              &lt;/div&gt;\n",
       "            &lt;/div&gt;\n",
       "          &lt;/div&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "      &lt;div class=&quot;no-responsive&quot;&gt;\n",
       "        &lt;div class=&quot;no-responsive__content&quot;&gt;\n",
       "          &lt;h1 class=&quot;no-responsive__title&quot;&gt;Hold on! :)&lt;/h1&gt;\n",
       "          &lt;p class=&quot;no-responsive__text&quot;&gt;\n",
       "            It looks like your current screen size or device is not yet supported by the WhyLabs Sandbox. The Sandbox is\n",
       "            best experienced on a desktop computer. Please try maximizing this window or switching to another device. We\n",
       "            are working on adding support for a larger variety of devices.\n",
       "          &lt;/p&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "    \n",
       "  &lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://code.jquery.com/jquery-3.6.0.min.js&quot; integrity=&quot;sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js&quot; integrity=&quot;sha512-cd6CHE+XWDQ33ElJqsi0MdNte3S+bQY819f7p3NUHgwQQLXSKjE4cPZTeGNI+vaxZynk1wVU3hoHmow3m089wA==&quot; crossorigin=&quot;anonymous&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script&gt;\n",
       "    function registerHandlebarHelperFunctions() {\n",
       "      //helper fun\n",
       "      function formatLabelDate(timestamp) {\n",
       "        const date = new Date(timestamp);\n",
       "        const format = d3.timeFormat(&quot;%Y-%m-%d %I:%M:%S %p %Z&quot;);\n",
       "        return format(date);\n",
       "      }\n",
       "\n",
       "      function fixNumberTo(number, decimals = 3) {\n",
       "        return parseFloat(number).toFixed(decimals);\n",
       "      }\n",
       "\n",
       "      const randomNumbers = (range) =&gt; Math.floor(Math.random() * range)\n",
       "\n",
       "      const findFetureWithNumberSummary = (column) =&gt; {\n",
       "        const fetureIndex = Object.values(column.columns)\n",
       "              .findIndex((feture) =&gt; feture.numberSummary)\n",
       "\n",
       "        return Object.keys(column.columns)[fetureIndex]\n",
       "      }\n",
       "\n",
       "      const alertListItemStatus = (status, passedItem, failedItem) =&gt; {\n",
       "        if (status) {\n",
       "          return passedItem\n",
       "        } else {\n",
       "          return failedItem\n",
       "        }\n",
       "      }\n",
       "\n",
       "      const alertListElement = (name, text, status, summary) =&gt; {\n",
       "        if (summary == null){\n",
       "          return (\n",
       "          `&lt;div\n",
       "             data-inferred-type=${alertListItemStatus(status, &quot;passed&quot;, &quot;failed&quot;)}\n",
       "             class=&quot;alert-list-item display-flex justify-content-space-between align-items-center mb-2&quot;\n",
       "           &gt;\n",
       "            &lt;div class=&quot;alert-list-text&quot;&gt;\n",
       "              ${\n",
       "                name &amp;&amp;\n",
       "                alertListItemStatus(\n",
       "                  status,\n",
       "                  `&lt;mark class=&quot;blue-mark&quot;&gt;${name}&lt;/mark&gt;`,\n",
       "                  `&lt;mark class=&quot;red-mark&quot;&gt;${name}&lt;/mark&gt;`\n",
       "                )\n",
       "              }\n",
       "              ${text}\n",
       "            &lt;/div&gt;\n",
       "              ${\n",
       "                alertListItemStatus(\n",
       "                  status,\n",
       "                  `\n",
       "                  &lt;div class=&quot;turquoise-background-color alert-tag&quot;&gt;Passed&lt;/div&gt;\n",
       "                  `\n",
       "                  ,\n",
       "                  `\n",
       "                  &lt;div class=&quot;bordeaux-background-color alert-tag&quot;&gt;Failed&lt;/div&gt;\n",
       "                  `\n",
       "                )\n",
       "              }\n",
       "              &lt;/div&gt;`\n",
       "        )\n",
       "\n",
       "        }\n",
       "        return (\n",
       "          `&lt;div\n",
       "             data-inferred-type=${alertListItemStatus(status, &quot;passed&quot;, &quot;failed&quot;)}\n",
       "             class=&quot;alert-list-item display-flex justify-content-space-between align-items-center mb-2&quot;\n",
       "           &gt;\n",
       "            &lt;div class=&quot;alert-list-text&quot;&gt;\n",
       "              ${\n",
       "                name &amp;&amp;\n",
       "                alertListItemStatus(\n",
       "                  status,\n",
       "                  `&lt;mark class=&quot;blue-mark&quot;&gt;${name}&lt;/mark&gt;`,\n",
       "                  `&lt;mark class=&quot;red-mark&quot;&gt;${name}&lt;/mark&gt;`\n",
       "                )\n",
       "              }\n",
       "              ${text}\n",
       "            &lt;/div&gt;\n",
       "              ${\n",
       "                alertListItemStatus(\n",
       "                  status,\n",
       "                  `\n",
       "                  &lt;div class=&quot;tooltip-full-number&quot;&gt;\n",
       "                    &lt;div class=&quot;turquoise-background-color alert-tag&quot;&gt;Passed\n",
       "                      &lt;span class=&quot;tooltiptext&quot;&gt;\n",
       "                          &lt;pre class=&quot;mb-1&quot;&gt; ${JSON.stringify(summary, null, 2)} &lt;/pre&gt;\n",
       "                        &lt;/span&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;`\n",
       "\n",
       "                  ,\n",
       "                  `\n",
       "                  &lt;div class=&quot;tooltip-full-number&quot;&gt;\n",
       "                    &lt;div class=&quot;bordeaux-background-color alert-tag&quot;&gt;Failed\n",
       "                      &lt;span class=&quot;tooltiptext&quot;&gt;\n",
       "                        &lt;pre class=&quot;mb-1&quot;&gt; ${JSON.stringify(summary, null, 2)} &lt;/pre&gt;\n",
       "                        &lt;/span&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;`\n",
       "                )\n",
       "              }\n",
       "              &lt;/div&gt;`\n",
       "        )\n",
       "      }\n",
       "\n",
       "      let failedConstraints = 0;\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getProfileTimeStamp&quot;, function (column) {\n",
       "        return formatLabelDate(+column.properties.dataTimestamp)\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getProfileName&quot;, function (column) {\n",
       "        return column.properties.tags.name\n",
       "      });\n",
       "\n",
       "\n",
       "      Handlebars.registerHelper(&quot;alertLIst&quot;, function (column) {\n",
       "        let alertListItem = column.map((value) =&gt; {\n",
       "          if (value[1][0]) {\n",
       "            let alertListValue = value[1].map((cstr)=&gt;{\n",
       "              return alertListElement(value[0],cstr[0],cstr[cstr.length - 1] === 0 || (failedConstraints++, false), value[3])\n",
       "            })\n",
       "            return alertListValue.join(&#x27; &#x27;)\n",
       "          } else {\n",
       "            return alertListElement(&#x27;&#x27;, value[0], value[2] === 0 ||  (failedConstraints++, false), value[3])\n",
       "          }\n",
       "        })\n",
       "         $(document).ready(() =&gt; {\n",
       "           $(&quot;.wl__feature-count--discrete&quot;).append(failedConstraints)\n",
       "           $(&quot;.wl__feature-count--non-discrete&quot;).append(column.length - failedConstraints)\n",
       "           $(&quot;.wl__feature-count--unknown&quot;).append(column.length)\n",
       "         })\n",
       "        return alertListItem.join(&#x27; &#x27;)\n",
       "      });\n",
       "\n",
       "    }\n",
       "\n",
       "    function openFilter() {\n",
       "      const $filterOptions = $(&quot;.dropdown-container&quot;);\n",
       "      const filterClass = $filterOptions.attr(&quot;class&quot;);\n",
       "\n",
       "      if (filterClass.indexOf(&quot;d-none&quot;) &gt; 0) {\n",
       "        $filterOptions.removeClass(&quot;d-none&quot;);\n",
       "        $(&quot;.filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.close-filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "      } else {\n",
       "        $filterOptions.addClass(&quot;d-none&quot;);\n",
       "        $(&quot;.close-filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "      }\n",
       "    }\n",
       "\n",
       "    function initHandlebarsTemplate() {\n",
       "      // Replace this context with JSON from .py file\n",
       "      const context = [[&quot;count of legs lower than 10&quot;, 1, 0, {&quot;metric&quot;: &quot;counts&quot;, &quot;n&quot;: 5, &quot;null&quot;: 1, &quot;nan&quot;: 1, &quot;inf&quot;: 0}], [&quot;null percentage of legs lower than 0.05&quot;, 0, 1, {&quot;metric&quot;: &quot;counts&quot;, &quot;n&quot;: 5, &quot;null&quot;: 1, &quot;nan&quot;: 1, &quot;inf&quot;: 0}], [&quot;null values of legs lower than 1&quot;, 0, 1, {&quot;metric&quot;: &quot;counts&quot;, &quot;n&quot;: 5, &quot;null&quot;: 1, &quot;nan&quot;: 1, &quot;inf&quot;: 0}], [&quot;legs has no missing values&quot;, 0, 1, {&quot;metric&quot;: &quot;counts&quot;, &quot;n&quot;: 5, &quot;null&quot;: 1, &quot;nan&quot;: 1, &quot;inf&quot;: 0}], [&quot;animal has no missing values&quot;, 1, 0, {&quot;metric&quot;: &quot;counts&quot;, &quot;n&quot;: 5, &quot;null&quot;: 0, &quot;nan&quot;: 0, &quot;inf&quot;: 0}]];\n",
       "      // Config handlebars and pass data to HBS template\n",
       "      const source = document.getElementById(&quot;entry-template&quot;).innerHTML;\n",
       "      const template = Handlebars.compile(source);\n",
       "      const html = template(context);\n",
       "      const target = document.getElementById(&quot;generated-html&quot;);\n",
       "      target.innerHTML = html;\n",
       "    }\n",
       "\n",
       "    function initWebsiteScripts() {\n",
       "      const $featureSearch = document.getElementById(&quot;wl__feature-search&quot;);\n",
       "      const $alertList = document.getElementById(&quot;alert-list&quot;);\n",
       "      const $discrete = document.getElementById(&quot;inferredDiscrete&quot;);\n",
       "      const $nonDiscrete = document.getElementById(&quot;inferredNonDiscrete&quot;);\n",
       "      const $unknown = document.getElementById(&quot;inferredUnknown&quot;);\n",
       "\n",
       "      const activeTypes = {\n",
       "        passed: true,\n",
       "        failed: true\n",
       "      };\n",
       "\n",
       "      let searchString = &quot;&quot;;\n",
       "\n",
       "      function debounce(func, wait, immediate) {\n",
       "        let timeout;\n",
       "\n",
       "        return function () {\n",
       "          const context = this;\n",
       "          const args = arguments;\n",
       "          const later = function () {\n",
       "            timeout = null;\n",
       "            if (!immediate) func.apply(context, args);\n",
       "          };\n",
       "\n",
       "          const callNow = immediate &amp;&amp; !timeout;\n",
       "          clearTimeout(timeout);\n",
       "          timeout = setTimeout(later, wait);\n",
       "          if (callNow) func.apply(context, args);\n",
       "        };\n",
       "      }\n",
       "\n",
       "      function filterNotification() {\n",
       "        const $notifCircleContainer = $(&quot;.notif-circle-container&quot;)\n",
       "        const $boxes = $(&#x27;.wl_filter-options&gt;.form-check&gt;input[name=checkbox]:checked&#x27;);\n",
       "        const item = Object.values($boxes).find(function(value) { return $(value)[0] === undefined});\n",
       "        if (item === undefined) {\n",
       "          $notifCircleContainer.removeClass(&quot;d-none&quot;)\n",
       "        } else {\n",
       "          $notifCircleContainer.addClass(&quot;d-none&quot;)\n",
       "        }\n",
       "      }\n",
       "\n",
       "      function handleSearch() {\n",
       "        const tableBodyChildren = $alertList.children;\n",
       "\n",
       "        for (let i = 0; i &lt; tableBodyChildren.length; i++) {\n",
       "          const type = tableBodyChildren[i].dataset.inferredType.toLowerCase();\n",
       "          const name = $(tableBodyChildren[i].children[0]).html().toLowerCase();\n",
       "          if (activeTypes[type] &amp;&amp; name.includes(searchString)) {\n",
       "            tableBodyChildren[i].style.display = &quot;&quot;;\n",
       "          } else {\n",
       "            tableBodyChildren[i].style.display = &quot;none&quot;;\n",
       "          }\n",
       "        }\n",
       "      }\n",
       "\n",
       "      const checkedBoxes = () =&gt; {\n",
       "        if ($(&#x27;.form-check-input:checked&#x27;).length === $(&quot;.form-check-input&quot;).length - 1) {\n",
       "          $($(&quot;.form-check-input&quot;)[$(&quot;.form-check-input&quot;).length - 1]).prop( &quot;checked&quot;, true );\n",
       "        }\n",
       "      }\n",
       "\n",
       "      $featureSearch.addEventListener(\n",
       "        &quot;keyup&quot;,\n",
       "        debounce((event) =&gt; {\n",
       "          searchString = event.target.value.toLowerCase();\n",
       "          handleSearch();\n",
       "        }, 100),\n",
       "      );\n",
       "\n",
       "      $discrete.addEventListener(&quot;change&quot;, (event) =&gt; {\n",
       "        const currentCheckbox = $(event.currentTarget);\n",
       "\n",
       "        if (event.currentTarget.checked) {\n",
       "          activeTypes[&quot;failed&quot;] = true;\n",
       "          checkedBoxes();\n",
       "        } else {\n",
       "          activeTypes[&quot;failed&quot;] = false;\n",
       "          $($(&quot;.form-check-input&quot;)[$(&quot;.form-check-input&quot;).length - 1]).prop( &quot;checked&quot;, false );\n",
       "        }\n",
       "        handleSearch();\n",
       "      });\n",
       "\n",
       "      $nonDiscrete.addEventListener(&quot;change&quot;, (event) =&gt; {\n",
       "        const currentCheckbox = $(event.currentTarget);\n",
       "\n",
       "        if (event.currentTarget.checked) {\n",
       "          activeTypes[&quot;passed&quot;] = true;\n",
       "          checkedBoxes();\n",
       "        } else {\n",
       "          activeTypes[&quot;passed&quot;] = false;\n",
       "          $($(&quot;.form-check-input&quot;)[$(&quot;.form-check-input&quot;).length - 1]).prop( &quot;checked&quot;, false );\n",
       "        }\n",
       "        handleSearch();\n",
       "      });\n",
       "\n",
       "      $unknown.addEventListener(&quot;change&quot;, (event) =&gt; {\n",
       "        const currentCheckbox = $(event.currentTarget);\n",
       "\n",
       "        if (event.currentTarget.checked) {\n",
       "          $(&quot;.form-check-input&quot;).prop( &quot;checked&quot;, true );\n",
       "          activeTypes[&quot;passed&quot;] = true;\n",
       "          activeTypes[&quot;failed&quot;] = true;\n",
       "          checkedBoxes();\n",
       "        } else {\n",
       "          $(&quot;.form-check-input&quot;).prop( &quot;checked&quot;, false );\n",
       "          activeTypes[&quot;passed&quot;] = false;\n",
       "          activeTypes[&quot;failed&quot;] = false;\n",
       "        }\n",
       "        handleSearch();\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function checkedBoxes() {\n",
       "      const $boxes = $(&#x27;input[name=checkbox]:checked&#x27;);\n",
       "      const $notifCircleContainer = $(&quot;.notif-circle-container&quot;)\n",
       "\n",
       "      if ($boxes.length) {\n",
       "        $notifCircleContainer.removeClass(&quot;d-none&quot;)\n",
       "      }\n",
       "    }\n",
       "\n",
       "    function openFilter() {\n",
       "      const $filterOptions = $(&quot;.dropdown-container&quot;);\n",
       "      const $notifCircleContainer = $(&quot;.notif-circle-container&quot;)\n",
       "      const filterClass = $filterOptions.attr(&quot;class&quot;);\n",
       "\n",
       "      if (filterClass.indexOf(&quot;d-none&quot;) &gt; 0) {\n",
       "        $notifCircleContainer.addClass(&quot;d-none&quot;)\n",
       "        $filterOptions.removeClass(&quot;d-none&quot;);\n",
       "        $(&quot;.filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.close-filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "      } else {\n",
       "        $filterOptions.addClass(&quot;d-none&quot;);\n",
       "        $(&quot;.close-filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "        checkedBoxes()\n",
       "      }\n",
       "    }\n",
       "\n",
       "    // Invoke functions -- keep in mind invokation order\n",
       "    registerHandlebarHelperFunctions();\n",
       "    initHandlebarsTemplate();\n",
       "    initWebsiteScripts();\n",
       "  &lt;/script&gt;\n",
       "&lt;/html&gt;\n",
       "\" width=100% height=300\n",
       "        frameBorder=0></iframe>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "builder = ConstraintsBuilder(dataset_profile_view=profile_view)\n",
    "builder.add_constraint(count_below_number(column_name=\"legs\", number=10))\n",
    "builder.add_constraint(null_percentage_below_number(column_name=\"legs\", number=0.05))\n",
    "builder.add_constraint(null_values_below_number(column_name=\"legs\", number=1))\n",
    "builder.add_constraint(no_missing_values(column_name=\"legs\"))\n",
    "builder.add_constraint(no_missing_values(column_name=\"animal\"))\n",
    "\n",
    "constraints = builder.build()\n",
    "\n",
    "from whylogs.viz import NotebookProfileVisualizer\n",
    "\n",
    "visualization = NotebookProfileVisualizer()\n",
    "visualization.constraints_report(constraints, cell_height=300)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Cardinality Constraints <a class=\"anchor\" id=\"card\"></a>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "from whylogs.core.constraints.factories import distinct_number_in_range"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Examples - Cardinality Constraints"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "import whylogs as why\n",
    "import pandas as pd\n",
    "data = {\n",
    "    \"animal\": [\"cat\", \"snake\", \"snake\", \"cat\", \"mosquito\"],\n",
    "    \"legs\": [4, 2, 0, None, 6],\n",
    "    \"weight\": [4.3, 1.8, 1.3, 4.1, 5.5e-6],\n",
    "}\n",
    "\n",
    "results = why.log(pd.DataFrame(data))\n",
    "profile_view = results.view()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div></div><iframe srcdoc=\"&lt;!DOCTYPE html&gt;\n",
       "&lt;html lang=&quot;en&quot;&gt;\n",
       "  &lt;head&gt;\n",
       "    &lt;meta charset=&quot;UTF-8&quot; /&gt;\n",
       "    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot; /&gt;\n",
       "    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;\n",
       "    &lt;meta name=&quot;description&quot; content=&quot;&quot; /&gt;\n",
       "    &lt;meta name=&quot;author&quot; content=&quot;&quot; /&gt;\n",
       "\n",
       "    &lt;title&gt;Profile Visualizer | whylogs&lt;/title&gt;\n",
       "\n",
       "    &lt;link rel=&quot;icon&quot; href=&quot;images/whylabs-favicon.png&quot; type=&quot;image/png&quot; sizes=&quot;16x16&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.googleapis.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; crossorigin /&gt;\n",
       "    &lt;link href=&quot;https://fonts.googleapis.com/css2?family=Asap:wght@400;500;600;700&amp;display=swap&quot; rel=&quot;stylesheet&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css&quot; /&gt;\n",
       "\n",
       "    &lt;script\n",
       "      src=&quot;https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js&quot;\n",
       "      integrity=&quot;sha512-RNLkV3d+aLtfcpEyFG8jRbnWHxUqVZozacROI4J2F1sTaDqo1dPQYs01OMi1t1w9Y2FdbSCDSQ2ZVdAC8bzgAg==&quot;\n",
       "      crossorigin=&quot;anonymous&quot;\n",
       "      referrerpolicy=&quot;no-referrer&quot;\n",
       "    &gt;&lt;/script&gt;\n",
       "\n",
       "    &lt;style type=&quot;text/css&quot;&gt;\n",
       "\n",
       "      /* Screen on smaller screens */\n",
       "      .no-responsive {\n",
       "        display: none;\n",
       "        position: fixed;\n",
       "        top: 0;\n",
       "        left: 0;\n",
       "        z-index: 1031;\n",
       "        width: 100vw;\n",
       "        height: 100vh;\n",
       "        background-color: var(--tealBackground);\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      @media screen and (min-width: 1000px) {\n",
       "        .desktop-content {\n",
       "          display: block;\n",
       "        }\n",
       "        .no-responsive {\n",
       "          display: none;\n",
       "        }\n",
       "      }\n",
       "\n",
       "      .no-responsive__content {\n",
       "        max-width: 600px;\n",
       "        width: 100%;\n",
       "        padding: 0 24px;\n",
       "      }\n",
       "\n",
       "      .no-responsive__title {\n",
       "        font-size: 96px;\n",
       "        font-weight: 300;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.167;\n",
       "      }\n",
       "\n",
       "      .no-responsive__text {\n",
       "        margin: 0;\n",
       "        font-size: 16px;\n",
       "        font-weight: 400;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.5;\n",
       "      }\n",
       "\n",
       "      .header-title {\n",
       "        font-size: 26px;\n",
       "        font-weight: 700;\n",
       "        color: #444444;\n",
       "      }\n",
       "\n",
       "      .tooltip-full-number {\n",
       "        position: relative;\n",
       "        display: inline-block;\n",
       "      }\n",
       "\n",
       "      .tooltip-full-number .tooltiptext {\n",
       "        visibility: hidden;\n",
       "        background: black;\n",
       "        color: white;\n",
       "        border: 1px solid black;\n",
       "        text-align: start;\n",
       "        padding: 3px;\n",
       "        position: absolute;\n",
       "        z-index: 1;\n",
       "        top: 0;\n",
       "        left: 100%;\n",
       "        margin-left: 5px;\n",
       "        opacity: 0;\n",
       "        transition: opacity 0.5s;\n",
       "        font-size: 13px;\n",
       "        font-weight: normal;\n",
       "        line-height: 100%;\n",
       "      }\n",
       "\n",
       "      .tooltip-full-number:hover .tooltiptext {\n",
       "        visibility: visible;\n",
       "        opacity: 1;\n",
       "      }\n",
       "\n",
       "\n",
       "      .wl-compare-profile {\n",
       "        position: relative;\n",
       "        left: 0;\n",
       "        padding: 30px;\n",
       "        margin-bottom: 20px;\n",
       "        background: var(--white);;\n",
       "        border-bottom: 1px solid #CED4DA;\n",
       "      }\n",
       "\n",
       "      .alert-list {\n",
       "        padding: 30px;\n",
       "        padding-top: 0;\n",
       "      }\n",
       "\n",
       "    .drift-detection {\n",
       "       justify-content: space-between;\n",
       "       align-items: center;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-circle {\n",
       "       width: 15px;\n",
       "       height: 15px;\n",
       "       border-radius: 50px;\n",
       "       display: inline-block;\n",
       "       margin-right: 8px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-drifts-item {\n",
       "         padding-right: 20px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-title {\n",
       "       font-family: Arial;\n",
       "       font-weight: bold;\n",
       "       font-size: 22px;\n",
       "       line-height: 130%;\n",
       "       color: #313B3D;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-drifts-item-count {\n",
       "       font-family: Arial;\n",
       "       font-weight: bold;\n",
       "       font-size: 14px;\n",
       "       line-height: 16px;\n",
       "       color: #000000;\n",
       "       padding-right: 8px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-drifts-item-name {\n",
       "       font-family: Arial;\n",
       "       font-style: normal;\n",
       "       font-weight: normal;\n",
       "       font-size: 12px;\n",
       "       line-height: 14px;\n",
       "       color: #000000;\n",
       "     }\n",
       "\n",
       "     .drift-detection-search-input {\n",
       "       display: flex;\n",
       "       align-items: center;\n",
       "       background: rgba(255, 255, 255, 0.7);\n",
       "       border: 1px solid #DBE5E7;\n",
       "       box-sizing: border-box;\n",
       "       border-radius: 4px;\n",
       "       width: 170px;\n",
       "       padding-left: 10px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-search-input img{\n",
       "       margin-right: 5px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-search-input input::placeholder {\n",
       "       font-family: Arial;\n",
       "       font-weight: normal;\n",
       "       font-size: 13px;\n",
       "       line-height: 16px;\n",
       "       color: #313B3D;\n",
       "     }\n",
       "\n",
       "     .dropdown-container {\n",
       "       position: absolute;\n",
       "       right: 30px;\n",
       "       top: 80px;\n",
       "       z-index: 999;\n",
       "       background: #FFFFFF;\n",
       "       border: 1px solid #DBE5E7;\n",
       "       box-sizing: border-box;\n",
       "       box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.05);\n",
       "       border-radius: 4px;\n",
       "       padding: 10px !important;\n",
       "       border: none !important;\n",
       "     }\n",
       "\n",
       "     .filter-options-title {\n",
       "       width: 240px;\n",
       "     }\n",
       "\n",
       "     .filter-options-title p {\n",
       "       margin: 0;\n",
       "     }\n",
       "\n",
       "     .form-check-input:checked {\n",
       "       background-color: #0E7384;\n",
       "       border-color: #0E7384;\n",
       "     }\n",
       "\n",
       "     .form-check-input[type=checkbox] {\n",
       "       border-radius: 2px;\n",
       "     }\n",
       "\n",
       "     .search-input{\n",
       "       padding-top: 0 !important;\n",
       "       padding-bottom: 0 !important;\n",
       "     }\n",
       "\n",
       "     .search-input input{\n",
       "       border: none;\n",
       "       background: none;\n",
       "       outline: none;\n",
       "       height: 40px;\n",
       "       width: 100%;\n",
       "       font-size: 14px;\n",
       "     }\n",
       "\n",
       "     .search-input img{\n",
       "       height: 19px;\n",
       "       pointer-events: none;\n",
       "     }\n",
       "\n",
       "     input::placeholder {\n",
       "       color: var(--secondaryLight1000);\n",
       "     }\n",
       "\n",
       "      .statistics {\n",
       "        width: 100%;\n",
       "      }\n",
       "\n",
       "     .close-filter-button {\n",
       "       display: flex;\n",
       "       justify-content: center;\n",
       "       align-items: center;\n",
       "       background: rgba(255, 255, 255, 0.7);\n",
       "       border: 1px solid #369BAC;\n",
       "       box-sizing: border-box;\n",
       "       border-radius: 4px;\n",
       "       width: 40px;\n",
       "       height: 40px;\n",
       "       cursor: pointer;\n",
       "       margin-left: 10px;\n",
       "     }\n",
       "\n",
       "      .statistic-number-title {\n",
       "        font-family: Arial;\n",
       "        font-weight: normal;\n",
       "        font-size: 14px;\n",
       "        line-height: 20px;\n",
       "        color: #6C757D;\n",
       "      }\n",
       "\n",
       "      .statistic-number {\n",
       "        font-family: Arial;\n",
       "        font-weight: bold;\n",
       "        font-size: 20px;\n",
       "        line-height: 140%;\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "        color: #4F595B;\n",
       "      }\n",
       "\n",
       "      .full-summary-statistics-wrap {\n",
       "        padding: 20px;\n",
       "      }\n",
       "\n",
       "      .statistics {\n",
       "        width: 100%;\n",
       "      }\n",
       "\n",
       "      .statistics-list {\n",
       "        width: 100% ;\n",
       "      }\n",
       "\n",
       "      mark {\n",
       "        padding: 5px;\n",
       "        border-radius: 4px;\n",
       "        font-family: Arial;\n",
       "        font-weight: normal;\n",
       "        font-size: 14px;\n",
       "        line-height: 140%;\n",
       "      }\n",
       "\n",
       "      .blue-mark {\n",
       "        background-color:  #369BAC1A;\n",
       "        color: #369BAC;\n",
       "      }\n",
       "\n",
       "      .red-mark {\n",
       "        background-color: #FFEFEE;\n",
       "        color: #F5473C;\n",
       "      }\n",
       "\n",
       "      .alert-tag {\n",
       "        height: 27px;\n",
       "        padding: 5px;\n",
       "        border-radius: 4px;\n",
       "        font-family: Arial;\n",
       "        font-weight: bold;\n",
       "        font-size: 12px;\n",
       "        line-height: 140%;\n",
       "        color: #FFFFFF;\n",
       "      }\n",
       "\n",
       "      .turquoise-background-color {\n",
       "        background-color: #1DBB42;\n",
       "      }\n",
       "\n",
       "      .bordeaux-background-color {\n",
       "        background-color: #C6462A;\n",
       "      }\n",
       "\n",
       "      .border-solid-gray {\n",
       "        border: 1px solid #CED4DA;\n",
       "        border-radius: 4px;\n",
       "      }\n",
       "\n",
       "      .display-flex {\n",
       "        display: flex;\n",
       "      }\n",
       "\n",
       "      .justify-content-space-between {\n",
       "        justify-content: space-between;\n",
       "      }\n",
       "\n",
       "      .justify-content-center {\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      .align-items-center {\n",
       "        align-items: center;\n",
       "      }\n",
       "\n",
       "      .align-items-flex-start {\n",
       "        align-items: flex-start;\n",
       "      }\n",
       "\n",
       "      .padding-right-30 {\n",
       "        padding-right: 30px;\n",
       "      }\n",
       "\n",
       "      .notif-circle-container{\n",
       "        position: absolute;\n",
       "        top: 25px;\n",
       "        right: 25px;\n",
       "        padding: 5.3px;\n",
       "        border-radius: 50%;\n",
       "        background-color: white;\n",
       "        cursor: pointer;\n",
       "      }\n",
       "\n",
       "      .notif-circle {\n",
       "        position: absolute;\n",
       "        top: 2px;\n",
       "        right: 2px;\n",
       "        padding: 3.3px;\n",
       "        border-radius: 50%;\n",
       "        background-color: #F2994A;\n",
       "      }\n",
       "\n",
       "      .alert-list-text {\n",
       "        width: 70%\n",
       "      }\n",
       "\n",
       "     @media screen and (min-width: 500px) {\n",
       "       .desktop-content {\n",
       "         display: block;\n",
       "       }\n",
       "       .no-responsive {\n",
       "         display: none;\n",
       "       }\n",
       "     }\n",
       "    &lt;/style&gt;\n",
       "  &lt;/head&gt;\n",
       "\n",
       "  &lt;body id=&quot;generated-html&quot;&gt;&lt;/body&gt;\n",
       "\n",
       "  &lt;script id=&quot;entry-template&quot; type=&quot;text/x-handlebars-template&quot;&gt;\n",
       "    \n",
       "      &lt;div class=&quot;desktop-content&quot;&gt;\n",
       "        &lt;div class=&quot;full-summary-statistics-wrap&quot;&gt;\n",
       "          &lt;div class=&quot;full-summary-statistics&quot;&gt;\n",
       "            &lt;div&gt;\n",
       "              &lt;div class=&quot;display-flex justify-content-center&quot;&gt;\n",
       "                &lt;div class=&quot;statistics-list border-solid-gray&quot;&gt;\n",
       "                  &lt;div&gt;\n",
       "                    &lt;div class=&quot;wl-compare-profile&quot; id=&quot;compare-profile&quot;&gt;\n",
       "                        &lt;div class=&quot;drift-detection-wrap&quot;&gt;\n",
       "                          &lt;div class=&quot;drift-detection display-flex align-items-flex-start&quot;&gt;\n",
       "                            &lt;div class=&quot;drift-detection-info flex-direction-colum&quot;&gt;\n",
       "                              &lt;div class=&quot;drift-detection-info-title-wrap display-flex&quot;&gt;\n",
       "                                &lt;p class=&quot;drift-detection-info-title&quot;&gt;\n",
       "                                  Constraints Report\n",
       "                                &lt;/p&gt;\n",
       "                              &lt;/div&gt;\n",
       "\n",
       "                              &lt;!-- &lt;/div&gt; --&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;div class=&quot;drift-detection-search-input-wrap display-flex&quot;&gt;\n",
       "                              &lt;div class=&quot;drift-detection-search-input search-input&quot;&gt;\n",
       "                                &lt;input type=&quot;text&quot; id=&quot;wl__feature-search&quot; placeholder=&quot;Quick search...&quot;/&gt;\n",
       "                                &lt;img src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAGdSURBVHgBpZK7TkJBEIZnZoVocdTYyQNALxpNKPQBMEaNJsbCRMKhl8ISWwt6AaksCF5iTHgAGhJD4AHkAaAzGiwUsjvOQnO4SYh/cXbPzO43OxcEj9Zy92EiFSXNIfvPyE1kKFfdoxJMENpP6DrvLC0vJoEwCgwto7DWcxoIIHBYbA3NmKwnDltjAeuZhyul1DaTTlfPB6Nt5Z53DOgky4P875+nlctY2+unjZviLklkJhi5bPUa3y/7qJuQUM7PinMy7CdQc1Gh16vnBxPzrMROmlKQEgKNASAHLQCmSIGpS75O+O5pdQAgVXaIqTkNwDDXHmcnW3VmHZoGMLoTsOt88+NrAMCIZdu+iLTyTwKRa1Md6YKfOgXbzO7K8sWku5u5RxcRV5EpPezrzcHGbXEXWaUkgkweZ/UC9YrK3zqggFw5FBZfm8EUavHj7AjAKpIvBDrGn+pNnlcyhYgqbcC41idr1gvB4SdZkDbzQa21gwv0Vj07aPTtL07XdDOyDXohCDNoHIRmAVRie20f+RKybRDQDvxHkXy/7b/DrayncLbMwQAAAABJRU5ErkJggg==&quot;/&gt;\n",
       "                              &lt;/div&gt;\n",
       "                              &lt;div class=&quot;wl__dropdown_arrow-icon&quot;&gt;\n",
       "                                &lt;div onclick=&quot;openFilter()&quot; class=&quot;close-filter-button&quot;&gt;\n",
       "                                &lt;div class=&quot;display-flex close-filter-icon d-none&quot;&gt;\n",
       "                                  &lt;img src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAADFSURBVHgBfY+xDcIwEEXvnLQBZQkYAEhDwwKpEEK0CCZgAEjJCEmgjYSAygxAHTZgFRSOsyUjY5mcZFnn/+78PwBXf3+MoKWUPuYjVBPFnTwpr9t/oNJfcTfXsAhRAlDqDhhQIPYgpAqNMDqcUqSAYZT1epr9gAHt6uXshvYme4DYHQJNDKh0dD0m5WXB10Y3Fqjtuh7fROn3oREDWxfeMLyRsMnc0OgDzdduaA0Pi3Plgr7Q2kaAePeBqh6rueSNBVt6fgCwBV1JLF3rlAAAAABJRU5ErkJggg==&quot;/&gt;\n",
       "                                &lt;/div&gt;\n",
       "                                &lt;div class=&quot;display-flex filter-icon&quot;&gt;\n",
       "                                  &lt;img src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACSSURBVHgBrZLBCYAwDEWTUjw7igcdwI1cxkNXUJzBEVzFAbSVKoKmaVrEB6GHJv/w+AACtRk7P9IONv1QOYUl96k0zv61m2tjARoLtSDI3EFsgIJ4uoXrMLazO72CRG2mzg/8BSdVlEjhpGZJjAWdAZJECpWalEhJSs1pHuUlMad5FFai1Lwg4Ckx1TxKIPFL8w55mEWd8VjPGAAAAABJRU5ErkJggg==&quot;/&gt;\n",
       "                                &lt;/div&gt;\n",
       "                                &lt;/div&gt;\n",
       "                              &lt;span class=&quot;notif-circle-container&quot;&gt;\n",
       "                                &lt;span class=&quot;notif-circle&quot;&gt;&lt;/span&gt;\n",
       "                              &lt;/span&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;/div&gt;\n",
       "                          &lt;/div&gt;\n",
       "                        &lt;/div&gt;\n",
       "                        &lt;div class=&quot;dropdown-container flex-direction-colum mb-2 d-none&quot; id=&quot;dropdown-container&quot;&gt;\n",
       "                          &lt;div class=&quot;filter-options&quot;&gt;\n",
       "                            &lt;div class=&quot;filter-options-title space-between dropdown&quot;&gt;\n",
       "                              &lt;p&gt;Select a view:&lt;/p&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;div class=&quot;form-check mb-1 mt-2&quot;&gt;\n",
       "                              &lt;input\n",
       "                                class=&quot;form-check-input wl__feature-filter-input&quot;\n",
       "                                type=&quot;checkbox&quot;\n",
       "                                name=&quot;checkbox&quot;\n",
       "                                value=&quot;Discrete&quot;\n",
       "                                id=&quot;inferredDiscrete&quot;\n",
       "                                checked\n",
       "                              /&gt;\n",
       "                              &lt;label class=&quot;form-check-label&quot; for=&quot;inferredDiscrete&quot;&gt;\n",
       "                                Failed constraints (&lt;span class=&quot;wl__feature-count--discrete&quot;&gt;&lt;/span&gt;)\n",
       "                              &lt;/label&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;div class=&quot;form-check mb-1&quot;&gt;\n",
       "                              &lt;input\n",
       "                                class=&quot;form-check-input wl__feature-filter-input&quot;\n",
       "                                type=&quot;checkbox&quot;\n",
       "                                name=&quot;checkbox&quot;\n",
       "                                value=&quot;Non-discrete&quot;\n",
       "                                id=&quot;inferredNonDiscrete&quot;\n",
       "                                checked\n",
       "                              /&gt;\n",
       "                              &lt;label class=&quot;form-check-label&quot; for=&quot;inferredNonDiscrete&quot;&gt;\n",
       "                                Passed constraints (&lt;span\n",
       "                                  class=&quot;wl__feature-count--non-discrete&quot;\n",
       "                                &gt;&lt;/span&gt;)\n",
       "                              &lt;/label&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;div class=&quot;form-check mb-1&quot;&gt;\n",
       "                              &lt;input\n",
       "                                class=&quot;form-check-input wl__feature-filter-input&quot;\n",
       "                                type=&quot;checkbox&quot;\n",
       "                                name=&quot;checkbox&quot;\n",
       "                                value=&quot;Unknown&quot;\n",
       "                                id=&quot;inferredUnknown&quot;\n",
       "                                checked\n",
       "                              /&gt;\n",
       "                              &lt;label class=&quot;form-check-label&quot; for=&quot;inferredUnknown&quot;&gt;\n",
       "                                All constraints (&lt;span class=&quot;wl__feature-count--unknown&quot;&gt;&lt;/span&gt;)\n",
       "                              &lt;/label&gt;\n",
       "                            &lt;/div&gt;\n",
       "                          &lt;/div&gt;\n",
       "                        &lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                    &lt;div class=&quot;alert-list&quot; id=&quot;alert-list&quot;&gt;\n",
       "                      {{{alertLIst this}}}\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                &lt;/div&gt;\n",
       "              &lt;/div&gt;\n",
       "            &lt;/div&gt;\n",
       "          &lt;/div&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "      &lt;div class=&quot;no-responsive&quot;&gt;\n",
       "        &lt;div class=&quot;no-responsive__content&quot;&gt;\n",
       "          &lt;h1 class=&quot;no-responsive__title&quot;&gt;Hold on! :)&lt;/h1&gt;\n",
       "          &lt;p class=&quot;no-responsive__text&quot;&gt;\n",
       "            It looks like your current screen size or device is not yet supported by the WhyLabs Sandbox. The Sandbox is\n",
       "            best experienced on a desktop computer. Please try maximizing this window or switching to another device. We\n",
       "            are working on adding support for a larger variety of devices.\n",
       "          &lt;/p&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "    \n",
       "  &lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://code.jquery.com/jquery-3.6.0.min.js&quot; integrity=&quot;sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js&quot; integrity=&quot;sha512-cd6CHE+XWDQ33ElJqsi0MdNte3S+bQY819f7p3NUHgwQQLXSKjE4cPZTeGNI+vaxZynk1wVU3hoHmow3m089wA==&quot; crossorigin=&quot;anonymous&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script&gt;\n",
       "    function registerHandlebarHelperFunctions() {\n",
       "      //helper fun\n",
       "      function formatLabelDate(timestamp) {\n",
       "        const date = new Date(timestamp);\n",
       "        const format = d3.timeFormat(&quot;%Y-%m-%d %I:%M:%S %p %Z&quot;);\n",
       "        return format(date);\n",
       "      }\n",
       "\n",
       "      function fixNumberTo(number, decimals = 3) {\n",
       "        return parseFloat(number).toFixed(decimals);\n",
       "      }\n",
       "\n",
       "      const randomNumbers = (range) =&gt; Math.floor(Math.random() * range)\n",
       "\n",
       "      const findFetureWithNumberSummary = (column) =&gt; {\n",
       "        const fetureIndex = Object.values(column.columns)\n",
       "              .findIndex((feture) =&gt; feture.numberSummary)\n",
       "\n",
       "        return Object.keys(column.columns)[fetureIndex]\n",
       "      }\n",
       "\n",
       "      const alertListItemStatus = (status, passedItem, failedItem) =&gt; {\n",
       "        if (status) {\n",
       "          return passedItem\n",
       "        } else {\n",
       "          return failedItem\n",
       "        }\n",
       "      }\n",
       "\n",
       "      const alertListElement = (name, text, status, summary) =&gt; {\n",
       "        if (summary == null){\n",
       "          return (\n",
       "          `&lt;div\n",
       "             data-inferred-type=${alertListItemStatus(status, &quot;passed&quot;, &quot;failed&quot;)}\n",
       "             class=&quot;alert-list-item display-flex justify-content-space-between align-items-center mb-2&quot;\n",
       "           &gt;\n",
       "            &lt;div class=&quot;alert-list-text&quot;&gt;\n",
       "              ${\n",
       "                name &amp;&amp;\n",
       "                alertListItemStatus(\n",
       "                  status,\n",
       "                  `&lt;mark class=&quot;blue-mark&quot;&gt;${name}&lt;/mark&gt;`,\n",
       "                  `&lt;mark class=&quot;red-mark&quot;&gt;${name}&lt;/mark&gt;`\n",
       "                )\n",
       "              }\n",
       "              ${text}\n",
       "            &lt;/div&gt;\n",
       "              ${\n",
       "                alertListItemStatus(\n",
       "                  status,\n",
       "                  `\n",
       "                  &lt;div class=&quot;turquoise-background-color alert-tag&quot;&gt;Passed&lt;/div&gt;\n",
       "                  `\n",
       "                  ,\n",
       "                  `\n",
       "                  &lt;div class=&quot;bordeaux-background-color alert-tag&quot;&gt;Failed&lt;/div&gt;\n",
       "                  `\n",
       "                )\n",
       "              }\n",
       "              &lt;/div&gt;`\n",
       "        )\n",
       "\n",
       "        }\n",
       "        return (\n",
       "          `&lt;div\n",
       "             data-inferred-type=${alertListItemStatus(status, &quot;passed&quot;, &quot;failed&quot;)}\n",
       "             class=&quot;alert-list-item display-flex justify-content-space-between align-items-center mb-2&quot;\n",
       "           &gt;\n",
       "            &lt;div class=&quot;alert-list-text&quot;&gt;\n",
       "              ${\n",
       "                name &amp;&amp;\n",
       "                alertListItemStatus(\n",
       "                  status,\n",
       "                  `&lt;mark class=&quot;blue-mark&quot;&gt;${name}&lt;/mark&gt;`,\n",
       "                  `&lt;mark class=&quot;red-mark&quot;&gt;${name}&lt;/mark&gt;`\n",
       "                )\n",
       "              }\n",
       "              ${text}\n",
       "            &lt;/div&gt;\n",
       "              ${\n",
       "                alertListItemStatus(\n",
       "                  status,\n",
       "                  `\n",
       "                  &lt;div class=&quot;tooltip-full-number&quot;&gt;\n",
       "                    &lt;div class=&quot;turquoise-background-color alert-tag&quot;&gt;Passed\n",
       "                      &lt;span class=&quot;tooltiptext&quot;&gt;\n",
       "                          &lt;pre class=&quot;mb-1&quot;&gt; ${JSON.stringify(summary, null, 2)} &lt;/pre&gt;\n",
       "                        &lt;/span&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;`\n",
       "\n",
       "                  ,\n",
       "                  `\n",
       "                  &lt;div class=&quot;tooltip-full-number&quot;&gt;\n",
       "                    &lt;div class=&quot;bordeaux-background-color alert-tag&quot;&gt;Failed\n",
       "                      &lt;span class=&quot;tooltiptext&quot;&gt;\n",
       "                        &lt;pre class=&quot;mb-1&quot;&gt; ${JSON.stringify(summary, null, 2)} &lt;/pre&gt;\n",
       "                        &lt;/span&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;`\n",
       "                )\n",
       "              }\n",
       "              &lt;/div&gt;`\n",
       "        )\n",
       "      }\n",
       "\n",
       "      let failedConstraints = 0;\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getProfileTimeStamp&quot;, function (column) {\n",
       "        return formatLabelDate(+column.properties.dataTimestamp)\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getProfileName&quot;, function (column) {\n",
       "        return column.properties.tags.name\n",
       "      });\n",
       "\n",
       "\n",
       "      Handlebars.registerHelper(&quot;alertLIst&quot;, function (column) {\n",
       "        let alertListItem = column.map((value) =&gt; {\n",
       "          if (value[1][0]) {\n",
       "            let alertListValue = value[1].map((cstr)=&gt;{\n",
       "              return alertListElement(value[0],cstr[0],cstr[cstr.length - 1] === 0 || (failedConstraints++, false), value[3])\n",
       "            })\n",
       "            return alertListValue.join(&#x27; &#x27;)\n",
       "          } else {\n",
       "            return alertListElement(&#x27;&#x27;, value[0], value[2] === 0 ||  (failedConstraints++, false), value[3])\n",
       "          }\n",
       "        })\n",
       "         $(document).ready(() =&gt; {\n",
       "           $(&quot;.wl__feature-count--discrete&quot;).append(failedConstraints)\n",
       "           $(&quot;.wl__feature-count--non-discrete&quot;).append(column.length - failedConstraints)\n",
       "           $(&quot;.wl__feature-count--unknown&quot;).append(column.length)\n",
       "         })\n",
       "        return alertListItem.join(&#x27; &#x27;)\n",
       "      });\n",
       "\n",
       "    }\n",
       "\n",
       "    function openFilter() {\n",
       "      const $filterOptions = $(&quot;.dropdown-container&quot;);\n",
       "      const filterClass = $filterOptions.attr(&quot;class&quot;);\n",
       "\n",
       "      if (filterClass.indexOf(&quot;d-none&quot;) &gt; 0) {\n",
       "        $filterOptions.removeClass(&quot;d-none&quot;);\n",
       "        $(&quot;.filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.close-filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "      } else {\n",
       "        $filterOptions.addClass(&quot;d-none&quot;);\n",
       "        $(&quot;.close-filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "      }\n",
       "    }\n",
       "\n",
       "    function initHandlebarsTemplate() {\n",
       "      // Replace this context with JSON from .py file\n",
       "      const context = [[&quot;animal distinct values estimate between 3 and 6 (inclusive)&quot;, 1, 0, {&quot;metric&quot;: &quot;cardinality&quot;, &quot;est&quot;: 3.000000014901161, &quot;upper_1&quot;: 3.0001498026537594, &quot;lower_1&quot;: 3.0}]];\n",
       "      // Config handlebars and pass data to HBS template\n",
       "      const source = document.getElementById(&quot;entry-template&quot;).innerHTML;\n",
       "      const template = Handlebars.compile(source);\n",
       "      const html = template(context);\n",
       "      const target = document.getElementById(&quot;generated-html&quot;);\n",
       "      target.innerHTML = html;\n",
       "    }\n",
       "\n",
       "    function initWebsiteScripts() {\n",
       "      const $featureSearch = document.getElementById(&quot;wl__feature-search&quot;);\n",
       "      const $alertList = document.getElementById(&quot;alert-list&quot;);\n",
       "      const $discrete = document.getElementById(&quot;inferredDiscrete&quot;);\n",
       "      const $nonDiscrete = document.getElementById(&quot;inferredNonDiscrete&quot;);\n",
       "      const $unknown = document.getElementById(&quot;inferredUnknown&quot;);\n",
       "\n",
       "      const activeTypes = {\n",
       "        passed: true,\n",
       "        failed: true\n",
       "      };\n",
       "\n",
       "      let searchString = &quot;&quot;;\n",
       "\n",
       "      function debounce(func, wait, immediate) {\n",
       "        let timeout;\n",
       "\n",
       "        return function () {\n",
       "          const context = this;\n",
       "          const args = arguments;\n",
       "          const later = function () {\n",
       "            timeout = null;\n",
       "            if (!immediate) func.apply(context, args);\n",
       "          };\n",
       "\n",
       "          const callNow = immediate &amp;&amp; !timeout;\n",
       "          clearTimeout(timeout);\n",
       "          timeout = setTimeout(later, wait);\n",
       "          if (callNow) func.apply(context, args);\n",
       "        };\n",
       "      }\n",
       "\n",
       "      function filterNotification() {\n",
       "        const $notifCircleContainer = $(&quot;.notif-circle-container&quot;)\n",
       "        const $boxes = $(&#x27;.wl_filter-options&gt;.form-check&gt;input[name=checkbox]:checked&#x27;);\n",
       "        const item = Object.values($boxes).find(function(value) { return $(value)[0] === undefined});\n",
       "        if (item === undefined) {\n",
       "          $notifCircleContainer.removeClass(&quot;d-none&quot;)\n",
       "        } else {\n",
       "          $notifCircleContainer.addClass(&quot;d-none&quot;)\n",
       "        }\n",
       "      }\n",
       "\n",
       "      function handleSearch() {\n",
       "        const tableBodyChildren = $alertList.children;\n",
       "\n",
       "        for (let i = 0; i &lt; tableBodyChildren.length; i++) {\n",
       "          const type = tableBodyChildren[i].dataset.inferredType.toLowerCase();\n",
       "          const name = $(tableBodyChildren[i].children[0]).html().toLowerCase();\n",
       "          if (activeTypes[type] &amp;&amp; name.includes(searchString)) {\n",
       "            tableBodyChildren[i].style.display = &quot;&quot;;\n",
       "          } else {\n",
       "            tableBodyChildren[i].style.display = &quot;none&quot;;\n",
       "          }\n",
       "        }\n",
       "      }\n",
       "\n",
       "      const checkedBoxes = () =&gt; {\n",
       "        if ($(&#x27;.form-check-input:checked&#x27;).length === $(&quot;.form-check-input&quot;).length - 1) {\n",
       "          $($(&quot;.form-check-input&quot;)[$(&quot;.form-check-input&quot;).length - 1]).prop( &quot;checked&quot;, true );\n",
       "        }\n",
       "      }\n",
       "\n",
       "      $featureSearch.addEventListener(\n",
       "        &quot;keyup&quot;,\n",
       "        debounce((event) =&gt; {\n",
       "          searchString = event.target.value.toLowerCase();\n",
       "          handleSearch();\n",
       "        }, 100),\n",
       "      );\n",
       "\n",
       "      $discrete.addEventListener(&quot;change&quot;, (event) =&gt; {\n",
       "        const currentCheckbox = $(event.currentTarget);\n",
       "\n",
       "        if (event.currentTarget.checked) {\n",
       "          activeTypes[&quot;failed&quot;] = true;\n",
       "          checkedBoxes();\n",
       "        } else {\n",
       "          activeTypes[&quot;failed&quot;] = false;\n",
       "          $($(&quot;.form-check-input&quot;)[$(&quot;.form-check-input&quot;).length - 1]).prop( &quot;checked&quot;, false );\n",
       "        }\n",
       "        handleSearch();\n",
       "      });\n",
       "\n",
       "      $nonDiscrete.addEventListener(&quot;change&quot;, (event) =&gt; {\n",
       "        const currentCheckbox = $(event.currentTarget);\n",
       "\n",
       "        if (event.currentTarget.checked) {\n",
       "          activeTypes[&quot;passed&quot;] = true;\n",
       "          checkedBoxes();\n",
       "        } else {\n",
       "          activeTypes[&quot;passed&quot;] = false;\n",
       "          $($(&quot;.form-check-input&quot;)[$(&quot;.form-check-input&quot;).length - 1]).prop( &quot;checked&quot;, false );\n",
       "        }\n",
       "        handleSearch();\n",
       "      });\n",
       "\n",
       "      $unknown.addEventListener(&quot;change&quot;, (event) =&gt; {\n",
       "        const currentCheckbox = $(event.currentTarget);\n",
       "\n",
       "        if (event.currentTarget.checked) {\n",
       "          $(&quot;.form-check-input&quot;).prop( &quot;checked&quot;, true );\n",
       "          activeTypes[&quot;passed&quot;] = true;\n",
       "          activeTypes[&quot;failed&quot;] = true;\n",
       "          checkedBoxes();\n",
       "        } else {\n",
       "          $(&quot;.form-check-input&quot;).prop( &quot;checked&quot;, false );\n",
       "          activeTypes[&quot;passed&quot;] = false;\n",
       "          activeTypes[&quot;failed&quot;] = false;\n",
       "        }\n",
       "        handleSearch();\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function checkedBoxes() {\n",
       "      const $boxes = $(&#x27;input[name=checkbox]:checked&#x27;);\n",
       "      const $notifCircleContainer = $(&quot;.notif-circle-container&quot;)\n",
       "\n",
       "      if ($boxes.length) {\n",
       "        $notifCircleContainer.removeClass(&quot;d-none&quot;)\n",
       "      }\n",
       "    }\n",
       "\n",
       "    function openFilter() {\n",
       "      const $filterOptions = $(&quot;.dropdown-container&quot;);\n",
       "      const $notifCircleContainer = $(&quot;.notif-circle-container&quot;)\n",
       "      const filterClass = $filterOptions.attr(&quot;class&quot;);\n",
       "\n",
       "      if (filterClass.indexOf(&quot;d-none&quot;) &gt; 0) {\n",
       "        $notifCircleContainer.addClass(&quot;d-none&quot;)\n",
       "        $filterOptions.removeClass(&quot;d-none&quot;);\n",
       "        $(&quot;.filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.close-filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "      } else {\n",
       "        $filterOptions.addClass(&quot;d-none&quot;);\n",
       "        $(&quot;.close-filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "        checkedBoxes()\n",
       "      }\n",
       "    }\n",
       "\n",
       "    // Invoke functions -- keep in mind invokation order\n",
       "    registerHandlebarHelperFunctions();\n",
       "    initHandlebarsTemplate();\n",
       "    initWebsiteScripts();\n",
       "  &lt;/script&gt;\n",
       "&lt;/html&gt;\n",
       "\" width=100% height=300\n",
       "        frameBorder=0></iframe>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "builder = ConstraintsBuilder(dataset_profile_view=profile_view)\n",
    "builder.add_constraint(distinct_number_in_range(column_name = \"animal\", lower = 3, upper = 6))\n",
    "\n",
    "constraints = builder.build()\n",
    "\n",
    "from whylogs.viz import NotebookProfileVisualizer\n",
    "\n",
    "visualization = NotebookProfileVisualizer()\n",
    "visualization.constraints_report(constraints, cell_height=300)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Types Metrics <a class=\"anchor\" id=\"types\"></a>"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Examples - Types Metrics"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "import whylogs as why\n",
    "import pandas as pd\n",
    "\n",
    "data = {\n",
    "    \"animal\": [\"cat\", \"snake\", \"snake\", \"cat\", \"mosquito\"],\n",
    "    \"legs\": [4, 2, 0, None, 6],\n",
    "    \"weight\": [4.3, 1.8, 1.3, 4.1, 5.5e-6],\n",
    "    \"flies\": [False, False, \"False\", False, True],\n",
    "    \"obj\": [{\"a\":1}, None, {\"a\":1}, {\"a\":1}, {\"a\":1}]\n",
    "}\n",
    "df = pd.DataFrame(data)\n",
    "results = why.log(df)\n",
    "profile_view = results.view()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Check Nullable Types"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div></div><iframe srcdoc=\"&lt;!DOCTYPE html&gt;\n",
       "&lt;html lang=&quot;en&quot;&gt;\n",
       "  &lt;head&gt;\n",
       "    &lt;meta charset=&quot;UTF-8&quot; /&gt;\n",
       "    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot; /&gt;\n",
       "    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;\n",
       "    &lt;meta name=&quot;description&quot; content=&quot;&quot; /&gt;\n",
       "    &lt;meta name=&quot;author&quot; content=&quot;&quot; /&gt;\n",
       "\n",
       "    &lt;title&gt;Profile Visualizer | whylogs&lt;/title&gt;\n",
       "\n",
       "    &lt;link rel=&quot;icon&quot; href=&quot;images/whylabs-favicon.png&quot; type=&quot;image/png&quot; sizes=&quot;16x16&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.googleapis.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; crossorigin /&gt;\n",
       "    &lt;link href=&quot;https://fonts.googleapis.com/css2?family=Asap:wght@400;500;600;700&amp;display=swap&quot; rel=&quot;stylesheet&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css&quot; /&gt;\n",
       "\n",
       "    &lt;script\n",
       "      src=&quot;https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js&quot;\n",
       "      integrity=&quot;sha512-RNLkV3d+aLtfcpEyFG8jRbnWHxUqVZozacROI4J2F1sTaDqo1dPQYs01OMi1t1w9Y2FdbSCDSQ2ZVdAC8bzgAg==&quot;\n",
       "      crossorigin=&quot;anonymous&quot;\n",
       "      referrerpolicy=&quot;no-referrer&quot;\n",
       "    &gt;&lt;/script&gt;\n",
       "\n",
       "    &lt;style type=&quot;text/css&quot;&gt;\n",
       "\n",
       "      /* Screen on smaller screens */\n",
       "      .no-responsive {\n",
       "        display: none;\n",
       "        position: fixed;\n",
       "        top: 0;\n",
       "        left: 0;\n",
       "        z-index: 1031;\n",
       "        width: 100vw;\n",
       "        height: 100vh;\n",
       "        background-color: var(--tealBackground);\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      @media screen and (min-width: 1000px) {\n",
       "        .desktop-content {\n",
       "          display: block;\n",
       "        }\n",
       "        .no-responsive {\n",
       "          display: none;\n",
       "        }\n",
       "      }\n",
       "\n",
       "      .no-responsive__content {\n",
       "        max-width: 600px;\n",
       "        width: 100%;\n",
       "        padding: 0 24px;\n",
       "      }\n",
       "\n",
       "      .no-responsive__title {\n",
       "        font-size: 96px;\n",
       "        font-weight: 300;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.167;\n",
       "      }\n",
       "\n",
       "      .no-responsive__text {\n",
       "        margin: 0;\n",
       "        font-size: 16px;\n",
       "        font-weight: 400;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.5;\n",
       "      }\n",
       "\n",
       "      .header-title {\n",
       "        font-size: 26px;\n",
       "        font-weight: 700;\n",
       "        color: #444444;\n",
       "      }\n",
       "\n",
       "      .tooltip-full-number {\n",
       "        position: relative;\n",
       "        display: inline-block;\n",
       "      }\n",
       "\n",
       "      .tooltip-full-number .tooltiptext {\n",
       "        visibility: hidden;\n",
       "        background: black;\n",
       "        color: white;\n",
       "        border: 1px solid black;\n",
       "        text-align: start;\n",
       "        padding: 3px;\n",
       "        position: absolute;\n",
       "        z-index: 1;\n",
       "        top: 0;\n",
       "        left: 100%;\n",
       "        margin-left: 5px;\n",
       "        opacity: 0;\n",
       "        transition: opacity 0.5s;\n",
       "        font-size: 13px;\n",
       "        font-weight: normal;\n",
       "        line-height: 100%;\n",
       "      }\n",
       "\n",
       "      .tooltip-full-number:hover .tooltiptext {\n",
       "        visibility: visible;\n",
       "        opacity: 1;\n",
       "      }\n",
       "\n",
       "\n",
       "      .wl-compare-profile {\n",
       "        position: relative;\n",
       "        left: 0;\n",
       "        padding: 30px;\n",
       "        margin-bottom: 20px;\n",
       "        background: var(--white);;\n",
       "        border-bottom: 1px solid #CED4DA;\n",
       "      }\n",
       "\n",
       "      .alert-list {\n",
       "        padding: 30px;\n",
       "        padding-top: 0;\n",
       "      }\n",
       "\n",
       "    .drift-detection {\n",
       "       justify-content: space-between;\n",
       "       align-items: center;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-circle {\n",
       "       width: 15px;\n",
       "       height: 15px;\n",
       "       border-radius: 50px;\n",
       "       display: inline-block;\n",
       "       margin-right: 8px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-drifts-item {\n",
       "         padding-right: 20px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-title {\n",
       "       font-family: Arial;\n",
       "       font-weight: bold;\n",
       "       font-size: 22px;\n",
       "       line-height: 130%;\n",
       "       color: #313B3D;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-drifts-item-count {\n",
       "       font-family: Arial;\n",
       "       font-weight: bold;\n",
       "       font-size: 14px;\n",
       "       line-height: 16px;\n",
       "       color: #000000;\n",
       "       padding-right: 8px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-drifts-item-name {\n",
       "       font-family: Arial;\n",
       "       font-style: normal;\n",
       "       font-weight: normal;\n",
       "       font-size: 12px;\n",
       "       line-height: 14px;\n",
       "       color: #000000;\n",
       "     }\n",
       "\n",
       "     .drift-detection-search-input {\n",
       "       display: flex;\n",
       "       align-items: center;\n",
       "       background: rgba(255, 255, 255, 0.7);\n",
       "       border: 1px solid #DBE5E7;\n",
       "       box-sizing: border-box;\n",
       "       border-radius: 4px;\n",
       "       width: 170px;\n",
       "       padding-left: 10px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-search-input img{\n",
       "       margin-right: 5px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-search-input input::placeholder {\n",
       "       font-family: Arial;\n",
       "       font-weight: normal;\n",
       "       font-size: 13px;\n",
       "       line-height: 16px;\n",
       "       color: #313B3D;\n",
       "     }\n",
       "\n",
       "     .dropdown-container {\n",
       "       position: absolute;\n",
       "       right: 30px;\n",
       "       top: 80px;\n",
       "       z-index: 999;\n",
       "       background: #FFFFFF;\n",
       "       border: 1px solid #DBE5E7;\n",
       "       box-sizing: border-box;\n",
       "       box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.05);\n",
       "       border-radius: 4px;\n",
       "       padding: 10px !important;\n",
       "       border: none !important;\n",
       "     }\n",
       "\n",
       "     .filter-options-title {\n",
       "       width: 240px;\n",
       "     }\n",
       "\n",
       "     .filter-options-title p {\n",
       "       margin: 0;\n",
       "     }\n",
       "\n",
       "     .form-check-input:checked {\n",
       "       background-color: #0E7384;\n",
       "       border-color: #0E7384;\n",
       "     }\n",
       "\n",
       "     .form-check-input[type=checkbox] {\n",
       "       border-radius: 2px;\n",
       "     }\n",
       "\n",
       "     .search-input{\n",
       "       padding-top: 0 !important;\n",
       "       padding-bottom: 0 !important;\n",
       "     }\n",
       "\n",
       "     .search-input input{\n",
       "       border: none;\n",
       "       background: none;\n",
       "       outline: none;\n",
       "       height: 40px;\n",
       "       width: 100%;\n",
       "       font-size: 14px;\n",
       "     }\n",
       "\n",
       "     .search-input img{\n",
       "       height: 19px;\n",
       "       pointer-events: none;\n",
       "     }\n",
       "\n",
       "     input::placeholder {\n",
       "       color: var(--secondaryLight1000);\n",
       "     }\n",
       "\n",
       "      .statistics {\n",
       "        width: 100%;\n",
       "      }\n",
       "\n",
       "     .close-filter-button {\n",
       "       display: flex;\n",
       "       justify-content: center;\n",
       "       align-items: center;\n",
       "       background: rgba(255, 255, 255, 0.7);\n",
       "       border: 1px solid #369BAC;\n",
       "       box-sizing: border-box;\n",
       "       border-radius: 4px;\n",
       "       width: 40px;\n",
       "       height: 40px;\n",
       "       cursor: pointer;\n",
       "       margin-left: 10px;\n",
       "     }\n",
       "\n",
       "      .statistic-number-title {\n",
       "        font-family: Arial;\n",
       "        font-weight: normal;\n",
       "        font-size: 14px;\n",
       "        line-height: 20px;\n",
       "        color: #6C757D;\n",
       "      }\n",
       "\n",
       "      .statistic-number {\n",
       "        font-family: Arial;\n",
       "        font-weight: bold;\n",
       "        font-size: 20px;\n",
       "        line-height: 140%;\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "        color: #4F595B;\n",
       "      }\n",
       "\n",
       "      .full-summary-statistics-wrap {\n",
       "        padding: 20px;\n",
       "      }\n",
       "\n",
       "      .statistics {\n",
       "        width: 100%;\n",
       "      }\n",
       "\n",
       "      .statistics-list {\n",
       "        width: 100% ;\n",
       "      }\n",
       "\n",
       "      mark {\n",
       "        padding: 5px;\n",
       "        border-radius: 4px;\n",
       "        font-family: Arial;\n",
       "        font-weight: normal;\n",
       "        font-size: 14px;\n",
       "        line-height: 140%;\n",
       "      }\n",
       "\n",
       "      .blue-mark {\n",
       "        background-color:  #369BAC1A;\n",
       "        color: #369BAC;\n",
       "      }\n",
       "\n",
       "      .red-mark {\n",
       "        background-color: #FFEFEE;\n",
       "        color: #F5473C;\n",
       "      }\n",
       "\n",
       "      .alert-tag {\n",
       "        height: 27px;\n",
       "        padding: 5px;\n",
       "        border-radius: 4px;\n",
       "        font-family: Arial;\n",
       "        font-weight: bold;\n",
       "        font-size: 12px;\n",
       "        line-height: 140%;\n",
       "        color: #FFFFFF;\n",
       "      }\n",
       "\n",
       "      .turquoise-background-color {\n",
       "        background-color: #1DBB42;\n",
       "      }\n",
       "\n",
       "      .bordeaux-background-color {\n",
       "        background-color: #C6462A;\n",
       "      }\n",
       "\n",
       "      .border-solid-gray {\n",
       "        border: 1px solid #CED4DA;\n",
       "        border-radius: 4px;\n",
       "      }\n",
       "\n",
       "      .display-flex {\n",
       "        display: flex;\n",
       "      }\n",
       "\n",
       "      .justify-content-space-between {\n",
       "        justify-content: space-between;\n",
       "      }\n",
       "\n",
       "      .justify-content-center {\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      .align-items-center {\n",
       "        align-items: center;\n",
       "      }\n",
       "\n",
       "      .align-items-flex-start {\n",
       "        align-items: flex-start;\n",
       "      }\n",
       "\n",
       "      .padding-right-30 {\n",
       "        padding-right: 30px;\n",
       "      }\n",
       "\n",
       "      .notif-circle-container{\n",
       "        position: absolute;\n",
       "        top: 25px;\n",
       "        right: 25px;\n",
       "        padding: 5.3px;\n",
       "        border-radius: 50%;\n",
       "        background-color: white;\n",
       "        cursor: pointer;\n",
       "      }\n",
       "\n",
       "      .notif-circle {\n",
       "        position: absolute;\n",
       "        top: 2px;\n",
       "        right: 2px;\n",
       "        padding: 3.3px;\n",
       "        border-radius: 50%;\n",
       "        background-color: #F2994A;\n",
       "      }\n",
       "\n",
       "      .alert-list-text {\n",
       "        width: 70%\n",
       "      }\n",
       "\n",
       "     @media screen and (min-width: 500px) {\n",
       "       .desktop-content {\n",
       "         display: block;\n",
       "       }\n",
       "       .no-responsive {\n",
       "         display: none;\n",
       "       }\n",
       "     }\n",
       "    &lt;/style&gt;\n",
       "  &lt;/head&gt;\n",
       "\n",
       "  &lt;body id=&quot;generated-html&quot;&gt;&lt;/body&gt;\n",
       "\n",
       "  &lt;script id=&quot;entry-template&quot; type=&quot;text/x-handlebars-template&quot;&gt;\n",
       "    \n",
       "      &lt;div class=&quot;desktop-content&quot;&gt;\n",
       "        &lt;div class=&quot;full-summary-statistics-wrap&quot;&gt;\n",
       "          &lt;div class=&quot;full-summary-statistics&quot;&gt;\n",
       "            &lt;div&gt;\n",
       "              &lt;div class=&quot;display-flex justify-content-center&quot;&gt;\n",
       "                &lt;div class=&quot;statistics-list border-solid-gray&quot;&gt;\n",
       "                  &lt;div&gt;\n",
       "                    &lt;div class=&quot;wl-compare-profile&quot; id=&quot;compare-profile&quot;&gt;\n",
       "                        &lt;div class=&quot;drift-detection-wrap&quot;&gt;\n",
       "                          &lt;div class=&quot;drift-detection display-flex align-items-flex-start&quot;&gt;\n",
       "                            &lt;div class=&quot;drift-detection-info flex-direction-colum&quot;&gt;\n",
       "                              &lt;div class=&quot;drift-detection-info-title-wrap display-flex&quot;&gt;\n",
       "                                &lt;p class=&quot;drift-detection-info-title&quot;&gt;\n",
       "                                  Constraints Report\n",
       "                                &lt;/p&gt;\n",
       "                              &lt;/div&gt;\n",
       "\n",
       "                              &lt;!-- &lt;/div&gt; --&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;div class=&quot;drift-detection-search-input-wrap display-flex&quot;&gt;\n",
       "                              &lt;div class=&quot;drift-detection-search-input search-input&quot;&gt;\n",
       "                                &lt;input type=&quot;text&quot; id=&quot;wl__feature-search&quot; placeholder=&quot;Quick search...&quot;/&gt;\n",
       "                                &lt;img src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAGdSURBVHgBpZK7TkJBEIZnZoVocdTYyQNALxpNKPQBMEaNJsbCRMKhl8ISWwt6AaksCF5iTHgAGhJD4AHkAaAzGiwUsjvOQnO4SYh/cXbPzO43OxcEj9Zy92EiFSXNIfvPyE1kKFfdoxJMENpP6DrvLC0vJoEwCgwto7DWcxoIIHBYbA3NmKwnDltjAeuZhyul1DaTTlfPB6Nt5Z53DOgky4P875+nlctY2+unjZviLklkJhi5bPUa3y/7qJuQUM7PinMy7CdQc1Gh16vnBxPzrMROmlKQEgKNASAHLQCmSIGpS75O+O5pdQAgVXaIqTkNwDDXHmcnW3VmHZoGMLoTsOt88+NrAMCIZdu+iLTyTwKRa1Md6YKfOgXbzO7K8sWku5u5RxcRV5EpPezrzcHGbXEXWaUkgkweZ/UC9YrK3zqggFw5FBZfm8EUavHj7AjAKpIvBDrGn+pNnlcyhYgqbcC41idr1gvB4SdZkDbzQa21gwv0Vj07aPTtL07XdDOyDXohCDNoHIRmAVRie20f+RKybRDQDvxHkXy/7b/DrayncLbMwQAAAABJRU5ErkJggg==&quot;/&gt;\n",
       "                              &lt;/div&gt;\n",
       "                              &lt;div class=&quot;wl__dropdown_arrow-icon&quot;&gt;\n",
       "                                &lt;div onclick=&quot;openFilter()&quot; class=&quot;close-filter-button&quot;&gt;\n",
       "                                &lt;div class=&quot;display-flex close-filter-icon d-none&quot;&gt;\n",
       "                                  &lt;img src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAADFSURBVHgBfY+xDcIwEEXvnLQBZQkYAEhDwwKpEEK0CCZgAEjJCEmgjYSAygxAHTZgFRSOsyUjY5mcZFnn/+78PwBXf3+MoKWUPuYjVBPFnTwpr9t/oNJfcTfXsAhRAlDqDhhQIPYgpAqNMDqcUqSAYZT1epr9gAHt6uXshvYme4DYHQJNDKh0dD0m5WXB10Y3Fqjtuh7fROn3oREDWxfeMLyRsMnc0OgDzdduaA0Pi3Plgr7Q2kaAePeBqh6rueSNBVt6fgCwBV1JLF3rlAAAAABJRU5ErkJggg==&quot;/&gt;\n",
       "                                &lt;/div&gt;\n",
       "                                &lt;div class=&quot;display-flex filter-icon&quot;&gt;\n",
       "                                  &lt;img src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACSSURBVHgBrZLBCYAwDEWTUjw7igcdwI1cxkNXUJzBEVzFAbSVKoKmaVrEB6GHJv/w+AACtRk7P9IONv1QOYUl96k0zv61m2tjARoLtSDI3EFsgIJ4uoXrMLazO72CRG2mzg/8BSdVlEjhpGZJjAWdAZJECpWalEhJSs1pHuUlMad5FFai1Lwg4Ckx1TxKIPFL8w55mEWd8VjPGAAAAABJRU5ErkJggg==&quot;/&gt;\n",
       "                                &lt;/div&gt;\n",
       "                                &lt;/div&gt;\n",
       "                              &lt;span class=&quot;notif-circle-container&quot;&gt;\n",
       "                                &lt;span class=&quot;notif-circle&quot;&gt;&lt;/span&gt;\n",
       "                              &lt;/span&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;/div&gt;\n",
       "                          &lt;/div&gt;\n",
       "                        &lt;/div&gt;\n",
       "                        &lt;div class=&quot;dropdown-container flex-direction-colum mb-2 d-none&quot; id=&quot;dropdown-container&quot;&gt;\n",
       "                          &lt;div class=&quot;filter-options&quot;&gt;\n",
       "                            &lt;div class=&quot;filter-options-title space-between dropdown&quot;&gt;\n",
       "                              &lt;p&gt;Select a view:&lt;/p&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;div class=&quot;form-check mb-1 mt-2&quot;&gt;\n",
       "                              &lt;input\n",
       "                                class=&quot;form-check-input wl__feature-filter-input&quot;\n",
       "                                type=&quot;checkbox&quot;\n",
       "                                name=&quot;checkbox&quot;\n",
       "                                value=&quot;Discrete&quot;\n",
       "                                id=&quot;inferredDiscrete&quot;\n",
       "                                checked\n",
       "                              /&gt;\n",
       "                              &lt;label class=&quot;form-check-label&quot; for=&quot;inferredDiscrete&quot;&gt;\n",
       "                                Failed constraints (&lt;span class=&quot;wl__feature-count--discrete&quot;&gt;&lt;/span&gt;)\n",
       "                              &lt;/label&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;div class=&quot;form-check mb-1&quot;&gt;\n",
       "                              &lt;input\n",
       "                                class=&quot;form-check-input wl__feature-filter-input&quot;\n",
       "                                type=&quot;checkbox&quot;\n",
       "                                name=&quot;checkbox&quot;\n",
       "                                value=&quot;Non-discrete&quot;\n",
       "                                id=&quot;inferredNonDiscrete&quot;\n",
       "                                checked\n",
       "                              /&gt;\n",
       "                              &lt;label class=&quot;form-check-label&quot; for=&quot;inferredNonDiscrete&quot;&gt;\n",
       "                                Passed constraints (&lt;span\n",
       "                                  class=&quot;wl__feature-count--non-discrete&quot;\n",
       "                                &gt;&lt;/span&gt;)\n",
       "                              &lt;/label&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;div class=&quot;form-check mb-1&quot;&gt;\n",
       "                              &lt;input\n",
       "                                class=&quot;form-check-input wl__feature-filter-input&quot;\n",
       "                                type=&quot;checkbox&quot;\n",
       "                                name=&quot;checkbox&quot;\n",
       "                                value=&quot;Unknown&quot;\n",
       "                                id=&quot;inferredUnknown&quot;\n",
       "                                checked\n",
       "                              /&gt;\n",
       "                              &lt;label class=&quot;form-check-label&quot; for=&quot;inferredUnknown&quot;&gt;\n",
       "                                All constraints (&lt;span class=&quot;wl__feature-count--unknown&quot;&gt;&lt;/span&gt;)\n",
       "                              &lt;/label&gt;\n",
       "                            &lt;/div&gt;\n",
       "                          &lt;/div&gt;\n",
       "                        &lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                    &lt;div class=&quot;alert-list&quot; id=&quot;alert-list&quot;&gt;\n",
       "                      {{{alertLIst this}}}\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                &lt;/div&gt;\n",
       "              &lt;/div&gt;\n",
       "            &lt;/div&gt;\n",
       "          &lt;/div&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "      &lt;div class=&quot;no-responsive&quot;&gt;\n",
       "        &lt;div class=&quot;no-responsive__content&quot;&gt;\n",
       "          &lt;h1 class=&quot;no-responsive__title&quot;&gt;Hold on! :)&lt;/h1&gt;\n",
       "          &lt;p class=&quot;no-responsive__text&quot;&gt;\n",
       "            It looks like your current screen size or device is not yet supported by the WhyLabs Sandbox. The Sandbox is\n",
       "            best experienced on a desktop computer. Please try maximizing this window or switching to another device. We\n",
       "            are working on adding support for a larger variety of devices.\n",
       "          &lt;/p&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "    \n",
       "  &lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://code.jquery.com/jquery-3.6.0.min.js&quot; integrity=&quot;sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js&quot; integrity=&quot;sha512-cd6CHE+XWDQ33ElJqsi0MdNte3S+bQY819f7p3NUHgwQQLXSKjE4cPZTeGNI+vaxZynk1wVU3hoHmow3m089wA==&quot; crossorigin=&quot;anonymous&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script&gt;\n",
       "    function registerHandlebarHelperFunctions() {\n",
       "      //helper fun\n",
       "      function formatLabelDate(timestamp) {\n",
       "        const date = new Date(timestamp);\n",
       "        const format = d3.timeFormat(&quot;%Y-%m-%d %I:%M:%S %p %Z&quot;);\n",
       "        return format(date);\n",
       "      }\n",
       "\n",
       "      function fixNumberTo(number, decimals = 3) {\n",
       "        return parseFloat(number).toFixed(decimals);\n",
       "      }\n",
       "\n",
       "      const randomNumbers = (range) =&gt; Math.floor(Math.random() * range)\n",
       "\n",
       "      const findFetureWithNumberSummary = (column) =&gt; {\n",
       "        const fetureIndex = Object.values(column.columns)\n",
       "              .findIndex((feture) =&gt; feture.numberSummary)\n",
       "\n",
       "        return Object.keys(column.columns)[fetureIndex]\n",
       "      }\n",
       "\n",
       "      const alertListItemStatus = (status, passedItem, failedItem) =&gt; {\n",
       "        if (status) {\n",
       "          return passedItem\n",
       "        } else {\n",
       "          return failedItem\n",
       "        }\n",
       "      }\n",
       "\n",
       "      const alertListElement = (name, text, status, summary) =&gt; {\n",
       "        if (summary == null){\n",
       "          return (\n",
       "          `&lt;div\n",
       "             data-inferred-type=${alertListItemStatus(status, &quot;passed&quot;, &quot;failed&quot;)}\n",
       "             class=&quot;alert-list-item display-flex justify-content-space-between align-items-center mb-2&quot;\n",
       "           &gt;\n",
       "            &lt;div class=&quot;alert-list-text&quot;&gt;\n",
       "              ${\n",
       "                name &amp;&amp;\n",
       "                alertListItemStatus(\n",
       "                  status,\n",
       "                  `&lt;mark class=&quot;blue-mark&quot;&gt;${name}&lt;/mark&gt;`,\n",
       "                  `&lt;mark class=&quot;red-mark&quot;&gt;${name}&lt;/mark&gt;`\n",
       "                )\n",
       "              }\n",
       "              ${text}\n",
       "            &lt;/div&gt;\n",
       "              ${\n",
       "                alertListItemStatus(\n",
       "                  status,\n",
       "                  `\n",
       "                  &lt;div class=&quot;turquoise-background-color alert-tag&quot;&gt;Passed&lt;/div&gt;\n",
       "                  `\n",
       "                  ,\n",
       "                  `\n",
       "                  &lt;div class=&quot;bordeaux-background-color alert-tag&quot;&gt;Failed&lt;/div&gt;\n",
       "                  `\n",
       "                )\n",
       "              }\n",
       "              &lt;/div&gt;`\n",
       "        )\n",
       "\n",
       "        }\n",
       "        return (\n",
       "          `&lt;div\n",
       "             data-inferred-type=${alertListItemStatus(status, &quot;passed&quot;, &quot;failed&quot;)}\n",
       "             class=&quot;alert-list-item display-flex justify-content-space-between align-items-center mb-2&quot;\n",
       "           &gt;\n",
       "            &lt;div class=&quot;alert-list-text&quot;&gt;\n",
       "              ${\n",
       "                name &amp;&amp;\n",
       "                alertListItemStatus(\n",
       "                  status,\n",
       "                  `&lt;mark class=&quot;blue-mark&quot;&gt;${name}&lt;/mark&gt;`,\n",
       "                  `&lt;mark class=&quot;red-mark&quot;&gt;${name}&lt;/mark&gt;`\n",
       "                )\n",
       "              }\n",
       "              ${text}\n",
       "            &lt;/div&gt;\n",
       "              ${\n",
       "                alertListItemStatus(\n",
       "                  status,\n",
       "                  `\n",
       "                  &lt;div class=&quot;tooltip-full-number&quot;&gt;\n",
       "                    &lt;div class=&quot;turquoise-background-color alert-tag&quot;&gt;Passed\n",
       "                      &lt;span class=&quot;tooltiptext&quot;&gt;\n",
       "                          &lt;pre class=&quot;mb-1&quot;&gt; ${JSON.stringify(summary, null, 2)} &lt;/pre&gt;\n",
       "                        &lt;/span&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;`\n",
       "\n",
       "                  ,\n",
       "                  `\n",
       "                  &lt;div class=&quot;tooltip-full-number&quot;&gt;\n",
       "                    &lt;div class=&quot;bordeaux-background-color alert-tag&quot;&gt;Failed\n",
       "                      &lt;span class=&quot;tooltiptext&quot;&gt;\n",
       "                        &lt;pre class=&quot;mb-1&quot;&gt; ${JSON.stringify(summary, null, 2)} &lt;/pre&gt;\n",
       "                        &lt;/span&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;`\n",
       "                )\n",
       "              }\n",
       "              &lt;/div&gt;`\n",
       "        )\n",
       "      }\n",
       "\n",
       "      let failedConstraints = 0;\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getProfileTimeStamp&quot;, function (column) {\n",
       "        return formatLabelDate(+column.properties.dataTimestamp)\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getProfileName&quot;, function (column) {\n",
       "        return column.properties.tags.name\n",
       "      });\n",
       "\n",
       "\n",
       "      Handlebars.registerHelper(&quot;alertLIst&quot;, function (column) {\n",
       "        let alertListItem = column.map((value) =&gt; {\n",
       "          if (value[1][0]) {\n",
       "            let alertListValue = value[1].map((cstr)=&gt;{\n",
       "              return alertListElement(value[0],cstr[0],cstr[cstr.length - 1] === 0 || (failedConstraints++, false), value[3])\n",
       "            })\n",
       "            return alertListValue.join(&#x27; &#x27;)\n",
       "          } else {\n",
       "            return alertListElement(&#x27;&#x27;, value[0], value[2] === 0 ||  (failedConstraints++, false), value[3])\n",
       "          }\n",
       "        })\n",
       "         $(document).ready(() =&gt; {\n",
       "           $(&quot;.wl__feature-count--discrete&quot;).append(failedConstraints)\n",
       "           $(&quot;.wl__feature-count--non-discrete&quot;).append(column.length - failedConstraints)\n",
       "           $(&quot;.wl__feature-count--unknown&quot;).append(column.length)\n",
       "         })\n",
       "        return alertListItem.join(&#x27; &#x27;)\n",
       "      });\n",
       "\n",
       "    }\n",
       "\n",
       "    function openFilter() {\n",
       "      const $filterOptions = $(&quot;.dropdown-container&quot;);\n",
       "      const filterClass = $filterOptions.attr(&quot;class&quot;);\n",
       "\n",
       "      if (filterClass.indexOf(&quot;d-none&quot;) &gt; 0) {\n",
       "        $filterOptions.removeClass(&quot;d-none&quot;);\n",
       "        $(&quot;.filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.close-filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "      } else {\n",
       "        $filterOptions.addClass(&quot;d-none&quot;);\n",
       "        $(&quot;.close-filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "      }\n",
       "    }\n",
       "\n",
       "    function initHandlebarsTemplate() {\n",
       "      // Replace this context with JSON from .py file\n",
       "      const context = [[&quot;animal is nullable string&quot;, 1, 0, {&quot;metric&quot;: &quot;types&quot;, &quot;integral&quot;: 0, &quot;fractional&quot;: 0, &quot;boolean&quot;: 0, &quot;string&quot;: 5, &quot;object&quot;: 0}], [&quot;legs is nullable integral&quot;, 0, 1, {&quot;metric&quot;: &quot;types&quot;, &quot;integral&quot;: 0, &quot;fractional&quot;: 4, &quot;boolean&quot;: 0, &quot;string&quot;: 0, &quot;object&quot;: 0}], [&quot;weight is nullable fractional&quot;, 1, 0, {&quot;metric&quot;: &quot;types&quot;, &quot;integral&quot;: 0, &quot;fractional&quot;: 5, &quot;boolean&quot;: 0, &quot;string&quot;: 0, &quot;object&quot;: 0}], [&quot;flies is nullable boolean&quot;, 0, 1, {&quot;metric&quot;: &quot;types&quot;, &quot;integral&quot;: 0, &quot;fractional&quot;: 0, &quot;boolean&quot;: 4, &quot;string&quot;: 1, &quot;object&quot;: 0}], [&quot;obj is nullable object&quot;, 1, 0, {&quot;metric&quot;: &quot;types&quot;, &quot;integral&quot;: 0, &quot;fractional&quot;: 0, &quot;boolean&quot;: 0, &quot;string&quot;: 0, &quot;object&quot;: 4}]];\n",
       "      // Config handlebars and pass data to HBS template\n",
       "      const source = document.getElementById(&quot;entry-template&quot;).innerHTML;\n",
       "      const template = Handlebars.compile(source);\n",
       "      const html = template(context);\n",
       "      const target = document.getElementById(&quot;generated-html&quot;);\n",
       "      target.innerHTML = html;\n",
       "    }\n",
       "\n",
       "    function initWebsiteScripts() {\n",
       "      const $featureSearch = document.getElementById(&quot;wl__feature-search&quot;);\n",
       "      const $alertList = document.getElementById(&quot;alert-list&quot;);\n",
       "      const $discrete = document.getElementById(&quot;inferredDiscrete&quot;);\n",
       "      const $nonDiscrete = document.getElementById(&quot;inferredNonDiscrete&quot;);\n",
       "      const $unknown = document.getElementById(&quot;inferredUnknown&quot;);\n",
       "\n",
       "      const activeTypes = {\n",
       "        passed: true,\n",
       "        failed: true\n",
       "      };\n",
       "\n",
       "      let searchString = &quot;&quot;;\n",
       "\n",
       "      function debounce(func, wait, immediate) {\n",
       "        let timeout;\n",
       "\n",
       "        return function () {\n",
       "          const context = this;\n",
       "          const args = arguments;\n",
       "          const later = function () {\n",
       "            timeout = null;\n",
       "            if (!immediate) func.apply(context, args);\n",
       "          };\n",
       "\n",
       "          const callNow = immediate &amp;&amp; !timeout;\n",
       "          clearTimeout(timeout);\n",
       "          timeout = setTimeout(later, wait);\n",
       "          if (callNow) func.apply(context, args);\n",
       "        };\n",
       "      }\n",
       "\n",
       "      function filterNotification() {\n",
       "        const $notifCircleContainer = $(&quot;.notif-circle-container&quot;)\n",
       "        const $boxes = $(&#x27;.wl_filter-options&gt;.form-check&gt;input[name=checkbox]:checked&#x27;);\n",
       "        const item = Object.values($boxes).find(function(value) { return $(value)[0] === undefined});\n",
       "        if (item === undefined) {\n",
       "          $notifCircleContainer.removeClass(&quot;d-none&quot;)\n",
       "        } else {\n",
       "          $notifCircleContainer.addClass(&quot;d-none&quot;)\n",
       "        }\n",
       "      }\n",
       "\n",
       "      function handleSearch() {\n",
       "        const tableBodyChildren = $alertList.children;\n",
       "\n",
       "        for (let i = 0; i &lt; tableBodyChildren.length; i++) {\n",
       "          const type = tableBodyChildren[i].dataset.inferredType.toLowerCase();\n",
       "          const name = $(tableBodyChildren[i].children[0]).html().toLowerCase();\n",
       "          if (activeTypes[type] &amp;&amp; name.includes(searchString)) {\n",
       "            tableBodyChildren[i].style.display = &quot;&quot;;\n",
       "          } else {\n",
       "            tableBodyChildren[i].style.display = &quot;none&quot;;\n",
       "          }\n",
       "        }\n",
       "      }\n",
       "\n",
       "      const checkedBoxes = () =&gt; {\n",
       "        if ($(&#x27;.form-check-input:checked&#x27;).length === $(&quot;.form-check-input&quot;).length - 1) {\n",
       "          $($(&quot;.form-check-input&quot;)[$(&quot;.form-check-input&quot;).length - 1]).prop( &quot;checked&quot;, true );\n",
       "        }\n",
       "      }\n",
       "\n",
       "      $featureSearch.addEventListener(\n",
       "        &quot;keyup&quot;,\n",
       "        debounce((event) =&gt; {\n",
       "          searchString = event.target.value.toLowerCase();\n",
       "          handleSearch();\n",
       "        }, 100),\n",
       "      );\n",
       "\n",
       "      $discrete.addEventListener(&quot;change&quot;, (event) =&gt; {\n",
       "        const currentCheckbox = $(event.currentTarget);\n",
       "\n",
       "        if (event.currentTarget.checked) {\n",
       "          activeTypes[&quot;failed&quot;] = true;\n",
       "          checkedBoxes();\n",
       "        } else {\n",
       "          activeTypes[&quot;failed&quot;] = false;\n",
       "          $($(&quot;.form-check-input&quot;)[$(&quot;.form-check-input&quot;).length - 1]).prop( &quot;checked&quot;, false );\n",
       "        }\n",
       "        handleSearch();\n",
       "      });\n",
       "\n",
       "      $nonDiscrete.addEventListener(&quot;change&quot;, (event) =&gt; {\n",
       "        const currentCheckbox = $(event.currentTarget);\n",
       "\n",
       "        if (event.currentTarget.checked) {\n",
       "          activeTypes[&quot;passed&quot;] = true;\n",
       "          checkedBoxes();\n",
       "        } else {\n",
       "          activeTypes[&quot;passed&quot;] = false;\n",
       "          $($(&quot;.form-check-input&quot;)[$(&quot;.form-check-input&quot;).length - 1]).prop( &quot;checked&quot;, false );\n",
       "        }\n",
       "        handleSearch();\n",
       "      });\n",
       "\n",
       "      $unknown.addEventListener(&quot;change&quot;, (event) =&gt; {\n",
       "        const currentCheckbox = $(event.currentTarget);\n",
       "\n",
       "        if (event.currentTarget.checked) {\n",
       "          $(&quot;.form-check-input&quot;).prop( &quot;checked&quot;, true );\n",
       "          activeTypes[&quot;passed&quot;] = true;\n",
       "          activeTypes[&quot;failed&quot;] = true;\n",
       "          checkedBoxes();\n",
       "        } else {\n",
       "          $(&quot;.form-check-input&quot;).prop( &quot;checked&quot;, false );\n",
       "          activeTypes[&quot;passed&quot;] = false;\n",
       "          activeTypes[&quot;failed&quot;] = false;\n",
       "        }\n",
       "        handleSearch();\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function checkedBoxes() {\n",
       "      const $boxes = $(&#x27;input[name=checkbox]:checked&#x27;);\n",
       "      const $notifCircleContainer = $(&quot;.notif-circle-container&quot;)\n",
       "\n",
       "      if ($boxes.length) {\n",
       "        $notifCircleContainer.removeClass(&quot;d-none&quot;)\n",
       "      }\n",
       "    }\n",
       "\n",
       "    function openFilter() {\n",
       "      const $filterOptions = $(&quot;.dropdown-container&quot;);\n",
       "      const $notifCircleContainer = $(&quot;.notif-circle-container&quot;)\n",
       "      const filterClass = $filterOptions.attr(&quot;class&quot;);\n",
       "\n",
       "      if (filterClass.indexOf(&quot;d-none&quot;) &gt; 0) {\n",
       "        $notifCircleContainer.addClass(&quot;d-none&quot;)\n",
       "        $filterOptions.removeClass(&quot;d-none&quot;);\n",
       "        $(&quot;.filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.close-filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "      } else {\n",
       "        $filterOptions.addClass(&quot;d-none&quot;);\n",
       "        $(&quot;.close-filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "        checkedBoxes()\n",
       "      }\n",
       "    }\n",
       "\n",
       "    // Invoke functions -- keep in mind invokation order\n",
       "    registerHandlebarHelperFunctions();\n",
       "    initHandlebarsTemplate();\n",
       "    initWebsiteScripts();\n",
       "  &lt;/script&gt;\n",
       "&lt;/html&gt;\n",
       "\" width=100% height=300\n",
       "        frameBorder=0></iframe>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\n",
    "from whylogs.core.constraints.factories import ( \n",
    "    column_is_nullable_integral,\n",
    "    column_is_nullable_boolean, \n",
    "    column_is_nullable_fractional,\n",
    "    column_is_nullable_object,\n",
    "    column_is_nullable_string,\n",
    ")\n",
    "from whylogs.core.constraints import ConstraintsBuilder\n",
    "\n",
    "\n",
    "builder = ConstraintsBuilder(dataset_profile_view=profile_view)\n",
    "builder.add_constraint(column_is_nullable_string(column_name=\"animal\"))\n",
    "builder.add_constraint(column_is_nullable_integral(column_name=\"legs\"))\n",
    "builder.add_constraint(column_is_nullable_fractional(column_name=\"weight\"))\n",
    "builder.add_constraint(column_is_nullable_boolean(column_name=\"flies\"))\n",
    "builder.add_constraint(column_is_nullable_object(column_name=\"obj\"))\n",
    "\n",
    "constraints = builder.build()\n",
    "\n",
    "from whylogs.viz import NotebookProfileVisualizer\n",
    "\n",
    "visualization = NotebookProfileVisualizer()\n",
    "visualization.constraints_report(constraints, cell_height=300)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The constraints above will pass if all values are of a given type. Null values are accepted.\n",
    "\n",
    "Note that for `legs`, the constraints failed. That is because whylogs leverages __pandas' dtypes__ when it is available, and when a `None` is present, the column is considered to be `fractional`, even though the remaining values were originally integers. "
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Combined Constraints <a class=\"anchor\" id=\"comb\"></a>"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Examples - Combined Metrics"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To create a constraint that checks for a non-nullable type, we combine two separate constraints:\n",
    "\n",
    "- `column is nullable datatype`\n",
    "- `null values below 1`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "import whylogs as why\n",
    "import pandas as pd\n",
    "\n",
    "data = {\n",
    "    \"animal\": [\"cat\", \"snake\", \"snake\", \"cat\", \"mosquito\"],\n",
    "    \"legs\": [4, 2, 0, None, 6],\n",
    "    \"weight\": [4.3, 1.8, 1.3, 4.1, 5.5e-6],\n",
    "    \"flies\": [False, False, \"False\", False, True],\n",
    "    \"obj\": [{\"a\":1}, None, {\"a\":1}, {\"a\":1}, {\"a\":1}]\n",
    "}\n",
    "df = pd.DataFrame(data)\n",
    "results = why.log(df)\n",
    "profile_view = results.view()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Check Non-nullable Types"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div></div><iframe srcdoc=\"&lt;!DOCTYPE html&gt;\n",
       "&lt;html lang=&quot;en&quot;&gt;\n",
       "  &lt;head&gt;\n",
       "    &lt;meta charset=&quot;UTF-8&quot; /&gt;\n",
       "    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot; /&gt;\n",
       "    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;\n",
       "    &lt;meta name=&quot;description&quot; content=&quot;&quot; /&gt;\n",
       "    &lt;meta name=&quot;author&quot; content=&quot;&quot; /&gt;\n",
       "\n",
       "    &lt;title&gt;Profile Visualizer | whylogs&lt;/title&gt;\n",
       "\n",
       "    &lt;link rel=&quot;icon&quot; href=&quot;images/whylabs-favicon.png&quot; type=&quot;image/png&quot; sizes=&quot;16x16&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.googleapis.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; crossorigin /&gt;\n",
       "    &lt;link href=&quot;https://fonts.googleapis.com/css2?family=Asap:wght@400;500;600;700&amp;display=swap&quot; rel=&quot;stylesheet&quot; /&gt;\n",
       "    &lt;link rel=&quot;preconnect&quot; href=&quot;https://fonts.gstatic.com&quot; /&gt;\n",
       "    &lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css&quot; /&gt;\n",
       "\n",
       "    &lt;script\n",
       "      src=&quot;https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.7.7/handlebars.min.js&quot;\n",
       "      integrity=&quot;sha512-RNLkV3d+aLtfcpEyFG8jRbnWHxUqVZozacROI4J2F1sTaDqo1dPQYs01OMi1t1w9Y2FdbSCDSQ2ZVdAC8bzgAg==&quot;\n",
       "      crossorigin=&quot;anonymous&quot;\n",
       "      referrerpolicy=&quot;no-referrer&quot;\n",
       "    &gt;&lt;/script&gt;\n",
       "\n",
       "    &lt;style type=&quot;text/css&quot;&gt;\n",
       "\n",
       "      /* Screen on smaller screens */\n",
       "      .no-responsive {\n",
       "        display: none;\n",
       "        position: fixed;\n",
       "        top: 0;\n",
       "        left: 0;\n",
       "        z-index: 1031;\n",
       "        width: 100vw;\n",
       "        height: 100vh;\n",
       "        background-color: var(--tealBackground);\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      @media screen and (min-width: 1000px) {\n",
       "        .desktop-content {\n",
       "          display: block;\n",
       "        }\n",
       "        .no-responsive {\n",
       "          display: none;\n",
       "        }\n",
       "      }\n",
       "\n",
       "      .no-responsive__content {\n",
       "        max-width: 600px;\n",
       "        width: 100%;\n",
       "        padding: 0 24px;\n",
       "      }\n",
       "\n",
       "      .no-responsive__title {\n",
       "        font-size: 96px;\n",
       "        font-weight: 300;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.167;\n",
       "      }\n",
       "\n",
       "      .no-responsive__text {\n",
       "        margin: 0;\n",
       "        font-size: 16px;\n",
       "        font-weight: 400;\n",
       "        color: var(--brandSecondary900);\n",
       "        line-height: 1.5;\n",
       "      }\n",
       "\n",
       "      .header-title {\n",
       "        font-size: 26px;\n",
       "        font-weight: 700;\n",
       "        color: #444444;\n",
       "      }\n",
       "\n",
       "      .tooltip-full-number {\n",
       "        position: relative;\n",
       "        display: inline-block;\n",
       "      }\n",
       "\n",
       "      .tooltip-full-number .tooltiptext {\n",
       "        visibility: hidden;\n",
       "        background: black;\n",
       "        color: white;\n",
       "        border: 1px solid black;\n",
       "        text-align: start;\n",
       "        padding: 3px;\n",
       "        position: absolute;\n",
       "        z-index: 1;\n",
       "        top: 0;\n",
       "        left: 100%;\n",
       "        margin-left: 5px;\n",
       "        opacity: 0;\n",
       "        transition: opacity 0.5s;\n",
       "        font-size: 13px;\n",
       "        font-weight: normal;\n",
       "        line-height: 100%;\n",
       "      }\n",
       "\n",
       "      .tooltip-full-number:hover .tooltiptext {\n",
       "        visibility: visible;\n",
       "        opacity: 1;\n",
       "      }\n",
       "\n",
       "\n",
       "      .wl-compare-profile {\n",
       "        position: relative;\n",
       "        left: 0;\n",
       "        padding: 30px;\n",
       "        margin-bottom: 20px;\n",
       "        background: var(--white);;\n",
       "        border-bottom: 1px solid #CED4DA;\n",
       "      }\n",
       "\n",
       "      .alert-list {\n",
       "        padding: 30px;\n",
       "        padding-top: 0;\n",
       "      }\n",
       "\n",
       "    .drift-detection {\n",
       "       justify-content: space-between;\n",
       "       align-items: center;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-circle {\n",
       "       width: 15px;\n",
       "       height: 15px;\n",
       "       border-radius: 50px;\n",
       "       display: inline-block;\n",
       "       margin-right: 8px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-drifts-item {\n",
       "         padding-right: 20px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-title {\n",
       "       font-family: Arial;\n",
       "       font-weight: bold;\n",
       "       font-size: 22px;\n",
       "       line-height: 130%;\n",
       "       color: #313B3D;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-drifts-item-count {\n",
       "       font-family: Arial;\n",
       "       font-weight: bold;\n",
       "       font-size: 14px;\n",
       "       line-height: 16px;\n",
       "       color: #000000;\n",
       "       padding-right: 8px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-info-drifts-item-name {\n",
       "       font-family: Arial;\n",
       "       font-style: normal;\n",
       "       font-weight: normal;\n",
       "       font-size: 12px;\n",
       "       line-height: 14px;\n",
       "       color: #000000;\n",
       "     }\n",
       "\n",
       "     .drift-detection-search-input {\n",
       "       display: flex;\n",
       "       align-items: center;\n",
       "       background: rgba(255, 255, 255, 0.7);\n",
       "       border: 1px solid #DBE5E7;\n",
       "       box-sizing: border-box;\n",
       "       border-radius: 4px;\n",
       "       width: 170px;\n",
       "       padding-left: 10px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-search-input img{\n",
       "       margin-right: 5px;\n",
       "     }\n",
       "\n",
       "     .drift-detection-search-input input::placeholder {\n",
       "       font-family: Arial;\n",
       "       font-weight: normal;\n",
       "       font-size: 13px;\n",
       "       line-height: 16px;\n",
       "       color: #313B3D;\n",
       "     }\n",
       "\n",
       "     .dropdown-container {\n",
       "       position: absolute;\n",
       "       right: 30px;\n",
       "       top: 80px;\n",
       "       z-index: 999;\n",
       "       background: #FFFFFF;\n",
       "       border: 1px solid #DBE5E7;\n",
       "       box-sizing: border-box;\n",
       "       box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.05);\n",
       "       border-radius: 4px;\n",
       "       padding: 10px !important;\n",
       "       border: none !important;\n",
       "     }\n",
       "\n",
       "     .filter-options-title {\n",
       "       width: 240px;\n",
       "     }\n",
       "\n",
       "     .filter-options-title p {\n",
       "       margin: 0;\n",
       "     }\n",
       "\n",
       "     .form-check-input:checked {\n",
       "       background-color: #0E7384;\n",
       "       border-color: #0E7384;\n",
       "     }\n",
       "\n",
       "     .form-check-input[type=checkbox] {\n",
       "       border-radius: 2px;\n",
       "     }\n",
       "\n",
       "     .search-input{\n",
       "       padding-top: 0 !important;\n",
       "       padding-bottom: 0 !important;\n",
       "     }\n",
       "\n",
       "     .search-input input{\n",
       "       border: none;\n",
       "       background: none;\n",
       "       outline: none;\n",
       "       height: 40px;\n",
       "       width: 100%;\n",
       "       font-size: 14px;\n",
       "     }\n",
       "\n",
       "     .search-input img{\n",
       "       height: 19px;\n",
       "       pointer-events: none;\n",
       "     }\n",
       "\n",
       "     input::placeholder {\n",
       "       color: var(--secondaryLight1000);\n",
       "     }\n",
       "\n",
       "      .statistics {\n",
       "        width: 100%;\n",
       "      }\n",
       "\n",
       "     .close-filter-button {\n",
       "       display: flex;\n",
       "       justify-content: center;\n",
       "       align-items: center;\n",
       "       background: rgba(255, 255, 255, 0.7);\n",
       "       border: 1px solid #369BAC;\n",
       "       box-sizing: border-box;\n",
       "       border-radius: 4px;\n",
       "       width: 40px;\n",
       "       height: 40px;\n",
       "       cursor: pointer;\n",
       "       margin-left: 10px;\n",
       "     }\n",
       "\n",
       "      .statistic-number-title {\n",
       "        font-family: Arial;\n",
       "        font-weight: normal;\n",
       "        font-size: 14px;\n",
       "        line-height: 20px;\n",
       "        color: #6C757D;\n",
       "      }\n",
       "\n",
       "      .statistic-number {\n",
       "        font-family: Arial;\n",
       "        font-weight: bold;\n",
       "        font-size: 20px;\n",
       "        line-height: 140%;\n",
       "        display: flex;\n",
       "        align-items: center;\n",
       "        color: #4F595B;\n",
       "      }\n",
       "\n",
       "      .full-summary-statistics-wrap {\n",
       "        padding: 20px;\n",
       "      }\n",
       "\n",
       "      .statistics {\n",
       "        width: 100%;\n",
       "      }\n",
       "\n",
       "      .statistics-list {\n",
       "        width: 100% ;\n",
       "      }\n",
       "\n",
       "      mark {\n",
       "        padding: 5px;\n",
       "        border-radius: 4px;\n",
       "        font-family: Arial;\n",
       "        font-weight: normal;\n",
       "        font-size: 14px;\n",
       "        line-height: 140%;\n",
       "      }\n",
       "\n",
       "      .blue-mark {\n",
       "        background-color:  #369BAC1A;\n",
       "        color: #369BAC;\n",
       "      }\n",
       "\n",
       "      .red-mark {\n",
       "        background-color: #FFEFEE;\n",
       "        color: #F5473C;\n",
       "      }\n",
       "\n",
       "      .alert-tag {\n",
       "        height: 27px;\n",
       "        padding: 5px;\n",
       "        border-radius: 4px;\n",
       "        font-family: Arial;\n",
       "        font-weight: bold;\n",
       "        font-size: 12px;\n",
       "        line-height: 140%;\n",
       "        color: #FFFFFF;\n",
       "      }\n",
       "\n",
       "      .turquoise-background-color {\n",
       "        background-color: #1DBB42;\n",
       "      }\n",
       "\n",
       "      .bordeaux-background-color {\n",
       "        background-color: #C6462A;\n",
       "      }\n",
       "\n",
       "      .border-solid-gray {\n",
       "        border: 1px solid #CED4DA;\n",
       "        border-radius: 4px;\n",
       "      }\n",
       "\n",
       "      .display-flex {\n",
       "        display: flex;\n",
       "      }\n",
       "\n",
       "      .justify-content-space-between {\n",
       "        justify-content: space-between;\n",
       "      }\n",
       "\n",
       "      .justify-content-center {\n",
       "        justify-content: center;\n",
       "      }\n",
       "\n",
       "      .align-items-center {\n",
       "        align-items: center;\n",
       "      }\n",
       "\n",
       "      .align-items-flex-start {\n",
       "        align-items: flex-start;\n",
       "      }\n",
       "\n",
       "      .padding-right-30 {\n",
       "        padding-right: 30px;\n",
       "      }\n",
       "\n",
       "      .notif-circle-container{\n",
       "        position: absolute;\n",
       "        top: 25px;\n",
       "        right: 25px;\n",
       "        padding: 5.3px;\n",
       "        border-radius: 50%;\n",
       "        background-color: white;\n",
       "        cursor: pointer;\n",
       "      }\n",
       "\n",
       "      .notif-circle {\n",
       "        position: absolute;\n",
       "        top: 2px;\n",
       "        right: 2px;\n",
       "        padding: 3.3px;\n",
       "        border-radius: 50%;\n",
       "        background-color: #F2994A;\n",
       "      }\n",
       "\n",
       "      .alert-list-text {\n",
       "        width: 70%\n",
       "      }\n",
       "\n",
       "     @media screen and (min-width: 500px) {\n",
       "       .desktop-content {\n",
       "         display: block;\n",
       "       }\n",
       "       .no-responsive {\n",
       "         display: none;\n",
       "       }\n",
       "     }\n",
       "    &lt;/style&gt;\n",
       "  &lt;/head&gt;\n",
       "\n",
       "  &lt;body id=&quot;generated-html&quot;&gt;&lt;/body&gt;\n",
       "\n",
       "  &lt;script id=&quot;entry-template&quot; type=&quot;text/x-handlebars-template&quot;&gt;\n",
       "    \n",
       "      &lt;div class=&quot;desktop-content&quot;&gt;\n",
       "        &lt;div class=&quot;full-summary-statistics-wrap&quot;&gt;\n",
       "          &lt;div class=&quot;full-summary-statistics&quot;&gt;\n",
       "            &lt;div&gt;\n",
       "              &lt;div class=&quot;display-flex justify-content-center&quot;&gt;\n",
       "                &lt;div class=&quot;statistics-list border-solid-gray&quot;&gt;\n",
       "                  &lt;div&gt;\n",
       "                    &lt;div class=&quot;wl-compare-profile&quot; id=&quot;compare-profile&quot;&gt;\n",
       "                        &lt;div class=&quot;drift-detection-wrap&quot;&gt;\n",
       "                          &lt;div class=&quot;drift-detection display-flex align-items-flex-start&quot;&gt;\n",
       "                            &lt;div class=&quot;drift-detection-info flex-direction-colum&quot;&gt;\n",
       "                              &lt;div class=&quot;drift-detection-info-title-wrap display-flex&quot;&gt;\n",
       "                                &lt;p class=&quot;drift-detection-info-title&quot;&gt;\n",
       "                                  Constraints Report\n",
       "                                &lt;/p&gt;\n",
       "                              &lt;/div&gt;\n",
       "\n",
       "                              &lt;!-- &lt;/div&gt; --&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;div class=&quot;drift-detection-search-input-wrap display-flex&quot;&gt;\n",
       "                              &lt;div class=&quot;drift-detection-search-input search-input&quot;&gt;\n",
       "                                &lt;input type=&quot;text&quot; id=&quot;wl__feature-search&quot; placeholder=&quot;Quick search...&quot;/&gt;\n",
       "                                &lt;img src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAGdSURBVHgBpZK7TkJBEIZnZoVocdTYyQNALxpNKPQBMEaNJsbCRMKhl8ISWwt6AaksCF5iTHgAGhJD4AHkAaAzGiwUsjvOQnO4SYh/cXbPzO43OxcEj9Zy92EiFSXNIfvPyE1kKFfdoxJMENpP6DrvLC0vJoEwCgwto7DWcxoIIHBYbA3NmKwnDltjAeuZhyul1DaTTlfPB6Nt5Z53DOgky4P875+nlctY2+unjZviLklkJhi5bPUa3y/7qJuQUM7PinMy7CdQc1Gh16vnBxPzrMROmlKQEgKNASAHLQCmSIGpS75O+O5pdQAgVXaIqTkNwDDXHmcnW3VmHZoGMLoTsOt88+NrAMCIZdu+iLTyTwKRa1Md6YKfOgXbzO7K8sWku5u5RxcRV5EpPezrzcHGbXEXWaUkgkweZ/UC9YrK3zqggFw5FBZfm8EUavHj7AjAKpIvBDrGn+pNnlcyhYgqbcC41idr1gvB4SdZkDbzQa21gwv0Vj07aPTtL07XdDOyDXohCDNoHIRmAVRie20f+RKybRDQDvxHkXy/7b/DrayncLbMwQAAAABJRU5ErkJggg==&quot;/&gt;\n",
       "                              &lt;/div&gt;\n",
       "                              &lt;div class=&quot;wl__dropdown_arrow-icon&quot;&gt;\n",
       "                                &lt;div onclick=&quot;openFilter()&quot; class=&quot;close-filter-button&quot;&gt;\n",
       "                                &lt;div class=&quot;display-flex close-filter-icon d-none&quot;&gt;\n",
       "                                  &lt;img src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAALCAYAAACprHcmAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAADFSURBVHgBfY+xDcIwEEXvnLQBZQkYAEhDwwKpEEK0CCZgAEjJCEmgjYSAygxAHTZgFRSOsyUjY5mcZFnn/+78PwBXf3+MoKWUPuYjVBPFnTwpr9t/oNJfcTfXsAhRAlDqDhhQIPYgpAqNMDqcUqSAYZT1epr9gAHt6uXshvYme4DYHQJNDKh0dD0m5WXB10Y3Fqjtuh7fROn3oREDWxfeMLyRsMnc0OgDzdduaA0Pi3Plgr7Q2kaAePeBqh6rueSNBVt6fgCwBV1JLF3rlAAAAABJRU5ErkJggg==&quot;/&gt;\n",
       "                                &lt;/div&gt;\n",
       "                                &lt;div class=&quot;display-flex filter-icon&quot;&gt;\n",
       "                                  &lt;img src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACSSURBVHgBrZLBCYAwDEWTUjw7igcdwI1cxkNXUJzBEVzFAbSVKoKmaVrEB6GHJv/w+AACtRk7P9IONv1QOYUl96k0zv61m2tjARoLtSDI3EFsgIJ4uoXrMLazO72CRG2mzg/8BSdVlEjhpGZJjAWdAZJECpWalEhJSs1pHuUlMad5FFai1Lwg4Ckx1TxKIPFL8w55mEWd8VjPGAAAAABJRU5ErkJggg==&quot;/&gt;\n",
       "                                &lt;/div&gt;\n",
       "                                &lt;/div&gt;\n",
       "                              &lt;span class=&quot;notif-circle-container&quot;&gt;\n",
       "                                &lt;span class=&quot;notif-circle&quot;&gt;&lt;/span&gt;\n",
       "                              &lt;/span&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;/div&gt;\n",
       "                          &lt;/div&gt;\n",
       "                        &lt;/div&gt;\n",
       "                        &lt;div class=&quot;dropdown-container flex-direction-colum mb-2 d-none&quot; id=&quot;dropdown-container&quot;&gt;\n",
       "                          &lt;div class=&quot;filter-options&quot;&gt;\n",
       "                            &lt;div class=&quot;filter-options-title space-between dropdown&quot;&gt;\n",
       "                              &lt;p&gt;Select a view:&lt;/p&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;div class=&quot;form-check mb-1 mt-2&quot;&gt;\n",
       "                              &lt;input\n",
       "                                class=&quot;form-check-input wl__feature-filter-input&quot;\n",
       "                                type=&quot;checkbox&quot;\n",
       "                                name=&quot;checkbox&quot;\n",
       "                                value=&quot;Discrete&quot;\n",
       "                                id=&quot;inferredDiscrete&quot;\n",
       "                                checked\n",
       "                              /&gt;\n",
       "                              &lt;label class=&quot;form-check-label&quot; for=&quot;inferredDiscrete&quot;&gt;\n",
       "                                Failed constraints (&lt;span class=&quot;wl__feature-count--discrete&quot;&gt;&lt;/span&gt;)\n",
       "                              &lt;/label&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;div class=&quot;form-check mb-1&quot;&gt;\n",
       "                              &lt;input\n",
       "                                class=&quot;form-check-input wl__feature-filter-input&quot;\n",
       "                                type=&quot;checkbox&quot;\n",
       "                                name=&quot;checkbox&quot;\n",
       "                                value=&quot;Non-discrete&quot;\n",
       "                                id=&quot;inferredNonDiscrete&quot;\n",
       "                                checked\n",
       "                              /&gt;\n",
       "                              &lt;label class=&quot;form-check-label&quot; for=&quot;inferredNonDiscrete&quot;&gt;\n",
       "                                Passed constraints (&lt;span\n",
       "                                  class=&quot;wl__feature-count--non-discrete&quot;\n",
       "                                &gt;&lt;/span&gt;)\n",
       "                              &lt;/label&gt;\n",
       "                            &lt;/div&gt;\n",
       "                            &lt;div class=&quot;form-check mb-1&quot;&gt;\n",
       "                              &lt;input\n",
       "                                class=&quot;form-check-input wl__feature-filter-input&quot;\n",
       "                                type=&quot;checkbox&quot;\n",
       "                                name=&quot;checkbox&quot;\n",
       "                                value=&quot;Unknown&quot;\n",
       "                                id=&quot;inferredUnknown&quot;\n",
       "                                checked\n",
       "                              /&gt;\n",
       "                              &lt;label class=&quot;form-check-label&quot; for=&quot;inferredUnknown&quot;&gt;\n",
       "                                All constraints (&lt;span class=&quot;wl__feature-count--unknown&quot;&gt;&lt;/span&gt;)\n",
       "                              &lt;/label&gt;\n",
       "                            &lt;/div&gt;\n",
       "                          &lt;/div&gt;\n",
       "                        &lt;/div&gt;\n",
       "                      &lt;/div&gt;\n",
       "                    &lt;div class=&quot;alert-list&quot; id=&quot;alert-list&quot;&gt;\n",
       "                      {{{alertLIst this}}}\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;\n",
       "                &lt;/div&gt;\n",
       "              &lt;/div&gt;\n",
       "            &lt;/div&gt;\n",
       "          &lt;/div&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "      &lt;div class=&quot;no-responsive&quot;&gt;\n",
       "        &lt;div class=&quot;no-responsive__content&quot;&gt;\n",
       "          &lt;h1 class=&quot;no-responsive__title&quot;&gt;Hold on! :)&lt;/h1&gt;\n",
       "          &lt;p class=&quot;no-responsive__text&quot;&gt;\n",
       "            It looks like your current screen size or device is not yet supported by the WhyLabs Sandbox. The Sandbox is\n",
       "            best experienced on a desktop computer. Please try maximizing this window or switching to another device. We\n",
       "            are working on adding support for a larger variety of devices.\n",
       "          &lt;/p&gt;\n",
       "        &lt;/div&gt;\n",
       "      &lt;/div&gt;\n",
       "    \n",
       "  &lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://code.jquery.com/jquery-3.6.0.min.js&quot; integrity=&quot;sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.min.js&quot; integrity=&quot;sha512-cd6CHE+XWDQ33ElJqsi0MdNte3S+bQY819f7p3NUHgwQQLXSKjE4cPZTeGNI+vaxZynk1wVU3hoHmow3m089wA==&quot; crossorigin=&quot;anonymous&quot; referrerpolicy=&quot;no-referrer&quot;&gt;&lt;/script&gt;\n",
       "\n",
       "  &lt;script&gt;\n",
       "    function registerHandlebarHelperFunctions() {\n",
       "      //helper fun\n",
       "      function formatLabelDate(timestamp) {\n",
       "        const date = new Date(timestamp);\n",
       "        const format = d3.timeFormat(&quot;%Y-%m-%d %I:%M:%S %p %Z&quot;);\n",
       "        return format(date);\n",
       "      }\n",
       "\n",
       "      function fixNumberTo(number, decimals = 3) {\n",
       "        return parseFloat(number).toFixed(decimals);\n",
       "      }\n",
       "\n",
       "      const randomNumbers = (range) =&gt; Math.floor(Math.random() * range)\n",
       "\n",
       "      const findFetureWithNumberSummary = (column) =&gt; {\n",
       "        const fetureIndex = Object.values(column.columns)\n",
       "              .findIndex((feture) =&gt; feture.numberSummary)\n",
       "\n",
       "        return Object.keys(column.columns)[fetureIndex]\n",
       "      }\n",
       "\n",
       "      const alertListItemStatus = (status, passedItem, failedItem) =&gt; {\n",
       "        if (status) {\n",
       "          return passedItem\n",
       "        } else {\n",
       "          return failedItem\n",
       "        }\n",
       "      }\n",
       "\n",
       "      const alertListElement = (name, text, status, summary) =&gt; {\n",
       "        if (summary == null){\n",
       "          return (\n",
       "          `&lt;div\n",
       "             data-inferred-type=${alertListItemStatus(status, &quot;passed&quot;, &quot;failed&quot;)}\n",
       "             class=&quot;alert-list-item display-flex justify-content-space-between align-items-center mb-2&quot;\n",
       "           &gt;\n",
       "            &lt;div class=&quot;alert-list-text&quot;&gt;\n",
       "              ${\n",
       "                name &amp;&amp;\n",
       "                alertListItemStatus(\n",
       "                  status,\n",
       "                  `&lt;mark class=&quot;blue-mark&quot;&gt;${name}&lt;/mark&gt;`,\n",
       "                  `&lt;mark class=&quot;red-mark&quot;&gt;${name}&lt;/mark&gt;`\n",
       "                )\n",
       "              }\n",
       "              ${text}\n",
       "            &lt;/div&gt;\n",
       "              ${\n",
       "                alertListItemStatus(\n",
       "                  status,\n",
       "                  `\n",
       "                  &lt;div class=&quot;turquoise-background-color alert-tag&quot;&gt;Passed&lt;/div&gt;\n",
       "                  `\n",
       "                  ,\n",
       "                  `\n",
       "                  &lt;div class=&quot;bordeaux-background-color alert-tag&quot;&gt;Failed&lt;/div&gt;\n",
       "                  `\n",
       "                )\n",
       "              }\n",
       "              &lt;/div&gt;`\n",
       "        )\n",
       "\n",
       "        }\n",
       "        return (\n",
       "          `&lt;div\n",
       "             data-inferred-type=${alertListItemStatus(status, &quot;passed&quot;, &quot;failed&quot;)}\n",
       "             class=&quot;alert-list-item display-flex justify-content-space-between align-items-center mb-2&quot;\n",
       "           &gt;\n",
       "            &lt;div class=&quot;alert-list-text&quot;&gt;\n",
       "              ${\n",
       "                name &amp;&amp;\n",
       "                alertListItemStatus(\n",
       "                  status,\n",
       "                  `&lt;mark class=&quot;blue-mark&quot;&gt;${name}&lt;/mark&gt;`,\n",
       "                  `&lt;mark class=&quot;red-mark&quot;&gt;${name}&lt;/mark&gt;`\n",
       "                )\n",
       "              }\n",
       "              ${text}\n",
       "            &lt;/div&gt;\n",
       "              ${\n",
       "                alertListItemStatus(\n",
       "                  status,\n",
       "                  `\n",
       "                  &lt;div class=&quot;tooltip-full-number&quot;&gt;\n",
       "                    &lt;div class=&quot;turquoise-background-color alert-tag&quot;&gt;Passed\n",
       "                      &lt;span class=&quot;tooltiptext&quot;&gt;\n",
       "                          &lt;pre class=&quot;mb-1&quot;&gt; ${JSON.stringify(summary, null, 2)} &lt;/pre&gt;\n",
       "                        &lt;/span&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;`\n",
       "\n",
       "                  ,\n",
       "                  `\n",
       "                  &lt;div class=&quot;tooltip-full-number&quot;&gt;\n",
       "                    &lt;div class=&quot;bordeaux-background-color alert-tag&quot;&gt;Failed\n",
       "                      &lt;span class=&quot;tooltiptext&quot;&gt;\n",
       "                        &lt;pre class=&quot;mb-1&quot;&gt; ${JSON.stringify(summary, null, 2)} &lt;/pre&gt;\n",
       "                        &lt;/span&gt;\n",
       "                    &lt;/div&gt;\n",
       "                  &lt;/div&gt;`\n",
       "                )\n",
       "              }\n",
       "              &lt;/div&gt;`\n",
       "        )\n",
       "      }\n",
       "\n",
       "      let failedConstraints = 0;\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getProfileTimeStamp&quot;, function (column) {\n",
       "        return formatLabelDate(+column.properties.dataTimestamp)\n",
       "      });\n",
       "\n",
       "      Handlebars.registerHelper(&quot;getProfileName&quot;, function (column) {\n",
       "        return column.properties.tags.name\n",
       "      });\n",
       "\n",
       "\n",
       "      Handlebars.registerHelper(&quot;alertLIst&quot;, function (column) {\n",
       "        let alertListItem = column.map((value) =&gt; {\n",
       "          if (value[1][0]) {\n",
       "            let alertListValue = value[1].map((cstr)=&gt;{\n",
       "              return alertListElement(value[0],cstr[0],cstr[cstr.length - 1] === 0 || (failedConstraints++, false), value[3])\n",
       "            })\n",
       "            return alertListValue.join(&#x27; &#x27;)\n",
       "          } else {\n",
       "            return alertListElement(&#x27;&#x27;, value[0], value[2] === 0 ||  (failedConstraints++, false), value[3])\n",
       "          }\n",
       "        })\n",
       "         $(document).ready(() =&gt; {\n",
       "           $(&quot;.wl__feature-count--discrete&quot;).append(failedConstraints)\n",
       "           $(&quot;.wl__feature-count--non-discrete&quot;).append(column.length - failedConstraints)\n",
       "           $(&quot;.wl__feature-count--unknown&quot;).append(column.length)\n",
       "         })\n",
       "        return alertListItem.join(&#x27; &#x27;)\n",
       "      });\n",
       "\n",
       "    }\n",
       "\n",
       "    function openFilter() {\n",
       "      const $filterOptions = $(&quot;.dropdown-container&quot;);\n",
       "      const filterClass = $filterOptions.attr(&quot;class&quot;);\n",
       "\n",
       "      if (filterClass.indexOf(&quot;d-none&quot;) &gt; 0) {\n",
       "        $filterOptions.removeClass(&quot;d-none&quot;);\n",
       "        $(&quot;.filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.close-filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "      } else {\n",
       "        $filterOptions.addClass(&quot;d-none&quot;);\n",
       "        $(&quot;.close-filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "      }\n",
       "    }\n",
       "\n",
       "    function initHandlebarsTemplate() {\n",
       "      // Replace this context with JSON from .py file\n",
       "      const context = [[&quot;animal is nullable string&quot;, 1, 0, {&quot;metric&quot;: &quot;types&quot;, &quot;integral&quot;: 0, &quot;fractional&quot;: 0, &quot;boolean&quot;: 0, &quot;string&quot;: 5, &quot;object&quot;: 0}], [&quot;null values of animal lower than 1&quot;, 1, 0, {&quot;metric&quot;: &quot;counts&quot;, &quot;n&quot;: 5, &quot;null&quot;: 0, &quot;nan&quot;: 0, &quot;inf&quot;: 0}], [&quot;legs is nullable integral&quot;, 0, 1, {&quot;metric&quot;: &quot;types&quot;, &quot;integral&quot;: 0, &quot;fractional&quot;: 4, &quot;boolean&quot;: 0, &quot;string&quot;: 0, &quot;object&quot;: 0}], [&quot;null values of legs lower than 1&quot;, 0, 1, {&quot;metric&quot;: &quot;counts&quot;, &quot;n&quot;: 5, &quot;null&quot;: 1, &quot;nan&quot;: 1, &quot;inf&quot;: 0}], [&quot;weight is nullable fractional&quot;, 1, 0, {&quot;metric&quot;: &quot;types&quot;, &quot;integral&quot;: 0, &quot;fractional&quot;: 5, &quot;boolean&quot;: 0, &quot;string&quot;: 0, &quot;object&quot;: 0}], [&quot;null values of weight lower than 1&quot;, 1, 0, {&quot;metric&quot;: &quot;counts&quot;, &quot;n&quot;: 5, &quot;null&quot;: 0, &quot;nan&quot;: 0, &quot;inf&quot;: 0}], [&quot;flies is nullable boolean&quot;, 0, 1, {&quot;metric&quot;: &quot;types&quot;, &quot;integral&quot;: 0, &quot;fractional&quot;: 0, &quot;boolean&quot;: 4, &quot;string&quot;: 1, &quot;object&quot;: 0}], [&quot;null values of flies lower than 1&quot;, 1, 0, {&quot;metric&quot;: &quot;counts&quot;, &quot;n&quot;: 5, &quot;null&quot;: 0, &quot;nan&quot;: 0, &quot;inf&quot;: 0}], [&quot;obj is nullable object&quot;, 1, 0, {&quot;metric&quot;: &quot;types&quot;, &quot;integral&quot;: 0, &quot;fractional&quot;: 0, &quot;boolean&quot;: 0, &quot;string&quot;: 0, &quot;object&quot;: 4}], [&quot;null values of obj lower than 1&quot;, 0, 1, {&quot;metric&quot;: &quot;counts&quot;, &quot;n&quot;: 5, &quot;null&quot;: 1, &quot;nan&quot;: 0, &quot;inf&quot;: 0}]];\n",
       "      // Config handlebars and pass data to HBS template\n",
       "      const source = document.getElementById(&quot;entry-template&quot;).innerHTML;\n",
       "      const template = Handlebars.compile(source);\n",
       "      const html = template(context);\n",
       "      const target = document.getElementById(&quot;generated-html&quot;);\n",
       "      target.innerHTML = html;\n",
       "    }\n",
       "\n",
       "    function initWebsiteScripts() {\n",
       "      const $featureSearch = document.getElementById(&quot;wl__feature-search&quot;);\n",
       "      const $alertList = document.getElementById(&quot;alert-list&quot;);\n",
       "      const $discrete = document.getElementById(&quot;inferredDiscrete&quot;);\n",
       "      const $nonDiscrete = document.getElementById(&quot;inferredNonDiscrete&quot;);\n",
       "      const $unknown = document.getElementById(&quot;inferredUnknown&quot;);\n",
       "\n",
       "      const activeTypes = {\n",
       "        passed: true,\n",
       "        failed: true\n",
       "      };\n",
       "\n",
       "      let searchString = &quot;&quot;;\n",
       "\n",
       "      function debounce(func, wait, immediate) {\n",
       "        let timeout;\n",
       "\n",
       "        return function () {\n",
       "          const context = this;\n",
       "          const args = arguments;\n",
       "          const later = function () {\n",
       "            timeout = null;\n",
       "            if (!immediate) func.apply(context, args);\n",
       "          };\n",
       "\n",
       "          const callNow = immediate &amp;&amp; !timeout;\n",
       "          clearTimeout(timeout);\n",
       "          timeout = setTimeout(later, wait);\n",
       "          if (callNow) func.apply(context, args);\n",
       "        };\n",
       "      }\n",
       "\n",
       "      function filterNotification() {\n",
       "        const $notifCircleContainer = $(&quot;.notif-circle-container&quot;)\n",
       "        const $boxes = $(&#x27;.wl_filter-options&gt;.form-check&gt;input[name=checkbox]:checked&#x27;);\n",
       "        const item = Object.values($boxes).find(function(value) { return $(value)[0] === undefined});\n",
       "        if (item === undefined) {\n",
       "          $notifCircleContainer.removeClass(&quot;d-none&quot;)\n",
       "        } else {\n",
       "          $notifCircleContainer.addClass(&quot;d-none&quot;)\n",
       "        }\n",
       "      }\n",
       "\n",
       "      function handleSearch() {\n",
       "        const tableBodyChildren = $alertList.children;\n",
       "\n",
       "        for (let i = 0; i &lt; tableBodyChildren.length; i++) {\n",
       "          const type = tableBodyChildren[i].dataset.inferredType.toLowerCase();\n",
       "          const name = $(tableBodyChildren[i].children[0]).html().toLowerCase();\n",
       "          if (activeTypes[type] &amp;&amp; name.includes(searchString)) {\n",
       "            tableBodyChildren[i].style.display = &quot;&quot;;\n",
       "          } else {\n",
       "            tableBodyChildren[i].style.display = &quot;none&quot;;\n",
       "          }\n",
       "        }\n",
       "      }\n",
       "\n",
       "      const checkedBoxes = () =&gt; {\n",
       "        if ($(&#x27;.form-check-input:checked&#x27;).length === $(&quot;.form-check-input&quot;).length - 1) {\n",
       "          $($(&quot;.form-check-input&quot;)[$(&quot;.form-check-input&quot;).length - 1]).prop( &quot;checked&quot;, true );\n",
       "        }\n",
       "      }\n",
       "\n",
       "      $featureSearch.addEventListener(\n",
       "        &quot;keyup&quot;,\n",
       "        debounce((event) =&gt; {\n",
       "          searchString = event.target.value.toLowerCase();\n",
       "          handleSearch();\n",
       "        }, 100),\n",
       "      );\n",
       "\n",
       "      $discrete.addEventListener(&quot;change&quot;, (event) =&gt; {\n",
       "        const currentCheckbox = $(event.currentTarget);\n",
       "\n",
       "        if (event.currentTarget.checked) {\n",
       "          activeTypes[&quot;failed&quot;] = true;\n",
       "          checkedBoxes();\n",
       "        } else {\n",
       "          activeTypes[&quot;failed&quot;] = false;\n",
       "          $($(&quot;.form-check-input&quot;)[$(&quot;.form-check-input&quot;).length - 1]).prop( &quot;checked&quot;, false );\n",
       "        }\n",
       "        handleSearch();\n",
       "      });\n",
       "\n",
       "      $nonDiscrete.addEventListener(&quot;change&quot;, (event) =&gt; {\n",
       "        const currentCheckbox = $(event.currentTarget);\n",
       "\n",
       "        if (event.currentTarget.checked) {\n",
       "          activeTypes[&quot;passed&quot;] = true;\n",
       "          checkedBoxes();\n",
       "        } else {\n",
       "          activeTypes[&quot;passed&quot;] = false;\n",
       "          $($(&quot;.form-check-input&quot;)[$(&quot;.form-check-input&quot;).length - 1]).prop( &quot;checked&quot;, false );\n",
       "        }\n",
       "        handleSearch();\n",
       "      });\n",
       "\n",
       "      $unknown.addEventListener(&quot;change&quot;, (event) =&gt; {\n",
       "        const currentCheckbox = $(event.currentTarget);\n",
       "\n",
       "        if (event.currentTarget.checked) {\n",
       "          $(&quot;.form-check-input&quot;).prop( &quot;checked&quot;, true );\n",
       "          activeTypes[&quot;passed&quot;] = true;\n",
       "          activeTypes[&quot;failed&quot;] = true;\n",
       "          checkedBoxes();\n",
       "        } else {\n",
       "          $(&quot;.form-check-input&quot;).prop( &quot;checked&quot;, false );\n",
       "          activeTypes[&quot;passed&quot;] = false;\n",
       "          activeTypes[&quot;failed&quot;] = false;\n",
       "        }\n",
       "        handleSearch();\n",
       "      });\n",
       "    }\n",
       "\n",
       "    function checkedBoxes() {\n",
       "      const $boxes = $(&#x27;input[name=checkbox]:checked&#x27;);\n",
       "      const $notifCircleContainer = $(&quot;.notif-circle-container&quot;)\n",
       "\n",
       "      if ($boxes.length) {\n",
       "        $notifCircleContainer.removeClass(&quot;d-none&quot;)\n",
       "      }\n",
       "    }\n",
       "\n",
       "    function openFilter() {\n",
       "      const $filterOptions = $(&quot;.dropdown-container&quot;);\n",
       "      const $notifCircleContainer = $(&quot;.notif-circle-container&quot;)\n",
       "      const filterClass = $filterOptions.attr(&quot;class&quot;);\n",
       "\n",
       "      if (filterClass.indexOf(&quot;d-none&quot;) &gt; 0) {\n",
       "        $notifCircleContainer.addClass(&quot;d-none&quot;)\n",
       "        $filterOptions.removeClass(&quot;d-none&quot;);\n",
       "        $(&quot;.filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.close-filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "      } else {\n",
       "        $filterOptions.addClass(&quot;d-none&quot;);\n",
       "        $(&quot;.close-filter-icon&quot;).addClass(&quot;d-none&quot;)\n",
       "        $(&quot;.filter-icon&quot;).removeClass(&quot;d-none&quot;)\n",
       "        checkedBoxes()\n",
       "      }\n",
       "    }\n",
       "\n",
       "    // Invoke functions -- keep in mind invokation order\n",
       "    registerHandlebarHelperFunctions();\n",
       "    initHandlebarsTemplate();\n",
       "    initWebsiteScripts();\n",
       "  &lt;/script&gt;\n",
       "&lt;/html&gt;\n",
       "\" width=100% height=300\n",
       "        frameBorder=0></iframe>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from whylogs.core.constraints.factories import ( \n",
    "    column_is_nullable_integral,\n",
    "    column_is_nullable_boolean, \n",
    "    column_is_nullable_fractional,\n",
    "    column_is_nullable_object,\n",
    "    column_is_nullable_string,\n",
    "    null_values_below_number,\n",
    ")\n",
    "from whylogs.core.constraints import ConstraintsBuilder\n",
    "\n",
    "\n",
    "builder = ConstraintsBuilder(dataset_profile_view=profile_view)\n",
    "builder.add_constraint(column_is_nullable_string(column_name=\"animal\"))\n",
    "builder.add_constraint(null_values_below_number(column_name=\"animal\",number=1))\n",
    "\n",
    "# The combination of these metrics makes a check of non-nullable integral\n",
    "builder.add_constraint(column_is_nullable_integral(column_name=\"legs\"))\n",
    "builder.add_constraint(null_values_below_number(column_name=\"legs\",number=1))\n",
    "\n",
    "# The combination of these metrics makes a check of non-nullable fractional\n",
    "builder.add_constraint(column_is_nullable_fractional(column_name=\"weight\"))\n",
    "builder.add_constraint(null_values_below_number(column_name=\"weight\",number=1))\n",
    "\n",
    "# The combination of these metrics makes a check of non-nullable boolean\n",
    "builder.add_constraint(column_is_nullable_boolean(column_name=\"flies\"))\n",
    "builder.add_constraint(null_values_below_number(column_name=\"flies\",number=1))\n",
    "\n",
    "# The combination of these metrics makes a check of non-nullable object\n",
    "builder.add_constraint(column_is_nullable_object(column_name=\"obj\"))\n",
    "builder.add_constraint(null_values_below_number(column_name=\"obj\",number=1))\n",
    "\n",
    "constraints = builder.build()\n",
    "\n",
    "from whylogs.viz import NotebookProfileVisualizer\n",
    "\n",
    "visualization = NotebookProfileVisualizer()\n",
    "visualization.constraints_report(constraints, cell_height=300)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.8.10 ('.venv': poetry)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "5dd5901cadfd4b29c2aaf95ecd29c0c3b10829ad94dcfe59437dbee391154aea"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}