多次运行程序后的IndexError

时间:2016-09-11 14:34:25

标签: python

运行多次生成密码的程序后,我得到一个IndexError:list Index超出范围。我不确定是什么导致了这个问题

import string
import random

def random_pass(length):
    alphabet = list(string.ascii_letters + string.digits + string.punctuation)
    password = []
    upper_case = list(string.ascii_uppercase)
    count = 0
    while count < length:
            random_num = random.randint(0,len(alphabet))
            password.append(alphabet[random_num])
            #Checks to see if first character is a uppercase Letter
            if password[0] not in upper_case:
                first_letter = random.randint(0,len(upper_case))
                password[0] = upper_case[first_letter]
            count += 1
    return ''.join(password)
def welcome():
  print("*****************************************************************")
  print("*****************************************************************")


def main(): 
    try:
        get_length = int(input("Please enter the length of your password "))
    except ValueError:
        print("Please enter numbers only")
        main()
    else:
        print("Your {} character password is {}".format(get_length, random_pass(get_length)))
        restart = input("Do you wish to create another password? y/n")
        password = []
    if restart.lower() == 'y':
        main()
    else:
        exit()
main()

2 个答案:

答案 0 :(得分:2)

random.randint也可以生成 end 值;您需要使用random.randrange生成包含起始值的范围内的随机数,排除结尾。

答案 1 :(得分:0)

Antti Haapala回答了您的问题但我看到了一些可以在您的代码中得到改进的事情。我们的想法是让您的代码更清晰。

首先,这是我的代码版本:

import string
import random

alphabet = string.ascii_letters + string.digits + string.punctuation

def random_pass(length):
    first_character = random.choice(string.ascii_uppercase)
    password = ''.join(random.choice(alphabet) for x in range(length - 1))
    return first_character + password

another_password = True
while another_password:
    try:
        length_requested = int(input("Please enter the length of your password "))
    except ValueError:
        print("Please enter numbers only")
        another_password = True
    else:
        print("Your {} character password is {}".format(length_requested, random_pass(length_requested)))
        restart = input("Do you wish to create another password (Y/N)? ")
        another_password = restart.lower() == 'y'

我对你做的修改代码:

  • 由于永远不会修改alphabet,因此每次调用random_pass()时都无需重新创建alphabet。我把它放在了每个函数之外的全局范围内
  • 由于您可以像访问列表中的元素一样访问字符串中的字符,因此您无需创建内容为string.ascii_uppercasestring.ascii_uppercase的列表。
  • 您没有更多地理解定义具有相同内容alphabet
  • 的变量
  • 您可以直接选择random.choice(alphabet)
  • 的随机字符,而不是选择用于在string.ascii_uppercase中选择字符的随机数字。
  • 您似乎要求密码的第一个字符必须是大写字母。在你的代码中,你在每个新角色的while循环中检查这个,但是一旦你设置它,第一个角色就不会改变。所以我把它拖到了这个循环之外。
  • 要构建其余密码,我使用generator expressionlength - 1.join()字符串方法中选择随机字符。由于我已经选择了第一个字符,我只需要main()个随机字符。
  • 如果您所做的只是稍后调用,则无需定义main()
    • 即使你定义restart.lower() == 'y',也不是一个好主意,因为对于每个请求的新密码(以及每次用户输入无效输入时),递归调用它,你的代码必须创建一个新的小范围这个函数调用的环境,更重要的是,它必须保留所有以前的小范围环境。你最终可能会耗尽内存。我用了一个while循环。
  • another_password会给出一个我用来更改exit()的布尔值,该值控制我们是否继续询问用户是否需要新密码
  • 除非您想要将退出代码返回给环境,否则无需致电.GetValue(int)

如果您有更多问题,请随时提出。并继续尝试。