题目要求:
定义一个函数,第一传参指的是密码的长度;如果第二个传参是True,生成的密码中至少含有一个数字;如果第三个传参是True,生成的密码中至少含有这些字符(!?=+-()#)中的一个。
我的代码虽然能够成功实现题目要求的功能,但是非常冗余,找不到缩减之法。让我们来与标准答案进行对比学习:
-
我的代码
import string from random import sample def generate_strong_password(length, num, characters): pool = string.ascii_lowercase if num: for number in range(0, 10): pool += str(number) if characters: char = "!?=+-()" pool += char # pool has all ascii_lowercase, puntuations and chars. while True: count_punc = 0 count_num = 0 pw = sample(pool,length) # 获得个数为length的随机取样字符,return as a list. line = "" for item in pw: if item in string.punctuation: count_punc += 1 # The number of punctuation recorded elif item.isdigit(): count_num +=1 # The number of numbers recorded if num == True and characters == True: if count_num >= 1 and count_punc >=1: # ensure at least one num and punctuation included for pwl in pw: line += pwl return line elif num == False and characters == False: for pwl in pw: line += pwl return line elif num == False and characters == True: if count_punc >= 1: # # ensure at least one punctuation included for pwl in pw: line += pwl return line else: if count_num>=1: # ensure at least one num included for pwl in pw: line += pwl return line if __name__ == "__main__": print(generate_strong_password(8, True, True)) -
标准答案
from random import choice, randint from string import ascii_lowercase, digits def generate_strong_password(length: int, numbers: bool, special_characters: bool): special_chars = "!?=+-()#" # One letter at beginning of the password passwd = choice(ascii_lowercase) choice_set = ascii_lowercase # If numbers is wanted, add at least one number if numbers: passwd = add_character(passwd, digits) # string的digits功能提供了0-9这10个数字 choice_set += digits # same for special characters if special_characters: passwd = add_character(passwd, special_chars) choice_set += special_chars # build the rest of the password from the whole set while (len(passwd) < length): passwd = add_character(passwd, choice_set) return passwd # Add a random character from the given set either # at the beginning or end of the string def add_character(passwd: str, characters): character = choice(characters) if randint(1,2) == 1: return character + passwd else: return passwd + character边看标准答案变思考,为什么答案这么写能够保证获得的密码是无序的呢?(特别是看到One letter at beginning of the password这一行时)
看到最后,明白了是add_character函数使之变得无序:两个字符排序时,只有前和后两种顺序,利用randint(1,2)保证了前后的任意性。
以下是用对表核准标准答案的简单具体分析。
反观我的代码,是先随机生成length长度的密码,再用if-else和while组合判断其中字母和符号的个数再输出。随机性只用到了sample。另外还有一个繁琐之处在于sample的使用使密码变成了一个数组,需要for循环生成字符串,又是一个浪费时间的点。
题源:Helsinki, programming, Part 7



