Skip to content
Advertisement

How to check check if a string contains a specific character(s) using range() functions and bools in Python?

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")
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement