I'm starting my first project (a password manager). What I have done so far is make it so the user can input whether they want to make a new password or look for a password. If they choose to enter a password, the account/purpose for the password and the actual password will be saved to a dictionary. For example, a purpose could be for "yahoo" and the password being "example". That dictionary is then written down in a text file. If the user decides to look for a password, all they would have to do is type in the account for the password. So far everything is working except for the fact that when I enter another password and account, it overwrites the pre-existing password and account instead of adding the new password to the dictionary.
import json
passwords = {
}
prompt = "If you want to make a new password, type 'Make password'."
prompt += "\nIf you want to look for a password, type 'Look for password'.\n"
answer = input(prompt)
def password_list(account_name, password_name):
passwords[account_name] = password_name
answer = answer.upper()
found = 0 # used to see whether account for password can be found
if answer == "MAKE PASSWORD":
account_name = input("What use is this password for? ")
account_name = account_name.upper()
password_name = input("What is the password? ")
password_list(account_name, password_name) # purpose and password saved to dict
with open("passwords.txt", 'w+') as f:
f.write(json.dumps(passwords))
print("Your password was saved!") # dictionary gets saved to text file
elif answer == "LOOK FOR PASSWORD":
with open("passwords.txt", "r") as f:
passwords = json.loads(f.read()) # text file gets opened to read
if not passwords: # if the list is empty...
print("Sorry but there are no passwords available. Make a new one!")
elif passwords: #if the list isn't empty...
search_account = input("What account is this password for? ")
search_account = search_account.upper()
for name in passwords.keys(): # list of accounts get searched
if search_account == name: #if an account is in the dictionary
print(f"The password is '{passwords.get(name)}'.")
found = 1
break
if found != 1:
print("Sorry, we can't find such name.")
Cool project.
It's because every time you start the script you force the password dic to be empty. So when you add a password, it's added to a new empty dic and than you overwrite the file with this empty dic + new_password.
When you code, think about the most likely outcome at every run: the file exists. IF it doesn't, than create it.
This is what I demonstrate here in the load_passwords() function.
As an extra, I propose to you a more Pythonic (and efficient) way to search through a dictionary's keys in O(1) rather than O(n).
import json
prompt = "If you want to make a new password, type 'Make password'."
prompt += "\nIf you want to look for a password, type 'Look for password'.\n"
answer = input(prompt).upper()
def load_passwords():
try:
with open("passwords.txt", "r") as f:
passwords = json.loads(f.read()) # text file gets opened to read
return passwords
except FileNotFoundError:
print("Sorry but there are no passwords available. Make a new one!")
return {}
def password_list(account_name, password_name):
passwords = load_passwords()
passwords[account_name] = password_name
return passwords
if answer == "MAKE PASSWORD":
account_name = input("What use is this password for? ").upper()
password_name = input("What is the password? ")
passwords = password_list(account_name, password_name) # purpose and password saved to dict
with open("passwords.txt", 'w+') as f:
f.write(json.dumps(passwords))
print("Your password was saved!") # dictionary gets saved to text file
elif answer == "LOOK FOR PASSWORD":
passwords = load_passwords()
if passwords: #if the list isn't empty...
search_account = input("What account is this password for? ").upper()
# this is much better
if search_account in passwords:
print(f"The password is '{passwords.get(search_account)}'.")
else:
print("Sorry, we can't find such name.")
Note: Be sure to encrypt your passwords before saving to a file.
"You should probably initialize your password list by reading your json file if it's there. Otherwise, when you run MAKE PASSWORD, it adds the new password to an empty dict and overwrites the existing password file which might've had a password in there before." – rchome
Related
I am trying to make a simple login system because I am bored and want to learn python, I am trying to store the usernames in a file but new usernames are just replacing the current one in the list.
#USENRAME UNENCRYPTED PASSWORD SYS
print ("WOuld you like to login or signup (login/signup)")
choice = input()
if choice == "signup":
print ("Can you enter your username please?")
username = input()
with open('username') as f:
if username in f.read():
print("That Username already exists")
else:
f= open("username","w+")
f.write(username + "\n")
f.close()
Say if the first username I enter is "Dave" and then I close the program, the next username I register with being "Harry" The "Harry" will just replace the "Dave" In line one of the "usernames" file.
You dont need to open your file twice, but when you open it the first time what you you want to be able to do is append to what is already there.
with open('username.txt','a+') as f:
if username in f.read():
print("That Username already exists")
else:
f.write(username + "\n")
Try reading this if you're unsure.
https://www.guru99.com/reading-and-writing-files-in-python.html
I'm making a user login for a little project I'm working on at school, practising my file handling and whatnot. For the most part, it's going fine, but I'm having trouble when I try and create new users. The new user needs to have an original username and password to be created, otherwise, it should tell them that their choice is unavailable. For some reason, it works fine with the first username and password in the files and makes the user retry. But when I try and create a new user with a name that I know I shouldn't be able to, it lets me.
def signUp():
username = str(input("\nPlease enter your new username "))
file = open ("usernames.txt","r")
for x in file:
if username in x:
print ("\nThat username is already in use, please try another")
signUp()
else:
print ("Your username is now ",username)
file.close()
password = input("\nPlease create a password ")
file = open ("passwords.txt","r")
for x in file:
if password in x:
print ("\nThat password is already in use, please try another")
signUp()
else:
print ("Your password is now ", password," Don't forget it")
file.close()
file = open ("usernames.txt","a")
file.write (username)
file.write ("\n")
file.close()
file = open ("passwords.txt","a")
file.write (password)
file.write ("\n")
file.close()
print ("\nYour login details have been saved")
print ("Please login")
logIn()
In the username file, it has the names:
Alex
Josh
The password file has:
123qwe
ewq321
The code works for Alex and 123qwe and stops them from being repeated, but not for Josh or ewq321.
At the moment, I'm not looking for any other improvements. I'll refine it all later. For now, I just need help with this little predicament. I understand that my explanation is a little confusing, so it might help to copy what I've already done and play around with it. Obviously, this isn't the whole code, so it might not make perfect sense.
The problem is in both loops, exactly on the else clause.
Your code checks that if the only first username already exists that's because you introduced an else on the loop, and also you need to get out of the program if the username already exists using return.
Here is the new code:
def signUp():
username = str(input("\nPlease enter your new username "))
file = open ("usernames.txt","r")
for x in file:
if username in x:
print ("\nThat username is already in use, please try another")
signUp()
return
print ("Your username is now ",username)
file.close()
password = input("\nPlease create a password ")
file = open ("passwords.txt","r")
for x in file:
if password in x:
print ("\nThat password is already in use, please try another")
signUp()
return
print ("Your password is now ", password," Don't forget it")
file.close()
file = open ("usernames.txt","a")
file.write (username)
file.write ("\n")
file.close()
file = open ("passwords.txt","a")
file.write (password)
file.write ("\n")
file.close()
print ("\nYour login details have been saved")
I want to create a simple log-in account program in Python using the "CSV" library. Here is the code:
import csv
account_password = ""
with open("accounts.csv") as csvfile:
reader = csv.reader(csvfile)
while True:
username = input("\nEnter username: ")
# Checks if username exists
for row in reader:
if row[0] == username:
account_password = row[1] # Get user's password
break
password = input("Enter password: ")
# Check if password is valid
if password == account_password:
break
else:
print("Username/password is incorrect. Try again.")
print("\nSuccessfully logged in!")
Here is how my CSV file looks like. The first column is the usernames and the second one is the passwords:
Tim,myPassword
John,monkey32
Fred,WooHoo!
When I tried to test my program in IDLE, I noticed an unusual log-in issue.
If I log in with the correct credentials, then the program works perfectly fine:
If I log in with incorrect log in details, the program works as expected:
But here is the issue. After entering incorrect log in details, the program asks the user to try again. This is done with a "while loop" in my code. Yet when I "try again", but with the correct details, the program thinks the log-in details are incorrect:
Here is the same issue with another user from the csv file:
I would love it if anyone could let me know what is wrong with my code.
Please also show the full updated code along with an explanation for why the code in the answer is working and the difference between it and mine.
Thank you.
It looks like that for row in reader running only once
try change the order of your code
Try to open the file inside the while True: like this:
while True:
with open("accounts.csv") as csvfile:
reader = csv.reader(csvfile)
should work fine because you close the file before each iteration
for row in csv.reader(csvfile) goes through the file line by line, once. After the file is exhausted, it doesn't do anything. You can instead load it into memory as a dictionary (provided it is not too large, otherwise you probably need a DB):
import csv
account_passwords = dict()
with open("accounts.csv") as csvfile:
reader = csv.reader(csvfile)
for row in reader:
account_passwords[row[0]] = row[1]
while True:
username = input("\nEnter username: ")
password = input("Enter password: ")
if username in account_passwords and \
account_passwords[username] == password:
print("\nSuccessfully logged in!")
break
else:
print("Username/password is incorrect. Try again.")
If you're doing this for anything serious, consider hashing the passwords and using getpass.getpass instead of input for reading passwords.
csv.reader(%filename%) is generator.
Python generators can be processed only once. So when your enter incorrect details generator goes up to last row and found nothing. When your code return to "while True" reader will be empty and "for row in reader:" will not return any values.
Correct (or at least working) version should be something like this:
import csv
account_password = ""
def get_pass_from_file(username):
with open("accounts.csv") as csvfile:
for item in csv.reader(csvfile):
if item[0] == username:
return item[1]
if __name__ == '__main__':
while True:
username = input("\nEnter username: ")
account_password = get_pass_from_file(username)
if account_password is None:
print("Username not found. Try again.")
continue
password = input("Enter password: ")
if password == account_password:
break
else:
print("Username/password is incorrect. Try again.")
print("\nSuccessfully logged in!")
I have a whole system created and I just want the users to have to have a username and password to access the system.
This is the code i have written to add the username and password to the saved dictionary, but everytime i run this is just overwrites whatever is in the store.
username=input("What would you like the username to be?")
password=input("What would you like the password to be?")
newperson = {username,password}
pickle.dump(newperson, open("Userstore","wb"))
how would i code it to keep the information already stored in "Userstore" and add the newperson to the dictionary?
You can do the following logic:
check if Userstore present, if it present then read the already saved data.
Code:
import pickle
import os
filename = "Userstore"
userdict = {}
if os.path.isfile(filename):
userdict = pickle.load(open(filename, "rb"))
username = input("What would you like the username to be?")
password = input("What would you like the password to be?")
userdict[username] = password
print userdict
pickle.dump(userdict, open("Userstore", "wb"))
def info(): #Here you can write your password and username.
Username = raw_input ("Username: ")
Password = raw_input ("Password: ")
print("")
for line in open('/home/hello/Usernames.txt'):
if Username == Username in line: #Checks if username is available.
print ("Username is already taken!\n")
info()
else:
User = open("/home/hello/Usernames.txt", "w") #Registers username.
User.write(Username)
Psw = open("/home/hello/Passwords.txt", "w") #Registers password.
Psw.write(Password)
print ("You have succsesfully registered!") #If you managed to register.
break
info()
This is an account registerer that can register both username and password. But I need help with something... How can I make it check multiple lines of strings in a file, and how can I make the program write a new line of string in the text files when I register without replacing the old string?
Open the file for appending ('a') mode instead of writing ('w') which truncate the file.