1

This program works to check usernames and passwords to let a user in. However, at the end where I am adding a new user, I want the user to immediately be able to try to import their newly created username and password so they can enter the program, without re-running after their username and password are added to the database. However, this code is returning the error "list index is out of range"

STAGE 1: Opening the files and grabbing data

filename1 = "c:\Users\Anna Hamelin\Documents\Python Scripts\SourceCode\Project2\usernames.txt" file = open(filename1, "r")

#Usernames
users = file.read()
usernameslist = [line.strip() for line in open("c:\\Users\\Anna Hamelin\\Documents\\Python Scripts\\SourceCode\\Project2\\usernames.txt")]
#print(users)                #Check file
#print(usernameslist)       #Check usernames list
file.close()

filename2 = "c:\\Users\\Anna Hamelin\\Documents\\Python Scripts\\SourceCode\\Project2\\passwords.txt"
file = open(filename2, "r")

#Passwords
passwords = file.read()
passwordslist = [line.strip() for line in open("c:\\Users\\Anna Hamelin\\Documents\\Python Scripts\\SourceCode\\Project2\\passwords.txt")]
#print(passwords)            #Check file
#print(passwordslist)       #Check passwords list
file.close()

#Compile the usernames and passwords lists for easy checking
#compiled_list = list(zip(usernameslist,passwordslist))
#print(compiled_list)

#Scores
filename3 = "c:\\Users\\Anna Hamelin\\Documents\\Python Scripts\\SourceCode\\Project2\\scores.txt"
file = open(filename3, "r")

scores = file.read()
scoreslist = [line.strip() for line in open("c:\\Users\\Anna Hamelin\\Documents\\Python Scripts\\SourceCode\\Project2\\scores.txt")]
#print(scores)           #Check file
#print(scoreslist)       #Check scores
file.close()

#STAGE 2
#Print Welcome/Intro message

response = input("-"*50 + "\nWelcome! Do you have an account (y/n)? ")
print("-"*50)

#If user has an account:
if response == "y":
    #Create a login function:
    #def login():
        goodlogin = False
        username = input("Please enter your username: ")
        password = input("Please enter your password: ")  
        for id in range(len(usernameslist)):
            if username == usernameslist[id] and password == passwordslist[id]:
                goodlogin = True 
                
        if goodlogin:
            print(print_in_green + "Access granted!" + print_default)
        else:
            print(print_in_red + "Incorrect Login credentials, please try again." + print_default)
    #login()

#If user does not have account:
else: 
    newusername = input("What is your new username? ")
    newpassowrd = input("What is your new password? ")
    file = open(filename1, "a")
    file.write("\n" + newusername)
    file = open(filename2, "a")
    file.write("\n" + newpassowrd)
    file.close
    print("Now that you have created an account, please continue.")
    goodlogin = False
    username = input("Please enter your username: ")
    password = input("Please enter your password: ")  
    for id in range(len(usernameslist)):
        if username == usernameslist[id] and password == passwordslist[id]:
                goodlogin = True 
                
    if goodlogin:
            print(print_in_green + "Access granted!" + print_default)
    else:
            print(print_in_red + "Incorrect Login credentials, please try again." + print_default)
Community
  • 1
  • 1
Anna Hamelin
  • 39
  • 1
  • 9
  • 1
    Not related, but note, `file.close` should be `file.close()` – juanpa.arrivillaga Nov 16 '18 at 17:40
  • 1
    Anyway, it sounds like you want to add some sort of loop that keeps querying the user to either continue with the program or exit, is that what you are looking for? This may be a bit broad. – juanpa.arrivillaga Nov 16 '18 at 17:41
  • @juanpa.arrivillaga I want to use the code from above to allow the user to login directly after creating a new username or password – Anna Hamelin Nov 16 '18 at 17:48
  • Then probably just wrap your main `if ... else` in a `while True:...` loop. You'll have to decide how you want to handle when the loop terminates. Check out the answers to [this related question](https://stackoverflow.com/questions/23294658/asking-the-user-for-input-until-they-give-a-valid-response) for inspiration. – juanpa.arrivillaga Nov 16 '18 at 17:53
  • In particular, see [this extensive answer](https://stackoverflow.com/a/23294659/5014455) – juanpa.arrivillaga Nov 16 '18 at 18:09

2 Answers2

0

You can abstract that interaction logic out into a loop. You can also remove a bunch of code with you use the with option of opening/closing files. Here's a prototype to keep users and passwords updated.

Your authentication is .... not safe haha, since multiple users can have the same password etc. I would create a hash out of the combination of the user and password, but thats a different story :)

