[Tutor] function with multiple checks

Jerry Hill malaclypse2 at gmail.com
Mon Sep 27 17:46:17 CEST 2010


On Mon, Sep 27, 2010 at 11:09 AM, Tim Miller <tim at lashni.net> wrote:
> I've got a small function that I'm using to check whether a password is of a
> certain length and contains mixed case, numbers and punctuation.
>
> Originally I was using multiple "if re.search" for the patterns but it
> looked terrible so I've read up on list comprehensions and it's slightly
> improved. I just can't escape the feeling that there's a more elegant way to
> do this that I'm missing.
>
> I've been looking through all the python stuff that I thought might be
> relevant (lambda, map, filter, set, frozenset, etc) but nothing has come
> together. Just wondering if anyone has suggested reading material for
> alternate ways they'd handle this code.

The way you've written it obviously works fine.  That being said, I'd
probably do something like this:

from string import ascii_lowercase, ascii_uppercase, digits, punctuation

def complex_password(password):
    '''Checks to make sure a password is complex'''
    checks = [
        lambda p: len(p) > 12,
        lambda p: any(c in punctuation for c in p),
        lambda p: any(c in digits for c in p),
        lambda p: any(c in ascii_uppercase for c in p),
        lambda p: any(c in ascii_lowercase for c in p),
        ]

    return all(check(password) for check in checks)

if __name__ == '__main__':
    passwords = ['password', 'Password1234567', 'Password1.234567']
    for password in passwords:
        print password, complex_password(password)


In the complex_password function, I create a list of tests, each of
which is a function that returns either true or false.  In this case I
used lambdas to create the function objects, since all the tests
easily fit on a single line, but it would be fine to define a function
elsewhere and use it in the list if you had more complicated checks to
do.

all() is a built in function that returns True if all of the elements
in an iterable are true (or the iterable is empty), and otherwise
returns False.  That seems like an ideal way to execute a bunch of
tests and return True if all of them pass, and otherwise return false.
 In this case, the iterable is a generator expression that evaluates
each of the rules with the supplied password.

any() is similar, but it returns True if any member of the iterable is True.

Looking back at it, I probably should have used longer variable names
in my rules, which would have made them a bit easier to read.  When I
was writing them, I was worried about the lines getting too long with
longer names.  It didn't turn out to be a problem though.

-- 
Jerry


More information about the Tutor mailing list