views:

83

answers:

6

I'm writing a module to act on data being sent to a database from Python. Since boolean is not a SQL datatype, those values have to be converted to some pre-defined value. I decided while defining the tables that I would use 'T' and 'F' in a varchar(1) field as my Boolean stand in.

In attempting to make this conversion while being properly Pythonic, I did a direct comparison and acted on the results, as so:

        if SQLParameters[i] == True:
            SQLParameters[i] = 'T'                
        elif SQLParameters[i] == False:
            SQLParameters[i] = 'F'

This is on code that runs regardless of type, so if SQLParameters[i] is 1 or "Blarg" or 123, I just want to leave it alone, whereas when it's a Boolean, I need to perform the conversion.

This worked just fine until I tried to insert the actual value 1 (one), at which point I learned that 1 == True = True. I can plainly see two possible solutions for this issue:

  1. change the data dictionary to use 0 and 1 in a number(1) field as the Boolean stand-in, making the conversion simpler
  2. add a condition to the code above to check the actual type of the parameter to be converted (which strikes me as unpythonic).

Does anyone have an idea about how to accomplish this without either changing the data dictionary or explicitly checking the type?

+8  A: 

You can use is:

if SQLParameters[i] is True:
    SQLParameters[i] = 'T'                
elif SQLParameters[i] is False:
    SQLParameters[i] = 'F'
sth
This best answers the specific question I asked. However, it seems the consensus viewpoint is that I should change my data dictionary, which would remove the need for the code in question altogether.
Allan
+3  A: 
if isinstance(SQLParameters[i], bool):
    SQLParameters[i] = 'T' if SQLParameters[i] else 'F'

or

if isinstance(SQLParameters[i], bool):
    SQLParameters[i] = 'FT'[SQLParameters[i]]
adw
+1: Except for the extraneous type-checking, this is golden. :)
jathanism
how about `SQLParameters[i] = 'FT'[bool(SQLParameters[i])]`
TokenMacGuy
A: 

You could check the type of the object:

In [8]: isinstance(True, bool)
Out[8]: True

In [9]: isinstance(1, bool)
Out[9]: False
ars
+1  A: 

Try using

if SQLParameters[i] is True:
     SQLParameters[i] = 'T'                
elif SQLParameters[i] is False:
     SQLParameters[i] = 'F'

"is" captures identities. http://docs.python.org/reference/expressions.html

True Pythonic (weak datatyping and abbreviated code) would be SQLParameters[i] = 'T' if SQLParameters[i] else 'F'

l337x911
Wouldn't the second solution fail to capture the identity (which is the source of my issue)?
Allan
+1  A: 

There is no need to explicitly test against the identity or value of SQLParameters[i] being True or False. In Python anything that is unset (such as empty sequences), None, 0, or False evaluates to False; everything else evaluates to True.

So with that in mind you could simply do this:

if SQLParameters[i]:
    SQLParameters[i] = 'T'
else:
    SQLParameters[i] = 'F'
jathanism
This will return set the parameter to 'T' for all non-zero values. Part of the problem is that the parameter in question may not be a Boolean.
Allan
That is true. I wanted this to be a clear alternative to identity checking.
jathanism
A: 

I do recommend that you use 0 and 1. The SQLite libary does it that way. I would explicitly set the new value to False and then change it to true (or vice versa).

convertedvalue = 0
   if SQLParameters[i] is True:
      convertedvalue = 1
SQLParameters[i] = convertedvalue
David W