How do I shorten this boolean expression?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
14
down vote

favorite












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.







share|improve this question






















  • When I google I found a website featuring Strong Randome Password Generator.
    – KaiserKatze
    Aug 16 at 5:50






  • 1




    i dunno if you can. any single char is going to be either a number of an uppercase. so you’d need to accumulate 2 results somehow in one for loop. closest i can see is returning a set of functions matching char, where functions are isupper and isdigit. if len(set) == 2, passed!
    – JL Peyret
    Aug 16 at 6:12






  • 2




    Did you forget to check any(char.islower() for char in password) ?
    – moooeeeep
    Aug 16 at 6:28






  • 2




    Yes, I was planning on adding that next, but then the expression got REALLY long. You see my problem now :)
    – Matt Davis
    Aug 16 at 6:29






  • 1




    Don't ask for short code. Ask for simple and readable code.
    – user202729
    Aug 16 at 13:33














up vote
14
down vote

favorite












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.







share|improve this question






















  • When I google I found a website featuring Strong Randome Password Generator.
    – KaiserKatze
    Aug 16 at 5:50






  • 1




    i dunno if you can. any single char is going to be either a number of an uppercase. so you’d need to accumulate 2 results somehow in one for loop. closest i can see is returning a set of functions matching char, where functions are isupper and isdigit. if len(set) == 2, passed!
    – JL Peyret
    Aug 16 at 6:12






  • 2




    Did you forget to check any(char.islower() for char in password) ?
    – moooeeeep
    Aug 16 at 6:28






  • 2




    Yes, I was planning on adding that next, but then the expression got REALLY long. You see my problem now :)
    – Matt Davis
    Aug 16 at 6:29






  • 1




    Don't ask for short code. Ask for simple and readable code.
    – user202729
    Aug 16 at 13:33












up vote
14
down vote

favorite









up vote
14
down vote

favorite











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.







share|improve this question














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.









share|improve this question













share|improve this question




share|improve this question








edited Aug 24 at 14:23









aloisdg

7,90223549




7,90223549










asked Aug 16 at 5:21









Matt Davis

948




948











  • When I google I found a website featuring Strong Randome Password Generator.
    – KaiserKatze
    Aug 16 at 5:50






  • 1




    i dunno if you can. any single char is going to be either a number of an uppercase. so you’d need to accumulate 2 results somehow in one for loop. closest i can see is returning a set of functions matching char, where functions are isupper and isdigit. if len(set) == 2, passed!
    – JL Peyret
    Aug 16 at 6:12






  • 2




    Did you forget to check any(char.islower() for char in password) ?
    – moooeeeep
    Aug 16 at 6:28






  • 2




    Yes, I was planning on adding that next, but then the expression got REALLY long. You see my problem now :)
    – Matt Davis
    Aug 16 at 6:29






  • 1




    Don't ask for short code. Ask for simple and readable code.
    – user202729
    Aug 16 at 13:33
















  • When I google I found a website featuring Strong Randome Password Generator.
    – KaiserKatze
    Aug 16 at 5:50






  • 1




    i dunno if you can. any single char is going to be either a number of an uppercase. so you’d need to accumulate 2 results somehow in one for loop. closest i can see is returning a set of functions matching char, where functions are isupper and isdigit. if len(set) == 2, passed!
    – JL Peyret
    Aug 16 at 6:12






  • 2




    Did you forget to check any(char.islower() for char in password) ?
    – moooeeeep
    Aug 16 at 6:28






  • 2




    Yes, I was planning on adding that next, but then the expression got REALLY long. You see my problem now :)
    – Matt Davis
    Aug 16 at 6:29






  • 1




    Don't ask for short code. Ask for simple and readable code.
    – user202729
    Aug 16 at 13:33















When I google I found a website featuring Strong Randome Password Generator.
– KaiserKatze
Aug 16 at 5:50




When I google I found a website featuring Strong Randome Password Generator.
– KaiserKatze
Aug 16 at 5:50




1




1




i dunno if you can. any single char is going to be either a number of an uppercase. so you’d need to accumulate 2 results somehow in one for loop. closest i can see is returning a set of functions matching char, where functions are isupper and isdigit. if len(set) == 2, passed!
– JL Peyret
Aug 16 at 6:12




i dunno if you can. any single char is going to be either a number of an uppercase. so you’d need to accumulate 2 results somehow in one for loop. closest i can see is returning a set of functions matching char, where functions are isupper and isdigit. if len(set) == 2, passed!
– JL Peyret
Aug 16 at 6:12




2




2




Did you forget to check any(char.islower() for char in password) ?
– moooeeeep
Aug 16 at 6:28




Did you forget to check any(char.islower() for char in password) ?
– moooeeeep
Aug 16 at 6:28




2




2




Yes, I was planning on adding that next, but then the expression got REALLY long. You see my problem now :)
– Matt Davis
Aug 16 at 6:29




Yes, I was planning on adding that next, but then the expression got REALLY long. You see my problem now :)
– Matt Davis
Aug 16 at 6:29




1




1




Don't ask for short code. Ask for simple and readable code.
– user202729
Aug 16 at 13:33




Don't ask for short code. Ask for simple and readable code.
– user202729
Aug 16 at 13:33












6 Answers
6






active

oldest

votes

















up vote
21
down vote



accepted










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.






