I've looked up similar stackoverflow questions but none are quite like this.
Quite simply, I have the following code that seeks to look up a dictionary for a username and corresponding password. If they match, then access granted and go to the loggedin function, else access denied.
Having set it up like below, it works perfectly when the credentials are correct, but on getting them wrong, results in a key error:
Code
username=input("Enter username:")
password=input("Enter password:")
accessgranted=False
while accessgranted==False:
if userinfo_dict[username]==password:
loggedin()
accessgranted==True
else:
break
print("Sorry, wrong credentials")
main()
Error
if userinfo_dict[username]==password:
KeyError: 'ee'
The file is simply:
user1,pass1
user2,pass2
Could someone please
a) Correct and comment on the error
b) Suggest alternative or more efficient ways of achieving the same thing
The problem is, as many others already pointed out, you are trying to get the value for a non-existing key.
An easy workaround would be to check if userinfo_dict[username] == password only if username is an existing key.
username = input("Enter username:")
password = input("Enter password:")
access_granted = False
while access_granted is False:
if username in userinfo_dict.keys() and userinfo_dict[username] == password:
loggedin()
access_granted = True
else:
break
print("Sorry, wrong credentials")
main()
Edit: access_granted flag is useless, you could do just:
username = input("Enter username:")
password = input("Enter password:")
if username in userinfo_dict.keys() and userinfo_dict[username] == password:
loggedin()
else:
print("Sorry, wrong credentials")
You could check that both the username and passwords are in the dictionary and that they are a key-value pair, with the following:
#Check that both username and password in dictionary
if username in userinfo_dict.keys() and password in userinfo_dict.values():
if userinfo_dict[username] == password:
accessgranted = True
else:
print('Access Denied') #Print if either username or password not in dictionary
The keys() method returns a list of the keys in the dictionary whereas the values() method returns a list of the values in the dictionary.
Almost always use dictionary.get(key) instead of dictionary[key]. The former is safe for when keys don't exist (like in this case) while the latter will throw an error.
if userinfo_dict.get(username) == password: # returns None is key doesn't exist
loggedin()
accessGranted=True
else:
break
What the error is telling you is that you have entered the value "ee" for the user name, but there is no user named "ee" (that is, no key-value pair with the key "ee") in the dictionary. This is the expected result when attempting to get the value for a non-existent key.
The correct python idiom for testing for the presence of a key is:
if user_name in userinfo_dict:
I concur to the above. The problem is with getting the non-existing key. Try it either:
via try/except block,
via dictionary get() method.
Also the code requires a bit of refactoring e.g.:
checking to False via 'is' a;
accessgranted==True should be assignment, not comparison;
the logic of loop had to be changed as well.
See below:
username = input("Enter username:")
password = input("Enter password:")
access_granted = False
while access_granted is False:
if userinfo_dict.get(username) == password:
# loggedin()
access_granted = True
else:
print("Sorry, wrong credentials")
break
# main()
Related
For practice purposes I tried coding a little registration/login system which stores the registered users' data in a list.
I tried to solve this by getting user input (name, nickname and password), then create a list with the chosen "Name" which then stores "Nickname" and "PW" . This then should be then stored in the created list "users" which is being created in the beginning.
So I would have a list with different names/persons which includes their data.
The problem is that in the else statement it won't let me create the name-variable list with (username, password) in it. "TypeError: string indices must be integers"
users = []
def register():
print("Please insert your Name")
name = input()
print("Please insert your Username")
username = input()
print("Please type your Password")
userpw = input()
if name in users:
print("Account already exist, try again")
register()
else:
users.append(name[username, userpw])
This code creates a dictionary for a user and then check if its already registrated. I recommend using some sort of database to avoid dataloss from program restarts.
users = []
def register():
print("Please insert your Name")
name = input()
print("Please insert your Username")
username = input()
print("Please type your Password")
userpw = input()
for x in users:
if x['name'] == name:
print("Account already exist, try again")
register()
return
user = {'name': name,
'username': username,
'password': userpw}
users.append(user)
This is my code for Verifying User ID and password from a csv file.
CODE
import pandas as pd
login():
df=pd.read_csv("IDPASS.csv")
for i in range(len(df)):
x=input("Enter User Name=")
y=input("ENter The Password=")
if (df.iloc[i]["ID"])==x:
if str(df.iloc[i]["PASS"])==y:
print("Succesfully Logined")
break
else:
print("Invalid Password")
print("Try Again!!")
else:
print("Invalid Username")
print("Try Again!!")
login()
Output1:
Enter User Name=JEET1073
ENter The Password=str1234
Succesfully Logined
Here I have entered correct id password and the code is executed perfectly!!
Output2:
Enter User Name=dw
ENter The Password=wd
Invalid Username
Try Again!!
Enter User Name=JEET1073
ENter The Password=str1234
Invalid Username
Try Again!!
Enter User Name=JEET1073
ENter The Password=str1234
Invalid Username
Try Again!!
Enter User Name=JEET1073
ENter The Password=str1234
Invalid Username
Try Again!!
Enter User Name=JEET1073
ENter The Password=str1234
Invalid Username
Try Again!!
Here at first i have entered wrong id and password and then i was trying to enter the correct id and password but it was showing invalid username. any solutions will be appreciated,also i want a solution in which if a user enters wrong id password the code should run again asking id and password till the user id and password entered is not correct.Thanks in advance.
After the clarification, this should be the functionality you are seeking.
First import pandas and read the csv:
import pandas as pd
df = pd.read_csv("IDPASS.csv")
We will now read the values stored in the csv and store them as a list. A list of users and a list of passwords. A good practice would be to do this outside of any loops.
csv_id_list = df['ID'].to_list()
csv_pass_list = df['PASS'].to_list()
If you don't know how long your loop will have to go on for (we don't know how many times the user will try the password) use a while loop. Initialize the initial state of the correct login variable.
correct_login = False
Now where the magic happens. We will start a while loop. While correct_login is false, we will keep asking the user for their username and password. IF the input by the user matches a list element, get the index for that list element, then start another IF statement. . This will break the while loop. ELSE they get an invalid password message, IF the input matches the list element at the correct index, print correct_msg and correct_login = True. Break while loop. ELSE correct_login is still false, user must try again.
This means that the user must input the correct username and the password it corresponds to, they cannot input the password of another user and log in.
while not correct_login:
x = input("Enter User Name=")
y = input("Enter The Password=")
correct_msg = 'Successfully logged in.'
incorrect_msg = 'Invalid Password.' + '\n' + 'Try Again.'
if x in csv_id_list:
x_index = csv_id_list.index(x)
if y == csv_pass_list[x_index]:
print(correct_msg)
correct_login = True
else:
correct_login = False
print(incorrect_msg)
else:
correct_login = False
print(incorrect_msg)
For some reason the and operator is not functioning properly within the while loop.
When I go to run the code it will exit the loop when either the password or username are matching and not both.
Any help would be great.
root_password = "password123"
root_username = "root"
username = "default"
password = "default"
while username != root_username and password != root_password:
username = input("Username: ")
password = input("Password: ")
if username != root_username and password != root_password:
print("Wrong Credentials")
print("Welcome")
The and operator is exactly doing what it should, it stays in the loop as long as both are not matching.
What you want is continuing loop until both match, so you have to use the OR operator here
This will result in True only when both, username and password don't match. In case the username is correct but password is wrong, False and True = False, and loop will end. What you need is to prompt "Wrong credentials" when either of them is wrong, using OR.
This is a common error while operating on negations or complements. Refer to De-Morgan Laws:
!(username == root_username and password==root_password)
is
username != root_username or password!=root_password
One way to do this is to create a conditional which checks if both the username and password are matching and then put a not in front of that conditional, like this:
not (username == root_username and password == root_password)
This just checks if the user doesn't have a matching username and password, or doesn't have the right credentials.
As Speeeddy has stated, using De-Morgan Laws, this conditional is the same as username != root_username or password != root_password, but this just makes the code easier to read and understand.
Here's the code with this change:
root_password = "password123"
root_username = "root"
username = "default"
password = "default"
while not (username == root_username and password == root_password):
username = input("Username: ")
password = input("Password: ")
if not (username == root_username and password == root_password):
print("Wrong Credentials")
print("Welcome")
accounts = {"key":"value","thy":"l23","user2":"psw2"}
a = input("Enter username: ")
b = input("Enter password: ")
if accounts[a:b] == True:
print("Welcome")
TypeError: unhashable type: 'slice'
What does the error mean? How can I fix it?
If I understand what you're trying to do (validate a username and password), you need to go about it this way:
accounts = {"key":"value","thy":"l23","user2":"psw2"}
a = input("Enter username: ")
b = input("Enter password: ")
if accounts[a] and accounts[a] == b:
print("Welcome")
This tests to see if a password exists for the entered user, then tests to see if the entered password matches the one stored in accounts.
The major problem with this method is that the entered password is printed out when you type it in. To get around this, use the getpass.getpass() function.
The
if accounts[a:b] == True:
should read
if accounts.get(a) == b:
The reason I used accounts.get(a) instead of accounts[a] is that the former would return None if a does not contain a valid username (the latter would raise an exception).
I have tried to create an app in Python that makes a user create a password and then makes them verify it. Obviously I had to create a loop so that when the user entered an unmatching password they had to try again. I am not very experienced with loops so here is what I got. How do I make this work?
here is the code:
password = raw_input ("Create a password: ")
passwordv = raw_input ("Retype your password: ")
a = ("Passwords don't match! Please try again!: ")
b = ("Congrats, you have created a password")
def password():
if password == passwordv :
print ("Congrats, you have created a password")
else :
print (a)
return password
return passwordv
while password !=passwordv:
print (a)
here is another set of code trying to do the same thing:
password = raw_input('Create a password: ')
passwordv = raw_input('Veryify your password: ')
while (password != passwordv):
print raw_input('Passwords do not match, try again: ')
if (password == passwordv) :
print ('Password set')
break
Your conditional to test whether the passwords match was included in the loop which checks that they don't match -- so, it never gets run.
Try this instead:
password = raw_input('Create a password: ')
passwordv = raw_input('Verify your password: ')
while (password != passwordv):
print raw_input('Passwords do not match, try again. ')
password = raw_input('Create a password: ')
passwordv = raw_input('Verify your password: ')
continue
print ('Password set')
Note how only the code that should be run if the passwords don't match is included within the while loop.
What you need here is an "N and a half times loop". To avoid repeating code (guided by the DRY principle) you might consider writing a function to get the passwords. The following might work:
def get_passwords():
password = raw_input('Create a password: ')
passwordv = raw_input('Veryify your password: ')
return password, passwordv
pw1, pw2 = get_passwords()
while pw1 != pw2:
print "Sorry, passwords do not match"
pw1, pw2 = get_passwords()
The loop won't be entered at all if the original passwords match. Otherwise it will repeat until they do.
password=raw_input('Enter password: \t\t\t')
passwordv=raw_input('Enter password again to verify: \t')
if password == passwordv:
print "\ncongratz you have created password"
else:
print "\nPlease try again...!"
while password != passwordv:
password=raw_input("Enter password: \t\t\t")
passwordv=raw_input("Enter password again to verify: \t")
if password == passwordv:
print"\ncongratz you have created password"
else:
print"\nPlease try again...!"
I know this one is long, It is just for basic understanding
The other answers provide the code that will do what you want. I thought that it could be interesting to tell you a little bit more what was wrong with the code you provided because the problem is more about your understanding of how things work.
1st attempt: a variable and a function have the same name
# Here you define your password variable as a string
password = raw_input ("Create a password: ")
[...]
# And then you reassign it here: it contains now the address of that function!
def password():
[...]
# Now you're comparing a function to a string: they'll never be equal
while password !=passwordv:
[...]
This could have been avoided simply by changing the name of your function (which is never called by the way so I'm not sure what you wanted to do but I thought you might find that interesting). Further reading: Python: function and variable with same name
2nd attempt: the values of the variables stay the same
password = raw_input('Create a password: ')
passwordv = raw_input('Veryify your password: ')
# At this point, if the test is true, you'll reach the end of the code without
# displaying the 'Password set' message you wanted
while (password != passwordv):
# This only prints a message
print raw_input('Passwords do not match, try again: ')
# The condition below can never be true: you just tested that they were
# different but did nothing to give them new values!
if (password == passwordv) :
print ('Password set')
break
The way to fix that is what the other answers provide: take your message out of the loop (getting out of the loop means that your condition was met) ; make sure that you do something inside the loop that will assure that the next test will be different from the previous one (otherwise, you will end up testing the same values over and over again) ; to avoid breaking inside the loop, set your values outside the loop, and then get new values inside the loop in case the initial test failed.
Here's an idea:
First define these:
MinPass = 6
MaxPass = 12
Then this:
print ("Now, lets try with a password. Please enter one here")
EnteredPassword = input("Password: ")
while len(EnteredPassword) < MinPass:
print ("That password is too small. Please try again")
EnteredPassword = input("Password: ")
while len(EnteredPassword) > MaxPass:
print ("That password is too long, please try again")
EnteredPassword = input("Password: ")
Hope this helps!