Hi,

I'm having some difficulty reading in boolean values from a file, particularly false values. Python can understand false values as empty strings, as well as a few other ways. For example:

In [43]: bool(0)
Out[43]: False

In [44]: bool(False)
Out[44]: False

In [45]: bool('')
Out[45]: False

The problem is, anything I read in from a file is read in as a string. So if a file has these values, all the booleans will evaluate to true. For example:

In [46]: bool('0')
Out[46]: True

In [47]: bool('False')
Out[47]: True

Therefore, in my file, I chose to use empty strings to denote false values in my file. However, when I read these in and try to convert them, they yield TRUE! Here's an example of my data:

5450    0.0 Infinity    0.0 1.0 ''  ''

f=open('params.txt', 'r')
for line in f:
    sline=line.strip().split()
    print sline[5], type(sline[5]), bool(sline[5])

Results in:

'' <type 'str'> True

Am I going crazy, why doesn't this evaluate to False? bool('') is False....

PS, I'm trying to avoid the solution of using 1's and 0's in the file and doing bool(int('1')) for reasons that aren't germane. Is there another way?

You would use len()

print sline[5], type(sline[5]), bool(len(sline[5]))

or eval(), although eval will do anything, so if someone puts "rm *" in the file that is being read, eval will delete the files.

for lit in ["False", "True"]:
    x = eval(lit)
    print x, type(x)

Thanks woooee. I hesitate to use eval for the reason you pointed out. I like the idea of using len(); that's smart; however, it does restrict user input style (for example, I'd like 'False' in the field to also work.)

For my use case, the programs actually know ahead of time what field types ought to be. Therefore, I can take advantage of this since my program expects a boolean. Therefore, my solution is to do something like:

_boolean_states = {'1': True, 'yes': True, 'true': True,
                   '0': False, 'no': False, 'false': False}    

for field in expected_fields:
   if field == bool:
      entry=_boolean_states[entry.lower()]  #.lower() for case insensitivity

Stole this idea from the ConfigParser package actually.

I will keep these other methods in mind for other use cases, thanks for helping me out.

There is no guarantee that "entry" is in the dictionary. You should do something like

_boolean_states = {'1': True, 'yes': True, 'true': True,
               '0': False, 'no': False, 'false': False}    

entry=entry.lower()
for field in expected_fields:
    if field == bool and entry in _boolean_states:
        entry=_boolean_states[entry]
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.