I am trying to build a strong password checker using Python. The conditions of the password are as follows:
Write a function strongPasswordChecker(s), that takes a string s as input, and return the MINIMUM change required to make s a strong password. If s is already strong, return 0.
Insertion, deletion or replace of any one character are all considered as one change.
The following is my attempt:
import re
class Solution:
def strongPasswordChecker(self, s: str) -> int:
# Holds the change
change = 0
# Checks if the password length is less than 6
if len(s) < 6:
change += 6 - len(s)
# Checks if the password length is greater than 20
elif len(s) > 20:
change += len(s) - 20
# Checks if the password has at least one digit
elif re.search(r'\d', s):
change += 1
# Checks if the password has at least one upper case letter
elif re.search(r'[A-Z]', s):
change += 1
# Checks if the password has at least one lower case letter
elif re.search(r'[a-z]', password):
change += 1
# Checks for repeating characters
for i in range(1, len(s)):
if i >= 3 and i < len(s):
if s[i] == s[i + 1] and s[i + 1] == s[i + 2]:
change += 1
return change
Despite checking for the repeating characters with the if statement above, I'm still getting the following error:
IndexError: String Index out of range
The problem is this statement can go out of bounds potentially, for example when i == len(s) - 1
then s[i + 1]
and s[i + 2]
will both index out of bounds.
for i in range(1, len(s)):
if i >= 3 and i < len(s):
if s[i] == s[i + 1] and s[i + 1] == s[i + 2]:
change += 1
If you want to make sure you don't have groups of 3 or longer, I'd use itertools.groupby
>>> any(len(list(g)) > 2 for k, g in groupby('aabbcc'))
False
>>> any(len(list(g)) > 2 for k, g in groupby('aabbbbbcc'))
True
To replace your for
loop in your code, you'd use this like
elif any(len(list(g)) > 2 for k, g in groupby(s)):
change += 1