I've made a few changes to your program. Firstly, I've changed it to use the modern print
function instead of the print
statement. The print
function is available in Python 2.6 and later. It's more powerful than the old print
statement, and IMHO it's a good idea to start using it in preparation for Python 3 (which doesn't have the print
statement).
To simplify reading & writing the username & password data we can use the standard csv
module. It's not strictly necessary for this simple task, but it means we don't have to worry about the messy details of parsing the name and password strings. Eg, if the strings contain spaces or quotes, the csv
will handle them correctly. Note that in Python 2 CSV files must be opened in binary mode, but in Python 3 they must be opened in text mode. This is rather annoying when you're trying to write code that runs correctly on both versions.
The easy way to look up a password given the username is to use a dictionary with the username as the key and the password as the value. This is much more efficient than scanning through a list row by row looking for a match.
Of course, in a real program we would never store passwords as plain text. That's extremely insecure! The usual procedure is to store a hashed version of the password, using a strong cryptographic hash function applied a very large number of times to make it a time-consuming operation. For further info please see PBKDF2, scrypt, and bcrypt.
Also, it's bad practice to let a potential attacker know that a username is valid but that the password they submitted is invalid. That allows them to easily build a list of valid usernames. Instead, you should always ask for the password, even if the username is invalid.
from __future__ import print_function
import csv
users = [
['Alice', 'aardvark'],
['Bob', 'bobcat'],
['Steve', 'swordfish'],
]
# Save the users list to a CSV file
users_filename = "users.txt"
with open(users_filename, "wb") as f:
writer = csv.writer(f)
writer.writerows(users)
def login_function():
# Load the usernames & passwords into a dictionary
with open(users_filename, "rb") as f:
users = dict(csv.reader(f))
# Give the user 3 chances to login
for i in range(2, -1, -1):
user_entry = raw_input("Enter your username: ")
password_entry = raw_input("Enter your password: ")
if user_entry in users and password_entry == users[user_entry]:
print("Username and password are correct")
return True
else:
print("Username and password are invalid")
print(i, "login attempts remaining")
print("Login failed")
return False
print(login_function())
demo
Enter your username: Alan
Enter your password: runner
Username and password are invalid
2 login attempts remaining
Enter your username: Alice
Enter your password: aardvark
Username and password are correct
True