Skip to content

Commit

Permalink
revert: remove condition -> expr conversion experiment
Browse files Browse the repository at this point in the history
  • Loading branch information
dangotbanned committed Jul 3, 2024
1 parent 5f7d949 commit f89990f
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 99 deletions.
52 changes: 0 additions & 52 deletions altair/vegalite/v5/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -984,58 +984,6 @@ def when(
return When(condition)


def _condition_to_expr_str(c: _SelectionType | _Conditions, /) -> str:
"""Convert the output of `alt.condition`/`when-then-otherwise` to an expression string."""
return _condition_to_expr_ref(c).expr


def _condition_to_expr_ref(c: _SelectionType | _Conditions, /) -> core.ExprRef:
"""Convert the output of `alt.condition`/`when-then-otherwise` to an `ExprRef`.
Notes
-----
- Purely to demonstrate how the translation could occur
- Ideally, the logic would live elsewhere
"""
if isinstance(c, core.SchemaBase):
c = c.to_dict()
if not isinstance(c, dict):
msg = f"Expected condition of type `dict`, but got: {type(c).__name__!r}."
raise TypeError(msg)
elif "value" in c:
# Had to change due to 0 returning False
otherwise = c.get("value")
if conditions := c.get("condition"):
if not isinstance(conditions, (dict, list)):
msg = f"Expected nested condition of type `dict | list`, but got: {type(conditions).__name__!r}."
raise TypeError(msg)
elif isinstance(conditions, dict):
condition = conditions
elif isinstance(conditions, list) and len(conditions) == 1:
condition = conditions[0]
else:
msg = (
f"Condition specifies {len(conditions)!r} `when-then` clauses.\n"
f"`alt.expr.if_` supports only `1`, followed by an `otherwise`.\n\n"
f"{c!r}"
)
raise ValueError(msg)

if when := condition.get("test"):
then = condition["value"]
expr = _expr_core.FunctionExpression("if", (when, then, otherwise))
return core.ExprRef(expr.to_dict())
else:
msg = f"Missing `test` key, unable to convert to `ExprRef.\n\n{c!r}"
raise KeyError(msg)
else:
msg = f"Missing `condition` key, equivalent to `when`, `then` clauses.\n\n{c!r}"
raise KeyError(msg)
else:
msg = f"Missing `value` key, equivalent to `otherwise` clause.\n\n{c!r}"
raise KeyError(msg)


# ------------------------------------------------------------------------
# Top-Level Functions

Expand Down
57 changes: 10 additions & 47 deletions tests/vegalite/v5/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,10 +253,9 @@ def test_chart_operations():


def test_when() -> None:
from altair.vegalite.v5 import api as _alt

select = alt.selection_point(name="select", on="click")
condition = _alt._predicate_to_condition(select, empty=False)
condition = alt.condition(select, alt.value(1), "two", empty=False).get("condition")
condition.pop("value")
when = alt.when(select, empty=False)
when_constraint = alt.when(Origin="Europe")
when_constraints = alt.when(
Expand Down Expand Up @@ -390,8 +389,6 @@ def test_when_labels_position_based_on_condition() -> None:
import pandas as pd
from altair.utils.schemapi import SchemaValidationError

from altair.vegalite.v5 import api as _alt

rand = np.random.RandomState(42)
df = pd.DataFrame({"xval": range(100), "yval": rand.randn(100).cumsum()})

Expand All @@ -409,7 +406,11 @@ def test_when_labels_position_based_on_condition() -> None:
.then(alt.value("red"))
.otherwise("black", str_as_lit=True)
)
param_color_py_when = alt.param(expr=_alt._condition_to_expr_str(when))
cond = when["condition"][0]
otherwise = when["value"]
param_color_py_when = alt.param(
expr=alt.expr.if_(cond["test"], cond["value"], otherwise)
)
assert param_color_py_expr.expr == param_color_py_when.expr

chart = (
Expand All @@ -434,7 +435,6 @@ def test_when_expressions_inside_parameters() -> None:
Original [expressions-inside-parameters](https://altair-viz.github.io/user_guide/interactions.html#expressions-inside-parameters)
"""
from altair.vegalite.v5 import api as _alt
import pandas as pd

source = pd.DataFrame({"a": ["A", "B", "C"], "b": [28, -5, 10]})
Expand All @@ -445,8 +445,10 @@ def test_when_expressions_inside_parameters() -> None:
.encode(y="a:N", x=alt.X("b:Q").scale(domain=[-10, 35]))
)
when_then_otherwise = alt.when(alt.datum.b >= 0).then(10).otherwise(-20)
cond = when_then_otherwise["condition"][0]
otherwise = when_then_otherwise["value"]
expected = alt.expr(alt.expr.if_(alt.datum.b >= 0, 10, -20))
actual = _alt._condition_to_expr_ref(when_then_otherwise)
actual = alt.expr(alt.expr.if_(cond["test"], cond["value"], otherwise))
assert expected == actual

text_conditioned = bar.mark_text(align="left", baseline="middle", dx=actual).encode(
Expand All @@ -457,45 +459,6 @@ def test_when_expressions_inside_parameters() -> None:
chart.to_dict()


def test_when_convert_expr() -> None:
from altair.vegalite.v5 import api as _alt

when = alt.when(Color="Green").then(5).otherwise(10)
converted = _alt._condition_to_expr_ref(when)

assert isinstance(converted, alt.ExprRef)

with pytest.raises(TypeError, match="int"):
_alt._condition_to_expr_ref(9) # type: ignore

with pytest.raises(KeyError, match="Missing `value`"):
_alt._condition_to_expr_ref(alt.when(Color="Green").then(5).to_dict())

with pytest.raises(KeyError, match="Missing `condition`"):
_alt._condition_to_expr_ref({"value": 10})

with pytest.raises(TypeError, match="'str'"):
_alt._condition_to_expr_ref({"value": 10, "condition": "words"}) # type: ignore

with pytest.raises(KeyError, match="Missing `test`"):
_alt._condition_to_expr_ref(
alt.when(alt.selection_point("name")).then(33).otherwise(11)
)

long = (
alt.when(Color="red")
.then(1)
.when(Color="blue")
.then(2)
.when(Color="green")
.then(3)
.otherwise(0)
)

with pytest.raises(ValueError, match="3"):
_alt._condition_to_expr_ref(long)


def test_selection_to_dict():
brush = alt.selection_interval()

Expand Down

0 comments on commit f89990f

Please sign in to comment.