Skip to content

Commit

Permalink
Return boolean from ImageMath comparison operations
Browse files Browse the repository at this point in the history
  • Loading branch information
radarhere committed Jul 12, 2024
1 parent 6a9acfa commit c6b86cb
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 205 deletions.
202 changes: 56 additions & 146 deletions Tests/test_imagemath_lambda_eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,8 @@ def test_compare() -> None:
)
== "I 2"
)
assert pixel(ImageMath.lambda_eval(lambda args: args["A"] == 1, images)) == "I 1"
assert pixel(ImageMath.lambda_eval(lambda args: args["A"] == 2, images)) == "I 0"
assert ImageMath.lambda_eval(lambda args: args["A"] == 1, images) is False
assert ImageMath.lambda_eval(lambda args: args["A"] == 2, images) is False


def test_one_image_larger() -> None:
Expand Down Expand Up @@ -299,198 +299,108 @@ def test_bitwise_rightshift() -> None:


def test_logical_eq() -> None:
assert (
pixel(ImageMath.lambda_eval(lambda args: args["A"] == args["A"], A=A)) == "I 1"
)
assert (
pixel(ImageMath.lambda_eval(lambda args: args["B"] == args["B"], B=B)) == "I 1"
)
assert (
pixel(ImageMath.lambda_eval(lambda args: args["A"] == args["B"], A=A, B=B))
== "I 0"
)
assert (
pixel(ImageMath.lambda_eval(lambda args: args["B"] == args["A"], A=A, B=B))
== "I 0"
)
assert ImageMath.lambda_eval(lambda args: args["A"] == args["A"], A=A) is True
assert ImageMath.lambda_eval(lambda args: args["B"] == args["B"], B=B) is True
assert ImageMath.lambda_eval(lambda args: args["A"] == args["B"], A=A, B=B) is False
assert ImageMath.lambda_eval(lambda args: args["B"] == args["A"], A=A, B=B) is False


def test_logical_ne() -> None:
assert (
pixel(ImageMath.lambda_eval(lambda args: args["A"] != args["A"], A=A)) == "I 0"
)
assert (
pixel(ImageMath.lambda_eval(lambda args: args["B"] != args["B"], B=B)) == "I 0"
)
assert (
pixel(ImageMath.lambda_eval(lambda args: args["A"] != args["B"], A=A, B=B))
== "I 1"
)
assert (
pixel(ImageMath.lambda_eval(lambda args: args["B"] != args["A"], A=A, B=B))
== "I 1"
)
assert ImageMath.lambda_eval(lambda args: args["A"] != args["A"], A=A) is False
assert ImageMath.lambda_eval(lambda args: args["B"] != args["B"], B=B) is False
assert ImageMath.lambda_eval(lambda args: args["A"] != args["B"], A=A, B=B) is True
assert ImageMath.lambda_eval(lambda args: args["B"] != args["A"], A=A, B=B) is True


def test_logical_lt() -> None:
assert (
pixel(ImageMath.lambda_eval(lambda args: args["A"] < args["A"], A=A)) == "I 0"
)
assert (
pixel(ImageMath.lambda_eval(lambda args: args["B"] < args["B"], B=B)) == "I 0"
)
assert (
pixel(ImageMath.lambda_eval(lambda args: args["A"] < args["B"], A=A, B=B))
== "I 1"
)
assert (
pixel(ImageMath.lambda_eval(lambda args: args["B"] < args["A"], A=A, B=B))
== "I 0"
)
assert ImageMath.lambda_eval(lambda args: args["A"] < args["A"], A=A) is False
assert ImageMath.lambda_eval(lambda args: args["B"] < args["B"], B=B) is False
assert ImageMath.lambda_eval(lambda args: args["A"] < args["B"], A=A, B=B) is True
assert ImageMath.lambda_eval(lambda args: args["B"] < args["A"], A=A, B=B) is False


def test_logical_le() -> None:
assert (
pixel(ImageMath.lambda_eval(lambda args: args["A"] <= args["A"], A=A)) == "I 1"
)
assert (
pixel(ImageMath.lambda_eval(lambda args: args["B"] <= args["B"], B=B)) == "I 1"
)
assert (
pixel(ImageMath.lambda_eval(lambda args: args["A"] <= args["B"], A=A, B=B))
== "I 1"
)
assert (
pixel(ImageMath.lambda_eval(lambda args: args["B"] <= args["A"], A=A, B=B))
== "I 0"
)
assert ImageMath.lambda_eval(lambda args: args["A"] <= args["A"], A=A) is True
assert ImageMath.lambda_eval(lambda args: args["B"] <= args["B"], B=B) is True
assert ImageMath.lambda_eval(lambda args: args["A"] <= args["B"], A=A, B=B) is True
assert ImageMath.lambda_eval(lambda args: args["B"] <= args["A"], A=A, B=B) is False


