Password Trainer v1.0 - Helping you learn a new password There are two reasons why many people choose weak passwords over stronger, more complicated ones:


They don't know that their passwords are insecure
They don't want to change to a better password because they are generally more complicated and harder to remember


So, I came up with this program: a password trainer! It helps you learn a new password, which should hopefully make point no. 2 more appealing.

While I am not new to the Python language, this my first attempt at correct styling according to PEP 0008. I have been focousing on the correct use of docstrings and commenting.

Code:

"""
Password Trainer v1.0
Copyright (c) 2016 angussidney
Released under the MIT license

This program helps you remember long, complicated, (and most importantly) secure passwords.
"""

import os

PASSWORD = "password123" # Insert your password here 
MAXIMUM_TRIES = 3 # The maximum number of attempts before the program stops annoying the user.

def main():
    """Prompts the user for their password and provides feedback."""
    tries = 0
    while tries &lt; MAXIMUM_TRIES:
        password_attempt = raw_input("Please type your password: ")
        print
        if password_attempt == PASSWORD:
            print "You entered your password correctly."
            break # Skips directly to end of session
        else:
            print "Your attempt was incorrect.\n"
            print_differences(password_attempt)
            raw_input("\nPress any key to continue...")
            tries += 1
            clear_screen()
    print "\nPassword training is complete for this session."
    raw_input("Press any key to continue...")

def clear_screen():
    """Clears the screen for a new password attempt."""
    os.system("cls" if os.name=="nt" else "clear")

def print_differences(attempt):
    """Prints the differences between the password attempt and the real password.
    Raises an error if the attempt is of the wrong length.

    Keyword arguments:
    attempt -- the password attempt

    Example output:
    Correct password: password123

    Your attempt:     passwood124
    Errors:                 x   x
    Corrections:            r   3
    """
    if len(attempt) != len(PASSWORD):
        print "Your password attempt was of the wrong length."
        print "Your attempt should have been %s characters long." % str(len(PASSWORD))
        print "No password accuracy breakdown available."
    else:
        print "Correct password: %s\n" % PASSWORD
        print "Your attempt:     %s" % attempt
        print "Errors:           ",
        for letter in range(len(PASSWORD)):
            if attempt[letter] == PASSWORD[letter]:
                print "\b ", # \b backspace character must be used to remove automatically added space
            else:
                print "\bx",
        print
        print "Corrections:      ",
        for letter in range(len(PASSWORD)):
            if attempt[letter] == PASSWORD[letter]:
                print "\b ",
            else:
                print "\b%s" % PASSWORD[letter],
        print

if __name__ == "__main__":
    main()


Notes:


Currently, the program simply returns an error if the length of the password attempt is different to that of the actual password. This will be changed in v2.0.
The program only works when run in the console. It does not work in IDLE (because the clear screen function and the backspace characters won't work)


What needs reviewing:

I would be greatful if you could review the following items:


Is my code following the PEP 0008 standard? Especially the comments and docstrings?
Is there a better way to print the corrections and errors, without using backspace characters (\b)?
password_attempt = raw_input(...)



When dealing with passwords, you want to try and minimize the amount of information any bypasser can see on the screen.

Python offers the getpass module to ease such inputs:

import getpass

password_attempt = getpass.getpass(...)


As such, you should also avoid printing plain passwords and attempts.