invalid email and return to begining - python

I'm new to python I got a question that might be easy but i can't get it.
i wanted to make aprogram that user gives email as username and password as password ,the program should check if email is in corect format and if its not it should print something and get email again so i used regex (Im giving this inputs to database and i thought using LIKE query but i don't think that might help)
so whats the problem with my code?!it keeps wrong email
import re
regex = r'\b[A-Za-z0-9._%+-]+#[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
def check(email):
if (re.fullmatch(regex, email)):
return
else:
print("corect format is like amireza#gmail.com")
return
while __name__ == '__main__':
username = input()
check(username)
password = input()

here is a working code for you:
import re
regex = r'\b[A-Za-z0-9._%+-]+#[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
def check(email):
if (re.fullmatch(regex, email)):
return True
else:
print("invalid input! correct format is like amireza#gmail.com")
return False
while __name__ == '__main__':
while True:
username = input("please enter email\n")
if check(username) is True:
break
password = input("please enter password\n")
break
print("username: %s, password: %s" % (username, password))
key correction:
your helper should return a boolean which lets you know if the input is legit or not. thus I returned a boolean to outside scope
one more thing: since you run it as a standalone script, the outermost while condition (while __name__ == '__main__') will always be True, which means you have to break out of it when you want to end your program execution. For simplicity I'd suggest using if __name__ == '__main__' instead

You could change your function check to return a boolean output that tells you whether the check was successful, as in
def check(email):
if (re.fullmatch(regex, email)):
return True
else:
print("corect format is like amireza#gmail.com")
return False
And then add a loop to your main code:
if __name__ == '__main__':
username = input()
while not check(username):
username = input()
Note that I did not actually run your code, but this should work.
EDIT: Heh, right, as the other answer explains, you should change your while into an if, I edited my code correspondingly.

Related

How to break the while loop if the condition is False?

I have a long function in which I am checking for different parameters and if any of the parameters is False, I don't want to execute the code further.
For your understanding, this is how I want to make it work
Email = True
while(Email == True):
print("Execute Me")
Email = False # Break the while loop here
print("Never execute me")
Here is the pseudo version of my code:
def users_preferences(prefs):
for pref in prefs:
send_email = True
while(send_email == True):
# Set send_email = False if email is not verified and don't move to the next line
# Set send_email = False if user's email is not a part of specific group
...
...
How can I break the loop if the condition is False at any point without further executing the code?
Edit: The problem with break statements is that it will become cumbersome to check the condition before running a new statement where you have number of statements
You can use a normal break statement:
Email = True
while Email:
print("Execute Me")
Email = False # Break the while loop here
if not Email:
break
print("Never execute me")
Edit: If the while loop doesn't do anything special, the code can be modified to be:
for pref in prefs:
if not is_email_verified(email) or not is_user_in_group(user, group):
continue
send_email(email)
Hello your code needs to be better indented. Also why haven't you tried using break statement to get out of the loop?
Email = True
while Email:
# do something
break
# continue doing something

Writing clean, flexible, and easy to maintain user input prompts

I'm often tasked with asking users for input. I've always just written my prompts "as-needed" in my main execution scripts. This is kind of ugly, and because I often ask for the same types of input across multiple scripts, a ton of my code is just copy/pasted prompt loops. Here's what I've done in the past:
while True:
username = input("Enter New Username: ")
if ldap.search(username):
print " [!] Username already taken."
if not validator.validate_username(username):
print " [!] Invalid Username."
else:
break
I'd like to create something that can be called like:
username = prompt(prompt="Enter New Username: ",
default=None,
rules=["user_does_not_exist",
"valid_username"])
Then the prompt function looks like:
def prompt(prompt, default, rules):
while True:
retval = input(prompt)
if default and retval == "":
break
return default
if not rule_match(retval, rules):
continue
break
return retval
def rule_match(value, rules):
if "user_does_not_exist" in rules:
if not user.user_exists(value):
return False
if "valid_username" in rules:
if not validator.username(value):
return False
if "y_n_or_yes_no" in rules:
if "ignore_case" in rules:
if value.lower() not in ["y", "yes", "n", "no"]:
return False
else:
if value not in ["y", "yes", "n", "no"]:
return False
return True
An alternative I'm considering is to make a Prompt class, which would allow for more flexibility with the results. For example, if I want to convert the "y" or "n" to True or False, the above doesn't really work.
create_another = Prompt(prompt="Create another user? (y/n): ,"
default=False,
rules=["y_n_or_yes_no",
"ignore_case"]).prompt().convert_to_bool()
The other alternative I'm considering is just making individualized prompts and naming them, with each one written similar to my very original code. This doesn't actually change anything. It just serves to get these loops out of my main execution code which makes the main execution code easier to browse:
username = prompt("get_new_username")
def prompt(prompt_name):
if prompt_name == "get_new_username":
while True:
username = input("Enter New Username: ")
if ldap.search(username):
print " [!] Username already taken."
if not validator.validate_username(username):
print " [!] Invalid Username."
else:
break
return username
if prompt_name == "y_n_yes_no_ignore_case":
# do prompt
if prompt_name == "y_n_yes_no":
# do prompt
if prompt_name == "y_n":
# do prompt
if prompt_name == "y_n_ignore_case":
# do prompt
if prompt_name == "yes_no":
# do prompt
if prompt_name == "yes_no_ignore_case":
# do prompt
I realize that it's probably just a good idea to settle on one accepted "y/n" format for all of my programs, and I will. This is just for the sake of showing that, in cases where I would need a very similar but slightly different prompt, it would result in a lot of copy/pasted code (no flexibility with this method at all).
What is a good approach to writing clean, flexible, and easy-to-maintain user prompts?
(I've seen this: Asking the user for input until they give a valid response and some other responses. My question is not about how to get input and validate it, it's about how to make a flexible input system that can be reused with across multiple programs).
I once wrote a function for something similar. The explanation is in the doc-string:
def xory(question = "", setx = ["yes"], sety = ["no"], setz = [], strict = False):
"""xory([question][, setx][, sety][, setz][, strict]) -> string
Asks question. If the answer is equal to one of the elements in setx,
returns True. If the answer is equal to one of the elements in sety,
returns False. If the answer is equal to one of the elements in setz,
returns the element in setz that answer is equal to. If the answer is
not in any of the sets, reasks the question. Strict controls whether
the answer is case-sensitive. If show is True, an indication of the
acceptable answers will be displayed next to the prompt."""
if isinstance(setx, str):
setx = [setx]
if isinstance(sety, str):
sety = [sety]
if isinstance(setz, str):
setz = [setz]
if (setx[0])[0] != (sety[0])[0]:
setx = [(setx[0])[0]] + setx
sety = [(sety[0])[0]] + sety
question = question.strip(" ") + " "
while True:
if show:
shows = "[%s/%s] " % (setx[0], sety[0])
else:
shows = ""
user_input = raw_input(question + shows)
for y in [setx, sety, setz]:
for x in y:
if (user_input == x) or ((not strict) and (user_input.lower() == x.lower())):
if y is setx:
return True
elif y is sety:
return False
else:
return x
question = ""
show = True
Examples:
>>> response = xory("1 or 0?", ["1", "one", "uno"], ["0", "zero", "null"], ["quit", "exit"])
1 or 0? x
[1/0] eante
[1/0] uno
>>> print(response)
True
>>> response = xory("Is that so?")
Is that so? Who knows?
[y/n] no
>>> print(response)
False
>>> response = xory("Will you do it?", setz=["quit", "exit", "restart"])
Will you do it? hm
[y/n] quit
>>> print(response)
quit
I'd advise to write a library that contains a number of very clearly defined building blocks, each one as small and light-weight as possible, without too many assumptions baked in about how you're going to put the pieces together.
That is, I'd include one function that does the loop, but instead of passing in a set of rules, I'd allow for exactly one function to be passed in that either returns a value (if a valid input was given and after converting it in any way necessary) or raises a ValueError if the input wasn't usable. Other building blocks would implement certain checks or transformations (like resolution of 'y' and 'n' into boolean values).
This way, you would leave it completely up to the user to assemble the stuff in a way suitable for the use case.
# library:
def prompt(prompt, default, postprocess):
value = input('{} ({}): '.format(prompt, default)) or default
try:
return postprocess(value)
except ValueError:
continue
def check_lower(value):
if not value.islower():
raise ValueError()
def to_bool(value):
return value in 'yes'
# using the library:
def postprocess(value):
check_lower(value)
return to_bool(value)
prompt('Really?', 'n', postprocess)
I would create a prompt function as such:
def prompt(prompt, default=None, rules=[]):
while True:
response = input(prompt)
if response:
valid = [rule(response) for rule in rules]
if not(False in valid):
return response
else:
print('Invalid input')
else:
return default
You could then create different validation functions such as
def filterValidEmail(string):
if '#' in string:
if '.' in string.split('#')[1]:
return True
else:
return False
else:
return False
And call these functions like so:
prompt('What is your email? ', rules=[filterValidEmail])
You could also tweak this so that you can tell the user what verification they failed or disallow blank inputs.

Validate dictionary membership with an if statement

I'm writing this code to verify that a user-provided value and key match what I have in my dict. When they match, the Welcome portion of the code will run, but if one of them is wrong then it will have to run the else statement.
name = input("Name: ")
code = input("Code: ")
users = {'rafiki':'12345', 'wanjiru':'12334', 'madalitso':'taxpos'}
if _______ in users: #at this point is where i need your support, yoverify both key and its value at once.
print ("Welcome back %s " % username)
else:
print ("Please check if your name or Code are correctly spelled")
In a single operation:
if users.get(name) == code:
Because dict.get return None for an unknown key instead of throwing a KeyError
Use this:
if name in users and users[name] == code:
print "Welcome back %s" % username
This should work:
if name in users and code == users[name]:

Python Amateur - 'Greeting program' - 'Referenced before assignment error'

Like I said in my previous question, I'm a python amateur. I've made a couple silly mistakes. I'm attempting to make a highly simple greeting program using Python 3.4 however I have encountered an error. The error I have is:
UnboundLocalError: local variable 'lastNameFunction' referenced before assignment
Here's my code (I know I probably don't need to post it all, but there isn't much of it):
def main():
import time
running = True
while (running):
firstNameInput = input("What is your first name?\n")
firstName = firstNameInput.title()
print ("You have entered '%s' as your first name. Is this correct?"%firstName)
time.sleep (1)
choice = input("Enter 'Y' for Yes or 'N' for No\n")
if(choice.upper() == "Y"):
lastNameFunction()
elif(choice.upper() == "N"):
main()
def lastNameFunction():
lastNameInput = input("Hi %s. Please enter your last name. \n"%firstName)
lastName = lastNameInput.title()
if __name__ == '__main__':
main()
I'd appreciate any help and advice! Please take into consideration I am really new to this stuff. I'm also not quite sure on having a function inside of a function, but I thought it would be a fix so that the 'firstName' was available when entering the 'lastName'.
Thanks in advance! :)
You need to move the lastNameFunction declaration somewhere before you call it using lastNameFunction(), e.g.:
def main():
import time
running = True
while (running):
firstNameInput = input("What is your first name?\n")
firstName = firstNameInput.title()
print ("You have entered '%s' as your first name. Is this correct?" % firstName)
time.sleep (1)
choice = input("Enter 'Y' for Yes or 'N' for No\n")
def lastNameFunction():
lastNameInput = input("Hi %s. Please enter your last name. \n" % firstName)
lastName = lastNameInput.title()
if(choice.upper() == "Y"):
lastNameFunction()
elif(choice.upper() == "N"):
main()
if __name__ == '__main__':
main()
You can also move it outside the main function, but you will then need to pass the firstName in using the function arguments:
def lastNameFunction(firstName):
lastNameInput = input("Hi %s. Please enter your last name. \n" % firstName)
lastName = lastNameInput.title()
def main():
...
lastNameFunction(firstName)
...
Move your lastNameFunction to somewhere before the call. Ideally, you would place this above the main function.
def lastNameFunction():
lastNameInput = input("Hi %s. Please enter your last name. \n"%firstName)
lastName = lastNameInput.title()
def main():
...
The problem is you called lastNameFunction() before you defined it in the while loop. Try defining the function outside the while loop.
The organisation of the whole program seems a little bit off.
Imports usually go at the top of the module.
Functions defined in functions are usually just for closures, which you a) don't need here and b) might be a bit advanced for your current experience level.
Recursive calls like your calling main() from within main() are wrong. When you adopt that style of control flow instead of a loop, you will eventually run into limitations of recursive calls (→ RuntimeError). You already have the necessary loop, so simply leaving out the elif branch already asks the user again for the first name.
running isn't used anywhere, so you can remove it and just use while True:.
I would move asking the user for ”anything” + the question if the input was correct into its own function:
def ask_string(prompt):
while True:
result = input(prompt).title()
print("You have entered '{0}'. Is this correct?".format(result))
choice = input("Enter 'Y' for Yes or 'N' for No\n")
if choice.upper() == 'Y':
return result
def main():
first_name = ask_string('What is your first name?\n')
last_name = ask_string(
'Hi {0}. Please enter your last name.\n'.format(first_name)
)
print(first_name, last_name)
if __name__ == '__main__':
main()

