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\$
  • 2
    \$\begingroup\$ What do you plan to use this for? \$\endgroup\$ – Gareth Rees Dec 18 '13 at 21:41
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\$
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\$
  • \$\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\$ – LetMeSOThat4U Dec 18 '13 at 22:05
  • \$\begingroup\$ len(value)value. &&and. value.lower()[0]value[0].lower(). bool(value)value. \$\endgroup\$ – Gareth Rees Dec 18 '13 at 22:08
  • \$\begingroup\$ argh and I forgot one more thing: ''[0] -> IndexError \$\endgroup\$ – LetMeSOThat4U Dec 18 '13 at 22:10
  • \$\begingroup\$ 'no' is a string, so it will be handled by the other return statement. \$\endgroup\$ – Gareth Rees Dec 18 '13 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\$ – LetMeSOThat4U Dec 18 '13 at 22:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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