share|improve this answer






















  • in your for loop wouldn't this add more brevity flags[i] = cond(c) and then return all(flags)
    – Akash Singh
    Aug 16 at 10:39







  • 2




    OP's password requirements for a password generator are absolutely sane: they need to make sure they generate passwords that insane websites accept.
    – Dmitry Grigoryev
    Aug 16 at 12:22










  • A slight comment regarding your indentation: These while-loops often take more than a single line. In such cases, you should indent the second line twice to prevent your while-loop definition from using the same indentation as your next logic line: python.org/dev/peps/pep-0008/#id17
    – Berry M.
    Aug 16 at 12:32










  • @AkashSingh Using flags[i] = cond(c) has the potential to overwrite some True values, and waiting till the end to return prevents early exiting if the required characters are found early.
    – Hans Musgrave
    Aug 16 at 13:29






  • 1




    @BerryM. Interesting. I don't agree with that PEP wholeheartedly, but I see where they're coming from. I'll change it in the answer.
    – Hans Musgrave
    Aug 16 at 13:34


















up vote
3
down vote













I agree with the answers presented, but to address your original question and your next step:




@moooeeeep: Did you forget to check any(char.islower() for char in
password) ?



@Matt Davis: Yes, I was planning on adding that next, but then the
expression got REALLY long. You see my problem now :)




simplifying your original logic slightly, we can do something like:



while not all([any(map(str.isdigit, password)), any(map(str.isupper, password)), any(map(str.islower, password))]):


I.e. apply all() to a list of any(). For the test cases:



["goat", "Goat", "goat1", "GOAT", "GOAT1", "Goat1"]


only "Goat1" passes as it meets all three criteria.






share|improve this answer




















  • neat use of all(any)!
    – JL Peyret
    Aug 16 at 20:52

















up vote
2
down vote













