Skip to content

Commit

Permalink
Fix error when intent is invalid (#351)
Browse files Browse the repository at this point in the history
  • Loading branch information
westernguy2 committed Apr 14, 2021
1 parent 939799f commit c8b163c
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 18 deletions.
8 changes: 6 additions & 2 deletions lux/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,13 +322,17 @@ def recommendation(self, recommendation: Dict):

@property
def current_vis(self):
from lux.processor.Validator import Validator

# _parse_validate_compile_intent does not call executor,
# we only attach data to current vis when user request current_vis
if (
valid_current_vis = (
self._current_vis is not None
and len(self._current_vis) > 0
and self._current_vis[0].data is None
):
and self._current_vis[0].intent
)
if valid_current_vis and Validator.validate_intent(self._current_vis[0].intent, self):
lux.config.executor.execute(self._current_vis, self)
return self._current_vis

Expand Down
6 changes: 5 additions & 1 deletion lux/processor/Compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from lux.vis import Clause
from typing import List, Dict, Union
from lux.vis.Vis import Vis
from lux.processor.Validator import Validator
from lux.core.frame import LuxDataFrame
from lux.vis.VisList import VisList
from lux.utils import date_utils
Expand Down Expand Up @@ -82,7 +83,8 @@ def compile_intent(ldf: LuxDataFrame, _inferred_intent: List[Clause]) -> VisList
vis_collection: list[lux.Vis]
vis list with compiled lux.Vis objects.
"""
if _inferred_intent:
valid_intent = _inferred_intent # ensures intent is non-empty
if valid_intent and Validator.validate_intent(_inferred_intent, ldf, True):
vis_collection = Compiler.enumerate_collection(_inferred_intent, ldf)
# autofill data type/model information
Compiler.populate_data_type_model(ldf, vis_collection)
Expand All @@ -94,6 +96,8 @@ def compile_intent(ldf: LuxDataFrame, _inferred_intent: List[Clause]) -> VisList
Compiler.determine_encoding(ldf, vis)
ldf._compiled = True
return vis_collection
elif _inferred_intent:
return []

@staticmethod
def enumerate_collection(_inferred_intent: List[Clause], ldf: LuxDataFrame) -> VisList:
Expand Down
9 changes: 6 additions & 3 deletions lux/processor/Validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def __repr__(self):
return f"<Validator>"

@staticmethod
def validate_intent(intent: List[Clause], ldf: LuxDataFrame) -> None:
def validate_intent(intent: List[Clause], ldf: LuxDataFrame, suppress_warning=False):
"""
Validates input specifications from the user to find inconsistencies and errors.
Expand All @@ -47,7 +47,8 @@ def validate_intent(intent: List[Clause], ldf: LuxDataFrame) -> None:
Returns
-------
None
Boolean
True if the intent passed in is valid, False otherwise.
Raises
------
Expand Down Expand Up @@ -105,8 +106,10 @@ def validate_clause(clause):
warn_msg += validate_clause(s)
else:
warn_msg += validate_clause(clause)
if warn_msg != "":
if warn_msg != "" and not suppress_warning:
warnings.warn(
"\nThe following issues are ecountered when validating the parsed intent:" + warn_msg,
stacklevel=2,
)

return warn_msg == ""
10 changes: 10 additions & 0 deletions tests/test_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,3 +275,13 @@ def test_intent_retained():

df._ipython_display_()
assert list(df.recommendation.keys()) == ["Enhance", "Filter"]


def test_metadata_propogate_invalid_intent():
df = pd.read_csv("https://raw.githubusercontent.com/lux-org/lux-datasets/master/data/employee.csv")
df.intent = ["Attrition"]
new_df = df.groupby("BusinessTravel").mean()
assert new_df.intent[0].attribute == "Attrition", "User-specified intent is retained"
assert new_df._inferred_intent == [], "Invalid inferred intent is cleared"
new_df._ipython_display_()
assert new_df.current_vis == []
22 changes: 10 additions & 12 deletions tests/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,19 +109,17 @@ def test_validator_invalid_value(global_var):
def test_validator_invalid_filter(global_var):
df = pytest.college_df

with pytest.raises(KeyError, match="'New England'"):
with pytest.warns(
UserWarning,
match="The input 'New England' looks like a value that belongs to the 'Region' attribute.",
):
df.intent = ["New England", "Southeast", "Far West"]
with pytest.warns(
UserWarning,
match="The input 'New England' looks like a value that belongs to the 'Region' attribute.",
):
df.intent = ["New England", "Southeast", "Far West"]


def test_validator_invalid_attribute(global_var):
df = pytest.college_df
with pytest.raises(KeyError, match="'blah'"):
with pytest.warns(
UserWarning,
match="The input attribute 'blah' does not exist in the DataFrame.",
):
df.intent = ["blah"]
with pytest.warns(
UserWarning,
match="The input attribute 'blah' does not exist in the DataFrame.",
):
df.intent = ["blah"]

0 comments on commit c8b163c

Please sign in to comment.