A Loop I can never return from - python

So I have been tasked with creating a Login function using an intake from a pickle file, my only issue (that I have noticed) so far is that I can never get out of the loop.
for counter in range(len(Users)):
UserN = input("Username: ")
if UserN in Users[counter]:
PassW = input("Password: ")
if PassW in Users[counter]:
print("User Authenticated")
break
else:
attempt = 1
while attempt != 4:
print("Password Incorrect | Attempt", attempt)
PassW = input("Password: ")
if PassW in Users[1]:
print("User Authenticated")
MainMenu()
else:
attempt = attempt + 1
if attempt == 4:
print("\nToo many attempts, you are locked out")
exit()
else:
print("\nUser not found!\n")

If the user is authenticated, the count of the attempt will stop increasing, but the condition for the while-loop is stop is attempt == 4, so it will be stuck until the user has typed in the wrong password 4 times.
To fix it, either add a variable authenticated before the while-loop and initialize it as False, then set it to True once the user has successfully been authenticated.
attempt = 1
authenticated = False
while attempt != 4 and !authenticated:
...
if PassW in Users[1]:
...
authenticated = True
Or if you don't want a new variable, simply break by
if PassW in Users[1]:
...
break
to break the loop

If you the password is found, you call another function but you never exit from the loop. You should add a break statement.

You can add a break statement under
MainMenu()
break;

