尝试使用以下代码检查字符串:
def check_password(x):
if has_unique_letters(x) == False:
print "Warning! Please ensure letters are not repeated."
if has_even_vowels(x) == False:
print "Warning! Please ensure password contains an even number of vowels."
if has_special_character(x) == False:
print "Warning! Please ensure password contains at least one of {@, #, *, $}"
if has_divisible_numbers(x) == False:
print "Warning! Please ensure all numbers are divisible by 2 or 3."
print "Sorry, your password does not meet our criteria."
print "Congratulations, your password meets our criteria."
x = raw_input("Please set your password:")
check_password(x)
但是我对如何制作感到困惑:
print "Sorry, your password does not meet our criteria."
和
print "Congratulations, your password meets our criteria."
这两句话表明正确。
我打算在其中一个条件不满足时显示每个"Warning!..."
和"Sorry,..."
,而在满足所有条件时显示"Congratulation,..."
。
但是,凭借我所拥有的内容,"Sorry,..."
行始终显示,并且"Congratulations,..."
行未显示。
我知道我一定做错了但我怎么能解决这个问题呢? 谢谢!
答案 0 :(得分:5)
创建一个包含密码中所有错误的列表。如果有错误,请说明密码不符合条件,然后打印所有密码错误类型。否则,请打印出符合标准的内容。
def check_password(password):
errors = []
if not has_unique_letters(password):
errors.append("Warning! Please ensure letters are not repeated.")
if not has_even_vowels(password):
errors.append("Warning! Please ensure password contains an even number of vowels.")
if not has_special_character(password):
errors.append("Warning! Please ensure password contains at least one of {@, #, *, $}")
if not has_divisible_numbers(password):
errors.append("Warning! Please ensure all numbers are divisible by 2 or 3.")
if errors:
print "Sorry, your password does not meet our criteria."
for e in errors:
print(e)
else:
print "Congratulations, your password meets our criteria."
password = raw_input("Please set your password:")
check_password(password)
答案 1 :(得分:4)
编辑:我最喜欢上一个代码示例,我认为这可能是最好的做法。
解决问题的一种简单方法是执行以下操作:
def check_password(x):
bad_password = False
if has_unique_letters(x) == False:
print "Warning! Please ensure letters are not repeated."
bad_password = True
if has_even_vowels(x) == False:
print "Warning! Please ensure password contains an even number of vowels."
bad_password = True
if has_special_character(x) == False:
print "Warning! Please ensure password contains at least one of {@, #, *, $}"
bad_password = True
if has_divisible_numbers(x) == False:
print "Warning! Please ensure all numbers are divisible by 2 or 3."
bad_password = True
if bad_password == True:
print "Sorry, your password does not meet our criteria."
else:
print "Congratulations, your password meets our criteria."
x = raw_input("Please set your password:")
check_password(x)
只需添加一个bool即可设置密码是否错误,这样您就无需进行任何奇怪的嵌套逻辑,也不会使代码过于复杂。
但是,有一些更优雅的方法可以解决这个问题。如果你想看到其中一些,请告诉我。但就功能而言,上述代码应该可以满足您的需求。
这是一种基于Alexander's答案处理错误的更实用的方法。
def check_password(password):
# by adding an array of error messages it enables you to pass all of the errors to other functions that can handle
# everything an independent way.
errors = []
if not has_unique_letters(password):
errors.append("Warning! Please ensure letters are not repeated.")
if not has_even_vowels(password):
errors.append("Warning! Please ensure password contains an even number of vowels.")
if not has_special_character(password):
errors.append("Warning! Please ensure password contains at least one of {@, #, *, $}")
if not has_divisible_numbers(password):
errors.append("Warning! Please ensure all numbers are divisible by 2 or 3.")
return errors
def handle_password_errors(errors):
# A function that can handle all of the password errors. This can print the errors or set flags in a GUI or any
# number of other things with out having to change any of the other functions.
if errors:
print "Sorry, your password does not meet our criteria."
for e in errors:
print(e)
else:
print "Congratulations, your password meets our criteria."
password = raw_input("Please set your password:")
check_password(password)
这是我首选的方法。现在的问题是如何将PASSWORD_ERRORS列表传递给需要它的函数?如果这些方法都在类中,我喜欢使const成为 init 的一部分,或者只是在类的顶部(类的内部)声明。
# Using a dictionary like this to store all of the possible password errors makes it easier if you want to change a
# specific error message in the future. It also enables you to add more associations to your errors. For example you
# can add a error flag to pass to a UI or function call.
PASSWORD_ERRORS = {
'unique_letter_error': {
'text': "Warning! Please ensure letters are not repeated.",
},
'even_vowels_error': {
'text': "Warning! Please ensure password contains an even number of vowels.",
},
'special_character_error': {
'text': "Warning! Please ensure password contains at least one of {@, #, *, $}",
},
'divisible_numbers_error': {
'text': "Warning! Please ensure all numbers are divisible by 2 or 3."
}
}
def check_password(password):
# by adding an array of error messages it enables you to pass all of the errors to other functions that can handle
# everything an independent way.
errors = []
if not has_unique_letters(password):
errors.append(PASSWORD_ERRORS['unique_letter_error'])
if not has_even_vowels(password):
errors.append(PASSWORD_ERRORS['even_vowels_error'])
if not has_special_character(password):
errors.append(PASSWORD_ERRORS['special_character_error'])
if not has_divisible_numbers(password):
errors.append(PASSWORD_ERRORS['divisible_numbers_error'])
return errors
def handle_password_errors(errors):
# A function that can handle all of the password errors. This can print the errors or set flags in a GUI or any
# number of other things with out having to change any of the other functions.
if errors:
print "Sorry, your password does not meet our criteria."
for e in errors:
# Here you can print the text or if the PASSWORD_ERRORS has more attributes you can handle the
# errors in different ways.
print(e['text'])
else:
print "Congratulations, your password meets our criteria."
password = raw_input("Please set your password:")
check_password(password)
答案 2 :(得分:1)
我实际上更喜欢过度设计这一点。请尝试以下方法:
class BadPasswordError(ValueError):
pass
def check_password(p:str, *validators:'(lambda p: True, "Error message")') -> bool:
for validator, err in validators:
if not validator(p):
raise BadPasswordError(err)
return True
这使您可以编写任意数量的自定义验证器并一次性传递它们。
password_validators = [(has_unique_letters, "Warning! Please ensure letters are not repeated."),
(has_even_vowels, "Warning! Please ensure password contains an even number of vowels."),
(has_special_characters, "Warning! Please ensure password contains at last one of {@, #, *, $}."),
(has_divisible_numbers, "Warning! Please ensure all numbers are divisible by 2 or 3.")]
try:
ok = check_password(user_inputted_password, password_validators)
except BadPasswordError as e:
print(e)
您甚至可以创建自定义装饰器来就地创建密码验证器。
import functools
def password_validator(errmsg):
def wrapper(f):
@functools.wraps(f)
def wrapped(*args):
if f(*args):
return True
else:
raise BadPasswordError(errmsg)
return wrapped
return wrapper
@password_validator("Warning! Please ensure letters are not repeated.")
def has_unique_letters(p):
return len(set(p)) == len(p)
# repeat for each validator....
然后你要做的就是依次运行每个验证器并捕获BadPasswordError
。
validators = [has_unique_letters, has_even_vowels, has_special_characters, has_divisible_numbers]
for validator in validators:
try:
validator(p)
except BadPasswordError as e:
print(e)
答案 3 :(得分:1)
也许你可以这样试试;在此代码中,您将看到警告消息,直到您修复密码,但对于前者,如果有2个错误,那么第一条错误消息将来自顶部(来自if-elif博客),然后每当您修复顶部时错误,您将收到第二条错误消息,该消息低于第一个错误并且您也会修复它,同时将它们逐一修复,您最后会收到恭喜消息。
def check_password(x):
problem = 0
if has_unique_letters(x)==False:
problem = 1
elif has_even_vowels(x)==False:
problem = 2
elif has_special_character(x)==False:
problem = 3
elif has_divisible_numbers(x)==False:
problem = 4
if(problem == 1):
print "Warning! Please ensure letters are not repeated."
elif(problem ==2):
print "Warning! Please ensure password contains an even number of vowels."
elif(problem==3):
print "Warning! Please ensure password contains at least one of {@, #, *, $}"
elif(problem==4):
print "Warning! Please ensure all numbers are divisible by 2 or 3."
elif(problem==0):
print "Congratulations, your password meets our criteria."