I’m trying to check in Python GUI if the user’s email is valid after every key release. So I set global bool variables, which are at
and dotcom
for email validity, but every time I input a valid email format. the bools are still set to false.
This is my function for checking the email validity
def keyup_email(e): global at global dotcom for x in range(len(custemail.get())): #gets email length after every key release if custemail.get()[-1] == "@" and x > 3: #check if inputted email contains "@" after typing it at = True print("at is" + str(at)) else: c_email_format.config(text="Bad email") at = False print("at is" + str(at)) if x > 5 and custemail.get()[-4:] == ".com" and at == True: #check if inputted email's last 4 characters is ".com" dotcom = True print("dotcom is" + str(dotcom)) else: c_email_format.config(text="Bad email") dotcom = False print("dotcom is" + str(dotcom)) if at == True and dotcom == True: c_email_format.config(text="Good email")
These are my GUI widgets used for email validation
c_email = Label(window, text="Customer Email:", width=15, height=1, bg="yellow") c_email.grid(column=1, row=4) custemail = StringVar() custemail = Entry(window, textvariable=custemail) custemail.grid(column=2, row=4) custemail.bind("<KeyRelease>", keyup_email) c_email_format = Label(window, text="[a-z]@[a-z].com", width=15, height=1, bg="yellow") c_email_format.grid(column=3, row=4)
Every key release after inputting @ and .com still prints out at
and dotcom
as false
when I tried debugging the cause of the problem. I searched ahead on strings, range functions, substrings, and conditionals, but I’m still clueless as to why my bools are still outputting false
, which means that only else
condition is the only functioning conditional
Advertisement
Answer
Currently you are doing some strange things. You iterate over the length of the email, but then you don’t use the iterator to check the values. Also you overwrite every True statement, because you don’t check if it is already True. e.g. if you already found an ‘@’ you still check for it afterwards and set at to False again.
I have two solutions for you my friend. One is a cleaned up version of your code:
def keyup_email(e): global at global dotcom email = custemail.get() for x in range(len(email)): #iterate over the whole email if not at: #if we found an '@' already, we don't want to check again to overwrite it at = email[x] == "@" and x > 3 #we can just set at to the result of the boolean operation print("at is" + str(at)) if not dotcom: #if we found 'dotcom' already, we don't want to overwrite it dotcom = x > 5 and email[x:] == ".com" and at #again, we can just set dotcom to the boolean value print("dotcom is" + str(dotcom)) if at and dotcom: #as at and dotcom are boolean we don't have to do an '== True'-check c_email_format.config(text="Good email") else: c_email_format.config(text="Bad email")
Problem with this is, that you still need to reset at and dotcom when you delete a key, because then we need to check everything again.
An alternative would be to use ‘re’ to check for a regex:
import re def keyup_email(e): contains_at = re.search("@", custemail.get()) #check whether email contains an '@' symbol ends_with_dotcom = re.search('.com$', custemail.get()) #check whether email ends with '.com' if(contains_at != None and ends_with_dotcom != None): # if neither contains_at nor ends_with_dotcom are None, we found a valid email c_email_format.config(text="Good Email") else: c_email_format.config(text="Bad Email")