Leaving aside the question of what are good or bad criteria for a password (and I'm sure we've all had to implement a specification we didn't agree with in our time), there is nothing wrong with the way you have written this logic expression.



It is clear what you mean by the code, and unless you find it is actually too slow in practice then you should not sacrifice clarity for some theoretical gain in performance or efficiency, or making a line a few characters shorter.



Don't forget that you can break code across multiple lines in Python using indentation, so you can add more conditions without losing readability:



while not (
any(char.isdigit() for char in password) and
any(char.isupper() for char in password) and
any(char.islower() for char in password) and
any(char.somethingelse() for char in password) ):
do-something


As a beginner, learning to write clear and understandable code is far more important than worrying about a few microseconds or bytes here and there.






share|improve this answer






















  • Thanks for this. The real problem came up when I planned to add an .islower() and one other criteria next. It doubled the length and became excessively long
    – Matt Davis
    Aug 16 at 20:12










  • See my edit....
    – nekomatic
    Aug 17 at 9:50

















up vote
1
down vote













Similar to the lambda version. Return a set of tuples matching any of those tests. remove (False, False) from result. length set should be 2.



input_exp = [ 
("abc", False),
("A3", True),
("A", False),
("ab3", False),
("3", False),
("3A", True),

]

def check(string_):
"""each iteration evaluates to any one of (True,False) /(False,True)/ (False,False).
remove False,False from set.
check len==2"""

res = len(set([(c.isupper(), c.isdigit()) for c in string_]) - set([(False, False)])) == 2

return res


for string_, exp in input_exp:
got = check(string_)

if exp is got:
print("good. %s => %s" % (string_, got))
else:
print("bad . %s => %s" % (string_, got))


output:



good. abc => False
good. A3 => True
good. A => False
good. ab3 => False
good. 3 => False
good. 3A => True





share|improve this answer


















  • 1




    Your check function reads like intentionally obfuscated code. It’s not at all obvious what it does, and why/how it does it. :-(
    – Konrad Rudolph
    Aug 16 at 10:18










  • Try (False,True),(True,False)<=.
    – user202729
    Aug 16 at 13:37











  • Also, set comprehension...
    – user202729
    Aug 16 at 13:41










  • @Konrad. I stuck with the OP’s stated intent to do it in a single list comprehension pass. It is not very readable, but I would not code it this way at all in other circumstances. Perhaps, instead of just criticizing, you’d consider putting up your own solution?
    – JL Peyret
    Aug 16 at 15:25











  • @JLPeyret Even so, why the convoluted set operations rather than comparatively straightforward conjunctions and disjunctions?
    – Konrad Rudolph
    Aug 16 at 15:50

















up vote
-2
down vote













Use re module to do what you want.



import re

pattern = re.compile('[A-Z0-9]+')

password1 = 'asdf1234'
password2 = 'ASDF1234'

for p in (password1, password2):
if pattern.fullmatch(p):
print('Password', p, 'is fine')
else:
print('Password', p, 'is bad')





share|improve this answer
















  • 2




    wouldn't the above code categorize asdASDf1234 as a bad password ?
    – Hari Krishnan
    Aug 16 at 5:51







  • 2




    @HariKrishnan Yes, and furthermore it would categorise “012345” as a good password.
    – Konrad Rudolph
    Aug 16 at 10:17

















up vote
-2
down vote













This is not the shorter version, but it is a decent way to validate password by variety of checks.



Using Regular Expressions is best way to validate passwords.



The following code validates the password by conditions:



  • Minimum 8 characters.

  • The alphabets must be between [a-z]

  • At least
    one alphabet should be of Upper Case [A-Z]

  • At least 1 number or digit
    between [0-9].

  • At least 1 character from [ _ or @ or $ ].

Python program to check validation of password
Module of regular expression is used with search()



import re 
password = "R@m@_f0rtu9e$"
flag = 0
while True:
if (len(password)<8):
flag = -1
break
elif not re.search("[a-z]", password):
flag = -1
break
elif not re.search("[A-Z]", password):
flag = -1
break
elif not re.search("[0-9]", password):
flag = -1
break
elif not re.search("[_@$]", password):
flag = -1
break
elif re.search("s", password):
flag = -1
break
else:
flag = 0
print("Valid Password")
break

if flag ==-1:
print("Not a Valid Password")





share|improve this answer


















  • 2




    So you suggest the right tool to shorten the expression as requested then provide a much longer version?
    – Pierre Arlaud
    Aug 16 at 7:24






  • 1




    Your suggested code tests a completely different rule set for password validity. And it’s an abysmally bad rule set (worse, in fact, than OP’s). Please don’t do this.
    – Konrad Rudolph
    Aug 16 at 10:16











Your Answer





StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51870069%2fhow-do-i-shorten-this-boolean-expression%23new-answer', 'question_page');

);

Post as a guest






























6 Answers
6






active

oldest

votes








6 Answers
6






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
21
down vote



accepted










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.






share|improve this answer






















  • in your for loop wouldn't this add more brevity flags[i] = cond(c) and then return all(flags)
    – Akash Singh
    Aug 16 at 10:39







  • 2




    OP's password requirements for a password generator are absolutely sane: they need to make sure they generate passwords that insane websites accept.
    – Dmitry Grigoryev
    Aug 16 at 12:22










  • A slight comment regarding your indentation: These while-loops often take more than a single line. In such cases, you should indent the second line twice to prevent your while-loop definition from using the same indentation as your next logic line: python.org/dev/peps/pep-0008/#id17
    – Berry M.
    Aug 16 at 12:32










  • @AkashSingh Using flags[i] = cond(c) has the potential to overwrite some True values, and waiting till the end to return prevents early exiting if the required characters are found early.
    – Hans Musgrave
    Aug 16 at 13:29






  • 1




    @BerryM. Interesting. I don't agree with that PEP wholeheartedly, but I see where they're coming from. I'll change it in the answer.
    – Hans Musgrave
    Aug 16 at 13:34















up vote
21
down vote



accepted










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.






share|improve this answer






















  • in your for loop wouldn't this add more brevity flags[i] = cond(c) and then return all(flags)
    – Akash Singh
    Aug 16 at 10:39







  • 2




    OP's password requirements for a password generator are absolutely sane: they need to make sure they generate passwords that insane websites accept.
    – Dmitry Grigoryev
    Aug 16 at 12:22










  • A slight comment regarding your indentation: These while-loops often take more than a single line. In such cases, you should indent the second line twice to prevent your while-loop definition from using the same indentation as your next logic line: python.org/dev/peps/pep-0008/#id17
    – Berry M.
    Aug 16 at 12:32










  • @AkashSingh Using flags[i] = cond(c) has the potential to overwrite some True values, and waiting till the end to return prevents early exiting if the required characters are found early.
    – Hans Musgrave
    Aug 16 at 13:29






  • 1




    @BerryM. Interesting. I don't agree with that PEP wholeheartedly, but I see where they're coming from. I'll change it in the answer.
    – Hans Musgrave
    Aug 16 at 13:34













up vote
21
down vote



accepted







up vote
21
down vote



accepted






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.






share|improve this answer














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.







share|improve this answer














share|improve this answer



share|improve this answer








edited Aug 17 at 0:22

























answered Aug 16 at 6:09









Hans Musgrave

1,819415




1,819415











  • in your for loop wouldn't this add more brevity flags[i] = cond(c) and then return all(flags)
    – Akash Singh
    Aug 16 at 10:39







  • 2




    OP's password requirements for a password generator are absolutely sane: they need to make sure they generate passwords that insane websites accept.
    – Dmitry Grigoryev
    Aug 16 at 12:22










  • A slight comment regarding your indentation: These while-loops often take more than a single line. In such cases, you should indent the second line twice to prevent your while-loop definition from using the same indentation as your next logic line: python.org/dev/peps/pep-0008/#id17
    – Berry M.
    Aug 16 at 12:32










  • @AkashSingh Using flags[i] = cond(c) has the potential to overwrite some True values, and waiting till the end to return prevents early exiting if the required characters are found early.
    – Hans Musgrave
    Aug 16 at 13:29






  • 1




    @BerryM. Interesting. I don't agree with that PEP wholeheartedly, but I see where they're coming from. I'll change it in the answer.
    – Hans Musgrave
    Aug 16 at 13:34

















  • in your for loop wouldn't this add more brevity flags[i] = cond(c) and then return all(flags)
    – Akash Singh
    Aug 16 at 10:39







  • 2




    OP's password requirements for a password generator are absolutely sane: they need to make sure they generate passwords that insane websites accept.
    – Dmitry Grigoryev
    Aug 16 at 12:22










  • A slight comment regarding your indentation: These while-loops often take more than a single line. In such cases, you should indent the second line twice to prevent your while-loop definition from using the same indentation as your next logic line: python.org/dev/peps/pep-0008/#id17
    – Berry M.
    Aug 16 at 12:32










  • @AkashSingh Using flags[i] = cond(c) has the potential to overwrite some True values, and waiting till the end to return prevents early exiting if the required characters are found early.
    – Hans Musgrave
    Aug 16 at 13:29






  • 1




    @BerryM. Interesting. I don't agree with that PEP wholeheartedly, but I see where they're coming from. I'll change it in the answer.
    – Hans Musgrave
    Aug 16 at 13:34
















in your for loop wouldn't this add more brevity flags[i] = cond(c) and then return all(flags)
– Akash Singh
Aug 16 at 10:39





in your for loop wouldn't this add more brevity flags[i] = cond(c) and then return all(flags)
– Akash Singh
Aug 16 at 10:39





2




2




OP's password requirements for a password generator are absolutely sane: they need to make sure they generate passwords that insane websites accept.
– Dmitry Grigoryev
Aug 16 at 12:22




OP's password requirements for a password generator are absolutely sane: they need to make sure they generate passwords that insane websites accept.
– Dmitry Grigoryev
Aug 16 at 12:22












A slight comment regarding your indentation: These while-loops often take more than a single line. In such cases, you should indent the second line twice to prevent your while-loop definition from using the same indentation as your next logic line: python.org/dev/peps/pep-0008/#id17
– Berry M.
Aug 16 at 12:32




A slight comment regarding your indentation: These while-loops often take more than a single line. In such cases, you should indent the second line twice to prevent your while-loop definition from using the same indentation as your next logic line: python.org/dev/peps/pep-0008/#id17
– Berry M.
Aug 16 at 12:32












@AkashSingh Using flags[i] = cond(c) has the potential to overwrite some True values, and waiting till the end to return prevents early exiting if the required characters are found early.
– Hans Musgrave
Aug 16 at 13:29




@AkashSingh Using flags[i] = cond(c) has the potential to overwrite some True values, and waiting till the end to return prevents early exiting if the required characters are found early.
– Hans Musgrave
Aug 16 at 13:29




1




1




@BerryM. Interesting. I don't agree with that PEP wholeheartedly, but I see where they're coming from. I'll change it in the answer.
– Hans Musgrave
Aug 16 at 13:34





@BerryM. Interesting. I don't agree with that PEP wholeheartedly, but I see where they're coming from. I'll change it in the answer.
– Hans Musgrave
Aug 16 at 13:34













up vote
3
down vote













I agree with the answers presented, but to address your original question and your next step:




@moooeeeep: Did you forget to check any(char.islower() for char in
password) ?



@Matt Davis: Yes, I was planning on adding that next, but then the
expression got REALLY long. You see my problem now :)




