I have a program that needs a username system, I want the user to enter their username and the program checks the file 'username' to see if it is in the list. My code below works if there is only one person in the list, otherwise it prints correct and incorrect. How would I change my code so if just one line matches the input it prints correct.
username = input("enter username: ")
search = open("username", "r")
for line in search:
if username in line:
print ("correct")
else:
print ("incorrect")
You could exploit the for...else construct that python has.
with open("username") as f:
for line in f:
if username in line:
print("correct")
break
else:
print("incorrect")
The else block is run if the program exited naturally - without breaking out from the loop.
If you do not like traditional for loops, then I suggest you this solution:
with open("username") as f:
isInList = [username in line for line in f]:
if any(isInList):
print ("correct")
else:
print("incorrect")
One way of achieving this is to simply return after it finds a match. Using return and encapsulating the logic into a function would allow you to do other things with result. Also, I would suggest using the with statement for opening files as it has better error handling and automatically takes care of closing the file and cleanup. Here is a short tutorial on the with statement.
username = input("enter username: ")
def read_file():
with open("username", "r") as f:
for line in f:
if username in line:
return "correct"
else:
return "incorrect"
result = read_file()
print(result)
# Or do whatever else you want with the result
Related
i want to make python create a file if it doesn't exist ,then take text from users input and append into my file and to be able to use my code several times without changing text before it
def register():
f=open('1.txt','w')
f=open('1.txt','r')
users=f.readlines()
f=open('1.txt','a')
while True:
username = input('Enter your username: ')
password = input('Enter your password: ')
if username in users:
print('this username is taken')
else:
f.write(f'{username}\n')
f.write(f'{password}')
break
this is my code
EAFP approach (which is more pythonic that LBYL):
try to create a file
handle specific exception if it exists
either way do your logic in finally block
try:
with open("1.txt","x") as f: pass
except FileExistsError:
print("File already exists!")
finally:
with open("1.txt", "r+") as f:
lines = f.readlines()
username, password = input("Type username and password (separated by a space): ").split()
if f"{username}\n" in lines:
print('This username is taken!')
else:
f.writelines([f"{username}\n",f"{password}\n"])
Keep in mind though that:
if the username and password are the same this won't work correctly (or at least not as expected imho, as homework figure out why :D )
passwords in general should NOT be kept as plain text
you should add the "boilerplate" if __name__=="__main__": thingy if it's a standalone and no part of a function/class etc
you could wrap the input in try...except ValueError block to be extra safe when somebody enters a single value or three values and so on
Comments:
If you do something like this:
f=open('1.txt','w')
f=open('1.txt','r')
The 2nd line shadows the first one, so it makes no sense, it's the same as:
x=2
x=3
print(x)
The 1st assignment is "dead"
Most often you want to use with when handling files operations, otherwise it's your responsibility to close the file as well.
Im new to python and I'm trying to code a python login program. Instead of printing out "Welcome to the database" when the username provided is correct, it printed out both "Welcome to the database" and "Username invalid. Please try again.". May I know which part of my code needs to be corrected?
def login():
while True:
name = input("Name: ")
with open('username.txt', "r")as name_file:
for line in name_file.readlines():
if name == line.strip():
print("welcome to database")
else:
print("Username invalid. Please try again")
You are looping through all the users in the text file and for each of them printing to the console. The thing you probably want could be done like this:
def login():
while True:
loginSucessful = False
name = input("Name: ")
with open('username.txt', "r")as name_file:
for line in name_file.readlines():
if name == line.strip():
loginSucessful = True
break
if loginSucessful:
print("welcome to database")
else:
print("Username invalid. Please try again")
You could use a boolean variable to keep track of successful logins like #Michalor did. Or you can use Python's for/else loop to do the same thing without adding a new variable. If the login is successful and you break out of the loop, the "else" statement isn't executed. Using "break" also has the advantage that you don't need to test all of the other users after you have found a successful login.
def login():
while True:
name = input("Name: ")
with open('username.txt', "r")as name_file:
for line in name_file.readlines():
if name == line.strip():
print("welcome to database")
break
else:
print("Username invalid. Please try again")
Of course, this kind of function doesn't provide much security, as you can keep guessing the names in the text file until you find a valid one, or if you can get your hands on the text file itself you can just look the names up. For actual login code, it's probably best to use some kind of login library that handles the security details for you.
I have a very simple 'login' program that I've almost got finished. I'm trying to get my make_acc() function to write the username on line 1 and the password on line 2, as well as make my login() function read those separate lines per what needs to be checked. I'm pretty sure the answer has to do with marking the readline command for which line needs to be read, but I'm not sure how to implement it in my code properly. Here's the code.
# This function has the user input a username for their account
def make_acc():
username = input('Make a username:')
file = open('acc_data.txt','w')
file.write(username)
file.close()
#password = input('Make a password:')
#file = open('acc_data.txt','w')
#file.write(password)
# This function has the user login to a preexisting account
def login():
input_user = input('Enter your username:')
file = open('acc_data.txt','r')
username = file.readline()
if input_user == username:
print('You are now logged in')
else:
print('That user does not exist')
login()
# This variable will be defined as a yes or no depending on whether or not the use has an account
acc_bool = input('Do you already have an account?:')
# This if statement runs the login() function if the user answered yes to the previous input
if acc_bool == 'yes':
login()
# This elif statement runs the make_acc() function if the user answered no to the previous input
elif acc_bool == 'no':
make_acc()
login()
This should do it:
def make_acc():
username = input('Make a username:')
password = input('Make a password:')
with open('acc_data.txt','a') as file:
file.write(username+'\n')
file.write(password)
def login():
input_user = input('Enter your username:')
with open('acc_data.txt','r') as file:
if input_user in [u for i,u in enumerate(file.readlines()) if not u%2]:
print('You are now logged in')
else:
print('That user does not exist')
login()
Instead of having the usernames and passwords all in 2 lines, you can use indexes to determine whether a line is a username or password: even indexes are for usernames, and odd ones are for passwords.
UPDATE:
This part: [u for i,u in enumerate(file.readlines()) if not u%2] lists all the strings in file.readlines() (a list of all the lines in f.read()) if the index of the string, i, doesn't leave a remainder when divided by 2.
You see, enumerate() will basically let us iterate through an array and let use easily access the index of the current iteration.
First, uncomment the part of make_acc that asks for a password and add a file.close().
Then, notice that when you've run the program and inputted the two pieces of information, only one is left in the file, this is because, when calling open(), you use the
w mode, which truncates the file before allowing you to write. The consequence of this is that when you open the file again a couple of lines later, all information previously stored is lost. The solution is to use mode r+ or a or just not close the file until the end of the function, thereby avoiding having to reopening it when writing the password.
Next, when reading from the file, you can use file.readline() just as you already are doing. Choosing what line to read happens by default, because every call to readline advances what line is being read. This means that the second time you call it since you opened the file, the second line will be read.
I am doing a project for school - and as part of it, I need to check if their username is already stored within a text file:
def checkUsername():
userName = str(input("WHAT IS YOUR NAME?"))
if userName in usernames.read():
print("WELCOME BACK" + userName)
print("LET\'S GET STARTED")
return False
else:
usernames.write(userName)
print("WELCOME TO THE SYSTEM!")
return False
Despite my efforts to resolve this issue, I cannot seem to figure it out. Can anyone help?
What you are missing is first opening the file for reading:
def checkUsername():
userName = str(input("WHAT IS YOUR NAME?"))
with open("usernames.txt", 'r') as usernames:
if userName in usernames.read():
print("WELCOME BACK" + userName)
print("LET\'S GET STARTED")
return False
else:
usernames.write(userName)
print("WELCOME TO THE SYSTEM!")
return False
with open opens the file at the specified path (change usernames.txt to the full path of the file) and 'r' signifies that the file is to be opened with reading permissions. This is usually advantageous to using python's open() method, which requires you close() the file when you are finished reading it.
Side note: notice you have returned False under both conditions of your function.
One issue with this function is that usernames is not defined, and the other is that both ends of the if block will return False.
One way you could solve these would be
def checkUsername(usernames_file):
fp = open(usernames_file, 'r') # the default mode is 'r', but it's explicit here
usernames = fp.read()
userName = str(input("WHAT IS YOUR NAME?"))
if userName in usernames:
print("WELCOME BACK" + userName)
print("LET\'S GET STARTED")
fp.close()
return True # note, not False
else:
fp.write(userName)
print("WELCOME TO THE SYSTEM!")
fp.close()
return False
That snippet above is different in a few ways, but it also ignores two likely errors you might also be facing: case sensitivity in inputs (the input(...) line could be whatever the user wants), and line separation in usernames_file. Hopefully this pushes you in the right direction though.
You need to open() the file before calling the read() method.
Check if username isn't empty after using strip()
You can use the ternary conditional operator (a if condition else b)
i.e.:
def checkUsername(user):
if user.strip():
with open("myfile") as users:
print(f"WELCOME BACK {user}\nLET'S GET STARTED") if user in users.read() else print(f"WELCOME TO THE SYSTEM!")
else:
print("Error: empty username")
user = input("WHAT IS YOUR NAME?")
checkUsername(user)
I am making a login system for my project, and I have the usernames and passwords stored in a text file, with usernames in the first column and passwords in the second column, and then separating each login/password with a new line and using : as a barrier between the username/password.
Upon entering the correct username and password, I always get incorrect login, however if I only compare the username to the file it functions properly. Even if I print the password and username straight from the file and then print it next to the username/password I entered, it is still the exact same yet still say incorrect login!
def login():
file=open("user.txt","r")
user=input("enter usename")
password=input("enter password")
Check=False
for line in file:
correct=line.split(":")
if user==correct[0] and password==correct[1]:
Check=True
break
if Check==True:
print("succesffuly logged in")
file.close()
mainMenu()
else:
print("incorrect log in")
file.close()
login()
I suspect you have a \n at the end of each user / password string. I suspect line looks like user:pass\n after being read in. Use line.strip().split(':') to remove the newline, which is causing password==correct[1] to fail.
Replace:
for line in file:
correct=line.split(":")
With:
for line in file:
correct=line.strip().split(":")
For why, see https://docs.python.org/2/library/string.html#string.strip
string.strip(s[, chars])
Return a copy of the string with leading and trailing characters removed. If chars is omitted or None, whitespace characters are removed. If given and not None, chars must be a string; the characters in the string will be stripped from the both ends of the string this method is called on.
We can just check using in
def login():
file = open("user.txt", "r")
user = input("enter usename ")
password = input("enter password ")
if ('{0}:{1}'.format(user, password)) in file:
print('yay')
else:
print('Boo !! User not found')
login()
if you wanted to use the for loop I would suggest:
def login():
file = open("user.txt", "r")
user = input("enter usename ")
password = input("enter password ")
for line in file:
temp_user, temp_password = line.strip().split(':')
if temp_user == user and temp_password == password.strip():
print('yay')
else:
print('boo username and password not found!')
login()
Really important, WARNING!
Please take necessary security measurements as this code does not provide any, there are a lot of vulnerabilities that could be exploited. No hashing function and Python itself does not provide a lot of security, I would suggest using getpass.getpass explanation HERE