Reputation: 196
def test_string_membership():
assert False == 'c' in 'apple'
assert True == 'a' in 'apple'
assert True == 'app' in 'apple'
p.s:- I am a beginner in python and unable to find out whats wrong. My assertion fails when I run the code.
Upvotes: 1
Views: 670
Reputation: 881103
You have a problem with comparison chaining, the Python syntax that treats:
x < y < z
as:
x < y and y < z.
In your case, that means the expression False == 'c' in 'apple'
is being treated as:
(False == 'c') and ('c' in 'apple')
both of which are false, hence causing the assertion. Details on comparison chaining for Python 3 can be found here.
So the way to avoid this chianing is to make the expression explicit, with something like:
assert False == ('c' in 'apple')
assert True == ('a' in 'apple')
assert True == ('app' in 'apple')
or, even better, since comparing with true/false
is rarely a good idea:
assert 'c' not in 'apple' # or "not('c' in 'apple')" if you're testing 'in'.
assert 'a' in 'apple'
assert 'app' in 'apple'
Upvotes: 3
Reputation: 368904
False == 'c' in 'apple'
is not interpreted as
False == ('c' in 'apple')
but,
(False == 'c') and ('c' in apple)
becaue of comparison chaining.
To get what you want, put parentheses explicitly.
False == ('c' in 'apple')
or more preferably use in
/ not in
:
def test_string_membership():
assert 'c' not in 'apple'
assert 'a' in 'apple'
assert 'app' in 'apple'
Upvotes: 4
Reputation: 251355
Contrary to the other answers, what is happening here is not operator precedence but comparison chaining. a == b in c
means (a == b) and (b in c)
, just like a < b < c
means (a < b) and (b < c)
. However, in either case, the upshot is the same, which is that it's not what you meant to do. As noted in the other answers and comments, it can be fixed by using parentheses, or, better, by not using an equality comparison at all and just doing assert 'c' not in 'apple'
.
You can see that this is comparison chaining by a slightly different example:
>>> 'a' == 'a' in 'ab'
True
This would obviously be false no matter which way the precedence went, but it is true because 'a' == 'a'
and 'a' in 'ab'
are both true.
Upvotes: 2
Reputation: 34146
You may use ()
in this case. There are better ways to do what you are trying.
def test_string_membership():
assert False == ('c' in 'apple')
assert True == ('a' in 'apple')
assert True == ('app' in 'apple')
This is because of precedence. Read more about this on Python docs.
in, not in, is, is not, <, <=, >, >=, <>, !=, ==
are in the same precedence level. So Python will evaluate
False == 'c' in 'apple'
from left to right.
Upvotes: 1
Reputation: 31
Using parenthesis should solve this as in
def test_string_membership():
assert False == ('c' in 'apple')
assert True == ('a' in 'apple')
assert True == ('app' in 'apple')
Upvotes: 1