-1

我开始学习 Python 并开始尝试使用示例代码块。我编辑了几次,在最后一次编辑中,我添加了一个可选的随机密码生成器。然后我决定将密码生成器放在一个单独的文档中更有意义,所以我复制了必要的代码并制作了一个新文档。但是,在编辑后,我无法在密码中生成偶数位数。

巴斯宾

错误代码的副本(Pastebin)

import math
import random
alpha = ['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']
print('Would you like a random password suggestion generator', 'Yes or No')
permissionRandomGenerator = input().lower()
print('How long do you want your password?')
lengthRandomGenerator = int(input())
if permissionRandomGenerator == 'yes':
    def randInt():
        return math.floor(random.random()*10)
    def randChar():
        return alpha[math.floor(random.random()*27)]
    randPasswordList = []
    listInsert = 0
    def changeCase(f):
        g = round(random.random())
        if g == 0:
            return f.lower()
        elif g == 1:
            return f.upper()
    while listInsert < lengthRandomGenerator:
        randPasswordList.insert(listInsert, randInt())
        listInsert = listInsert + 1
        if listInsert >= lengthRandomGenerator:
            break
        randPasswordList.insert(listInsert, randChar())
        randPasswordList[listInsert] = changeCase(randPasswordList[listInsert])
        listInsert = listInsert + 1
        continue
    listInsert = 0
    printList = 0
    if lengthRandomGenerator <= 0:
        print('It has to be longer than that')
    elif lengthRandomGenerator >= 25:
        print('I can\'t generate a password that long')
    elif math.isnan(lengthRandomGenerator):
        print('error: not valid data type')
    else:
        while printList < (len(randPasswordList)-1):
            printItem = randPasswordList[printList]
            print(printItem)
            printList = printList + 1
    printList = 0
    randPasswordList = []
elif permissionRandomGenerator == 'no':
    print('Too bad...')
else:
    print('You had to answer Yes or No')
4

3 回答 3

2

我稍微重构了你的程序,去掉了很多不必要的步骤和不一致的地方。这里是完整的,然后我将解释每个部分:

import random
import string
import sys

possible_chars = string.ascii_letters + string.digits + string.punctuation

def nextchar(chars):
    return random.choice(chars)

yes_or_no = input("""
Would you like a random password suggestion generated?
Type Yes to continue: """).lower()

if yes_or_no == 'yes':
    try:
        pwd_len = int(input('How long do you want your password? '))
    except ValueError:
        sys.exit("You need to enter an integer. Please start the program over.")

    if 0 < pwd_len < 26:
        new_pwd = ""
        for _ in range(pwd_len):
            new_pwd += nextchar(possible_chars)
        print("Your new password is:\n" + new_pwd)

    else:
        print("I can only generate passwords between 1 and 25 characters long.")

else:
    print("Well then, why did you run me?")

Python 不仅仅是语法和内置函数,它还是标准库或标准库。您将一直使用 stdlib 的模块,所以当您认为自己会使用一个时,请阅读文档!您将了解该模块、它的预期用途、它的一些历史和变化(例如在哪个版本中添加了某个函数),以及其中包含的所有类、函数和属性。确保你阅读了整件事(没有一个是那个长)并尝试至少对每件事情的作用有一个基本的了解。这样,例如在这种情况下,您将能够为工作选择最佳功能。我在业余时间喜欢做的一件事就是随机选择一个模块并阅读文档,只是为了学习。它们通常写得很好,而且通常很有包容性。习惯于使用 Monty Python 参考资料,它们无处不在。

import random
import string
import sys

进口是第一位的,而且应该几乎总是只在顶部。我喜欢按字母顺序排列我的,stdlib 在最上面,然后是一个空行,然后是 3rd-party 模块,包括接下来的自写模块。在导入之后也放一两行空行。要记住的一件事,我在评论中提到:可读性很重要。代码不仅可以被机器阅读,也可以被人阅读。必要时发表评论。慷慨地使用空格(还要记住,空格在 Python 中在语法上也很重要,因此它会迫使您正确缩进)以分隔相关的代码、函数、类、块等。我强烈建议您阅读、重读并花时间思考PEP-8,Python 风格指南。它的建议不是绝对的,但许多执行编码标准的项目都依赖它。尝试尽可能多地遵循它。如果一行出现 83 个字符,不要担心,但要注意你在做什么。

我之所以在阅读文档中做出如此大的贡献是因为以下几行:

possible_chars = string.ascii_letters + string.digits + string.punctuation

def nextchar(chars):
    return random.choice(chars)

他们摆脱了大约一半的代码。string包含一堆用于处理字符串的预定义常量。我选择的三个应该都是很好的有效密码字符。如果您使用的系统不会使用标点符号,只需将其删除即可。请注意,这possible_chars是一个字符串 - 就像元组、列表和字典一样,字符串是可迭代的,因此您不需要为每个可能的字符单独制作一个列表。

接下来是函数 - 它替换了你的randInt(),randChar()changeCase()函数,以及一堆你的内联代码,说实话,这很奇怪。我喜欢你想出的决定一个字母是大写还是小写的方法,但是当你有和上面的常量时,剩下的太费力了。random.choice()string

yes_or_no = input("""
Would you like a random password suggestion generated?
Type Yes to continue: """).lower()

