1

So I am doing a code to login and create a username and password and when logging in, i am reading an external file that contain all the user name and passwords in dictionary form e.g. {"aaaaaaaa": "aaaaaaA999"}

This is the code to read it

f3 = open("helloworld.txt","r")
user = input("Enter login name: ")

if user in f3.read():
   passw = input("Enter password: ")
   print("")

   if user in f3.read() and passw in f3.read():
        print ("Login successful!\n")


   else:
        print("")
        print("User doesn't exist!\n")
f3.close()

However when I try and read it it keeps saying that the user doesn't exist, any suggestions

  • `read()` only works the first time you do it like that. – Mad Physicist Oct 17 '17 at 17:50
  • If you are saving all the usernames and passwords in dictionary form you might consider saving it as a json file and loading it into a dictionary so that you can just load the file and check if the username exists and if so, if the password is correct. https://docs.python.org/3/library/json.html – L. MacKenzie Oct 17 '17 at 17:52

3 Answers3

2

The function f3.read() is reading the entire file at once, and moving the file pointer to the end. Any subsequent file read without closing and reopening the file is going to return None.

You need to actually parse the file into a data structure that allows you to search for containment, instead of checking to see if the name or password exists in the entire file. What happens if two users have the same password? If you're just searching for a single string through the whole file, you're not ensuring that a password is correct for the given username.

For example, assume your file looks something like this:

username1,password1
username2,password2
username3,password3

Your parsing code should open and read the file, and check for containment without searching the whole file every time:

users = {}

with open("helloworld.txt") as f3:
    for line in f3:
        name, password = line.split(",")
        users[name] = password.strip()

user = input("Enter login name: ")

if user in users:
    passw = input("Enter password: ")
    print()

    if passw == users[user]:
        print("Login successful!")

    else:
        print("Bad password")

else:
    print("Bad username")

Note that I changed your file open to use a context manager (the keyword with). You should do this for more reliable resource management. You could also make further improvements by make the dictionary generation a dictionary comprehension, and possibly by using exceptions to handle the dictionary checking instead of if X in Y:

with open("helloworld.txt") as f3:
    pairs = (line.split(",") for line in f3)
    users = {name:password.strip() for name, password in pairs}

user = input("Enter login name: ")
passw = input("Enter password: ")

try:
    if passw == users[user]:
        print("Login successful!")
    else:
        print("Bad password")
except KeyError:
    print("Bad username")

You could even condense the user/password dictionary creation into a single comprehension, but I think that hampers readability significantly without any benefit.

skrrgwasme
  • 9,358
  • 11
  • 54
  • 84
0

The reason you're having the problem is this:

if user in f3.read() and passw in f3.read():

when you use f3.read() for the first time it will move the pointer to the end and you won't be able to read it again without reopening.

So, you can read and parse it the first time you read the file, something like this:

import ast
# since you're storing the credentials in a dict format
# ast.literal_eval can be used to parse the str to dict
creds = ast.literal_eval(f3.read())
if user in creds and creds[user] == passw:
    #login success 

Another way of re-reading file contents without reopening it would be to call f3.seek(0) before calling f3.read(). That'll move the pointer to start again but the above is better for your case.

Ashish Ranjan
  • 5,523
  • 2
  • 18
  • 39
0

It is better to use the "with" statement while you read and write data into a file like so:

with open("helloworld.txt","r") as f3:
    # Read user data
    user_data = f3.read()

    # Verify username and password are right

The with statement gives better exception handling and automatically closes the file and does any clean up necessary

suripoori
  • 311
  • 2
  • 10