3
\$\begingroup\$

This is my second program written in python. It basically creates a password made up of numbers, capital and lower case letters with the option to include special characters and dashes. I created a simpler project and I decided to build upon it to create version 2. Since I am still new, I would like to receive advice and any thoughts on how to improve my code as well as a programmer. Such as how random this password is, any syntax errors, or any ways to simplify my code. I commented as best as I could. Any thoughts would be appreciated.

#version 2 introduces option to include special characters and 
the option for the password to be separated into
#sections by a dash as well as a more secure and better created 
password which has no certain pattern to it
#as the previous version did

#loop goes through steps until user decides to quit
# 1. ask for user input if special characters can be added and set 
     to var response
# 2. come up with random number between 1 and 3, set = to var 
     typevalue if special is no
#    come up with random number between 1 and 4, set = to var 
     typevalue if special is yes
# 3. assign randint between 0 and 25 to lowercase and uppercase 
     var, assign randint between 0-9 to number var,
#    assign randint between 0-9 to character var
# 4. if type=0 number value is added to objects list
#    if type=1 upper[uppercase] is added to objects list
#    if type=2 lower[lowercase] is added to objects list
#    if response is yes and only yes, characters[character] is 
     added to objects list

from random import randint

upper = 
["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"]
lower = ["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"]
characters = ["!","@","#","$","%","^","&","*","_","+"]

objects = []


def RunFun(a,b):
    typevalue = randint(a, b)
    lowercase = randint(0, 25)
    uppercase = randint(0, 25)
    number = randint(0, 9)
    character = randint(0, 9)
    if typevalue == 1:
        objects.append(upper[uppercase])
    elif typevalue == 2:
        objects.append(number)
    elif typevalue == 3:
        objects.append(lower[lowercase])
    elif typevalue == 4:
        objects.append(characters[character])

def RunType2(c,d):
    first = c
    second = d
    for i in range(16):
        RunFun(first, second)
    Function1()


def Function1():
    dashes = raw_input("Would you like it to be seperated into" 
    four sections of four characters divided by a dash? 
    Y for yes N for no: ")
    if dashes == "Y" or dashes == "y":
        #print "dashes %s" % (objects)
        print "%s%s%s%s-%s%s%s%s-%s%s%s%s-%s%s%s%s" % (
            objects[0], objects[1], objects[2], objects[3],
            objects[4], objects[5], objects[6], objects[7],
            objects[8], objects[9], objects[10], objects[11],
            objects[12], objects[13], objects[14], objects[15])
    else:
        #print "no dashes %s" % (objects)
        print "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s" % (
            objects[0], objects[1], objects[2], objects[3],
            objects[4], objects[5], objects[6], objects[7],
            objects[8], objects[9], objects[10], objects[11],
            objects[12], objects[13], objects[14], objects[15])


#-------------foundation-----------
while True:
    #requests user input which determines if special characters 
    #are included
    answer = raw_input("Can it have special characters? Y for yes 
    N for no. X to exit: ")

    if answer == "Y" or answer == "y":
        RunType2(1,4) #hands over value 1 and 4 to include 
                      #characters in the creation
    elif answer == "N" or answer == "n":
        RunType2(1,3) #hands over values 1 and 3, opts out 4 
                      #which is special characters
    elif answer == "x" or answer == "X":
        exit()
    else:
        print "Invalid Input."
            del objects[:]
\$\endgroup\$
3
\$\begingroup\$
  • At the top of the module use triple quotes to document things instead of using comments. At the top level it will also act as a docstring for your module.
  • Use random.choice on the iterable instead of getting a random int first and then using it get an from iterable.
  • if answer == "Y" or answer == "y" etc can be replaced with if answer.lower() == "y".
  • Use better variables names, for example a and b in FunRun(a, b) doesn't make any sense.
  • Use new style string formatting instead of the old sprintf based syntax. Or better join str.join in your case if you want to merge bunch of items.
  • Your code has too many PEP 8 issues as per PEP8 online tool. You should check PEP 8 and use extensions like flake8, pylint etc to catch those.
\$\endgroup\$
2
\$\begingroup\$

I use Python 3, so I am unsure if all of these suggestions apply to Python 2.

String module

You can use the string module instead of manually typing a, b, c / A, B, C / 1, 2, 3 etc.

Naming

Your function RunFun() should have a more descriptive name. As it is, looking at your code, I wouldn't understand what the name had to do with the actual code. Maybe select_values. This goes for your other functions too: RunType2() and especially Function1() are really bad names.

"".join()

You can make use of "".join() in Function1(), to clean up the code.

Answer in []

Instead of if answer == "y" or answer == "Y":, use if answer in ["y", "Y"]:. This is much more clean-

Comments

Some of your comments are, frankly, useless: #requests user input which determines if special characters #are included, answer = raw_input("Can it have special characters? Y for yes N for no. X to exit: ").

Decoration

Get rid of this:

#-------------foundation-----------

PEP-8

Follow PEP-8:

  • Functions should use lowercase_with_underscores capitalization;
  • Comments should ideally be on a new line, and should start with a single space and a capitalized letter, for readability;
  • You should consistently leave two newlines in between functions;
  • You should split sections of code with a single newline for readability.

Security

You are using the random module, which is not fit for security purposes:

Warning The pseudo-random generators of this module should not be used for security purposes. Use os.urandom() or SystemRandom if you require a cryptographically secure pseudo-random number generator.

While Python 3.6 offers a secrets module, I am unsure about Python 2.x. Please, however, don't make the mistake of using random for generating passwords.

Right now, it seems that your password generator is quite weak. The password entropy remains low, which means you must resort to using os.urandom() and asking the user to provide enough entropy.

\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.