def test_logical_gt() -> None:
assert (
pixel(ImageMath.lambda_eval(lambda args: args["A"] > args["A"], A=A)) == "I 0"
)
assert (
pixel(ImageMath.lambda_eval(lambda args: args["B"] > args["B"], B=B)) == "I 0"
)
assert (
pixel(ImageMath.lambda_eval(lambda args: args["A"] > args["B"], A=A, B=B))
== "I 0"
)
assert (
pixel(ImageMath.lambda_eval(lambda args: args["B"] > args["A"], A=A, B=B))
== "I 1"
)
assert ImageMath.lambda_eval(lambda args: args["A"] > args["A"], A=A) is False
assert ImageMath.lambda_eval(lambda args: args["B"] > args["B"], B=B) is False
assert ImageMath.lambda_eval(lambda args: args["A"] > args["B"], A=A, B=B) is False
assert ImageMath.lambda_eval(lambda args: args["B"] > args["A"], A=A, B=B) is True


def test_logical_ge() -> None:
assert (
pixel(ImageMath.lambda_eval(lambda args: args["A"] >= args["A"], A=A)) == "I 1"
)
assert (
pixel(ImageMath.lambda_eval(lambda args: args["B"] >= args["B"], B=B)) == "I 1"
)
assert (
pixel(ImageMath.lambda_eval(lambda args: args["A"] >= args["B"], A=A, B=B))
== "I 0"
)
assert (
pixel(ImageMath.lambda_eval(lambda args: args["B"] >= args["A"], A=A, B=B))
== "I 1"
)
assert ImageMath.lambda_eval(lambda args: args["A"] >= args["A"], A=A) is True
assert ImageMath.lambda_eval(lambda args: args["B"] >= args["B"], B=B) is True
assert ImageMath.lambda_eval(lambda args: args["A"] >= args["B"], A=A, B=B) is False
assert ImageMath.lambda_eval(lambda args: args["B"] >= args["A"], A=A, B=B) is True


