Python read next line from what the user inputs - python

So basically I have a program which can create a users username and password in a document and search for the password used with the username that is input by the person using the program.
For example:
The programs asks me to input a username I enter: '13'.
Under 13 in the text document is 'sadfsdfsdf'.
I want the program to skip to below the 'Username: 13' and read and print 'Password: sadfsdfsdf'.
note that I have multiple usernames and passwords In the .txt file
u = 'Username: '
Thanks in advance!
def SearchRecordProgram():
while True:
user_search = input("Please enter the username you wish to see the password for: ")
full_user = u + user_search
if full_user in open('User_Details.txt').read():
print(" ")
print ("Username found in our records")
print(" ")
print(full_user)
break
else:
print("Username entered does not match our records")

So, imagining your file is like so:
Username : 13
Password : sadfsdfsdf
Username : 15
Password : Lalalala
You can parse it (with regular expressions) like so:
import re # regular expression module
regex = re.compile("Username :(.*)\nPassword :(.*)")
# read text from file
with open(filePath,'r') as f:
text = f.read()
u_pass = regex.findall(text)
# [(' 13', ' sadfsdfsdf'), (' 15', ' Lalalala')]
user_dict = {u:password for u,password in u_pass}
# {' 13': ' sadfsdfsdf', ' 15': ' Lalalala'}
Now you can get the password of someone by asking for the password of that user :
# given username and password_input
if username in user_dict and user_dict[username] == password_input:
# if username exists and password okay
print "Authentication succeeded."

When you want to open a file, you should almost always use the with statement:
with open('User_Details.txt') as read_file:
# Do reading etc. with `read_file` variable
This will ensure that any errors are being handled correctly and the file is not left open.
Now that the file is open, we need to loop through each line until we find one that matches our username. I hope you know how for loop works:
username = 'Username: 13' # Get this however you want
with open('User_Details.txt') as read_file:
for line in read_file:
line = line.strip() # Removes any unnecessary whitespace characters
if line == username:
# We found the user! Next line is password
And we need to get the next line which contains the password. There are many ways to get the next line, but one simple way is to use the next() function which simply gets us the next element from an iterable (the next line from a file in this case):
username = 'Username: 13'
with open('User_Details.txt') as read_file:
for line in read_file:
line = line.strip()
if line == username:
password = next(read_file)
break # Ends the for loop, no need to go through more lines
Now you have a password and an username, and you can do whatever you want with them. It's often a good idea to have the inputs and outputs outside of your program's logic, so don't print the password right inside the for loop, but instead just receive it there and then do the printing outside.
You might even wanna turn the whole search logic into a function:
def find_next_line(file_handle, line):
"""Finds the next line from a file."""
for l in file_handle:
l = l.strip()
if l == line:
return next(file_handle)
def main():
username = input("Please enter the username you wish to see the password for: ")
username = 'Username: ' + username
with open('User_Details.txt') as read_file:
password = find_next_line(read_file, username)
password = password[len('Password: '):]
print("Password '{0}' found for username '{1}'".format(password, username))
if __name__ == '__main__':
main()
Finally, it's absolutely insane to store anything in this format (not to mention password security stuff, but I get you're just learning stuff), why not do something like:
username:password
markus:MarkusIsHappy123
BOB:BOB'S PASSWORD
This could then easily be converted into a dict:
with open('User_Details.txt') as read_file:
user_details = dict(line.strip().split(':') for line in read_file)
And now to get a password for an username, you'd do:
username = input('Username: ')
if username in user_details:
print('Password:', user_details[username])
else:
print('Unknown user')

Maybe not the pretties, but something like this will work:
with open(users_file, "r") as f:
lines = f.read()
def get_password(user_id):
entries = iter(lines.splitlines())
for entry in entries:
if(entry.startswith("{}:{}".format(prefix, user_id))):
return next(entries)
print "Password:", get_password("13")