The logic in your code seems quite wonky.
This code assumes that the username is the first appearing in Users; if the second user logs in, they need to enter their name twice, the third user 3 times, and so on. If you mistype your name on your "turn", you won't be able to log in at all.
I would suggest the following structure:
Turn your variable "Users" into a dictionary, mapping user name to password.
Ask the user name.
If the user name does not appear, either stop or loop (you might want to prompt to ask whether they want to try again or not, or just let them press ctrl-D to stop (and catch the ensuing EOFError or KeyboardInterrupt (which happens if they press ctrl-C instead).
Some other issues, that are not as crucial for this question but good guidelines:
Use proper style conventions. Variable names should not start with upper case characters. Same for goes for functions. It should be users, passw, main_menu().
You really should not store passwords in a pickle file; that is obfuscation rather than security. Have a look at https://www.geeksforgeeks.org/getpass-and-getuser-in-python-password-without-echo/ for better practices.
When you say the user is locked out, nothing actually happens. They are not really locked out; they could just try again. That means you can just create a bit that brute-forces password guesses
Let them enter the password, with a maximum number of guesses.
A good rule is to test for attempt > 3 instead of attempt == 4. This does not make a difference here, but in larger functions, it's often good practice to make the test a bit "wider".

Related

Noob's python journey pt. 1: Functions and commands that jump everywhere [duplicate]

This question already has answers here:
Asking the user for input until they give a valid response
(22 answers)
Closed 3 years ago.
So, noob here, now that's out of the way let's get to the problem shall we?
(First post, ever)
So, my code (below) is quite inconsistent. I have just begun, about two days ago, and I'm dying to become better and love all kinds of critique, so unload all you've got.
When the user enters "login" to login he gets prompted to enter the username (a separate function creating a global variable for the password function to use as the welcoming name.) and is immediately redirected to the password check. Here there are two outcomes: 1. The user types in the correct password, the user will be "let in:" "Welcome " + username + "." 2. The user types in the wrong password/types anything that isn't the password: the user is sent back to the username check. But what happens for me is that the Python instead jumps back to the intro code and exits the program with: "Invalid input." And it seems as if the program goes to the password function, does its thing and immediately reverts to the former function.
Tl:Dr: Functions don't loop as they should, instead return to the previous function, thus ignoring the action I wrote.
Excuse me for the wall of text, and please, please please for the love of god or anything, don't hit me with a wall of code and "Fixed!" I'm very new and barely understand anything outside this patch of code which I myself wrote with my new gained experience. Otherwise it will end up with a [ctrl + c --> ctrl + v] situation and I really, really want to learn, not copy. So if you think you have what it takes, please do your best, everything is appreciated :)
Ps: Tips & Tricks are valuable for me!
PPs: If you want more code, just say it and I'll do my best.
Changes in the login screen:
choice = input
if input blah blah:
"function"
creating a whole function for it
moving the commands around
messing with other codes
# Password check.
def password_check():
print("Please enter your password")
print("")
password = input("")
if password == "1234":
return "Welcome " + username + "."
elif password != "1234":
username_check()
# Intro screen: invalid input notifier.
if choice != ["login", "exit"]:
print("Invalid input.")
input(" ")
Your if statement checking password was in the global area and not inside your function.
# Password check.
def password_check():
password = input("Please enter your password\n\n ")
if password == "1234":
return "Welcome " + username + "."
elif password != "1234":
username_check()
# Intro screen: invalid input notifier.
if choice != ["login", "exit"]:
print("Invalid input.")
input(" ")

How do I use an elif statement properly?

Please don't judge me.. I've only been working with Python for a month now.
While laying in my bed I thought of making this and created it in a few minutes but I made to many else and if statements and my code just looks so messy, I kept adding things that weren't needed..(For fun :D)
Anyways, here is my code.. If you could tell me how to use the "elif" statements properly that'd be awesome.(I'm still learning python)
Question: I've tried using an elif statement multiple times and I keep getting an error. How do I fix this?
key = True # Game key, if this is false the program won't work.
print("Please type a password: ") # Asking for users password
Pass = input()
print("Thank you for typing your password, please make sure it's secure by trying again..") # Ask them to confirm their password by re-typing it
Again = input()
if Pass == Again:
print("Thank you for choosing a working password, please create your character")
print("Please type your username without numbers")
else:
print("Something's wrong with your password or username!")
# Has user confirm if his information is correct
User = input()
print("checking..")
if User.isalpha() and key == True:
print("So your Username is " + User + " and your chosen password is: " + str(Pass))
else:
print("Either your key is broken or something is wrong..")
if len(User) >= 4: # Checking if the chosen username has 4 or more characters in it
print("The length of your Username is: ")
print(str(len(User)))
print("If this information is correct please type 'true' or 'false'")
else:
print("Please type a username longer than 4 characters!")
answer = input() # I kinda fucked up because my coding is dirty and unorganized lol..
if answer == str(True):
print("Thank you, we're setting up your account! :D")
else:
print("Please re-run the program and fix your information!")
We can't debug code you haven't posted, and (as is to be expected - you are on a learning exercise here, and there's a lot to think about) your program structure isn't very helpful. For example, when the user enters non-matching passwords you tell them about it, but nevertheless continue to ask them for their username. Don't worry about this, you will soon learn how to fix it.
Since you ask about the elif, it is basically a syntax abbreviation for else if that avoids going to multiple indentation levels. Suppose you wanted a value of '1' or '2' to take different actions, and to declare other values invalid. You could write
if value == '1':
#take action appropriate to 1
else:
if value == '2':
# take action appropriate to 2
else:
raise ValueError("Allowed inputs are '1' or '2'")
Note that the different actions are at different indentation levels. The more cases you have to consider, the more levels of indentation you have to introduce. So it's generally felt to be more readable to write
if value == '1':
# Take action appropriate to 1
elif value == '2':
# Take action appropriate to 2
else:
raise ValueError("Allowed inputs are '1' or '2'")
Now all the actions and decisions are at the same indentation levels. That's pretty much all there is to it. If you leave the else case off then you won't take any actions at all, so it's normally used to specify the default action, in this case raising an exception.
PS: If you want to be sure the user has entered two matching passwords before you proceed, look at the while loop, which allows you to repeat a set of actions until some condition (in this case the passwords being equal) is true.
Here is an example if if/elif/else statement in python3:
test = 'mytest'
if test == 'not_my_test':
print('nope')
elif test == 'mytest':
print('yay')
else:
print('something else')
You can find more information here : https://docs.python.org/3/tutorial/controlflow.html
EDIT:
As a general remark, you should not define variable using capital letters (PEP convention: https://www.python.org/dev/peps/pep-0008/?)
So using Elif
if Pass == Again:
print("Thank you for choosing a working password, please create your character")
print("Please type your username without numbers")
elif Pass != Again:
print("Something's wrong with your password or username!")
Though what is this error you're getting, we can't really help you without it.

username input and matching using python-(Stuck in while loop)

I want to create a class based user registration portal and for that I wanted to add some usernames. But if they are already taken, then the code should prompt the
user to add another username and I tried to do so with this code.
a=0
User=['name123']
username=raw_input("Enter username : ")
while a==0:
for i in User:
if i==username:
a=0
break
else:
a=1
if a==0:
usernarme=raw_input("Username already taken.\nEnter another username :")
But it gets stuck in the loop and displays the following message repeatedly
even after entering a valid username. What I am doing wrong?
"Username already taken"
That will fix all your issues with loop.
User=['name123']
username=raw_input("Enter username : ")
while username in User:
username=raw_input("Username already taken.\nEnter another username :")
P.S. I'm strongly recommend you to read Dive Into Python and The Zen of Python
Here's a more pythonic version of your code, that's easier to understand and to fix:
users = ['name123']
username = raw_input("Enter username : ")
while username in users:
username = raw_input("Username already taken.\nEnter another username :")
Notes:
Always use lower case for variable names.
Use in instead of looping over users explicitly in the loop.
Avoid break in a while loop and rather change the value of
your loop condition.

Simple password check with limited retries

I'm trying to do a simple password check with limited retries.
If user keys in wrong password, program prompts to try again (3 retries).
After 3 failed retries, program prompts user has reached maximum retries.
If User keys in correct password, program will "grant access".
import sys
print (sys.version)
pssw = ''
attempt = 0
print('Please key in your password.')
while (pssw != "remember") and (attempt < 3):
pssw = input()
attempt = attempt + 1
print ('No that is not correct. Try again.')
if attempt == 3:
print ('Sorry you have reached maximum number of attempts')
break
if (pssw == "remember"):
print('Access Granted!')
Problem #1
Expectation: After keying in the correct password "Remember", program should print output "Access Granted"
But program output:
3.6.2 (v3.6.2:5fd33b5926, Jul 16 2017, 20:11:06)
Please key in your password.
remember
No that is not correct. Try again.
Access Granted!
Problem #2
Expectation: After keying in the correct password "Remember" on the last try, program should print output "Access Granted"
But program output:
Please key in your password.
test
No that is not correct. Try again.
test
No that is not correct. Try again.
remember
No that is not correct. Try again.
Sorry you have reached maximum number of attempts
What am I doing wrong?
I will just explain your errors because someone posted another code approach.
I think it's important that you understand your erros and do not just copy another code.
First, the line break is incorrect because a break cant be outside a loop, use sys.exit() instead.
Problem #1:
If you enter the right password your program will exit the loop and execute the next statements:
print ('No that is not correct. Try again.')
if attempt == 3:
print ('Sorry you have reached maximum number of attempts')
break
if (pssw == "remember"):
print('Access Granted!')
So it will print "No that is not correct. Try again.".
Check if attempt is equal to 3. It isn't because you entered the right password at the first attempt.
Check if password is equal to "remember". It is, so program will print "Access granted".
Problem #2:
Your second output is incoherent with the code you posted.
Normal output for the code you posted is:
Please key in your password.
test
test
remember
No that is not correct. Try again.
Sorry you have reached maximum number of attempts
This is the normal output for the code you posted, but it's wrong anyway.
It's because if tou type an incorrect password, the loop will just continue and thus ask again for your password without printing anything.

How do I add a retry option to a function in Python?

Pretty new to Python, trying to create a simple login system here (has to be done this way). I've already defined a user() function which asks for the username and checks its validity. This function starts by calling the user function. Here is the main part:
user()
if user in userlist:
while True:
pass = raw_input("Enter password, or X to retry: ")
if pass == 'X':
break
if userlist[user] == pass:
break
else:
print "Invalid password."
I want the function to loop back to asking for username input if X is entered. The rest of it works fine but as it stands, entering X just ends the function and doesn't loop it back to the start. Is this just not possible or can I rewrite it to work? I assume I'd need to include user() into the loop but I've encountered various errors while trying.
You intentionally say to exit the loop if the user enters X by using the break statement. That's why the loop is exiting. Instead of break use continue.
if password == 'X':
continue
This will start the loop over again at the top.
As another user notes, you can't use pass as a variable name. The code you posted clearly isn't the code you're actually running. Anyway, I've assumed that you really used the name password.
Don't use pass as a variable name because it clobbers the builtin pass. What you want is
if passwd == 'X':
continue #restart at top of loop
You'll have to do:
if password == 'X':
continue #restarts loop at while

Categories

Resources