How do I shorten this boolean expression?

Matt Davis :

I'm a beginner making a password generator and need to ensure the password has both numbers and capital letters. The condition for this while loop is redundant. for char in password appears twice. How would you write it?

while not (any(char.isdigit() for char in password) and (any(char.isupper() for 
char in password))):

In the loop it generates another password.

My goal here is to better understand how to construct the while loop's expression, not to solve the problem a different way.

Hans Musgrave :

First things first, I wish websites would stop with the inane password requirements. They reduce the entropy of the password AND make it harder for people to remember. It's especially bad when the requirements aren't clearly laid out in the UI so people can design an appropriate password without guessing what traps you may have laid for them.

That said, your syntax is quite a bit shorter than some of the regex implementations. If you wanted to apply De Morgan's laws to break up the question into logic which is arguably easier to reason about you could do the following (at a performance loss with respect to short-circuiting).

while all(not char.isdigit() for char in password)
       or all(not char.isupper() for char in password):

It seems your real problem with this though is the two passes through password. Interestingly, the regex approaches have the same problem, hidden behind some additional syntax. If you're willing to sacrifice the brevity of your solution for a bit of generality, the ability to short circuit, and a single pass through your data then you can extract the condition into its own method like so:

def satisfies(password, *conditions):
    flags = [False] * len(conditions)
    for c in password:
        for i, cond in enumerate(conditions):
            if cond(c):
                flags[i] = True
                if all(flags):
                    return True
    return False

while satisfies(password, str.isdigit, str.isupper):
    pass

Stepping through this, it goes through each character and each condition (for example the condition of needing a digit) and checks to see if it has been satisfied. If so, it records that event and checks if it can exit early. At the end, the only possible way the for loops have exited is if a condition hasn't been met anywhere in password, so we return False.

Just for fun, you can get a similar effect (without early stopping) with the use of the reduce() function. It's built in to Python 2.x, and you'll need to import it from functools in Python 3.x.

while not all(reduce(
        lambda (a, b), (d, e): (a or d, b or e),
        ((c.isdigit(), c.isupper()) for c in password))):

This effectively keeps a running tally of whether you've satisfied the isdigit and isupper requirements at that point in the password. After checking the whole password, you simply use all() to read your tallies and make sure you've actually satisfied both requirements.

If your goal is run time rather than some ethereal notion like "passes through the data" (not to be disparaging; they can matter quite a bit in other contexts), your best improvements would come from some sort of high-performance library like numpy designed to vectorize the queries you perform. Since the bulk of the work being performed here isn't the pass through the data, but it is the check being performed on the characters in each pass, eliminating passes through the data won't do much for run time. You'll realize the most savings by making the actual checks as fast as possible.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

how do I shorten this

How do I simplify(expand) this Boolean expression?

How do I to shorten If else

How can I shorten the regex expression here?

How do I store a boolean test/expression without Evaluating it?

How do I simplify the boolean expression A+A'BC+BC'?

How do I shorten an <img> source in JavaScript?

How do I shorten an array in Perl 6?

Ruby - How do I shorten my method

How do I shorten this switch case?

How do i shorten a if statement in that situation?

How do I shorten the multiple IFs

How do I shorten this error inside the textField?

How do I shorten the name of a program for powershell

How can I shorten this function using a FirstOrDefault and Lambda expression?

VHDL: How can I shorten a 32bit expression?

Why do I need to cast this boolean expression?

How do I solve the 'Failed assertion: boolean expression must not be null' exception in Flutter

How do I evaluate a boolean expression given as a String in X++ [AX 2012]

How do I create a simplified logic circuit of this given [(A’B’)’ + (A’+ B’)’]’ ? and What is the simplified Boolean expression?

How do I shorten Google Cloud Storage Signed download URLs?

how do I shorten strings by removing pairs of identical letters correctly?

How do I shorten the current directory path shown on terminal?

How do I shorten a two-dimensional list?

How do I shorten and expand a uuid to a 15 or less characters

How do I shorten this code to make the date SQL compatible?

How do I shorten that specific code in C#?

How do I shorten an array in Matlab to prevent a dimension mismatch?

How do I shorten this code with python list comprehension?