def SearchRecordProgram():
while True:
user_search = input("Please enter the username > ")
file = open('User_Details.txt')
usernames = file.readlines() # Read file into list
file.close()
if user_search in usernames: # Username exists
print ('Found Username')
password = usernames[usernames.index(user_search)+1]
print ('Password is: ' + password)
break # Exit loop
else: # Username doesn't exist
print("Username entered does not match our records")
Note that this will not work if a password happens to be a username, e.g:
user1
password1
user2
user3 # This is the password for user3
user3
password3
If you search for "user3" this code will output "user3" as the password for "user3" because it finds the first instance of "user3" (line 4) and then looks to the next line (line 5), which is the next username.
Even worse, if "user3" is the last line in the file, it will end with an error because there are no more lines. You could add a check that the index of the found username is even (i.e. index 0, 2, 4, 8) with this code:
if not usernames.index(user_search) % 2: # Checks the remainder after / by 2.
# If it's 0 then it's an even index.
password = usernames[usernames.index(user_search)+1]
print ('Password is: ' + password)
but there isn't much you can do if this happens.
However, you could manipulate the file of usernames to only have usernames like this:
lst = [0, 1, 2, 3, 4, 5, 6, 7]
print (lst[0::2])
which prints
[0, 2, 4, 6]
So the code could be changed to this:
def SearchRecordProgram():
while True:
user_search = input("Please enter the username > ")
usernames = open('User_Details.txt').readlines() # Read file into list
if user_search in usernames[0::2]: # Username exists
print ('Found Username')
password = usernames[1::2][usernames[0::2]].index(user_search)]
print ('Password is: ' + password)
break # Exit loop
else: # Username doesn't exist
print("Username entered does not match our records")
Here is a breakdown
password = usernames[1::2] # Gets the odd items (passwords)
[ # Get index item. The index returned from searching
# the usernames will be the same as the index needed
# for the password, as looking at just the odd items:
# [0, 2, 4, 6]
# [1, 3, 5, 7] - even has the same index as next odd.
usernames[0::2] # Gets even items (usernames)
].index(user_search)]
# Only searches the usernames. This
# means passwords being the same is not
# an issue - it doesn't search them

Related

how can i make store a username in txt file without having the same username twice?

user = input("\nInput user's Login ID: ")
while True:
password = str(input ("Input user's Password: "))
rpass = str(input("Re-enter the Password: "))
if password == rpass:
file = open("username.txt", "a")
file.write (user)
file.close()
break
else:
print("You have entered the wrong password, Try Again")
I want make a program where users can sign up with their username and password and it can be stored into a txt file. And the next person that is going to sign up won't be able to use the same username.
I renewed the code but the same problem happened, the previous username is not detected.
Every time you write to the file, it appends to the same line.
if data == user+ ":" +password:
This condition is never true as a result.
One possible solution is to add \n after every write.
file.write (user +" : "+ password +"\n")
And your condition would be
if data == user+ " : " +password:
Be mindful of whitespaces and other characters. It should be an exact match with this method.
Edit: You're checking whether the new username and password together are a match.
What you should be doing is matching user with data.split(':')[0][:-1] -
if data.split(":")[0][:-1] == user
This will collect the string till the ':' and truncate the trailing space.
If you want to use the parse module, you can run pip install parse and use this code:
import parse
pattern = '{[a-z][A_Z][0-9]} : {[a-z][A_Z][0-9]}'
lines = []
user = input ("enter username: ")
password = input ("enter password: ")
with open('username.txt', 'r') as f:
line = f.readline()
while line:
u, p = parse.parse(pattern, line)
lines.append((u, p))
line = f.readline()
users = [ u for (u, p) in lines ]
if user in users:
print(f'Username {user} is taken, please try again.')
else:
with open('username.txt', 'a') as f:
f.write(f'{user} : {password}')
print(f'Username and password successfully created.')

Python: how do I compare two lists (username & password) read from a .txt to a user input

I have written a code that is supposed to request a user to input a username and password. The program should then open a .txt file containing a list of usernames and passwords and check to see if the entered entries are valid against username and password database in the .txt file. This is the first time I am posting here so please advise what else you would require. I have hopefully attached my .py file and .txt file.
I am able to input the first username and password, but the second one, I have to input twice in order for it to be successful. I'm sure that is due to the for loop, but then I do not know how else to do the compare the inputs with the username and passwords stored in the .txt
#======== User Login ====================
#read the use.txt
username_reg = []
password_reg = []
i = 0
username_list = []
password_list = []
with open('user.txt', 'r+') as f: #open user.txt
for line in f: #Now we reading user.txt
line = line.replace(" ", "") #replace space before password with no space
line = line.replace("\n", "") #remove the next line character as this will take a space in the list
line = line.split(",") #separate user name and password
username_reg = line[0]
password_reg = line[1]
username_list.append(username_reg)
password_list.append(password_reg)
#List check
print(username_list)
print(password_list)
print(len(username_list))
username = input("Please enter username: ")
password = input("Please enter password: ")
for i in range(len(username_list)):
if username == str(username_list[i]) and password == str(password_list[i]):
print('''Please select one of the following options:
r - register user
a - add task
va - view all tasks
vm - view my tasks
e - exit''')
break
while username != str(username_list[i]) and password != str(password_list[i]):
print("invalid username or password")
username = input("Please enter username: ")
password = input("Please enter password: ")
i += 1
print("Great success")
I would approach this in a different way. Dictionaries work great when it comes to associate some specific data to a entity. In this case, I would use one to associate the password to each username.
Considering that your database stores the info as follows:
user1, password1
user2, password2
user3, password3
Then we can perform the following operation:
content = {}
with open('db.txt', 'r') as file:
for line in file.read().splitlines():
user = line.split(', ')
content.update({user[0]: user[1]})
username = input("Please enter username: ")
password = input("Please enter password: ")
if password == content[username]:
print('''Please select one of the following options:
r - register user
a - add task
va - view all tasks
vm - view my tasks
e - exit''')
We are basically opening the file, reading its lines (by using the splitlines() function of the str class), and the iterating over each line, separating the username and the password (by using split(', ') because ', ' is the separator) and updating the contentdictionary with a new record corresponding to each user.
Then, after asking for credentials, we just look the given username in our content dictionary and check that the password is the same.
I have tried to modify the for loop a bit and it works for me. Take a look.
i = 0; login = 0 #Here login is like a flag. Which get the value 1 once the login is successful else stays 0.
while i < len(username_list):
if username == str(username_list[i]) and password == str(password_list[i]):
login = 1
print('''Please select one of the following options:
r - register user
a - add task
va - view all tasks
vm - view my tasks
e - exit''')
break
i+=1
if i==len(username_list) and login == 0:
print("invalid username or password")
username = input("Please enter username: ")
password = input("Please enter password: ")
i = 0
The second if condition in the for loop checks if the login is not successful for all the values in the lists, it means the username and passwords are incorrect, so the if condition asks for the new inputs and resets the while loop to start again from 0.

