Repository: great-expectations/great_expectations

Issue:
Use cleaner solution for non-truncating division in python 2
Prefer `from __future__ import division` to `1.*x/y`


Discussion:
Done inline during improve_partitions push.

Resolving patch:
diff --git a/great_expectations/expectations/core/expect_column_kl_divergence_to_be_less_than.py b/great_expectations/expectations/core/expect_column_kl_divergence_to_be_less_than.py
--- a/great_expectations/expectations/core/expect_column_kl_divergence_to_be_less_than.py
+++ b/great_expectations/expectations/core/expect_column_kl_divergence_to_be_less_than.py
@@ -777,7 +777,13 @@ def _get_kl_divergence_chart(cls, partition_object, header=None):
 
                 chart = bars.to_dict()
             elif partition_object.get("values"):
-                values = partition_object["values"]
+                is_boolean_list = all(
+                    isinstance(value, bool) for value in partition_object["values"]
+                )
+                if is_boolean_list:
+                    values = [str(value) for value in partition_object["values"]]
+                else:
+                    values = partition_object["values"]
 
                 df = pd.DataFrame({"values": values, "fraction": weights})
 
@@ -873,7 +879,13 @@ def _atomic_kl_divergence_chart_template(cls, partition_object: dict) -> tuple:
 
             chart = bars.to_dict()
         elif partition_object.get("values"):
-            values = partition_object["values"]
+            is_boolean_list = all(
+                isinstance(value, bool) for value in partition_object["values"]
+            )
+            if is_boolean_list:
+                values = [str(value) for value in partition_object["values"]]
+            else:
+                values = partition_object["values"]
 
             df = pd.DataFrame({"values": values, "fraction": weights})
 


Test patch:
diff --git a/tests/expectations/snapshots/snap_test_expectation_atomic_renderers.py b/tests/expectations/snapshots/snap_test_expectation_atomic_renderers.py
--- a/tests/expectations/snapshots/snap_test_expectation_atomic_renderers.py
+++ b/tests/expectations/snapshots/snap_test_expectation_atomic_renderers.py
@@ -50,6 +50,51 @@
     "value_type": "GraphType",
 }
 
+snapshots[
+    "test_atomic_diagnostic_observed_value_with_boolean_columun_expect_column_kl_divergence_to_be_less_than 1"
+] = {
+    "name": "atomic.diagnostic.observed_value",
+    "value": {
+        "graph": {
+            "$schema": "https://vega.github.io/schema/vega-lite/v4.8.1.json",
+            "autosize": "fit",
+            "config": {"view": {"continuousHeight": 300, "continuousWidth": 400}},
+            "data": {"name": "data-d8f1a1ab1f79e142d9ca399157673554"},
+            "datasets": {
+                "data-d8f1a1ab1f79e142d9ca399157673554": [
+                    {"fraction": 0.5, "values": "True"},
+                    {"fraction": 0.5, "values": "False"},
+                ]
+            },
+            "encoding": {
+                "tooltip": [
+                    {"field": "values", "type": "nominal"},
+                    {"field": "fraction", "type": "quantitative"},
+                ],
+                "x": {"field": "values", "type": "nominal"},
+                "y": {"field": "fraction", "type": "quantitative"},
+            },
+            "height": 400,
+            "mark": "bar",
+            "width": 250,
+        },
+        "header": {
+            "schema": {"type": "StringValueType"},
+            "value": {
+                "params": {
+                    "observed_value": {
+                        "schema": {"type": "string"},
+                        "value": "None (-infinity, infinity, or NaN)",
+                    }
+                },
+                "template": "KL Divergence: $observed_value",
+            },
+        },
+        "schema": {"type": "GraphType"},
+    },
+    "value_type": "GraphType",
+}
+
 snapshots[
     "test_atomic_diagnostic_observed_value_expect_column_quantile_values_to_be_between 1"
 ] = {
diff --git a/tests/expectations/test_expectation_atomic_renderers.py b/tests/expectations/test_expectation_atomic_renderers.py
--- a/tests/expectations/test_expectation_atomic_renderers.py
+++ b/tests/expectations/test_expectation_atomic_renderers.py
@@ -234,6 +234,52 @@ def test_atomic_diagnostic_observed_value_expect_column_kl_divergence_to_be_less
     snapshot.assert_match(res)
 
 
+def test_atomic_diagnostic_observed_value_with_boolean_columun_expect_column_kl_divergence_to_be_less_than(
+    snapshot, get_diagnostic_rendered_content
+):
+    # Please note that the vast majority of Expectations are calling `Expectation._atomic_diagnostic_observed_value()`
+    # As such, the specific expectation_type used here is irrelevant and is simply used to trigger the parent class.
+    expectation_config = {
+        "expectation_type": "expect_column_kl_divergence_to_be_less_than",
+        "kwargs": {
+            "column": "boolean_event",
+            "partition_object": {
+                "bins": [True, False],
+                "weights": [0.5, 0.5],
+            },
+            "threshold": 0.1,
+        },
+        "meta": {},
+        "ge_cloud_id": "4b53c4d5-90ba-467a-b7a7-379640bbd729",
+    }
+    update_dict = {
+        "expectation_config": ExpectationConfiguration(**expectation_config),
+        "result": {
+            "observed_value": 0.0,
+            "details": {
+                "observed_partition": {
+                    "values": [True, False],
+                    "weights": [0.5, 0.5],
+                },
+                "expected_partition": {
+                    "values": [True, False],
+                    "weights": [0.5, 0.5],
+                },
+            },
+        },
+    }
+    rendered_content = get_diagnostic_rendered_content(update_dict)
+
+    res = rendered_content.to_json_dict()
+    pprint(res)
+
+    # replace version of vega-lite in res to match snapshot test
+    res["value"]["graph"]["$schema"] = re.sub(
+        r"v\d*\.\d*\.\d*", "v4.8.1", res["value"]["graph"]["$schema"]
+    )
+    snapshot.assert_match(res)
+
+
 def test_atomic_prescriptive_summary_expect_column_max_to_be_between(
     snapshot, get_prescriptive_rendered_content
 ):