2
\$\begingroup\$
def truthy(v):
    if issubclass(v.__class__, numbers.Number):
        return bool(int(v))
    if isinstance(v, basestring):
        vl = v.lower()[0]
        if vl == 'y' or vl == 't':
            return True
    return False
  1. Is there some type/class I missed that can be evaluated by Python as True/False that I missed here?

  2. Drawbacks? Better ways?

\$\endgroup\$
1
  • 2
    \$\begingroup\$ What do you plan to use this for? \$\endgroup\$ Dec 18, 2013 at 21:41

2 Answers 2

2
\$\begingroup\$

I can't test this right now, but the isinstance seems very unpythonic to me. Assuming that your original logic is correct, why not:

def truthy(v):
    try:
        return bool(int(v))
    except ValueError:
        pass
    try:
        first = v.lower()[0]
        return (first == 'y') or (first == 't')
    except AttributeError:
        pass
    return False

That way, you don't need to worry about missing any types -- if it's convertible to an int or if it implements a lower() method you'll catch it.

\$\endgroup\$
0
2
\$\begingroup\$

How about:

accepted_truthy_characters = {'y', 't'}

def truthy(value):
    if isinstance(value, basestring):
        return value and value[0].lower() in accepted_truthy_characters
    return bool(value)

In Python 3.x, basestring won't work and you'll need isinstance(value, str) instead.

One thing you missed is that value might be a string, but it might be empty, which would leave you with an IndexError.

Python's bool() will check an int for you, so I don't think you need to check if it's a Number, convert it with int(), and then bool(), unless I'm missing something about your use case.

Out of curiosity, why do you need this? Are you checking user input? Won't that always be a string anyway? And in that case, wouldn't it be better to just check a few allowed "positive" strings?

\$\endgroup\$
14
  • \$\begingroup\$ this is for parsing (INI) config file settings. Sysadmins are used to entire menagerie of truthy/falsy values across different sw, like: unset value (falsy), 'True', 'true', 't', 'y', 'yes', 1, 0..., so they can make errors. e.g. PHP rubbish is notorious for using all kinds of inconsistent truthy/falsy settings. \$\endgroup\$ Dec 18, 2013 at 22:05
  • \$\begingroup\$ len(value)value. &&and. value.lower()[0]value[0].lower(). bool(value)value. \$\endgroup\$ Dec 18, 2013 at 22:08
  • \$\begingroup\$ argh and I forgot one more thing: ''[0] -> IndexError \$\endgroup\$ Dec 18, 2013 at 22:10
  • \$\begingroup\$ 'no' is a string, so it will be handled by the other return statement. \$\endgroup\$ Dec 18, 2013 at 22:16
  • \$\begingroup\$ @Gareth: if I'm writing "truthy/falsy" filter for a range of input types, I'd prefer to return clean boolean types only rather than truthy/falsy values again.. \$\endgroup\$ Dec 18, 2013 at 22:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.