How to read external file in python?

i need to be able to save and get usernames and passwords from an external file. this is what i have done so far however it constantly says that username or password is incorrect even when i enter it correctly. does anyone know how to fix this problem.
this is my current code
import time
print("Welcome...")
welcome = input("Do you have an acount? y/n: ")
if welcome == "n":
while True:
username = input("Enter a username:")
password = input("Enter a password:")
password1 = input("Confirm password:")
if password == password1:
file = open("gcsetask.txt", "a")
file.write(username + ":" + password)
file.write('\n')
file.close()
welcome = "y"
time.sleep(0.4)
print("now lets login")
break
print("Passwords do NOT match!")
if welcome == "y":
while True:
login1 = input("Enter username:")
login2 = input("Enter Password:")
file = open("gcsetask.txt", "r")
data = file.readlines()
file.close()
if data == (login1 + ":" + login2):
print("Welcome")
break
print("Incorrect username or password.")
Three methods to read a file
read() It returns the read bytes in form of a string.
fileObject.read()
You can also define, how many bytes to read by
`fileObject.read([n]) //If n is not define, it will read the whole file`
readline([n]) It reads the line and return in the form of string, It only read single line
fileObject.readline([n])
readlines() It reads all the lines of the file and return each line a string element in a list
fileObject.readlines()
Hope it helps
I have changed the code to look at each line of that file. Allowing multiple users.
import time
print("Welcome...")
welcome = input("Do you have an acount? y/n: ")
if welcome == "n":
while True:
username = input("Enter a username:")
password = input("Enter a password:")
password1 = input("Confirm password:")
if password == password1:
file = open("gcsetask.txt", "a")
file.write(username+":"+password)
file.write('\n')
file.close()
welcome = "y"
time.sleep(0.4)
print("now lets login")
break
print("Passwords do NOT match!")
if welcome == "y":
while True:
login1 = input("Enter username:")
login2 = input("Enter Password:")
file = open("gcsetask.txt", "r")
data = file.readlines()
file.close()
for line in data:
if line == (login1+":"+login2+"\n"):
print("Welcome")
break
else:
print("Incorrect username or password.")
The function readlines() saves each line in a string inside a list.
If a file contains-
first line
second line
readlines() gives: ['first line','second line']
Try accessing them using index such as data[0] and data[1]
When you use file.readlines(), the function returns a list of all lines in the file. Thus, when you define data as:
data = file.readlines()
if you print(data), you get something similar to:
['user:pass\n'] # note the the \n at the end
Then, in the following line:
if data == (login1+":"+login2):
you're trying to compare a string (login1+":"+login2) with a list, which is always False because they have different type.
Changing the condition to:
if login1+":"+login2 in data:
should fix this problem (but you'll have a different one, see below).
About the trailing \n:
file.readlines() splits the lines in a list, but does not remove the newline character. This will cause your test to still fail always, because you don't account for it in the test.
Possible solutions are:
1) include the \n in the string you search:
if '{}:{}\n'.format(login1,login2) in data:
2) read the whole file and use splitlines instead, which will remove the newline characters
data = file.read().splitlines()
The readlines method returns the list of lines which you need to iterate on it to find the appropriate login information.
data = file.readlines()
login_info = f"{login1}:{login2}\n"
if login_info in data:
print("Welcome")
break
And also you can remove \n from the end of each line using splitlines.
data = file.read().splitlines()
login_info = f"{login1}:{login2}"
if login_info in data:
print("Welcome")
break
And another alternative is remove \n from parsed lines manually.
data = [line.rstrip('\n') for line in file.readlines()]
login_info = f"{login1}:{login2}"
if login_info in data:
print("Welcome")
break

