-2

I have a simple function that tests an item in a tuple to see if it is truthy or not. For some reason all tests come back True (...if connection:...), even though the value being tested is either a 1 (assumed True) or 0 (assumed false).

I tested to see if 1 == True (output: True), 1 == False (False), connection is True (False) just to try to understand what is going on.

User input: players = [('a', 1), ('b', 0)]

Function:

def validplayers(players):
    for player, connection in players:
        if connection:
            player
        print player, connection, 1 == True, 1 == False, connection is True

Output:

a 1 True False False
b 0 True False False

The connection var is passing a 1 or 0 which type(connection) defines as an int.

theeviininja
  • 157
  • 7
  • You are not *doing* anything in the `if` statement. You just reference `player`, but nothing else. That expression achieves nothing. – Martijn Pieters Apr 02 '17 at 15:27
  • I'm a student learning python. Shouldn't the function show only those players who have a 1 (True) connection? – theeviininja Apr 02 '17 at 15:30
  • Why should it? The `print` statement is not part of the `if` test. It is **always** executed. – Martijn Pieters Apr 02 '17 at 15:31
  • If you want that to happen, the `print` is positioned at the wrong indentation. – trincot Apr 02 '17 at 15:31
  • Are questions from students learning the language not accepted? Not sure why or what downvoting a question means. Is it a stupid question or does this mean that its too easy for stack overflow? – theeviininja Apr 02 '17 at 15:39

1 Answers1

3

Your error is looking at connection is True. This is always going to be False. is tests for identity, two expressions resulting in a reference to the same object in memory.

If you want to print the truth value of an object, use the bool() function:

>>> bool(1)
True
>>> bool(0)
False

That 1 == True works at all is because in Python, the bool type is a subclass of int:

>>> issubclass(bool, int)
True

The integer value of True is 1, and False has an integer value of 0. Testing for equality won't work for other integer values:

>>> 1 == True
True
>>> 2 == True
False
>>> bool(2)
True

Note that your if test is otherwise meaningless; the only thing that is executed or not is the line player, which is a no-op expression that just returns the reference to player, but since there is nothing else there the reference is unused.

If you wanted the print statement to be executed only when if is true, you need to indent it to be further to the right from if and make it part of the nested block:

def validplayers(players):
    for player, connection in players:
        if connection:
            print player, connection, bool(connection)

This then only prints something for player a:

>>> def validplayers(players):
...     for player, connection in players:
...         if connection:
...             print player, connection, bool(connection)
...
>>> validplayers([('a', 1), ('b', 0)])
a 1 True
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Thanks for this explanation! This solved the problem. I want to eventually use this function in my module to pass valid players into another function to form 'teams'. I might have more silly questions coming up. – theeviininja Apr 02 '17 at 15:40