您可能没有意识到,但在获取用户之前您不需要print()描述字符串input()- 只需将字符串作为单个参数传递给input(),您将获得相同的效果。我还使用了三引号 """'''也可以使用)字符串文字,它与更常见的单'引号和双引号"字符串文字不同,其中包含的任何换行符或制表符都不需要转义。现在的结论是你可以写几行文本,当你写print()出来时,它会变成几行。

    try:
        pwd_len = int(input('How long do you want your password? '))
    except ValueError:
        sys.exit("You need to enter an integer. Please start the program over.")

try/except在下一部分使用了一个块。如果用户在输入提示符处输入一个非整数 up,则该int()函数将失败并显示ValueError. 我选择了最简单的处理方式:如果出现错误,打印一条消息并退出。您可以这样做,以便程序在出现错误时重新请求输入,但我认为这超出了本练习的范围。

    if 0 < pwd_len < 26:
        new_pwd = ""
        for _ in range(pwd_len):
            new_pwd += nextchar(possible_chars)
        print("Your new password is:\n" + new_pwd)

    else:
        print("I can only generate passwords between 1 and 25 characters long.")

这是所有动作发生的地方。使用一个if/else块,我们测试所需的密码长度,如果它在 1 到 25 之间(任意上限),我们生成密码。这是通过for循环和range()函数完成的(阅读文档以了解其工作原理)。你会注意到我在for循环中使用了一个常见的 Python 习惯用法:因为我实际上并不需要由 生成的数字range(),所以我通过使用下划线字符代替变量来“把它扔掉” 。_最后,该else语句处理备选方案 - 或者pwd_len是 0 或更小,或者是 26 或更大。

else:
    print("Well then, why did you run me?")

我们在节目的最后!这elseif yes_or_no == 'yes':语句配对 - 用户在输入提示符处输入了除 yes 以外的其他内容。

希望这将帮助您更多地了解 Python 的工作原理以及如何有效地使用它进行编程。如果您觉得自己花费了太多时间来实现您认为应该更容易的事情,那么您可能是对的。Python 的众多优势之一是它的“包含电池”理念——您可以使用 stdlib 做很多事情。

于 2016-05-04T20:56:32.660 回答
0

我做了一些小的编辑,我的代码现在似乎可以工作了。这是成品(我放注释以显示代码的作用,并标记编辑。):

import math
import random                                 #Import necessary modules
alpha = ['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']  #List with alphabet
print('Would you like a random password suggestion generator', 'Yes or No')  #Prints the question for permission
permissionRandomGenerator = input().lower()   #Stores the answer of the above question in lower case
if permissionRandomGenerator == 'yes':        #Generates a password if the answer of the first question is 'yes'
print('How long do you want your password?')  #Asks for length
lengthRandomGenerator = int(input())          #Stores length as an integer
    def randInt():                            #Creates a random integer
        return math.floor(random.random()*10)
    def randChar():                          #Selects a random string from the list with the alphabet
        return alpha[math.floor(random.random()*27) - 1]
    randPasswordList = []                    #Creates a list to store the password
    listInsert = 0                           #Creates a list index variable
    def changeCase(f):                       #Defines a function to randomly change the case of letters before adding them to the list randPasswordList
        g = round(random.random())
        if g == 0:
            return f.lower()
        elif g == 1:
            return f.upper()
    while listInsert < lengthRandomGenerator + 1:  #Creates a random password and inserts it into randPasswordList  (I added `+ 1` here)
        randPasswordList.insert(listInsert, randInt())
        listInsert = listInsert + 1
        if listInsert >= lengthRandomGenerator:
            break
        randPasswordList.insert(listInsert, randChar())
        randPasswordList[listInsert] = changeCase(randPasswordList[listInsert])    #Calls the changeCase function whenever it inserts a letter
        listInsert = listInsert + 1
        continue
    listInsert = 0
    printList = 0
    if lengthRandomGenerator <= 0:           #If the length it 0 or less (for example, negatives) the password will not generate (I need to fix this a little bit.  Currently the code attempts to create a password beforehand)
        print('It has to be longer than that')
    elif lengthRandomGenerator >= 25:
        print('I can\'t generate a password that long')
    elif math.isnan(lengthRandomGenerator):  #Currently this doesn't do anything, it needs to be moved farther forward
        print('error: not valid data type')
    else:
        while printList < (len(randPasswordList)-1):    #Prints the list item by item
            printItem = randPasswordList[printList]
            print(printItem)
            printList = printList + 1
    printList = 0                             #Resets the variables
    randPasswordList = []
elif permissionRandomGenerator == 'no':
    print('Too bad...')
else:
    print('You had to answer Yes or No')

注意:我编写这段代码纯粹是为了实验和更好地学习 Python 的基本方面。这段代码没有优化,也没有我可以(并且将)做的那样随机。

PS对不起,如果评论不完整,我还在学习这门语言。

于 2016-05-04T21:03:58.320 回答
0

我不知道你为什么为这个简单的问题做的过于复杂,你可以使用string对象提供的常量,我宁愿有以下程序来生成随机密码

import random, sys, string

def pgen(length=8):
    if length < 8:
        length = 8 
    keys = list(string.printable[:-6])
    random.shuffle(keys)
    return ''.join(keys)[:length]


if __name__ == '__main__':
    try:
        print( pgen(int(sys.argv[1])))
    except Exception as e:
        print("Provide length of password \n passwordgen.py <length_of_password>")

输出

magautam@nix1947:/tmp$ python passwordgen.py 12
HNLxi!{.qe=b

magautam@nix1947:/tmp$ python passwordgen.py 45
}w5u?+C=e[DfI.n'*1G(m{r0FH|UBKz/@kL>;Sh`tEW8-
于 2016-07-01T10:47:49.063 回答