if block doesn't trigger, even when it should

Clearly I'm doing something wrong here...
accountManager = open("accountManager.txt","r")
userNameInvalid = True
while userNameInvalid == True:
userName = input("Username (this is public): ")
userNameLine = 0
for line in accountManager.readlines():
if (((userNameLine % 6) == 2) and (userName == line)):
print("The username \"" + userName + "\" taken, please choose another one.")
userNameInvalid = True
break
userNameInvalid = False
userNameLine += 1
For context: accountManager is a txt file (currently open in 'r' mode) that looks like the following:
*empty line*
Real name 1
Username 1
Email 1
Notes 1
*empty line*
*empty line*
Real name 2
Username 2
Email 2
Notes 2
*empty line*
*empty line*
Real name 3
Username 3
Email 3
Notes 3
*empty line*
As you can see, it comes in little "chunks" of 6 lines, the number of which would be unknown.
What I want it to do:
Only when the input is "Username 1", "Username 2" or "Username 3", the if statement should trigger.
What happens:
if statement never runs
UPDATE:
If statement now runs, but now, if you at first enter a taken username, it will get stuck in the while loop and never get out... Why?
It's because of the condition userName == line is never true. When you read a line using f.read(), or f.readlines(), each line is terminated with the new line character \n. So, for example, instead of "Username 1", the line will be "Username 1\n". A simple way to solve this is to append "\n" to the comparison string userName as the following.
userName = input("Username (this is public): ") + "\n"
Also, f.readlines() returns an empty list if you don't reset the file object. You can get stuck in the while loop as the result. You can fix it using f.seek(0), but instead of re-reading the file multiple times, save the list of lines for re-use.
accountManager = open("accountManager.txt","r")
userNameInvalid = True
lines = accountManager.readlines()
while userNameInvalid == True:
userName = input("Username (this is public): ")
userNameLine = 0
for line in lines:
if userNameLine % 6 == 2 and userName == line:
print("The username \"" + userName + "\" taken, please choose another one.")
userNameInvalid = True
break
userNameInvalid = False
userNameLine += 1
As you have it the code is hard to follow. I would restructure the code by first reading all the data into a more usable format, and only then validate it. You can take each section of user data and place them into a list of small dicts.
Using a while loop and iter/next you could pretty easily parse the data. You should also strip the line to remove extra whitespace:
raw_data = iter(accountManager.readlines())
user_data = []
try:
while True:
next(raw_data) # clear blank line
user_data.append(
{
'real_name': next(raw_data).strip(),
'username': next(raw_data).strip(),
'email': next(raw_data).strip(),
'notes': next(raw_data).strip(),
}
)
next(raw_data) # clear blank line
except StopIteration: # no more values in raw_data iter
pass # do nothing, we expect this
Once you have the data, I would use a set to check for duplicates:
username_invalid = False
usernames = set()
for data in user_data:
username = data['username']
if username in usernames:
print(
f'The username "{username}" '
'is taken, please choose another one.'
)
username_invalid = True
break
usernames.add(username)

How to use text file to load data and assign it to a variable?

i am new to python(learner).I created a simple program which asks for username and password and i used getpass()function to hide password
.But i want my program to load username and password from a text file.
#!/usr/bin/env python
import getpass
import os
print (' ')
print (' ')
print ('Please enter username and password in order to continue :')
print (' ')
print (' ')
user = (str(input(' USERNAME : ')))
usr_list = open("usr.txt", "r")
for line in usr_list:
line.strip()
if line == user:
password = getpass.getpass(" PASSWORD : ")
if password == 'root':
os.system("python3 cross.py")
else:
print ('WRONG! Password')
os.system("python3 sec.py")
else:
print ('WRONG! Username')
os.system("python3 sec.py")
now, if i remove text file and open function from code and insert a string like "user1" if user == "user1": it works fine.
You can read data from text file simple:
with open('your_text_file.txt', 'r') as f:
username = f.readline()
password = f.readline()
This is mean that you are open file "your_text_file.txt" for reading ('r' as second parameter) and we read first line, after that we read the next line
This is work if your username and password write in the different line:
your_text_file.txt:
sume_username
verylongandstrongpassword
You can read about read and write file here

Categories