I need help with looking for a username in a text file so that the user should enter a username that is not already stored in the file.
The text file looks like this:
aaa12 aaa12
aaa16 aaa16
iii12 iii12
Code:
username=input("Enter a username:")
with open("users.txt") as openfile:
for line in openfile:
for part in line.split():
if username in part:
print("Try again")
I don't think it works. Is there any other solutions I could use?
You can do the in (__contains__) test directly on the string (line here) itself, no need for split-ing and making a list:
for line in openfile:
if username in line:
print("Try again")
break
For white separated username (as shown in the example), and each username is a whole match:
for line in openfile:
if username in line.split():
print("Try again")
break
Note that, matching username is never going to be perfect. If simple matching does not work, then probably you should think about picking a suitable container first rather than doing text processing.
You're rechecking too many times - you were on the way, but I suggest first collecting, then checking:
users = set()
with open("users.txt") as openfile:
for line in openfile:
users.update(line.split())
#Another way:
#for user in line.split():
#users.add(user)
first = True
while first or (username in users):
if not first: print("Try again, exists!")
username=input("Enter a username:")
first = False
username=input("Enter a username:")
exists = False
with open("users.txt") as openfile:
for line in openfile:
if username in line:
exists = True
if not exists:
print("Try again")
This would handle if you have usernames in multiple lines in the text file. Basically, you don't need all the hoops of splitting in python, which is a beauty really.
Related
I am making a small simple password manager in python. I have the functions of creating an account which has 3 inputs, Username, Password, and Website. I have a function to view all the accounts which shows the contents of the file info.txt where all that information goes. Im trying to create a function to delete an entry but im not sure how to make the function delete all the lines of information associated with the Username. I want an input asking "Which account to delete" you put the username, and it will delete all information associated with the username in info.txt
Code:
import os.path #Imports os module using path for file access
def checkExistence(): #Checking for existence of file
if os.path.exists("info.txt"):
pass #pass is used as a placeholder bc if no code is ran in an if statement and error comes.
else:
file = open("info.txt", "w") #creates file with name of info.txt and W for write access
file.close()
def appendNew():
#This function will append a new password in the txt file
file = open("info.txt", "a") #Open info.txt use a for appending IMPORTANT: opening a file with w for write will write over all existing data
userName = input("Enter username: ")
print(userName)
os.system('cls')
password = input("Enter password: ")
print(password)
os.system('cls')
website = input("Enter website: ")
print(website)
os.system('cls')
print()
print()
usrnm = "Username: " + userName + "\n" #Makes the variable usrnm have a value of "Username: {our username}" and a new line
pwd = "Password: " + password + "\n"
web = "Website: " + website + "\n"
file.write("----------------------------------\n")
file.write(usrnm)
file.write(pwd)
file.write(web)
file.write("----------------------------------\n")
file.write("\n")
file.close()
def readPasswords():
file = open("info.txt", "r") #Open info.txt with r for read
content = file.read() # Content is everything read from file variable (info.txt)
file.close()
print(content)
checkExistence()
while True:
choice = input("Do you want to: \n 1. Add account\n 2. View accounts\n 3. Delete account\n")
print(choice)
if choice == "1":
os.system('cls')
appendNew()
elif choice == "2":
os.system('cls')
readPasswords()
elif choice == "3":
os.system('cls')
else:
os.system('cls')
print("huh? thats not an input.. Try again.\n")
I tried making a delete account function by deleting the line which matched the username. My only problem is that it only deletes the line in info.txt with the username, but not the password and website associated with that username.
Firstly, you're using the wrong tool for the problem. A good library to try is pandas, using .csv files (which one can think of as pore program oriented excel files). However, if you really want to use the text file based approach, your solution would look something like this:
with open(textfile, 'r+') as f:
lines = [line.replace('\n', '') for line in f.readlines()]
# The above makes a list of all lines in the file without \n char
index = lines.index(username)
# Find index of username in these lines
for i in range(5):
lines.pop(index)
# Delete the next five lines - check your 'appendNew' function
# you're using five lines to write each user's data
print(lines)
f.write("\n".join(lines))
# Finally, write the lines back with the '\n' char we removed in line 2
# Here is your readymade function:
def removeName(username):
with open("info.txt", 'r+') as f:
lines = [line.replace('\n', '') for line in f.readlines()]
try:
index = lines.index(username)
except ValueError:
print("Username not in file!")
return
for i in range(5):
lines.pop(index)
print(lines)
f.write("\n".join(lines))
# Function that also asks for username by itself
def removeName_2():
username = input("Enter username to remove:\t")
with open("info.txt", 'r+') as f:
lines = [line.replace('\n', '') for line in f.readlines()]
try:
index = lines.index(username)
except ValueError:
print("Username not in file!")
return
for i in range(5):
lines.pop(index)
print(lines)
f.write("\n".join(lines))
# Usage:
removeName(some_username_variable)
removeName_2()
Again, this is a rather clunky and error prone approach. If you ever change the format in which each user's details are stored, your would have to change the number of lines deleted in the for loop. Try pandas and csv files, they save a lot of time.
If you're uncomfortable with those or you're just starting to code, try the json library and .json files - at a high level they're simple ways of storing data into files and they can be parsed with the json library in a single line of code. You should be able to find plenty of advice online about pandas and json.
If you're unable to follow what the function does, try reading up on try-except blocks and function parameters (as well as maybe global variables).
The entire program works fine if I have one username in the users.csv file, but as soon as a second is added repl (IDE) quits the program. I know the code is very messy and amateur but for now I'm just looking to fix this part.
Part that needs to be altered v
def login():
existing = input("Do you already have a account? Y/N >" ).upper()
if existing == "Y":
pass
else:
print("Welcome to the regristration page")
file = open("users.csv", "a+")
file.write("{}\n".format(input("What would you like your username to be? >")))
file.close()
login()
def auth_users():
username = input("What is your username?")
file = open("users.csv","r")
reader = csv.reader(file)
for record in reader:
if record[0] == username:
continue
else:
exit()
file.close()
auth_users()
Program in its entirety
def login():
existing = input("Do you already have a account? Y/N >" ).upper()
if existing == "Y":
pass
else:
print("Welcome to the regristration page")
file = open("users.csv", "a+")
file.write("{}\n".format(input("What would you like your username to be? >")))
file.close()
login()
def auth_users():
username = input("What is your username?")
file = open("users.csv","r")
reader = csv.reader(file)
for record in reader:
if record[0] == username:
continue
else:
exit()
file.close()
auth_users()
There is no error while running your program. Either way, no matter if the user exists in your file or not, your program will end without output.
You can try to improve things a bit:
def auth_users():
username = input("What is your username?")
file = open("users.csv","r")
reader = csv.reader(file)
for record in reader:
if record[0] == username:
print(f"Hello, {username}")
exit() # You found the guy, exit your program here
# Don't exit here: go through all the names until you find the guy (or not)
# End of the loop. We didn't find the guy.
print("You're not registered")
Here is the problem
for record in reader:
if record[0] == username:
continue
else:
exit()
You are probably mistaken in your use of exit() and continue. The exit function is usually called when you want to exit out of python's interactive mode and raises the SystemExit exception (in this case causing your program to exit). continue on the other hand tells python to move on to the next step in the loop.
You probably want to do something like this instead:
for record in reader:
if record[0] == username:
# Handle authenticated users here
print("Login successful")
return # exit the function
# Handle unauthenticated users here
print("User not found")
You should also consider replacing your file opening and closing with context managers. Instead of:
my_file = open("some-file", "r")
# read some input from the file
my_file.close()
# ...
my_file = open("some-file", "w")
# write some output to the file
my_file.close()
use:
with open("some-file", "r") as my_file:
# read my_file in here
# ...
with open("some-file", "w") as my_file:
# write to my_file in here
This way python tries to close your file even if an exception is encountered along the way.
I am new to Python and am having trouble with looping while checking strings in a file. For this program, I am checking to see if a username that the user wants to create already exists. If the username already exists in the file, the program prompts the user to enter another username. The loop ends when the user enters a username that is not in the file. Here is the relevant code:
# Prompting for username and password
username = input("Enter your username: ")
password = input("Enter your password: ")
# open password file
f = open("password.txt", "r")
# while username exists in file
while username in f.read():
username = input("Enter your username: ")
f.close()
If I enter a username that exists in the password file, the program does prompt me to enter another username; however, when I enter the same username, the program does not stay in the loop. Any ideas on why this is occurring?
When you run f.read() Python will read the file in and then continue onto the next line of the file in the next iteration. It wont go back to the top of the file. So it exits the loop since the username in the next line of the file is either an empty string or another name. To fix this you could use a context manager like so:
# Prompting for username and password
username = input("Enter your username: ")
password = input("Enter your password: ")
# read in the file data
with open('password.txt') as f:
data = f.read()
# while username exists in file
while username in data:
username = input("Enter your username: ")
Then depending on how the data is structured in your .txt file then you can call split() on data if it's using a new line.
There is no condition to check whether the new username is in the file or not.
Maybe an easier way to do this would be to use the following approach?
username = input("Enter your username: ")
password = input("Enter your password: ")
# open password file
f = open("password.txt", "r")
data = f.read()
# while username exists in file
while username in data:
new = input("Enter your username: ")
if new in data:
continue
else:
break
username = new
f.close()
This is because you are using f.read() in the while condition.
f.read reads the whole content of the file at once and there's nothing else to read from file, leading to the end of while loop.
If you want to check for usernames in the file, I'd suggest you create a list of usernames that you read from the file and use it in your while loop for checking.
If your file has contents:
username1, username2, ...
You can do
listOfUsernames = f.read().split(',')
and then use this for checking in while loop.
I have a code where I have an email and a password in a text file in a list, formatted like this: ["tom#gmail.com","Password1"],["harry#gmail.com","Password2].
My code reads from the text file and compares it with a user input to see if it is present in the text file. For some reason when I input the first email "tom#gmail.com" it reads that from the text file but not "Password1", however it reads "harry#gmail.com" correctly as well as "Password2" correctly. I cant find any way to get around this and fix this? No error is received so I'm not sure where its going wrong. Here is my code:
def Login():
with open("logindata.txt","r") as file:
for line in file:
line=line.split(",")
logindata.append([line[0],line[1].rstrip()])
print(logindata)
found=False
while found == False:
email=input("Enter email:")
password=input("Enter password:")
with open("logindata.txt","r")as file:
for line in file:
line = line.split(",")
if email in line:
print("Correct email")
if password in line:
print("Correct Password")
found=True
if __name__ == "__main__":
Login()
if the code is run and you try the inputs I gave at the start then only the second email and password combination works. Here is what the text file looks like text file format
Appending:
username=input("Enter a new email")
password=input("Enter a password")
with open('logindata.txt','a')as file:
line='\n'+ username + ',' + password
file.write(line)
print("user added")
You are reading text with line separators. Your lines don't look like this:
tom#gmail.com,Password1
They actually look like this:
tom#gmail.com,Password1\n
When splitting that on the comma, you get this:
line = ['tom#gmail.com', 'Password1\n']
and the test 'Password1' in line fails, but 'Password1\n' in line would succeed.
The \n is a newline character. You'd need to remove that first; you could use str.strip() to handily remove all whitespace from the start and end:
for line in file:
line = line.strip().split(",")
if email in line:
print("Correct email")
if password in line:
print("Correct Password")
Rather than manually split, you can use the csv module to read your file:
import csv
with open("logindata.txt", "r") as file:
reader = csv.reader(file)
for user, pw in reader:
if email == user:
print("Correct email")
if password == pw:
print("Correct Password")
I'm a beginner in Python and ran across an error. I am trying to create a programme that will take a username and password made by a user, write them into lists and write those lists to files. Here is some of my code:
This is the part where the user is creating a username&password.
userName=input('Please enter a username')
password=input('Please enter a password')
password2=input('Please re-enter your password')
if password==password2:
print('Your passwords match.')
while password!=password2:
password2=input('Sorry. Your passwords did not match. Please try again')
if password==password2:
print('Your passwords match')
My code works fine up until this point, where I get the error:
invalid file: <_io.TextIOWrapper name='usernameList.txt' mode='wt' encoding='cp1252'>.
I'm not sure why this error is being returned.
if password==password2:
usernames=[]
usernameFile=open('usernameList.txt', 'wt')
with open(usernameFile, 'wb') as f:
pickle.dump(usernames,f)
userNames.append(userName)
usernameFile.close()
passwords=[]
passwordFile=open('passwordList.txt', 'wt')
with open(passwordFile, 'wb') as f:
pickle.dump(passwords,f)
passwords.append(password)
passwordFile.close()
Is there any way to fix the error, or another way to write the lists to a file?
Thanks
You had the right idea, but there were a number of issues. When the user passwords do not match, normally you would prompt for both again.
The with block is designed to open and close your files, so there is no need to add a close at the end.
The script below shows what I mean, you will then have two files holding a Python list. So trying to view it will not make much sense, you will now need to write the corresponding read part to your code.
import pickle
userName = input('Please enter a username: ')
while True:
password1 = input('Please enter a password: ')
password2 = input('Please re-enter your password: ')
if password1 == password2:
print('Your passwords match.')
break
else:
print('Sorry. Your passwords did not match. Please try again')
user_names = []
user_names.append(userName)
with open('usernameList.txt', 'wb') as f_username:
pickle.dump(user_names, f_username)
passwords = []
passwords.append(password1)
with open('passwordList.txt', 'wb') as f_password:
pickle.dump(passwords, f_password)
usernameFile=open('usernameList.txt', 'wt')
with open(usernameFile, 'wb') as f:
In the second line usernameFile is a file object. The first argument to open must be a file name (io.open() also supports file descriptor numbers as ints). open() tries to coerce its argument to a string.
In your case, this results in
str(usernameFile) == '<_io.TextIOWrapper name='usernameList.txt' mode='wt' encoding='cp1252'>'
which is not a valid filename.
Replace with
with open('usernameList.txt', 'wt') as f:
and get rid of usernameFile completely.