If I first enter data that is valid it works fine, but if I enter invalid data, then valid data, None is returned. Here is an example of the problem:
code:
def passwordLength(password):
if (len(password) < 4) or (len(password) > 15):
print("Error from server: Your password must be at least four and at most fifteen characters long.")
enterPasswords()
else:
return True
def passwordMatch(password, password2):
if password != password2:
print("Error from server: Your passwords don't match.")
enterPasswords()
else:
return True
def enterPasswords():
password = input("Message from server: Please enter your desired password: ")
if passwordLength(password):
password2 = input("Message from server: Please re-enter your password: ")
print(password, password2)
if passwordMatch(password, password2):
print(password)
return password
password = enterPasswords()
print(password)
Your problem is that you are not using recursion properly. Take the example of non-matching passwords: hello and hello1.
Your function will be fine until if passwordMatch(password, password2):. At this point, passwordMatch returns None. That is because in passwordMatch you do not say return enterPasswords(), so the return value defaults to None, NOT the return value of the new call to enterPasswords.
if password != password2:
print("Error from server: Your passwords don't match.")
enterPasswords() # Doesn't return anything, so it defaults to None
If you were to use the function like so then you wouldn't have an issue.
def passwordMatch(password, password2):
if password != password2:
print("Error from server: Your passwords don't match.")
return enterPasswords()
else:
return True
Please notice that you have the same problem in passwordLength.
So what happens is that if you first enter invalid data (let's say an invalid password length), you call enterPasswords() again from the passwordLength() function. That prompts you for another password. This time you enter valid input. You get down to where you should return the password, and you return it. The problem is, on the stack, you are returning to where you called enterPasswords() from the passwordLength() function. That is where you are returning the valid password to. It doesn't do anything with it, execution is returned to the original call to enterPasswords() (where the input was invalid) and you're going to return None from there.
A visualization:
enterPasswords() called
prompted for input, give string of length 3
passwordLength(password) called
Invalid string length, print an error and then call enterPasswords()
prompted for input, give valid string
passwordLength(password) called
valid length, return true
prompted for input for second password
passwordMatch(password, password2) called
passwords match, return True
print password
return password to the first passwordLength() call
nothing else to do here, pop the stack and return to the first enterPasswords()
nothing else to do here, pop the stack
print(password), but password is None here
Related
database=[['username1','password1'],['username2','password2']]
def check_match():
check_username()
check_password()
for pair in database:
if check_username==pair[0]:
if check_password==pair[1]:
print('login succesful!')
return
else:
print('login failed')
return
This is the code I have currently to check if index 0 of a list matches index 1 of the same list, It's not working though. check_username() and check_password() hold the contents of a list based on user input.
I realized I called the incorrect functions in the given function, that's my bad, thanks for the help though!
Here is a simple answer. You can modify it accordingly but i made it to satisfy the basic needs;
database=[['username1','password1'],['username2','password2']]
username = 'username1'
password = 'password2'
def login(username, password):
for i in range(len(database)):
if username == database[i][0] and password == database[i][1]:
print("login successfull")
return
print("invalid credentials")
login(username, password)
username and password can be taken from the user.
Loging in with jack works fine but I cant login with jake even thought he exists in the array. It just skips the whole for loop "for i in storedusername". An help would be grateful.
Here's the code:
import pygame
import sys
import random
storedusername = ["jack","jack","jack","jake","jack","jack","jack",] # The place where the username is stored
storedpass = ["abcde","abcde","abcde","12345","abcde","abcde","abcde",] # The current place where the password is stored
Login = False
def login(): # Function used to login
global Login # Global the logins fucntion
Login = False # Sets Login to false
user = input("Enter Username: ") # User enters the username that they would like to login with
print(user)
for i in storedusername: # Loops through the items in the list
if i == user: # Compares the items in the list with the username that the user has entered
print("user found") # If the user was found then the program will tell the user that
pos = int(storedusername.index(user)) # Finds the position where the username is stored
print(pos)
for j in range(0,10): # Has 10 tries to do this loop
password = input("Enter Password: ") # The user enters the password which they think matches with the username.
#for i in range(0,10):
if password == storedpass[pos]: # Goes to the position where the password matches the username is stored and compares the values.
print("password match username") # Program returns if the username and password match
Login = True # Turns login to True
return Login # Returnes Login
break
else:
print("Pasword does not match try again") # If the password does not match then the program will notify it.
print("too many attempts close the program") # If there are too many attempts than it will close.
else:
print("not found") # If the username is not found than it will be promted that it is not found.
return Login # Returns login.
login()
You are using the variable i both for outer and inner loop, so it is changed inside.
It must be:
for i in ... :
...
for j in ... :
...
You were right to think that the indentation wasn't correct. As you had it before, if you entered a username not present in the list, you would still be asked for the password ten times for each user in storedusername (a total of 70 times!). Moving the block from for i in range(0,10) one indentation further fixes it.
for i in storedusername: ############ It skips this loop
if i == user:
print("user found")
pos = int(storedusername.index(user))
print(pos) ########### All the way up to here
# >>>> indent here
for i in range(0,10): # Has 10 tries to do this loop
password = input("Enter Password: ") # The user enters the password which they think matches with the username.
#for i in range(0,10):
if password == storedpass[pos]: # Goes to the position where the password matches the username is stored and compares the values.
print("password match username") # Program returns if the username and password match
Login = True # Turns login to True
return Login # Returnes Login
break
else:
print("Pasword does not match try again") # If the password does not match then the program will notify it.
# >>>>>
print("too many attempts close the program") # If there are too many attempts than it will close.
else:
print("not found") # If the username is not found than it will be promted that it is not found.
You may see that not working because of wrong indentation of that
else:
print(
"Pasword does not match try again") # If the password does not match then the program will notify it.
print(
"too many attempts close the program") # If there are too many attempts than it will close.
block.
Please move it to to left, and it should be better.
That modified version
storedusername = ["jack", "jack", "jack", "jake", "jack", "jack",
"jack", ] # The place where the username is stored
storedpass = ["abcde", "abcde", "abcde", "12345", "abcde", "abcde",
"abcde", ] # The current place where the password is stored
(width, height) = (644, 412)
Login = False
def login(): # Function used to login
global Login # Global the logins fucntion
Login = False # Sets Login to false
user = input(
"Enter Username: ") # User enters the username that they would like to login with
print(user)
for i in storedusername: ############ It skips this loop
if i == user:
print("user found")
pos = int(storedusername.index(user))
print(pos) ########### All the way up to here
for i in range(0, 10): # Has 10 tries to do this loop
password = input(
"Enter Password: ") # The user enters the password which they think matches with the username.
# for i in range(0,10):
if password == storedpass[
pos]: # Goes to the position where the password matches the username is stored and compares the values.
print(
"password match username") # Program returns if the username and password match
Login = True # Turns login to True
return Login # Returnes Login
break
# --> wrong indentation
else:
print(
"Pasword does not match try again") # If the password does not match then the program will notify it.
print(
"too many attempts close the program") # If there are too many attempts than it will close.
# <-- wrong indentation
else:
print(
"not found") # If the username is not found than it will be promted that it is not found.
return Login # Returns login.
# register()
login()
allows for
Enter Username: jack
jack
user found
0
Enter Password: abde
Pasword does not match try again
Enter Password: abcde
password match username
Process finished with exit code 0
I'm not going to modify the flow of your solution, but I'd suggest to write comments before the line, not in it. Also you should avoid variables shadowing (using the same variable like i in different scopes). The last thing is that you got slightly wrong indent for password checking - it was run even wihtout matched name. I allowed myself to propose version with all these modifiactions. Please take a look on that:
def login():
""" Function used to login"""
# Global the logins fucntion
global Login
Login = False
# User enters the username that they would like to login with
user = input("Enter Username: ")
print(user)
for stored_user_name in stored_user_names:
if stored_user_name == user:
print("user found")
pos = int(stored_user_names.index(user))
# Has 10 tries to do this loop
for try_attempt in range(0, 10):
# The user enters the password which they think matches with the username.
password = input("Enter Password: ")
# Goes to the position where the password matches the username is stored and compares the values.
if password == storedpasswords[pos]:
# Program returns if the username and password match
print("password match username")
Login = True # Turns login to True
return Login # Returnss Login
else:
# If the password does not match then the program will notify it.
print("Password does not match try again")
# If there are too many attempts than it will close.
print("too many attempts close the program")
else:
# If the username is not found than it will be promted that it is not found.
print("not found")
return Login
Can you tell me the input so that the check statement is passed along with the try..except of the input pin
#!/usr/bin/python
# Secure Pin system
import sys
users = {'admin': '<REDACTED>'}
def register(username, password):
if username in users:
return "User already exits."
users[username] = password
return "Registered Successfully."
def login(username, password):
if username not in users:
return "Wrong pin/password"
if password != users[username]:
return "Wrong pin/password"
if username == "admin":
return "The FLAG is what you entered in the \"Pin\" field to get here!"
return "You must login as admin to get the flag"
def handle_command(command):
if command not in ["REG", "LOGIN"]:
return "Invalid Command!"
print "Username:",
sys.stdout.flush()
username = raw_input()
try:
print "Pin ([0-9]+):",
sys.stdout.flush()
password = input() # we only support numbers in password
except:
return "Please enter a valid password. Pin can only contain digits."
if command == 'REG':
return register(username, password)
if command == 'LOGIN':
return login(username, password)
if __name__=="__main__":
print "Hey welcome to the admin panel"
print "Commands: REG, LOGIN"
try:
print ">",
sys.stdout.flush()
command = raw_input()
print handle_command(command)
sys.stdout.flush()
except:
pass
The code is all right but the only thing is to bypass the input check
There is a bug that is to be identified
If you want to check whether the input from user only has numbers, then you can use the method - str.isnumeric() , to check whether the string only contains numbers.
Example -
>>> "123".isnumeric()
True
>>> "123.21".isnumeric()
False
>>> "abcd".isnumeric()
False
You can do this check instead of a try/except block (since you do not really use the password as a number after this block).
To ensure the user enters a number, you could convert the script to use a function as follows:
def get_input_number(prompt):
while True:
try:
user_num = int(raw_input(prompt))
return user_num
except ValueError:
print "Please enter a valid password. Pin can only contain digits."
password = get_input_number("Pin ([0-9]+): ")
This would then keep prompting until a number is entered.
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!
I am new to python..
In my test function I am passing some text data which considers "invalid password".
In such case I return Data_Check as "invalid password" but now client as asked if "invalid password" is more than once in data variable then only return "INVALID PASSWORD" otherwise it should return "VALID" itself.
please tell me in below function what changes can be done.
def test(data):
Data_Check = 'VALID'
if (data.lower()).find('invalid password') >= 1:
Data_Check = 'INVALID PASSWORD'
return Data_Check
s.find(t) will tell you the position of t in s, not how often t occurs in s.
Your want http://docs.python.org/library/stdtypes.html#str.count
if data.lower().count('invalid password') > 1:
# do something
Improvement on your solution:
if data.lower().count('invalid password') > 1:
return 'INVALID PASSWORD'
return 'VALID'
One-liner solution:
return 'VALID' if data.lower().count('invalid password') <= 1 else 'INVALID PASSWORD'
And on a side note, you should separate your if's "do something" block onto a new line.