密码生成器不打印任何值,即使它应该打印创建的密码



当我通过测试以下代码时

PWD = create_password(4, 5, 8, 10, 72, True)
show_created_password(PWD)

没有打印任何值。一开始我使用yield,但问题发生后,我尝试了return,但问题仍然存在。如何解决此问题?

原始代码:

"""
Generator Module for Password Manager
"""
# Imports
from passwordmeter import test
from random import choice, randint
import string_utils
# Generator
words = open('words.txt', 'r').read().split('n')
special_chars = ['!', '?', '%', '$', '*', '(', ')', '&', '@', '#', '^', '+', '=', '-', '_', '"', ';', ':', '<', '>', '/', '\']
uppercase_letters = ['A','B','C','D','E','F','G','H','I','J','K','L''M','N', 'O', 'P','Q','R','S','T','U','V','W','X','Y','Z']
def create_password(num_words, num_numbers, num_special, num_uppercase_words, char_limit = 0, Strengthen = False):
    """
    Generates Pasword from words, Uppercase letters, special chars, and numbers with the options of:
    :param num_words: Number of Words in password.
    :param num_numbers: Number of numbers in password.
    :param num_special: Number of Special Characters in password.
    :param num_uppercase_words: Number of uppercase words in password.
    :param char_limit: Limit of characters in password.
    :param Strengthen: Strengthens the password.
    """
    #TODO Connect the arguments with wx for user customization.
    pass_str = ' '
    if char_limit > 0:
        while True:
            if len(pass_str) == char_limit:
                if Strengthen == True:
                    pass_str = string_utils.shuffle(pass_str)
                    pass_str = pass_str.replace(" ", "")
                    yield pass_str
                else:
                    yield pass_str
                break
            else:
                for _ in range(num_words):
                    pass_str+=choice(words).lower().capitalize()
                for _ in range(num_numbers):
                    pass_str==str(randint(0,100))
                for _ in range(num_special):
                    pass_str+=choice(special_chars)
                for _ in range(num_uppercase_words):
                    pass_str+=choice(uppercase_letters)
    else:
        for _ in range(num_words):
            pass_str+=choice(words).lower().capitalize()
        for _ in range(num_numbers):
            pass_str+=str(randint(0,100))
        for _ in range(num_special):
            pass_str+=choice(special_chars)
        for _ in range(num_uppercase_words):
            pass_str+=choice(uppercase_letters)
        if Strengthen == True:
            pass_str = string_utils.shuffle(pass_str)
            pass_str = pass_str.replace(" ", "")
            yield pass_str
        else:
            yield pass_str
         
def show_created_password(created_password):
    """
    Shows password generated by generator
    """
    for value in created_password:
        pass_str = value
    strength,_=test(pass_str)
    #TODO make print statements into wx form in the mainapp.py file or through a different wx method
    print('nPassword: %s'%pass_str)
    print('Strength: %0.5f'%strength)

首先,忘记yield,使用returnyield用于生成一种特殊类型的函数,该函数可以运行多次,并在几个步骤中给出输出。例如,我可以用yield实现一个primes函数,这样每次调用它时,它都会给我下一个素数:

def primes():
    for n in (1, 2, 3, 5, 7, 11, 13, 17, 19):  # Instead of this you would actually compute the numbers
        yield n
prime_numbers = primes()
next(prime_numbers)  # 1
next(prime_numbers)  # 2
next(prime_numbers)  # 3
next(prime_numbers)  # 5
next(prime_numbers)  # 7

问题是while True循环永远不会结束。结束该循环的唯一方法是使用break,并且只有当过程的长度和字符限制完全相等时才会执行该代码,这很可能不会发生,因为每次迭代都要添加大量字符。假设您每次迭代添加50个字符,并且您的限制是75。第一次迭代条件为False(长度为0,限制为75(,因此我们添加了50个字符。第二次迭代条件为False(长度50,限制75(,因此我们再添加50个字符。第三次迭代为False(长度为100,限制为75(,因此我们再添加50个字符。您将永远迭代,并且限制永远不会与长度相同,长度将不断增长,直到您耗尽内存。

show_password也有一个错误。当您传递创建的密码时,您传递的是一个字符串。所以你需要去掉循环。我想你有这个循环是因为你错误地使用了yield

def create_password(num_words, num_numbers, num_special, num_uppercase_words, char_limit = 0, strengthen = False):
    """
    Generates password from words, uppercase letters, special chars, and numbers with the following options:
    :param num_words: number of words in password
    :param num_numbers: number of numbers in password
    :param num_special: number of special characters in password
    :param num_uppercase_words: number of uppercase words in password
    :param char_limit: limit of characters in password
    :param strengthen: strengthens the password
    """
    # TODO: Connect the arguments with wx for user customization.
    pass_str = ''.join(
        [choice(words).lower().capitalize() for _ in range(num_words)] + 
        [str(randint(0,100)) for _ in range(num_numbers)] + 
        [choice(special_chars) for _ in range(num_special)] + 
        [choice(uppercase_letters) for _ in range(num_uppercase_words)]
    )
    if strengthen:
        pass_str = string_utils.shuffle(pass_str)
        pass_str = pass_str.replace(' ', '')
    if char_limit > 0:
        pass_str = pass_str[:char_limit]
    return pass_str

def show_created_password(pass_str):
    """
    Shows password generated by generator
    """
    strength, _ = test(pass_str)
    #TODO make print statements into wx form in the mainapp.py file or through a different wx method
    print("Password: {:s}".format(pass_str))
    print("Strength: {:0.5f}".format(strength))
    print()

首先,如果是字符限制,则不需要任何循环,如果长度最小,则需要一个循环,但字符限制只需要确保在长度过长的情况下在末尾进行剪切。

Strengthen不应该用作变量、参数或函数名,标题大小写名称是为类名保留的,我将其更改为stregthen。我将添加到密码中的所有循环更改为[SOMETHING for _ in range(SOMENUMBER)]形式的列表理解。这将创建一个包含该数量元素的列表。然后,我添加了所有列表,将它们合并到一个列表中,然后用空字符串""将其连接起来。基本上,这会将列表中的所有项目连接到一个字符串中。一旦我们有了绳子,我们会检查是否需要加强它,然后我们会检查我们是否超过了极限来减少它。之后,我们可以返回密码。

另一种方法基本相同,删除了循环,但我使用了"Hello {}".format("world!")方式,我建议您使用它来代替"Hello %s"%"world!"

最新更新