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/core/expectation_validation_result.py b/great_expectations/core/expectation_validation_result.py
--- a/great_expectations/core/expectation_validation_result.py
+++ b/great_expectations/core/expectation_validation_result.py
@@ -147,7 +147,7 @@ def __ne__(self, other):
             # if invalid comparisons are attempted, the objects are not equal.
             return True
 
-    def __repr__(self):
+    def __repr__(self) -> str:
         """
         # TODO: <Alex>5/9/2022</Alex>
         This implementation is non-ideal (it was agreed to employ it for development expediency).  A better approach
@@ -155,7 +155,6 @@ def __repr__(self):
         """
         json_dict: dict = self.to_json_dict()
         if in_jupyter_notebook():
-            json_dict: dict = self.to_json_dict()
             if (
                 "expectation_config" in json_dict
                 and "kwargs" in json_dict["expectation_config"]
@@ -175,7 +174,7 @@ def __repr__(self):
 
         return json.dumps(json_dict, indent=2)
 
-    def __str__(self):
+    def __str__(self) -> str:
         """
         # TODO: <Alex>5/9/2022</Alex>
         This implementation is non-ideal (it was agreed to employ it for development expediency).  A better approach
diff --git a/great_expectations/render/renderer/v3/suite_profile_notebook_renderer.py b/great_expectations/render/renderer/v3/suite_profile_notebook_renderer.py
--- a/great_expectations/render/renderer/v3/suite_profile_notebook_renderer.py
+++ b/great_expectations/render/renderer/v3/suite_profile_notebook_renderer.py
@@ -240,9 +240,6 @@ def _add_onboarding_data_assistant_cells(self) -> None:
 import great_expectations as ge
 import great_expectations.jupyter_ux
 from great_expectations.core.batch import BatchRequest
-from great_expectations.rule_based_profiler.types.data_assistant_result import (
-    DataAssistantResult,
-)
 from great_expectations.checkpoint import SimpleCheckpoint
 from great_expectations.exceptions import DataContextError
 
@@ -281,7 +278,7 @@ def _add_onboarding_data_assistant_cells(self) -> None:
         self._add_onboarding_data_assistant_instructions()
         self.add_code_cell(
             code="""\
-data_assistant_result: DataAssistantResult = context.assistants.onboarding.run(
+result = context.assistants.onboarding.run(
     batch_request=batch_request,
     # include_column_names=include_column_names,
     exclude_column_names=exclude_column_names,
@@ -324,7 +321,7 @@ def _add_onboarding_data_assistant_cells(self) -> None:
     #     "round_decimals": 4,
     # },
 )
-validator.expectation_suite = data_assistant_result.get_expectation_suite(
+validator.expectation_suite = result.get_expectation_suite(
     expectation_suite_name=expectation_suite_name
 )
 """,
diff --git a/great_expectations/rule_based_profiler/types/data_assistant_result/data_assistant_result.py b/great_expectations/rule_based_profiler/types/data_assistant_result/data_assistant_result.py
--- a/great_expectations/rule_based_profiler/types/data_assistant_result/data_assistant_result.py
+++ b/great_expectations/rule_based_profiler/types/data_assistant_result/data_assistant_result.py
@@ -1,4 +1,6 @@
 import copy
+import datetime
+import json
 from collections import defaultdict, namedtuple
 from dataclasses import dataclass
 from typing import Any, Callable, Dict, KeysView, List, Optional, Set, Tuple, Union
@@ -8,6 +10,7 @@
 import pandas as pd
 from IPython.display import HTML, display
 
+from great_expectations import __version__ as ge_version
 from great_expectations.core import ExpectationConfiguration, ExpectationSuite
 from great_expectations.core.usage_statistics.events import UsageStatsEvents
 from great_expectations.core.usage_statistics.usage_statistics import (
@@ -15,7 +18,11 @@
     get_expectation_suite_usage_statistics,
     usage_statistics_enabled_method,
 )
-from great_expectations.core.util import convert_to_json_serializable, nested_update
+from great_expectations.core.util import (
+    convert_to_json_serializable,
+    in_jupyter_notebook,
+    nested_update,
+)
 from great_expectations.execution_engine.execution_engine import MetricDomainTypes
 from great_expectations.rule_based_profiler.helpers.util import (
     get_or_create_expectation_suite,
@@ -97,6 +104,10 @@ class DataAssistantResult(SerializableDictDot):
         "usage_statistics_handler",
     }
 
+    IN_JUPYTER_NOTEBOOK_KEYS = {
+        "execution_time",
+    }
+
     batch_id_to_batch_identifier_display_name_map: Optional[
         Dict[str, Set[Tuple[str, Any]]]
     ] = None
@@ -157,6 +168,45 @@ def __dir__(self) -> List[str]:
             }
         )
 
+    def __repr__(self) -> str:
+        """
+        # TODO: <Alex>6/22/2022</Alex>
+        This implementation is non-ideal (it was agreed to employ it for development expediency).  A better approach
+        would consist of "__str__()" calling "__repr__()", while all output options are handled through state variables.
+        """
+        json_dict: dict = self.to_json_dict()
+        if in_jupyter_notebook():
+            key: str
+            value: Any
+            json_dict = {
+                key: value
+                for key, value in json_dict.items()
+                if key in DataAssistantResult.IN_JUPYTER_NOTEBOOK_KEYS
+            }
+            json_dict.update(
+                {
+                    "num_profiler_rules": len(self.profiler_config.rules),
+                    "num_domains": len(self.metrics_by_domain),
+                    "num_expectation_configurations": len(
+                        self.expectation_configurations
+                    ),
+                    "auto_generated_at": datetime.datetime.now(
+                        datetime.timezone.utc
+                    ).strftime("%Y%m%dT%H%M%S.%fZ"),
+                    "great_expectations_version": ge_version,
+                }
+            )
+
+        return json.dumps(json_dict, indent=2)
+
+    def __str__(self) -> str:
+        """
+        # TODO: <Alex>6/22/2022</Alex>
+        This implementation is non-ideal (it was agreed to employ it for development expediency).  A better approach
+        would consist of "__str__()" calling "__repr__()", while all output options are handled through state variables.
+        """
+        return json.dumps(self.to_json_dict(), indent=2)
+
     @property
     def _usage_statistics_handler(self) -> Optional[UsageStatisticsHandler]:
         """


Test patch:
diff --git a/tests/integration/docusaurus/expectations/data_assistants/how_to_create_an_expectation_suite_with_the_onboarding_data_assistant.py b/tests/integration/docusaurus/expectations/data_assistants/how_to_create_an_expectation_suite_with_the_onboarding_data_assistant.py
--- a/tests/integration/docusaurus/expectations/data_assistants/how_to_create_an_expectation_suite_with_the_onboarding_data_assistant.py
+++ b/tests/integration/docusaurus/expectations/data_assistants/how_to_create_an_expectation_suite_with_the_onboarding_data_assistant.py
@@ -16,9 +16,6 @@
 from great_expectations.checkpoint import SimpleCheckpoint
 from great_expectations.core.batch import BatchRequest
 from great_expectations.core.yaml_handler import YAMLHandler
-from great_expectations.rule_based_profiler.types.data_assistant_result import (
-    DataAssistantResult,
-)
 
 yaml = YAMLHandler()
 
@@ -110,7 +107,7 @@
 # </snippet>
 
 # <snippet>
-onboarding_assistant_result: DataAssistantResult = context.assistants.onboarding.run(
+result = context.assistants.onboarding.run(
     batch_request=multi_batch_all_years_batch_request,
     # include_column_names=include_column_names,
     exclude_column_names=exclude_column_names,
@@ -166,7 +163,7 @@
 # Save your Expectation Suite
 
 # <snippet>
-validator.expectation_suite = onboarding_assistant_result.get_expectation_suite(
+validator.expectation_suite = result.get_expectation_suite(
     expectation_suite_name=expectation_suite_name
 )
 # </snippet>
diff --git a/tests/render/renderer/v3/test_suite_profile_notebook_renderer.py b/tests/render/renderer/v3/test_suite_profile_notebook_renderer.py
--- a/tests/render/renderer/v3/test_suite_profile_notebook_renderer.py
+++ b/tests/render/renderer/v3/test_suite_profile_notebook_renderer.py
@@ -73,9 +73,6 @@
 import great_expectations as ge
 import great_expectations.jupyter_ux
 from great_expectations.core.batch import BatchRequest
-from great_expectations.rule_based_profiler.types.data_assistant_result import (
-    DataAssistantResult,
-)
 from great_expectations.checkpoint import SimpleCheckpoint
 from great_expectations.exceptions import DataContextError""",
     # Batch request
@@ -87,7 +84,7 @@
 """,
     # OnboardingDataAssistant instantiation/usage
     """\
-data_assistant_result: DataAssistantResult = context.assistants.onboarding.run(
+result = context.assistants.onboarding.run(
     batch_request=batch_request,
     # include_column_names=include_column_names,
     exclude_column_names=exclude_column_names,
@@ -130,7 +127,7 @@
     #     "round_decimals": 4,
     # },
 )
-validator.expectation_suite = data_assistant_result.get_expectation_suite(
+validator.expectation_suite = result.get_expectation_suite(
     expectation_suite_name=expectation_suite_name
 )""",
 ]