The function is to find out how strong password is. It's considered strong if:
Is there a way to reduce the amount of code in the function? Please help me make the code of function shorter than 200 characters (try to solve without assigning values to variables)
import re
def golf(password):
if len(password) >= 10 \
and re.search("^[a-zA-Z0-9]+", password) \
and re.search("[a-z]+", password) \
and re.search("[A-Z]+", password) \
and re.search("[0-9]+", password):
print(password, True)
return True
else:
print(password, False)
return False
if __name__ == '__main__':
golf('A1213pokl') == False
golf('bAse730onE') == True
golf('asasasasasasasaas') == False
golf('QWERTYqwerty') == False
golf('123456123456') == False
golf('QwErTy911poqqqq') == True
golf('..........') == False
While you already have your answer, I'd even try to optimize the pattern. Instead of .*
and then backtracking, I'd apply the principle of contrast directly:
(?=\D*\d) # NOT a number, 0+ times, then one number
(?=[^A-Z]*[A-Z]) # NOT an UPPERCASE, 0+times, then an UPPERCASE
(?=[^a-z]*[a-z]) # same with lowercase
^[A-Za-z0-9]{10,}$ # allowed characters, 10+, with anchors on both sides
Condensed and demo:
(?=\D*\d)(?=[^A-Z]*[A-Z])(?=[^a-z]*[a-z])[A-Za-z0-9]{10,}$
The idea here is, that while .*
brings you down the line and then backtracks, the pattern above is likely to come to an end faster.
Python
snippet:
import re
def golf(password=None):
rx = re.compile(r'(?=\D*\d)(?=[^A-Z]*[A-Z])(?=[^a-z]*[a-z])[A-Za-z0-9]{10,}$')
return True if rx.match(password) else False
passwords = ['A1213pokl', 'bAse730onE', 'asasasasasasasaas', 'QWERTYqwerty', '123456123456', 'QwErTy911poqqqq', '..........']
vectors = [golf(password) for password in passwords]
print(vectors)
# [False, True, False, False, False, True, False]
The (not so :) stupid way:
from re import search as s
def golf(p):
return all([len(p)>=10,s("^[a-zA-Z0-9]+",p),s("[a-z]+",p),s("[A-Z]+",p),s("[0-9]+",p)])
And BTW, you probably want some assert
statements in your if __name__ == '__main__':
block...
This regex should do:
(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])^[a-zA-Z0-9]{10,}$
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With