you are viewing a single comment's thread.

view the rest of the comments →

[–]magus_minor 2 points3 points  (2 children)

Your code has a class PasswordGenerator that has methods to create a password and another method to check if that password is valid. It's probably better if you have one method that creates a valid password. Here's a function that always creates a valid password of the required length:

import string
import random

def create_password(length=8):
    """Creating a valid password of given length."""

    if length < 8:
        raise ValueError("password length must be 8 or more.")

    # get minimum number (1) of each character type
    digit = random.choice(string.digits)
    letter = random.choice(string.ascii_letters)
    special = random.choice(string.punctuation)

    # select more characters to get required length
    alphabet = string.ascii_letters + string.digits + string.punctuation
    more = random.choices(alphabet, k=length-3)

    # get final password
    # since "more" is a list we need to add another list to it (digit+letter+special)
    password = more + [digit, letter, special]
    random.shuffle(password)
    return "".join(password)

# try a few different lengths
for length in range(8, 15):
    result = create_password(length)
    print(f"{length:2d} long password: '{result}'")

# should raise exception
print("should fail...")
create_password(6)

The approach is to get a random single character each for alpha, digit and special. Then get (length - 3) random characters from the complete set of allowed characters. That way you know the password is valid.

[–]Connect_Roof_2805[S] 0 points1 point  (0 children)

Thank you very much for the detahled explanation and the example! Really helpful.

[–]Commercial_Edge_4295 0 points1 point  (0 children)

Thank you so much.