I have to make a program in which one of the functions is retrieval of usernames and results from a text file. (All on the same line)
For some reason, when I run it, only the first line is printed out. Why is this ? Also, this only happens when I try to run the program at school (part of an assignment), it prints everything it needs to on my laptop at home. (Python versions are also the same)
Here is my code :
def results():
username = input("Enter username :")
for line in open("resultsfile.txt","r"):
if username in line:
print (line)
elif username not in line:
("No such user")
Also, this is what the text file looks like (without bullet points) :
tud16 CS Easy 2points
ser23 CH Med 4points
tud16 CS Hard 1points
def results():
username = input("Enter username :")
for line in open("resultsfile.txt","r"):
if username in line:
print (line)
else:
print("No such user")
results()
You are iterating over a file but you are printing No such user for every line that does not match the username.
What you should do is evaluate after the loop if one of the lines in the file contained the username. To implement this you could introduce a boolean (found) indicating if a user has been found or not:
def results():
found = False
username = input("Enter username :")
for line in open("resultsfile.txt","r"):
if username in line:
print (line)
found = True
if not found:
print("No such user")
Related
I am attempting to implement a simple password checker which will allow the user to open a text file that contains generated passwords and check them against a list of criteria to see if the password is strong or weak. It should then output the password with the result of whether it is strong or weak.
With the current solution I can get the list of passwords to print, but when the check as to whether the password is strong or not, only one result is shown. I am attempting for the output to be the password that is generated with the result e.g. Randompassword123 - This is a weak password.
Below is the code I am currently using:
def multiplestrength(): # password strength check function
textfile = filedialog.askopenfilename(initialdir="/home", title = "Select text file to split",filetypes = (("text files","*.txt"),("all files","*.*")))
with open(textfile , mode="r",encoding="utf-8") as my_file:
data=my_file.read()
print(data)
def strongPassword(data):
if passRegex1.search(data) == None:
return False
if passRegex2.search(data) == None:
return False
if passRegex3.search(data) == None:
return False
if passRegex4.search(data) == None:
return False
else:
return True
passRegex1 = re.compile(r'\w{8,}')
passRegex2 = re.compile(r'\d+')
passRegex3 = re.compile(r'[a-z]')
passRegex4 = re.compile(r'[A-Z]')
if strongPassword(data) == True:
print("Strong Password")
else:
print("This is not a strong password")
The output I receive is below
So it appears that only one password is being checked from the list of 5 passwords in the text file. I believe there might need to be a for loop required somewhere for each password to be checked, but I am unsure what way to approach this. Another approach I was thinking would be to insert the passwords from the text file into a list and iterating through this list to get a result for each password. Does this possibly sound like the correct way to approach this?
Any help with this would be greatly appreciated.
Thanks
I have written a solution. I have added many comment for code as description.
Code:
import re
passRegex1 = re.compile(r'\w{8,}')
passRegex2 = re.compile(r'\d+')
passRegex3 = re.compile(r'[a-z]')
passRegex4 = re.compile(r'[A-Z]')
def strong_password(data): # the function name should be snake case
if not passRegex1.search(data): # Use "if not". It is the Pythonic way. It handles False/None/0/""/[] etc...
return False
if not passRegex2.search(data):
return False
if not passRegex3.search(data):
return False
if not passRegex4.search(data):
return False
else:
return True
with open("test.txt", mode="r", encoding="utf-8") as my_file: # Open file for reading
for line in my_file.readlines(): # Read all lines one-by-one
print("\nPassword: {}".format(line.strip())) # Print the current password ("strip" removes the whitespace characters from string).
if strong_password(line): # This statement is True if the "strong_password" function returns True
print("Strong Password")
continue # Get the next element (line of file)
print("This is not a strong password") # Else statement is not needed because the "if" contains a continue
My test file:
asdf
121234
adsf123
asdffdsatre323423
fdggfd2323____,,,**
tt
333345
asdfSDFGRAdsfAERTGRghRGads___++((((FDsaSDfAS4233423524
434
55555
Output:
>>> python3 test.py
Password: asdf
This is not a strong password
Password: 121234
This is not a strong password
Password: adsf123
This is not a strong password
Password: asdffdsatre323423
This is not a strong password
Password: fdggfd2323____,,,**
This is not a strong password
Password: tt
This is not a strong password
Password: 333345
This is not a strong password
Password: asdfSDFGRAdsfAERTGRghRGads___++((((FDsaSDfAS4233423524
Strong Password
Password: 434
This is not a strong password
Password: 55555
This is not a strong password
You could loop through the lines of your file using:
with open(textfile , mode="r",encoding="utf-8") as my_file:
for line in my_file:
# do something with the line, eg:
if strongPassword(line):
# ...
Edit: you might want to use line.strip() instead of line to get rid of the newline characters at the end (\n)
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)
This is a text file accountinfo.txt:
Luke TonyHawk123! luke33#gmail.com
Cindy JasonVoorhees123! cindy5#yahoo.com
I want to ask the user for their email to print the values (i.e. their username and password) on the left. For example, if the user inputs luke33#gmail.com, it should return Luke and TonyHawk123.
I've tried using strip and split, but my logic is wrong.
Work I've done so far:
account_file = open("accountinfo.txt")
email_string = account_file.read().strip().split()
while True:
email_account = input("Enter the email linked to your account: \n")
if email_account == "":
continue
if email_account in email_string:
# ???
else:
print("This email doesn't exist in our records.")
main()
You can apply csv.reader here:
import csv
with open("accountinfo.txt") as f:
reader = csv.reader(f, delimiter=" ")
email = input("Enter the email linked to your account: \n")
for row in reader:
if row and row[2] == email:
print(" ".join(row[:2]))
break
else:
print("This email doesn't exist in our records.")
main()
You can also split each line manually:
with open("accountinfo.txt") as f:
email = input("Enter the email linked to your account: \n")
for line in f:
if email and email in line:
print(line.rsplit(" ", 1)[0])
break
else:
print("This email doesn't exist in our records.")
main()
I don´t know how the information of each e-mail is arranged but if they´re in the same file. I did a similar program, but the information of each username was separated with a sting like this: "----------------". So I iterated through lines until it found the e-mail. Once it found it, I would print every line until it found another "----------------". So all the user´s information was between those lines. You can do something similar depending on how your information is arranged. You can iterate through the lines of the file with:
validation = False
for line in file:
if email in line:
validation = True
while line != "---------------":
print(line, end="")
if validation == False:
print("This email doesn't exist in our records.")
I am trying to create a very simple piece of code which will search through a text file to see if a username has been registered or not. However I am unsure how to search through the text file to find a match for the username.
Here is my code so far:
NotLoggedIn = False
while NotLoggedIn == False:
username = input("\nplease enter a username or to sign in type '!'")
for next in records:
if username == records:
print("hi")
NotLoggedIn = True
Thanks in advance.
Here is what you can try provided you have a textfile named records.txt since as per your question you need to search through a text file.
f = open("records.txt", 'r')
NotLoggedIn = False
while NotLoggedIn == False:
username = input("\nplease enter a username or to sign in type '!'")
for line in f.readlines():
if username in line:
print("hi, username exists in the file")
NotLoggedIn = True
break
if not NotLoggedIn:
print ("User does not exist in the file")
f.close()
It depends on how you wrote your text file.
if that text file is like this :
username1\nusername2\n
...
Then we can code like this :
f = open("records.txt","r")
m = f.readlines()
f.close()
NotLoggedIn = False
while NotLoggedIn == False:
username = input("\nplease enter a username or to sign in type '!'")
for line in m :
if line.replace("\n","") == username : # removing "\n" from the line
print("hi")
NotLoggedIn = True
break # No need to check others
It is important to be specific.
You shouldn't use "in" to find a username inside of a string, because if you have a username called string then if someone types str , it will be like this :
if "str" in "string"
Witch will be true But it doesn't exist in your text file. So try using "==" operator.
I have this text file that contains:
Ryan#Male#Ryan123#Ryan321#
Lina#Female#Lina123#Lina321#
the order is Name#Gender#username#password.
user = username.get() //from tkinter entry
pass = password.get()
counter = IntVar()
counter = 0
file = open("user.txt", "r")
for login in file:
login = login .split('#')
if user == login [2]:
counter += 1
if pass== login [3]:
counter += 1
file.close()
if counter == 2:
//go to next page
else:
print "wrong username or password!"
this works, but, when I tried to print login[2], it returned;
Ryan123
Lina123
and when I used Ryan as username, I still can login using Lina's password aswell. How can I make it check the content in .txt file row per row?
I mean like, check this row first:
Ryan#Male#Ryan123#Ryan321#
and when the login info is not found, it will proceed to next row.
The password problem is because you never reset counter between lines. But it can be done even more simply without counting conditions:
file = open("user.txt", "r")
for login in file:
login = login.split('#')
if user == login[2] and password == login[3]:
print 'Correct username/password'
break
else:
print 'Invalid username/password'
pass, by the way, is a keyword in Python, so it's a good idea to use something else for your variable name.
You need an "and" condition here, since password and username should match!
he_is_cool = False
for login in file:
login = login .split('#')
if user == login [2] and pass== login [3]:
he_is_cool = True
break
file.close()
if he_is_cool:
//go to next page
else:
print "wrong username or password!"
Note that break will "kill" your loop, when you have identified the user. The program will also work without break.
You are checking two different fields possibly lying on two different lines (e.g. the user matches Ryan and the password matches Lina's).
Normally user and password must both match for a single given user.
So you can get rid of the counters and try with
pwd = password.get()
with open("user.txt", "r") as file:
for login in file:
login = login .split('#')
if user == login[2] and pwd == login[3]:
pass # go to next page, substitute pass on this line!
else:
print "wrong username and password!"