Project 4
Password Checker
The Project
In a previous project, we wrote a password generator. Our generator created random passwords that met the PPS standard, which is: passwords should be at least 8 characters long, and they should include at least 3 of these 4 categories: number, uppercase letter, lowercase letter, symbol. One extra rule that we’re adding in this project is that passwords should NOT contain your PPS username or student ID number.
In this project, we’ll be writing a program that lets the user type in a password to see whether it’s good or not. If the password is good, the program will print out GOOD
; otherwise, the program will print out BAD
.
Your program will look something like this:
Enter your username (e.g. jrheard): jrheard
Enter your student ID (e.g. 123456): 123456
Enter the password you'd like to have checked: CarlsjRHeard!
BAD
Enter your username (e.g. jrheard): jrheard
Enter your student ID (e.g. 123456): 123456
Enter the password you'd like to have checked: jioafe#@ox.P
GOOD
The last line of your output MUST be GOOD
or BAD
.
Getting Started
Download this project’s starter code and open it in IDLE.
The starter code has two functions:
is_password_good(password, username, student_id)
-
main()
Requirements
Good passwords should be at least 8 characters long, include at least 3 of these 4 categories: number, uppercase letter, lowercase letter, symbol, and NOT contain the username or ID. If a password doesn't meet any of those requirements, it is a bad password.
For this project, a “symbol” is one of these: !@#$%^&*()-_=+,.
All your code should be contained in the 2 given functions. Each function has its own requirements.
Your password-checking code will go in the is_password_good(password, username, student_id)
function.
This function should:
- take arguments of a password like
'my_bad-password'
, a username like'jrheard'
, and a student ID number like'123456'
- return
True
if the password meets ALL the PPS password requirements listed above - return
False
if it does not meet all the requirements
Remember that False
isn’t the same thing as 'False'
. The Boolean values True
and False
don’t have quote marks around them.
The rest of your code, like user input and print statements, will go in main()
.
This function is called for you at the bottom of the starter code, so it will run every time you run your code.
In this function, you should:
- ask the user for their username
- ask the user for their student ID
- ask the user for a password to check
- call the
is_password_good
function with appropriate inputs - print
GOOD
if the password passed all the tests, and printBAD
if not - the last line of your output must be
GOOD
orBAD
Useful Code Snippets
These code snippets are hints. They solve problems that are really similar to, but not quite the same as the problems you’ll be solving in this assignment. You will need to think about these snippets and make changes to them or rewrite them entirely from scratch. Don’t just copy-paste them into your program and expect them to work.
Looping over each letter in a string
You will definitely be looping over each letter of the password and doing something based on the letters you see.
Here’s how to loop over each letter of a string and do something with each letter:
word = "Pizza"
for letter in word: # Loop over each letter of the string....
print(letter) # ...and *do something* with that letter. (You probably won't be printing it.)
Output:
P
i
z
z
a
Checking whether one string is in another string
You can check to see if one string is in another string using Python’s in
operator, like this:
# `in` works for single letters...
print('z' in 'Pizza') # Output: True
print('f' in 'Pizza') # Output: False
# ...and also for longer strings.
print('llo' in 'Hello') # Output: True
print('potatoes' in 'Hello') # Output: False
Notice that you get a result of True
or False
, so you could use this code as a condition in an if
statement if you wanted to.
How might you use this technique to see if, for example, a letter is an uppercase letter or a symbol?
In order to check that a password meets the PPS criteria, you’ll want to loop over each character of the password and write some code that keeps track of whether the password has any lowercase letters, uppercase letters, symbols, or numbers.
Here’s a bit of code that checks to see how many 'z'
s there are in a particular string:
word = "Pizza"
count = 0
for letter in word:
if letter == 'z': # You could check whether the letter is a symbol, number, etc here
count += 1
print(count)
Output:
2
Remember, though, that we don’t care about how many uppercase letters are in a password; we just care about whether or not there are any. Here's another way to think about this.
word = "Pizza"
contains_zs = False
for letter in word:
if letter == 'z': # You could check whether the letter is a symbol, number, etc here
contains_zs == True
if contains_zs: # Remember, this is just an example...
print("This word has at least one z." # ...your if statement would do something different
else:
print("This word has NO z's."
Output:
This word has at least one z.
Checking for username & ID
We added a rule that the username and ID number are not allowed in the password, so if my username is jrheard
and my student ID is 123456
, then these are BAD passwords:
CarlsjRHeard!
Password123456
Here’s one slightly tricky thing about this part of the project: my username is "jrheard"
, and the password "CarlsjRHeard!"
is invalid, but Python thinks and are two different things because strings are case sensitive:
print("jrheard" == "jRHeard") # Output: False
Your password checker should be able to tell if a password contains your username, even if the password’s capitalization is different. One way to handle this problem is to call a string’s .lower()
or .upper()
method, like this:
print("jRHeard".lower()) # Output: jrheard
print("jRHeard".upper()) # Output: JRHEARD
You will definitely be using this technique in your program.
How might you use .lower()
or .upper()
to deal with the fact that string comparison in Python is case sensitive?
Debugging Tip
As you’re working on your program, you might find it useful to add some extra print()
calls that print out what programmers call “debug information” to help you understand what your program’s actually doing.
For instance:
Enter your username (e.g. jrheard): jrheard
Enter your student ID (e.g. 123456): 123456
Enter the password you'd like to have checked: CarlsjRHeard!
password length is 13
3 categories of character in password
student info contained in password: True
BAD
Enter your username (e.g. jrheard): jrheard
Enter your student ID (e.g. 123456): 123456
Enter the password you'd like to have checked: jiaoweijfoaw.329xA
password length is 18
4 categories of character in password
student info contained in password: False
GOOD
It’s OK to leave extra print()
calls in your code as long as the last line of your checker’s output says the word GOOD
or the word BAD
, with NOTHING ELSE on or after that line, like you see in the example above.
Submitting your project
Before submitting your project, review the rubric and make sure to test your program a bunch of times to make sure it works!
Try coming up with some passwords that you know should be marked GOOD
('r4J9uqpm'
) and some passwords that you know should be marked BAD
('a!A'
, 'a!AuSerNaMe'
) and put them into your program to make sure that it marks them correctly.
Your CODE should follow the style guidelines. The part about descriptive variable names is important! For instance:
n
is a bad variable name,username
is a good one.ns
is a bad variable name,number_of_symbols
is a good one.
On the first line of that file, write a comment with your name on it, like this:
# Tamara O'Malley
On Google Classroom, submit your program in a file called checker_your name.py
. For instance, I might submit a file called checker_Tamara.py
.
The projects in this class were created by JR Heard, a TEALS volunteer at Madison, 2017-2019. His version of this project lives at https://blog.jrheard.com/python/password-checker .
A note from JR: If you’d like to learn more about how I wrote these tests, here’s a talk I gave about this topic at the Portland Python meetup. It’s the best talk I’ve ever given, I’m really proud of it, consider watching it sometime!