试图检查满足这些条件的字符串

时间:2017-10-02 04:34:15

标签: python if-statement

尝试使用以下代码检查字符串:

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,..."行未显示。

我知道我一定做错了但我怎么能解决这个问题呢? 谢谢!

4 个答案:

答案 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."