def interact(user_names_ls, passwords_ls):
    goodlogin = False
    username = raw_input("Please enter your username: ")
    password = raw_input("Please enter your password: ")
    if username in user_names_ls and password in passwords_ls:
        goodlogin = True

    if goodlogin:
        print( "Access granted!")
    else:
        print("Incorrect Login credentials, please try again.")
        interact(user_names_ls, passwords_ls)


usernames_file_path = "usernames.txt"
with open(usernames_file_path, "r") as f:
    user_names_ls = f.readlines()
    user_names_ls = [user.rstrip() for user in user_names_ls]

passwords_file_path = "passwords.txt"
with open(passwords_file_path, "r") as f:
    passwords_ls = f.readlines()
    passwords_ls = [password.rstrip() for password in passwords_ls]


print("-"*50)
end_interaction = False

while not end_interaction:
    response = raw_input("-" * 50 + "\nWelcome! Do you have an account (y/n) [q to quit]? ")

    if response == "q":
        end_interaction = True

    #If user has an account:
    if response == "y":
        interact(user_names_ls, passwords_ls)

    #If user does not have account:
    else:
        newusername = raw_input("What is your new username? ")
        newpassowrd = raw_input("What is your new password? ")

        # here's where we can update our user and password cache
        user_names_ls.append(newusername)
        passwords_ls.append(newpassowrd)

# officially update the 'databases'
with open(usernames_file_path, "w") as f:
    user_names_ls = f.writelines(user_names_ls)


with open(usernames_file_path, "w") as f:
    passwords_ls = f.writelines(passwords_ls)

Sample interaction:

Welcome! Do you have an account (y/n) [q to quit]? n
What is your new username? he
What is your new password? 99
--------------------------------------------------
Welcome! Do you have an account (y/n) [q to quit]? y
Please enter your username: he
Please enter your password: 99
Access granted!
--------------------------------------------------
Welcome! Do you have an account (y/n) [q to quit]? 

btw - I used raw_input here but you can just swap that with input

LeKhan9
  • 1,300
  • 1
  • 5
  • 15
0

I added a couple of functions to reduce code reuse. Also I load the usernames and passwords in the login_user function so it always gets the latest copy.

users_path = "c:\\Users\\Anna Hamelin\\Documents\\Python Scripts\\SourceCode\\Project2\\usernames.txt"
passwords_path = "c:\\Users\\Anna Hamelin\\Documents\\Python Scripts\\SourceCode\\Project2\\passwords.txt"
scoreslist_path = "c:\\Users\\Anna Hamelin\\Documents\\Python Scripts\\SourceCode\\Project2\\scores.txt"


def get_file_contents(file_path):
    return [line.strip() for line in open(file_path)]

scoreslist = get_file_contents(scoreslist_path)

def add_file_contents(file_path, contents):
    with open(file_path, "a") as file:
        file.write(contents)

def login_user(new_account=False):
    usernameslist = get_file_contents(users_path)
    passwordslist = get_file_contents(passwords_path)

    if new_account:
        response = 'y'
    else:
        response = input("-"*50 + "\nWelcome! Do you have an account (y/n)? ")
        print("-"*50)

    #If user has an account:
    if response == "y":
            goodlogin = False
            username = input("Please enter your username: ")
            password = input("Please enter your password: ")
            for id in range(len(usernameslist)):
                if username == usernameslist[id] and password == passwordslist[id]:
                    goodlogin = True

            if goodlogin:
                print("Access granted!")
            else:
                print("Incorrect Login credentials, please try again.")

    #If user does not have account:
    else:
        newusername = input("What is your new username? ")
        newpassword = input("What is your new password? ")
        add_file_contents(users_path, '\n' + newusername)
        add_file_contents(passwords_path, '\n' + newpassword)
        login_user(new_account=True)

login_user()
Jason
  • 475
  • 2
  • 4
  • This is so helpful! I got a NameError: name 'get_file_contents' is not defined. How can I fix it? – Anna Hamelin Nov 16 '18 at 18:21
  • Did you copy/paste the code as is? It should work. It was running on my machine. get_file_contents is the function defined on line 7. – Jason Nov 16 '18 at 19:23
  • I copied and pasted. I can't figure out why I am getting that error. – Anna Hamelin Nov 16 '18 at 19:51
  • Guess I had it commented it when I ran it before. Moved scoreslist below the function declaration and fixed it. Should work for you now if you copy / paste it. Sorry about that. – Jason Nov 16 '18 at 20:08