simplifying your original logic slightly, we can do something like:



while not all([any(map(str.isdigit, password)), any(map(str.isupper, password)), any(map(str.islower, password))]):


I.e. apply all() to a list of any(). For the test cases:



["goat", "Goat", "goat1", "GOAT", "GOAT1", "Goat1"]


only "Goat1" passes as it meets all three criteria.






share|improve this answer




















  • neat use of all(any)!
    – JL Peyret
    Aug 16 at 20:52














up vote
3
down vote













I agree with the answers presented, but to address your original question and your next step:




@moooeeeep: Did you forget to check any(char.islower() for char in
password) ?



@Matt Davis: Yes, I was planning on adding that next, but then the
expression got REALLY long. You see my problem now :)




simplifying your original logic slightly, we can do something like:



while not all([any(map(str.isdigit, password)), any(map(str.isupper, password)), any(map(str.islower, password))]):


I.e. apply all() to a list of any(). For the test cases:



["goat", "Goat", "goat1", "GOAT", "GOAT1", "Goat1"]


only "Goat1" passes as it meets all three criteria.






share|improve this answer




















  • neat use of all(any)!
    – JL Peyret
    Aug 16 at 20:52












up vote
3
down vote










up vote
3
down vote









I agree with the answers presented, but to address your original question and your next step:




@moooeeeep: Did you forget to check any(char.islower() for char in
password) ?



@Matt Davis: Yes, I was planning on adding that next, but then the
expression got REALLY long. You see my problem now :)




simplifying your original logic slightly, we can do something like:



while not all([any(map(str.isdigit, password)), any(map(str.isupper, password)), any(map(str.islower, password))]):


I.e. apply all() to a list of any(). For the test cases:



["goat", "Goat", "goat1", "GOAT", "GOAT1", "Goat1"]


only "Goat1" passes as it meets all three criteria.






share|improve this answer












I agree with the answers presented, but to address your original question and your next step:




@moooeeeep: Did you forget to check any(char.islower() for char in
password) ?



@Matt Davis: Yes, I was planning on adding that next, but then the
expression got REALLY long. You see my problem now :)




simplifying your original logic slightly, we can do something like:



while not all([any(map(str.isdigit, password)), any(map(str.isupper, password)), any(map(str.islower, password))]):


I.e. apply all() to a list of any(). For the test cases:



["goat", "Goat", "goat1", "GOAT", "GOAT1", "Goat1"]


only "Goat1" passes as it meets all three criteria.







share|improve this answer












share|improve this answer



share|improve this answer










answered Aug 16 at 7:09









cdlane

15.1k21041




15.1k21041











  • neat use of all(any)!
    – JL Peyret
    Aug 16 at 20:52
















  • neat use of all(any)!
    – JL Peyret
    Aug 16 at 20:52















neat use of all(any)!
– JL Peyret
Aug 16 at 20:52




neat use of all(any)!
– JL Peyret
Aug 16 at 20:52










up vote
2
down vote