def test_logical_equal() -> None:
assert (
pixel(
ImageMath.lambda_eval(lambda args: args["equal"](args["A"], args["A"]), A=A)
)
== "I 1"
ImageMath.lambda_eval(lambda args: args["equal"](args["A"], args["A"]), A=A)
is True
)
assert (
pixel(
ImageMath.lambda_eval(lambda args: args["equal"](args["B"], args["B"]), B=B)
)
== "I 1"
ImageMath.lambda_eval(lambda args: args["equal"](args["B"], args["B"]), B=B)
is True
)
assert (
pixel(
ImageMath.lambda_eval(lambda args: args["equal"](args["Z"], args["Z"]), Z=Z)
)
== "I 1"
ImageMath.lambda_eval(lambda args: args["equal"](args["Z"], args["Z"]), Z=Z)
is True
)
assert (
pixel(
ImageMath.lambda_eval(
lambda args: args["equal"](args["A"], args["B"]), A=A, B=B
)
ImageMath.lambda_eval(
lambda args: args["equal"](args["A"], args["B"]), A=A, B=B
)
== "I 0"
is False
)
assert (
pixel(
ImageMath.lambda_eval(
lambda args: args["equal"](args["B"], args["A"]), A=A, B=B
)
ImageMath.lambda_eval(
lambda args: args["equal"](args["B"], args["A"]), A=A, B=B
)
== "I 0"
is False
)
assert (
pixel(
ImageMath.lambda_eval(
lambda args: args["equal"](args["A"], args["Z"]), A=A, Z=Z
)
ImageMath.lambda_eval(
lambda args: args["equal"](args["A"], args["Z"]), A=A, Z=Z
)
== "I 0"
is False
)


def test_logical_not_equal() -> None:
assert (
pixel(
ImageMath.lambda_eval(
lambda args: args["notequal"](args["A"], args["A"]), A=A
)
)
== "I 0"
ImageMath.lambda_eval(lambda args: args["notequal"](args["A"], args["A"]), A=A)
is False
)
assert (
pixel(
ImageMath.lambda_eval(
lambda args: args["notequal"](args["B"], args["B"]), B=B
)
)
== "I 0"
ImageMath.lambda_eval(lambda args: args["notequal"](args["B"], args["B"]), B=B)
is False
)
assert (
pixel(
ImageMath.lambda_eval(
lambda args: args["notequal"](args["Z"], args["Z"]), Z=Z
)
)
== "I 0"
ImageMath.lambda_eval(lambda args: args["notequal"](args["Z"], args["Z"]), Z=Z)
is False
)
assert (
pixel(
ImageMath.lambda_eval(
lambda args: args["notequal"](args["A"], args["B"]), A=A, B=B
)
ImageMath.lambda_eval(
lambda args: args["notequal"](args["A"], args["B"]), A=A, B=B
)
== "I 1"
is True
)
assert (
pixel(
ImageMath.lambda_eval(
lambda args: args["notequal"](args["B"], args["A"]), A=A, B=B
)
ImageMath.lambda_eval(
lambda args: args["notequal"](args["B"], args["A"]), A=A, B=B
)
== "I 1"
is True
)
assert (
pixel(
ImageMath.lambda_eval(
lambda args: args["notequal"](args["A"], args["Z"]), A=A, Z=Z
)
ImageMath.lambda_eval(
lambda args: args["notequal"](args["A"], args["Z"]), A=A, Z=Z
)
== "I 1"
is True
)
76 changes: 38 additions & 38 deletions Tests/test_imagemath_unsafe_eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ def test_convert() -> None:
def test_compare() -> None:
assert pixel(ImageMath.unsafe_eval("min(A, B)", images)) == "I 1"
assert pixel(ImageMath.unsafe_eval("max(A, B)", images)) == "I 2"
assert pixel(ImageMath.unsafe_eval("A == 1", images)) == "I 1"
assert pixel(ImageMath.unsafe_eval("A == 2", images)) == "I 0"
assert ImageMath.unsafe_eval("A == 1", images) is False
assert ImageMath.unsafe_eval("A == 2", images) is False


def test_one_image_larger() -> None:
Expand Down Expand Up @@ -162,60 +162,60 @@ def test_bitwise_rightshift() -> None:


def test_logical_eq() -> None:
assert pixel(ImageMath.unsafe_eval("A==A", A=A)) == "I 1"
assert pixel(ImageMath.unsafe_eval("B==B", B=B)) == "I 1"
assert pixel(ImageMath.unsafe_eval("A==B", A=A, B=B)) == "I 0"
assert pixel(ImageMath.unsafe_eval("B==A", A=A, B=B)) == "I 0"
assert ImageMath.unsafe_eval("A==A", A=A) is True
assert ImageMath.unsafe_eval("B==B", B=B) is True
assert ImageMath.unsafe_eval("A==B", A=A, B=B) is False
assert ImageMath.unsafe_eval("B==A", A=A, B=B) is False


def test_logical_ne() -> None:
assert pixel(ImageMath.unsafe_eval("A!=A", A=A)) == "I 0"
assert pixel(ImageMath.unsafe_eval("B!=B", B=B)) == "I 0"
assert pixel(ImageMath.unsafe_eval("A!=B", A=A, B=B)) == "I 1"
assert pixel(ImageMath.unsafe_eval("B!=A", A=A, B=B)) == "I 1"
assert ImageMath.unsafe_eval("A!=A", A=A) is False
assert ImageMath.unsafe_eval("B!=B", B=B) is False
assert ImageMath.unsafe_eval("A!=B", A=A, B=B) is True
assert ImageMath.unsafe_eval("B!=A", A=A, B=B) is True


def test_logical_lt() -> None:
assert pixel(ImageMath.unsafe_eval("A<A", A=A)) == "I 0"
assert pixel(ImageMath.unsafe_eval("B<B", B=B)) == "I 0"
assert pixel(ImageMath.unsafe_eval("A<B", A=A, B=B)) == "I 1"
assert pixel(ImageMath.unsafe_eval("B<A", A=A, B=B)) == "I 0"
assert ImageMath.unsafe_eval("A<A", A=A) is False
assert ImageMath.unsafe_eval("B<B", B=B) is False
assert ImageMath.unsafe_eval("A<B", A=A, B=B) is True
assert ImageMath.unsafe_eval("B<A", A=A, B=B) is False


def test_logical_le() -> None:
assert pixel(ImageMath.unsafe_eval("A<=A", A=A)) == "I 1"
assert pixel(ImageMath.unsafe_eval("B<=B", B=B)) == "I 1"
assert pixel(ImageMath.unsafe_eval("A<=B", A=A, B=B)) == "I 1"
assert pixel(ImageMath.unsafe_eval("B<=A", A=A, B=B)) == "I 0"
assert ImageMath.unsafe_eval("A<=A", A=A) is True
assert ImageMath.unsafe_eval("B<=B", B=B) is True
assert ImageMath.unsafe_eval("A<=B", A=A, B=B) is True
assert ImageMath.unsafe_eval("B<=A", A=A, B=B) is False


def test_logical_gt() -> None:
assert pixel(ImageMath.unsafe_eval("A>A", A=A)) == "I 0"
assert pixel(ImageMath.unsafe_eval("B>B", B=B)) == "I 0"
assert pixel(ImageMath.unsafe_eval("A>B", A=A, B=B)) == "I 0"
assert pixel(ImageMath.unsafe_eval("B>A", A=A, B=B)) == "I 1"
assert ImageMath.unsafe_eval("A>A", A=A) is False
assert ImageMath.unsafe_eval("B>B", B=B) is False
assert ImageMath.unsafe_eval("A>B", A=A, B=B) is False
assert ImageMath.unsafe_eval("B>A", A=A, B=B) is True


def test_logical_ge() -> None:
assert pixel(ImageMath.unsafe_eval("A>=A", A=A)) == "I 1"
assert pixel(ImageMath.unsafe_eval("B>=B", B=B)) == "I 1"
assert pixel(ImageMath.unsafe_eval("A>=B", A=A, B=B)) == "I 0"
assert pixel(ImageMath.unsafe_eval("B>=A", A=A, B=B)) == "I 1"
assert ImageMath.unsafe_eval("A>=A", A=A) is True
assert ImageMath.unsafe_eval("B>=B", B=B) is True
assert ImageMath.unsafe_eval("A>=B", A=A, B=B) is False
assert ImageMath.unsafe_eval("B>=A", A=A, B=B) is True


def test_logical_equal() -> None:
assert pixel(ImageMath.unsafe_eval("equal(A, A)", A=A)) == "I 1"
assert pixel(ImageMath.unsafe_eval("equal(B, B)", B=B)) == "I 1"
assert pixel(ImageMath.unsafe_eval("equal(Z, Z)", Z=Z)) == "I 1"
assert pixel(ImageMath.unsafe_eval("equal(A, B)", A=A, B=B)) == "I 0"
assert pixel(ImageMath.unsafe_eval("equal(B, A)", A=A, B=B)) == "I 0"
assert pixel(ImageMath.unsafe_eval("equal(A, Z)", A=A, Z=Z)) == "I 0"
assert ImageMath.unsafe_eval("equal(A, A)", A=A) is True
assert ImageMath.unsafe_eval("equal(B, B)", B=B) is True
assert ImageMath.unsafe_eval("equal(Z, Z)", Z=Z) is True
assert ImageMath.unsafe_eval("equal(A, B)", A=A, B=B) is False
assert ImageMath.unsafe_eval("equal(B, A)", A=A, B=B) is False
assert ImageMath.unsafe_eval("equal(A, Z)", A=A, Z=Z) is False


def test_logical_not_equal() -> None:
assert pixel(ImageMath.unsafe_eval("notequal(A, A)", A=A)) == "I 0"
assert pixel(ImageMath.unsafe_eval("notequal(B, B)", B=B)) == "I 0"
assert pixel(ImageMath.unsafe_eval("notequal(Z, Z)", Z=Z)) == "I 0"
assert pixel(ImageMath.unsafe_eval("notequal(A, B)", A=A, B=B)) == "I 1"
assert pixel(ImageMath.unsafe_eval("notequal(B, A)", A=A, B=B)) == "I 1"
assert pixel(ImageMath.unsafe_eval("notequal(A, Z)", A=A, Z=Z)) == "I 1"
assert ImageMath.unsafe_eval("notequal(A, A)", A=A) is False
assert ImageMath.unsafe_eval("notequal(B, B)", B=B) is False
assert ImageMath.unsafe_eval("notequal(Z, Z)", Z=Z) is False
assert ImageMath.unsafe_eval("notequal(A, B)", A=A, B=B) is True
assert ImageMath.unsafe_eval("notequal(B, A)", A=A, B=B) is True
assert ImageMath.unsafe_eval("notequal(A, Z)", A=A, Z=Z) is True
4 changes: 2 additions & 2 deletions docs/reference/ImageMath.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Example: Using the :py:mod:`~PIL.ImageMath` module
arguments instead of a dictionary, as shown in the above
example. Note that the names must be valid Python
identifiers.
:return: An image, an integer value, a floating point value,
:return: An image, an integer value, a floating point value, a boolean,
or a pixel tuple, depending on the expression.

.. py:function:: unsafe_eval(expression, options)
Expand All @@ -66,7 +66,7 @@ Example: Using the :py:mod:`~PIL.ImageMath` module
arguments instead of a dictionary, as shown in the above
example. Note that the names must be valid Python
identifiers.
:return: An image, an integer value, a floating point value,
:return: An image, an integer value, a floating point value, a boolean,
or a pixel tuple, depending on the expression.

Expression syntax
Expand Down
Loading

0 comments on commit c6b86cb

Please sign in to comment.