No matter what I do, the code always reverts to the first username or password is incorrect statement. Here is the code:
lines = []
usernames = []
passwords = []
foundU = False
foundP = False
counter = 0
with open("login_project/logins.txt", "r ") as f:
lines = f.readlines()
f.close()
for element in lines:
if counter % 2 == 0:
usernames.append(element.strip())
else:
passwords.append(element.strip())
counter = 1
def Search(lista, val, found):
for i in range(0, len(lista)):
if lista[i] == val:
found = True
else:
pass
return found
def login():
username = input("Please enter your username: ")
password = input("Please enter your password: ")
Search(usernames, username, foundU)
Search(passwords, password, foundP)
if foundU == False or foundP == False:
print("Username or password is incorrect")
elif usernames.index(username) != passwords.index(password):
print("Username or password is incorrect 2")
else:
print("Login succesful")
login()
The error occurs here mainly:
if foundU == False or foundP == False:
print("Username or password is incorrect")
elif usernames.index(username) != passwords.index(password):
print("Username or password is incorrect 2")
else:
print("Login succesful")
Would appreciate any help, only doing this at a GCSE level so I am still quite a begginer.
edit: also in the file is just:
User01
password
User02
password2
CodePudding user response:
Search never changes foundU or foundP. Passing a variable to a function in Python doesn't necessarily mean that if you change the variable in the function, that it will change the original. You just need to do something like foundU = Search(usernames, username). In addition, since foundU and foundP are globals, if you want to change their values globally, you have to declare them as globals:
...
def login():
global foundU
global foundP
username = input("Please enter your username: ")
password = input("Please enter your password: ")
foundU = Search(usernames, username, foundU)
foundP = Search(passwords, password, foundP)
...
However, Search is unnecessary, since Python's in operator does what you want. So you could just do:
foundU = username in usernames
foundP = password in passwords
CodePudding user response:
You have global variables foundU and foundP - these are not being modified inside your function when you call search. Even if they were - your function would simply create a local copy unless you "tell" your code not to.
def login():
global foundU # to modify a global from local scope
global foundP
username = input("Please enter your username: ")
password = input("Please enter your password: ")
# set var using returned val from call to function
foundU = Search(usernames, username, foundU)
foundP = Search(passwords, password, foundP)
If you were to have your login routine return an indicator of login (a bool perhaps) to where it is called, you may be better to remove the global vars and just use two locals.
After posting this, I noticed another problem with using the search function as implemented, and with using the "in" keyword as suggested.. neither will ensure that the username and password match... any username with any password would get authenticated.... so, here is a version that seems to work but it does not need the global vars
lines = []
usernames = []
passwords = []
counter = 0
with open("login_project/logins.txt", "r ") as f:
lines = f.readlines()
f.close()
# ensure there is a password for each user
assert len(usernames) == len(passwords), "Error reading file"
for element in lines:
if counter % 2 == 0:
usernames.append(element.strip())
else:
passwords.append(element.strip())
counter = 1
def validate(u_name, password):
'''Check that user and p/w are at same indices
in each of the lists'''
for i in range(0, len(usernames)):
if usernames[i] == u_name:
if passwords[i] == password:
return True
return False
def login():
username = input("Please enter your username: ")
password = input("Please enter your password: ")
found = validate(username, password)
if found:
print("Login successful")
return True
else:
print("Username or password is incorrect")
return False
login()
A better data structure may be to use a dict for usernames (keys) and passwords(values) and write these to a json file which looks very similar with the caveat that all the data is stored as str.