Leaving aside the question of what are good or bad criteria for a password (and I'm sure we've all had to implement a specification we didn't agree with in our time), there is nothing wrong with the way you have written this logic expression.



It is clear what you mean by the code, and unless you find it is actually too slow in practice then you should not sacrifice clarity for some theoretical gain in performance or efficiency, or making a line a few characters shorter.



Don't forget that you can break code across multiple lines in Python using indentation, so you can add more conditions without losing readability:



while not (
any(char.isdigit() for char in password) and
any(char.isupper() for char in password) and
any(char.islower() for char in password) and
any(char.somethingelse() for char in password) ):
do-something


As a beginner, learning to write clear and understandable code is far more important than worrying about a few microseconds or bytes here and there.






share|improve this answer






















  • Thanks for this. The real problem came up when I planned to add an .islower() and one other criteria next. It doubled the length and became excessively long
    – Matt Davis
    Aug 16 at 20:12










  • See my edit....
    – nekomatic
    Aug 17 at 9:50














up vote
2
down vote













Leaving aside the question of what are good or bad criteria for a password (and I'm sure we've all had to implement a specification we didn't agree with in our time), there is nothing wrong with the way you have written this logic expression.



It is clear what you mean by the code, and unless you find it is actually too slow in practice then you should not sacrifice clarity for some theoretical gain in performance or efficiency, or making a line a few characters shorter.



Don't forget that you can break code across multiple lines in Python using indentation, so you can add more conditions without losing readability:



while not (
any(char.isdigit() for char in password) and
any(char.isupper() for char in password) and
any(char.islower() for char in password) and
any(char.somethingelse() for char in password) ):
do-something


As a beginner, learning to write clear and understandable code is far more important than worrying about a few microseconds or bytes here and there.






share|improve this answer






















  • Thanks for this. The real problem came up when I planned to add an .islower() and one other criteria next. It doubled the length and became excessively long
    – Matt Davis
    Aug 16 at 20:12










  • See my edit....
    – nekomatic
    Aug 17 at 9:50












up vote
2
down vote










up vote
2
down vote









Leaving aside the question of what are good or bad criteria for a password (and I'm sure we've all had to implement a specification we didn't agree with in our time), there is nothing wrong with the way you have written this logic expression.



It is clear what you mean by the code, and unless you find it is actually too slow in practice then you should not sacrifice clarity for some theoretical gain in performance or efficiency, or making a line a few characters shorter.



Don't forget that you can break code across multiple lines in Python using indentation, so you can add more conditions without losing readability:



while not (
any(char.isdigit() for char in password) and
any(char.isupper() for char in password) and
any(char.islower() for char in password) and
any(char.somethingelse() for char in password) ):
do-something


As a beginner, learning to write clear and understandable code is far more important than worrying about a few microseconds or bytes here and there.






share|improve this answer














Leaving aside the question of what are good or bad criteria for a password (and I'm sure we've all had to implement a specification we didn't agree with in our time), there is nothing wrong with the way you have written this logic expression.



It is clear what you mean by the code, and unless you find it is actually too slow in practice then you should not sacrifice clarity for some theoretical gain in performance or efficiency, or making a line a few characters shorter.



Don't forget that you can break code across multiple lines in Python using indentation, so you can add more conditions without losing readability:



while not (
any(char.isdigit() for char in password) and
any(char.isupper() for char in password) and
any(char.islower() for char in password) and
any(char.somethingelse() for char in password) ):
do-something


As a beginner, learning to write clear and understandable code is far more important than worrying about a few microseconds or bytes here and there.







share|improve this answer














share|improve this answer



share|improve this answer








edited Aug 17 at 9:50

























answered Aug 16 at 9:23









nekomatic

3,86911222




3,86911222











  • Thanks for this. The real problem came up when I planned to add an .islower() and one other criteria next. It doubled the length and became excessively long
    – Matt Davis
    Aug 16 at 20:12










  • See my edit....
    – nekomatic
    Aug 17 at 9:50
















  • Thanks for this. The real problem came up when I planned to add an .islower() and one other criteria next. It doubled the length and became excessively long
    – Matt Davis
    Aug 16 at 20:12










  • See my edit....
    – nekomatic
    Aug 17 at 9:50















Thanks for this. The real problem came up when I planned to add an .islower() and one other criteria next. It doubled the length and became excessively long
– Matt Davis
Aug 16 at 20:12




Thanks for this. The real problem came up when I planned to add an .islower() and one other criteria next. It doubled the length and became excessively long
– Matt Davis
Aug 16 at 20:12












See my edit....
– nekomatic
Aug 17 at 9:50




See my edit....
– nekomatic
Aug 17 at 9:50










up vote
1
down vote













Similar to the lambda version. Return a set of tuples matching any of those tests. remove (False, False) from result. length set should be 2.



input_exp = [ 
("abc", False),
("A3", True),
("A", False),
("ab3", False),
("3", False),
("3A", True),

]

def check(string_):
"""each iteration evaluates to any one of (True,False) /(False,True)/ (False,False).
remove False,False from set.
check len==2"""

res = len(set([(c.isupper(), c.isdigit()) for c in string_]) - set([(False, False)])) == 2

return res


for string_, exp in input_exp:
got = check(string_)

if exp is got:
print("good. %s => %s" % (string_, got))
else:
print("bad . %s => %s" % (string_, got))


output:



good. abc => False
good. A3 => True
good. A => False
good. ab3 => False
good. 3 => False
good. 3A => True





share|improve this answer


















  • 1




    Your check function reads like intentionally obfuscated code. It’s not at all obvious what it does, and why/how it does it. :-(
    – Konrad Rudolph
    Aug 16 at 10:18










  • Try (False,True),(True,False)<=.
    – user202729
    Aug 16 at 13:37











  • Also, set comprehension...
    – user202729
    Aug 16 at 13:41










  • @Konrad. I stuck with the OP’s stated intent to do it in a single list comprehension pass. It is not very readable, but I would not code it this way at all in other circumstances. Perhaps, instead of just criticizing, you’d consider putting up your own solution?
    – JL Peyret
    Aug 16 at 15:25











  • @JLPeyret Even so, why the convoluted set operations rather than comparatively straightforward conjunctions and disjunctions?
    – Konrad Rudolph
    Aug 16 at 15:50














up vote
1
down vote













Similar to the lambda version. Return a set of tuples matching any of those tests. remove (False, False) from result. length set should be 2.



input_exp = [ 
("abc", False),
("A3", True),
("A", False),
("ab3", False),
("3", False),
("3A", True),

]

def check(string_):
"""each iteration evaluates to any one of (True,False) /(False,True)/ (False,False).
remove False,False from set.
check len==2"""

res = len(set([(c.isupper(), c.isdigit()) for c in string_]) - set([(False, False)])) == 2

return res


for string_, exp in input_exp:
got = check(string_)

if exp is got:
print("good. %s => %s" % (string_, got))
else:
print("bad . %s => %s" % (string_, got))


output:



good. abc => False
good. A3 => True
good. A => False
good. ab3 => False
good. 3 => False
good. 3A => True





share|improve this answer


















  • 1




    Your check function reads like intentionally obfuscated code. It’s not at all obvious what it does, and why/how it does it. :-(
    – Konrad Rudolph
    Aug 16 at 10:18










  • Try (False,True),(True,False)<=.
    – user202729
    Aug 16 at 13:37











  • Also, set comprehension...
    – user202729
    Aug 16 at 13:41










  • @Konrad. I stuck with the OP’s stated intent to do it in a single list comprehension pass. It is not very readable, but I would not code it this way at all in other circumstances. Perhaps, instead of just criticizing, you’d consider putting up your own solution?
    – JL Peyret
    Aug 16 at 15:25











  • @JLPeyret Even so, why the convoluted set operations rather than comparatively straightforward conjunctions and disjunctions?
    – Konrad Rudolph
    Aug 16 at 15:50












up vote
1
down vote










up vote
1
down vote









Similar to the lambda version. Return a set of tuples matching any of those tests. remove (False, False) from result. length set should be 2.



input_exp = [ 
("abc", False),
("A3", True),
("A", False),
("ab3", False),
("3", False),
("3A", True),

]

def check(string_):
"""each iteration evaluates to any one of (True,False) /(False,True)/ (False,False).
remove False,False from set.
check len==2"""

res = len(set([(c.isupper(), c.isdigit()) for c in string_]) - set([(False, False)])) == 2

return res


for string_, exp in input_exp:
got = check(string_)

if exp is got:
print("good. %s => %s" % (string_, got))
else:
print("bad . %s => %s" % (string_, got))


output:



good. abc => False
good. A3 => True
good. A => False
good. ab3 => False
good. 3 => False
good. 3A => True





share|improve this answer














Similar to the lambda version. Return a set of tuples matching any of those tests. remove (False, False) from result. length set should be 2.



input_exp = [ 
("abc", False),
("A3", True),
("A", False),
("ab3", False),
("3", False),
("3A", True),

]

def check(string_):
"""each iteration evaluates to any one of (True,False) /(False,True)/ (False,False).
remove False,False from set.
check len==2"""

res = len(set([(c.isupper(), c.isdigit()) for c in string_]) - set([(False, False)])) == 2

return res


for string_, exp in input_exp:
got = check(string_)

if exp is got:
print("good. %s => %s" % (string_, got))
else:
print("bad . %s => %s" % (string_, got))


output:



good. abc => False
good. A3 => True
good. A => False
good. ab3 => False
good. 3 => False
good. 3A => True






share|improve this answer














share|improve this answer



share|improve this answer








edited Aug 16 at 7:53

























answered Aug 16 at 6:34









JL Peyret

2,6731528




2,6731528







  • 1




    Your check function reads like intentionally obfuscated code. It’s not at all obvious what it does, and why/how it does it. :-(
    – Konrad Rudolph
    Aug 16 at 10:18










  • Try (False,True),(True,False)<=.
    – user202729
    Aug 16 at 13:37











  • Also, set comprehension...
    – user202729
    Aug 16 at 13:41










  • @Konrad. I stuck with the OP’s stated intent to do it in a single list comprehension pass. It is not very readable, but I would not code it this way at all in other circumstances. Perhaps, instead of just criticizing, you’d consider putting up your own solution?
    – JL Peyret
    Aug 16 at 15:25











  • @JLPeyret Even so, why the convoluted set operations rather than comparatively straightforward conjunctions and disjunctions?
    – Konrad Rudolph
    Aug 16 at 15:50












  • 1




    Your check function reads like intentionally obfuscated code. It’s not at all obvious what it does, and why/how it does it. :-(
    – Konrad Rudolph
    Aug 16 at 10:18










  • Try (False,True),(True,False)<=.
    – user202729
    Aug 16 at 13:37











  • Also, set comprehension...
    – user202729
    Aug 16 at 13:41










  • @Konrad. I stuck with the OP’s stated intent to do it in a single list comprehension pass. It is not very readable, but I would not code it this way at all in other circumstances. Perhaps, instead of just criticizing, you’d consider putting up your own solution?
    – JL Peyret
    Aug 16 at 15:25











  • @JLPeyret Even so, why the convoluted set operations rather than comparatively straightforward conjunctions and disjunctions?
    – Konrad Rudolph
    Aug 16 at 15:50







1




1




Your check function reads like intentionally obfuscated code. It’s not at all obvious what it does, and why/how it does it. :-(
– Konrad Rudolph
Aug 16 at 10:18




Your check function reads like intentionally obfuscated code. It’s not at all obvious what it does, and why/how it does it. :-(
– Konrad Rudolph
Aug 16 at 10:18












Try (False,True),(True,False)<=.
– user202729
Aug 16 at 13:37





Try (False,True),(True,False)<=.
– user202729
Aug 16 at 13:37













Also, set comprehension...
– user202729
Aug 16 at 13:41




Also, set comprehension...
– user202729
Aug 16 at 13:41












@Konrad. I stuck with the OP’s stated intent to do it in a single list comprehension pass. It is not very readable, but I would not code it this way at all in other circumstances. Perhaps, instead of just criticizing, you’d consider putting up your own solution?
– JL Peyret
Aug 16 at 15:25





@Konrad. I stuck with the OP’s stated intent to do it in a single list comprehension pass. It is not very readable, but I would not code it this way at all in other circumstances. Perhaps, instead of just criticizing, you’d consider putting up your own solution?
– JL Peyret
Aug 16 at 15:25













@JLPeyret Even so, why the convoluted set operations rather than comparatively straightforward conjunctions and disjunctions?
– Konrad Rudolph
Aug 16 at 15:50




@JLPeyret Even so, why the convoluted set operations rather than comparatively straightforward conjunctions and disjunctions?
– Konrad Rudolph
Aug 16 at 15:50










up vote
-2
down vote













Use re module to do what you want.



import re

pattern = re.compile('[A-Z0-9]+')

password1 = 'asdf1234'
password2 = 'ASDF1234'

for p in (password1, password2):
if pattern.fullmatch(p):
print('Password', p, 'is fine')
else:
print('Password', p, 'is bad')





share|improve this answer
















  • 2




    wouldn't the above code categorize asdASDf1234 as a bad password ?
    – Hari Krishnan
    Aug 16 at 5:51







  • 2




    @HariKrishnan Yes, and furthermore it would categorise “012345” as a good password.
    – Konrad Rudolph
    Aug 16 at 10:17














up vote
-2
down vote













Use re module to do what you want.



import re

pattern = re.compile('[A-Z0-9]+')

password1 = 'asdf1234'
password2 = 'ASDF1234'

for p in (password1, password2):
if pattern.fullmatch(p):
print('Password', p, 'is fine')
else:
print('Password', p, 'is bad')





share|improve this answer
















  • 2




    wouldn't the above code categorize asdASDf1234 as a bad password ?
    – Hari Krishnan
    Aug 16 at 5:51







  • 2




    @HariKrishnan Yes, and furthermore it would categorise “012345” as a good password.
    – Konrad Rudolph
    Aug 16 at 10:17












up vote
-2
down vote










up vote
-2
down vote









Use re module to do what you want.



import re

pattern = re.compile('[A-Z0-9]+')

password1 = 'asdf1234'
password2 = 'ASDF1234'

for p in (password1, password2):
if pattern.fullmatch(p):
print('Password', p, 'is fine')
else:
print('Password', p, 'is bad')





share|improve this answer












Use re module to do what you want.



import re

pattern = re.compile('[A-Z0-9]+')

password1 = 'asdf1234'
password2 = 'ASDF1234'

for p in (password1, password2):
if pattern.fullmatch(p):
print('Password', p, 'is fine')
else:
print('Password', p, 'is bad')






share|improve this answer












share|improve this answer



share|improve this answer










answered Aug 16 at 5:35









leotrubach

1,01659




1,01659







  • 2




    wouldn't the above code categorize asdASDf1234 as a bad password ?
    – Hari Krishnan
    Aug 16 at 5:51







  • 2




    @HariKrishnan Yes, and furthermore it would categorise “012345” as a good password.
    – Konrad Rudolph
    Aug 16 at 10:17












  • 2




    wouldn't the above code categorize asdASDf1234 as a bad password ?
    – Hari Krishnan
    Aug 16 at 5:51







  • 2




    @HariKrishnan Yes, and furthermore it would categorise “012345” as a good password.
    – Konrad Rudolph
    Aug 16 at 10:17







2




2




wouldn't the above code categorize asdASDf1234 as a bad password ?
– Hari Krishnan
Aug 16 at 5:51





wouldn't the above code categorize asdASDf1234 as a bad password ?
– Hari Krishnan
Aug 16 at 5:51





2




2




@HariKrishnan Yes, and furthermore it would categorise “012345” as a good password.
– Konrad Rudolph
Aug 16 at 10:17




@HariKrishnan Yes, and furthermore it would categorise “012345” as a good password.
– Konrad Rudolph
Aug 16 at 10:17










up vote
-2
down vote













This is not the shorter version, but it is a decent way to validate password by variety of checks.



Using Regular Expressions is best way to validate passwords.



The following code validates the password by conditions:



  • Minimum 8 characters.

  • The alphabets must be between [a-z]

  • At least
    one alphabet should be of Upper Case [A-Z]

  • At least 1 number or digit
    between [0-9].

  • At least 1 character from [ _ or @ or $ ].

Python program to check validation of password
Module of regular expression is used with search()



import re 
password = "R@m@_f0rtu9e$"
flag = 0
while True:
if (len(password)<8):
flag = -1
break
elif not re.search("[a-z]", password):
flag = -1
break
elif not re.search("[A-Z]", password):
flag = -1
break
elif not re.search("[0-9]", password):
flag = -1
break
elif not re.search("[_@$]", password):
flag = -1
break
elif re.search("s", password):
flag = -1
break
else:
flag = 0
print("Valid Password")
break

if flag ==-1:
print("Not a Valid Password")





share|improve this answer


















  • 2




    So you suggest the right tool to shorten the expression as requested then provide a much longer version?
    – Pierre Arlaud
    Aug 16 at 7:24






  • 1




    Your suggested code tests a completely different rule set for password validity. And it’s an abysmally bad rule set (worse, in fact, than OP’s). Please don’t do this.
    – Konrad Rudolph
    Aug 16 at 10:16















up vote
-2
down vote













This is not the shorter version, but it is a decent way to validate password by variety of checks.



Using Regular Expressions is best way to validate passwords.



The following code validates the password by conditions:



  • Minimum 8 characters.

  • The alphabets must be between [a-z]

  • At least
    one alphabet should be of Upper Case [A-Z]

  • At least 1 number or digit
    between [0-9].

  • At least 1 character from [ _ or @ or $ ].

Python program to check validation of password
Module of regular expression is used with search()



import re 
password = "R@m@_f0rtu9e$"
flag = 0
while True:
if (len(password)<8):
flag = -1
break
elif not re.search("[a-z]", password):
flag = -1
break
elif not re.search("[A-Z]", password):
flag = -1
break
elif not re.search("[0-9]", password):
flag = -1
break
elif not re.search("[_@$]", password):
flag = -1
break
elif re.search("s", password):
flag = -1
break
else:
flag = 0
print("Valid Password")
break

if flag ==-1:
print("Not a Valid Password")





share|improve this answer


















  • 2




    So you suggest the right tool to shorten the expression as requested then provide a much longer version?
    – Pierre Arlaud
    Aug 16 at 7:24






  • 1




    Your suggested code tests a completely different rule set for password validity. And it’s an abysmally bad rule set (worse, in fact, than OP’s). Please don’t do this.
    – Konrad Rudolph
    Aug 16 at 10:16













up vote
-2
down vote










up vote
-2
down vote









This is not the shorter version, but it is a decent way to validate password by variety of checks.



Using Regular Expressions is best way to validate passwords.



The following code validates the password by conditions:



  • Minimum 8 characters.

  • The alphabets must be between [a-z]

  • At least
    one alphabet should be of Upper Case [A-Z]

  • At least 1 number or digit
    between [0-9].

  • At least 1 character from [ _ or @ or $ ].

Python program to check validation of password
Module of regular expression is used with search()



import re 
password = "R@m@_f0rtu9e$"
flag = 0
while True:
if (len(password)<8):
flag = -1
break
elif not re.search("[a-z]", password):
flag = -1
break
elif not re.search("[A-Z]", password):
flag = -1
break
elif not re.search("[0-9]", password):
flag = -1
break
elif not re.search("[_@$]", password):
flag = -1
break
elif re.search("s", password):
flag = -1
break
else:
flag = 0
print("Valid Password")
break

if flag ==-1:
print("Not a Valid Password")





share|improve this answer














This is not the shorter version, but it is a decent way to validate password by variety of checks.



Using Regular Expressions is best way to validate passwords.



The following code validates the password by conditions:



  • Minimum 8 characters.

  • The alphabets must be between [a-z]

  • At least
    one alphabet should be of Upper Case [A-Z]

  • At least 1 number or digit
    between [0-9].

  • At least 1 character from [ _ or @ or $ ].

Python program to check validation of password
Module of regular expression is used with search()



import re 
password = "R@m@_f0rtu9e$"
flag = 0
while True:
if (len(password)<8):
flag = -1
break
elif not re.search("[a-z]", password):
flag = -1
break
elif not re.search("[A-Z]", password):
flag = -1
break
elif not re.search("[0-9]", password):
flag = -1
break
elif not re.search("[_@$]", password):
flag = -1
break
elif re.search("s", password):
flag = -1
break
else:
flag = 0
print("Valid Password")
break

if flag ==-1:
print("Not a Valid Password")






share|improve this answer














share|improve this answer



share|improve this answer








edited Aug 16 at 13:34

























answered Aug 16 at 5:32









Krishna Choudhary

257112




257112







  • 2




    So you suggest the right tool to shorten the expression as requested then provide a much longer version?
    – Pierre Arlaud
    Aug 16 at 7:24






  • 1




    Your suggested code tests a completely different rule set for password validity. And it’s an abysmally bad rule set (worse, in fact, than OP’s). Please don’t do this.
    – Konrad Rudolph
    Aug 16 at 10:16













  • 2




    So you suggest the right tool to shorten the expression as requested then provide a much longer version?
    – Pierre Arlaud
    Aug 16 at 7:24






  • 1




    Your suggested code tests a completely different rule set for password validity. And it’s an abysmally bad rule set (worse, in fact, than OP’s). Please don’t do this.
    – Konrad Rudolph
    Aug 16 at 10:16








2




2




So you suggest the right tool to shorten the expression as requested then provide a much longer version?
– Pierre Arlaud
Aug 16 at 7:24




So you suggest the right tool to shorten the expression as requested then provide a much longer version?
– Pierre Arlaud
Aug 16 at 7:24




1




1




Your suggested code tests a completely different rule set for password validity. And it’s an abysmally bad rule set (worse, in fact, than OP’s). Please don’t do this.
– Konrad Rudolph
Aug 16 at 10:16





Your suggested code tests a completely different rule set for password validity. And it’s an abysmally bad rule set (worse, in fact, than OP’s). Please don’t do this.
– Konrad Rudolph
Aug 16 at 10:16













 

draft saved


draft discarded


























 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51870069%2fhow-do-i-shorten-this-boolean-expression%23new-answer', 'question_page');

);

Post as a guest













































































這個網誌中的熱門文章

How to combine Bézier curves to a surface?

Mutual Information Always Non-negative

Why am i infinitely getting the same tweet with the Twitter Search API?