3
\$\begingroup\$

My code works fine but I definitely have unecessary repeat code. I'd like to use functions so I don't have repeat code. I would appreciate any advise on how to make my password generator code more concise.

I've tried looking through other forums but I couldn't find the answer I'm looking for.

import string
import random
lowerCase = string.ascii_lowercase[:26]
upperCase = string.ascii_uppercase[:26]
numberList = ["1","2","3","4","5","6","7","8","9"]
specialCharacters = ["*","&","@","!"]
responseList = ["weak","medium","strong"]
randomCharacters =[ ]
i=0

while True:
  choice = input("Want to create a password? To make your choice for your password strength, please respond with one of the following: weak/medium/strong. ")

  if choice in responseList:
    if choice == "weak":
      while i<=5:
        randomLetterLower = random.choice(lowerCase)
        randomCharacters.append(randomLetterLower)
        i += 1

    elif choice == "medium":
      while i<=4:
        randomLetterLower = random.choice(lowerCase)
        randomCharacters.append(randomLetterLower)
        randomLetterUpper = random.choice(upperCase)
        randomCharacters.append(randomLetterUpper)
        i += 1

    elif choice == "strong":
      while i<=1:
        randomLetterLower = random.choice(lowerCase)
        randomCharacters.append(randomLetterLower)
        randomLetterUpper = random.choice(upperCase)
        randomCharacters.append(randomLetterUpper)
        randomNumber = random.choice(numberList)
        randomCharacters.append(randomNumber)
        randomSpecialCharacter = random.choice(specialCharacters)
        randomCharacters.append(randomSpecialCharacter)
        i += 1

    output = " ".join(randomCharacters)
    print(output)
    i = 0
    randomCharacters =[]

  else:
    break
\$\endgroup\$

migrated from stackoverflow.com Jul 11 at 0:25

This question came from our site for professional and enthusiast programmers.

  • \$\begingroup\$ I'll write this up as an answer later, but if you are using Python 3.6 or newer for this, you should be using the secrets module for cryptographically secure random character selection; random was not designed for cryptographically secure random generation. \$\endgroup\$ – Thomas Ward Aug 10 at 18:45
3
\$\begingroup\$

A flexible and manageable approach would be to create a custom PasswordGenerator which will comprise all functionality for particular password levels. Putting it a separate module, thus it can be imported and used in any place of an application on demand.

The one of possible implementations (considering your conditions):

password_generator.py :

import string
import random


class PasswordGenerator:

    LOWERCASE = string.ascii_lowercase[:26]
    UPPERCASE = string.ascii_uppercase[:26]
    NUMBERS = ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
    SPECIAL_CHARS = ["*", "&", "@", "!"]
    LEVELS = ("weak", "medium", "strong")   # password levels

    @staticmethod
    def _compose_passphrase(iter_num, char_types):
        return ''.join(random.choice(c_type) for i in range(iter_num)
                       for c_type in char_types)

    @classmethod
    def weak(cls):
        iter_num = 6    # number of iterations
        char_types = (cls.LOWERCASE,)
        return cls._compose_passphrase(iter_num, char_types)

    @classmethod
    def medium(cls):
        iter_num = 5
        char_types = (cls.LOWERCASE, cls.UPPERCASE)
        return cls._compose_passphrase(iter_num, char_types)

    @classmethod
    def strong(cls):
        iter_num = 2
        char_types = (cls.LOWERCASE, cls.UPPERCASE, cls.NUMBERS, cls.SPECIAL_CHARS)
        return cls._compose_passphrase(iter_num, char_types)

Client script prompt_password.py :

from password_generator import PasswordGenerator

while True:
    choice = input("Want to create a password? To make your choice for your password strength, "
                   "please respond with one of the following: weak/medium/strong ")

    if choice in PasswordGenerator.LEVELS:
        print(getattr(PasswordGenerator, choice)())   # calling a respective method (password level)
    else:
        break

Running prompt_password.py:

Want to create a password? To make your choice for your password strength, please respond with one of the following: weak/medium/strong weak
ylwwcj
Want to create a password? To make your choice for your password strength, please respond with one of the following: weak/medium/strong weak
kktnkx
Want to create a password? To make your choice for your password strength, please respond with one of the following: weak/medium/strong medium
jLiAoWaHbA
Want to create a password? To make your choice for your password strength, please respond with one of the following: weak/medium/strong strong
qG8@sM7*
Want to create a password? To make your choice for your password strength, please respond with one of the following: weak/medium/strong strong
tY8&eL7@
Want to create a password? To make your choice for your password strength, please respond with one of the following: weak/medium/strong best


Process finished with exit code 0
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy