为什么 Python 在没有满足所有条件的情况下退出 while 循环?

时间:2021-03-12 00:48:21

标签: python

我正在为作业编写密码检查器。以下是要求:

[a-z] 之间至少有 2 个字母,[A-Z] 之间至少有 1 个字母。 [0-9] 之间至少有 1 个数字。 [?$#@] 中的至少 1 个字符。最小长度为 10 个字符。最大长度 14 个字符。此外,如果密码无效,程序应不断请求新密码,除非它验证成功。

出于某种奇怪的原因,我的代码忽略了 while 循环条件并在完成 for 循环后跳出它。我做错了什么,我该如何解决?任何帮助表示赞赏!

import string

#password
password = input("Enter a password that has at least two lower case letter, one upper case letter, one number between one and nine, and one of the following characters: '?$#@.'")


#requirements
ll = list(string.ascii_lowercase)
ul = list(string.ascii_uppercase)
nums = ["1","2","3","4","5","6","7","8","9"]
char = ["?","$","#","@"]

#counters
llcounter = 0
ulcounter = 0
numscounter = 0
charcounter = 0

while llcounter < 2 or ulcounter < 1 or numscounter < 1 or charcounter < 1:    
    if len(password) > 10 and len(password) < 14:
        for x in password:
            if x in ll:
                llcounter += 1
            elif x in ul:
                ulcounter += 1
            elif x in nums:
                numscounter += 1
            elif x in char:
                charcounter += 1
    else:
        password = input("Your password has not met the requirements, please try another one.")

4 个答案:

答案 0 :(得分:0)

那是因为您的嵌套循环逻辑有缺陷。它将不断迭代 for 循环,从不检查 while 循环条件。您希望在外部进行 for 循环迭代并在满足 while 条件时在外部中断

for ...:
    while ...:
      ...
    break 

 

答案 1 :(得分:0)

password = input( ... first prompt ... )
while True:
    set all counters = 0
    for x in password:
        if x in ll:
           ...etc, just like above...
    if llcounter >= 2 and ulcounter and numscounter and charcounter:
        break
    password = input ( ... second prompt ... )

答案 2 :(得分:0)

您需要查找 Validate input。你有交错的逻辑步骤。基本结构是:

valid_pwd = False
while not valid_pwd:
    password = input("Enter a password ...")
    # Make *one* pass to validate the password.
    #   Count each type of character;
    ...
    #   Also check the length
    length_valid = 10 < len(password) < 14
    chars_valid = (
        ll_count >= 2 and
        lu_count >= 1 and 
        ...
    )
    valid = length_valid and chars_valid
    if not valid:
        print("Invalid password")

这能让你坚持下去吗?

答案 3 :(得分:0)

在使用 Python 进行编码时,您应该始终尝试找到最Pythonic 的方式来实现您的想法,即充分利用该语言的潜力来编写简洁、清晰和实用的代码。

在您的情况下,您在多个地方有冗余代码,尤其是带有这么多计数器的 while 循环非常令人困惑。

此外,为了保持用户的活动输入会话,您应该将提示放在 while 循环中,否则第一次(也是唯一一次)输入的密码将始终相同,使循环本身变得毫无意义.

例如,您可以通过以下方式实施此密码检查。我对代码进行了评论,试图解释它实际在做什么。

import string

ll = list(string.ascii_lowercase)
ul = list(string.ascii_uppercase)
nums = list(string.digits)[1:] # List of digits except 0
sc = ["?","$","#","@"]



# while True meaning keep prompting forever until password requisites are satisfied. 
# This can be changed with a counter to exit the loop after a certain number of attempts. 
while True: 
    password = input("Enter a password that has blablabla...") # Prompt the user at every iteration of the loop.

    # The following if block merges all your conditions in the same place avoiding hyper-nested 
    # conditions that are always confusing and kind of ugly. 
    # The conditions are based on list comprehension 
    # (see py docs, since its a super cool feature that is the ultimate tool for conciseness).
    if (len([char for char in password if char in ll]) >=2 and
        [char for char in password if char in ul] != [] and
        [char for char in password if char in nums] != [] and
        [char for char in password if char in sc] != []):
        print(f" Your new password is: {password}")
        break # break interrupts the endless loop as soon as a valid password is entered
    else:
        print("Your password has not met the requirements, please try another one.")