Python optimization of simple login system

i don't have a problem with my code but i am very new to python and programming in general so i would like some inputs as to what i could do better.
I decided to do a very simple login / register system and i am hoping you have some input so i can improve myself. I don't post here so often and don't know if this is the sort of question usually asked, but i hope you will help me. Thanks in advance.
Here is the code:
username = ['mel1', 'mel2', 'mel3']
password = ['tyr1', 'tyr2', 'tyr3']
def log_sys():
logged_in = False
log_user = raw_input('Please type in your username: ')
log_pass = raw_input('Please type in your password: ')
if log_user in username:
index = username.index(log_user)
if log_pass == password[index]:
logged_in = True
if logged_in:
print 'You are logged in'
else:
print 'Wrong username or password'
log_sys()
def reg_sys(user):
regpass1 = raw_input('Please choose a password: ')
regpass2 = raw_input('Please retype password: ')
if regpass1 == regpass2:
username.append(user)
password.append(regpass1)
log_sys()
else:
print 'Passwords did not match'
reg_sys(user)
def reglog_system():
reglog = raw_input('Do you want to register or login?: ')
if reglog == 'register':
regname = raw_input('Please choose a username: ')
reg_sys(regname)
elif reglog == 'login':
log_sys()
else:
reglog_system()
reglog_system()
This is not a complete answer; I'm not a python expert.
I would strongly suggest using an associative array or dictionary / hash instead of a list / array for storing usernames and passwords. At a minimum, the performance for large lists of users will be better.
I would move the prompt for username when the user is registering into the function for that process; It seems odd that you pass the username into reg_sys() but prompt in log_sys().
Your test for password seems flawed; You only check to see if the first matches the second, without checking to see if either or both is None, an empty list, the empty string, or some other special value.
I hope that helps.
Got some criticism after all!
1) To make clear what your main function is, you should change:
reglog_system()
to
main()
2) Call your script with:
if __name__ == "main":
main()
Makes it more portable. You can then call it directly or import it as a module
3) Use some return functions:
return raw_input("foo")
And handle the return within main(). It makes your code easier on the eyes and may help deciding when/where to deal with the result of a function.
Performance wise, I can't really criticise anything else, at least nothing springs to mind. For future planning, maybe implement hashing? SHA256 seems pretty robust these days.
i found out that if you use example = input() you can use example directly
Example:
name = input("Username: ")
if name == 'Username':
passwd = input("Password: ")
if passwd == 'Password':
print("Login Sucsessful!")
else:
print("Incorrect Username or password.")

Categories