Prevent input() from being anything but alphabet characters - python

I am attempting to make a program for the sake of self-knowledge. I want to ask the user what their name is, and I only want the user to be able to use letters from the alphabet to answer, or only strings. I do not want them to be able to answer with numbers, symbols, etc.
def cc():
name = (input("""Hello, what happens to be your first name?
> """))
if type(name) is str:
print("You have entered a name correctly.")
elif type(name) is int:
print("Your name cannot be an integer. Try again.")
cc()
cc()

You can enforce this requirement using str.isalpha. From the documentation:
Return true if all characters in the string are alphabetic and there is at least one character, false otherwise. Alphabetic characters are those characters defined in the Unicode character database as “Letter”, i.e., those with general category property being one of “Lm”, “Lt”, “Lu”, “Ll”, or “Lo”. Note that this is different from the “Alphabetic” property defined in the Unicode Standard.
Here is an example program:
while True:
name = input('Enter a name using only alphabetic characters: ')
if name.isalpha():
break
Demo:
Enter name using only alphabetic characters: Bo2
Enter name using only alphabetic characters: Bo^&*(
Enter name using only alphabetic characters: Bob
Note this method will not work for people with hyphenated names such as "Anne-Marie".

I agree that this question is a little misleading. However, with what you have said, you just need to use a regex to accomplish this.
import re
...
if not re.findall('[^a-zA-Z]', 'abc1'):
print("You have entered a name correctly.")
else
print("Your name cannot be an integer. Try again.")
cc()

Related

How do I make an input() detect if the user input is something other than a string?

I am fairly new to Python and I wanted to generate a simple user input that asks for your name. I got the prompt to work but when I added code that detects if the input is not a string, it doesn't let me input anything at all.
It was working up until I added the code that tells the user if they used an unsupported character.
Here's the code I have so far:
while True:
name = input('What is your name? ')
if name is str:
print('Hi,%s. ' % name)
if name != str:
print('That is not a valid character!')
Python supplies methods to check if a string contains on alphabets, alphanumeric or numeric.
isalpha() returns True for strings with only alphabets.
isalnum() returns True for strings with only alphabets and numbers and nothing else.
isdigit() returns True for strings with only numbers.
Also your if-else statement is off
name = input('What is your name? ')
if name.isalpha():
print('Hi,%s. ' % name)
else:
print('That is not a valid character!')
When you do
name = input('What is your name? ')
you get a string called name, so checking it it is a string won't work.
What you can check is if it's an alphabetical character, using isalpha:
if name.isalpha():
# as you were
There are various other string methods ( see here ) which start is to check for numbers, lower case, spaces and so on.

Python Regex validation

I am brand new to Python.
I'm trying to ensure a username contains ONLY alpha characters (only a-z). I have the below code. If I type digits only (e.g. 7777) it correctly throws the error. If I type numbers and letters mix, but I START with a number, it also rejects. But if I start with a letter (a-z) and then have numbers in the string as well, it accepts it as correct. Why?
def register():
uf = open("user.txt","r")
un = re.compile(r'[a-z]')
up = re.compile(r'[a-zA-Z0-9()$%_/.]*$')
print("Register new user:\n")
new_user = input("Please enter a username:\n-->")
if len(new_user) > 10:
print("That username is too long. Max 10 characters please.\n")
register()
#elif not un.match(new_user):
elif not re.match('[a-z]',new_user):
print("That username is invalid. Only letters allowed, no numbers or special characters.\n")
register()
else:
print(f"Thanks {new_user}")
Why don't you use isalpha()?
string = '333'
print(string.isalpha()) # False
string = 'a33'
print(string.isalpha()) # False
string = 'aWWff'
print(string.isalpha()) # True
in your code, uf, un and up are unused variables.
the only point where you validate something is the line elif not re.match('[a-z]',new_user):, and you just check if there is at least one lowercase char.
To ensure that a variable contains only letters, use: elif not re.match('^[a-zA-Z]{1,10}$',new_user):
in the regex ^[a-zA-Z]{1,10}$ you find:
^ : looks for the start of the line
[a-zA-Z] : looks for chars between a and z and between A and Z
{1,10} : ensure that the char specified before (letter) is repeated between 1 and 10 times. As LhasaDad is suggesting in the comments, you may want to increase the minimum number of characters, e.g. to 4: {4,10}. We don't know what this username is for, but 1 char seems in any case too low.
$ : search for the end of the line
Since you were looking for a RegEx, I've produced and explained one, but Guy's answer is more pythonic.
IMPORTANT:
You're not asking for this, but you may encounter an error you're not expecting: since you're calling a function inside itself, you have a recursive function. If the user provides too many times (more than 1000) the wrong username, you'll receive a RecursionError
As the re.match docs say:
If zero or more characters at the beginning of string match the regular expression pattern, return a corresponding match object.
That's exactly what's happening in your case: a letter in the beginning of the string will satisfy the match. Try the expression [a-z]+$ which will make sure that the match expands till the end of the string.
You can check the length on the same go: [a-z]{1,10}$.

Input Name with space with validation

I am using the .isalpha function to take an input of a name. It is working but whenever i put on space between name for example a full name John Doe It gives me error.
What ive Tried so far
while not name.isalpha():
print('Entered Name is invalid')
name = input('Please Enter Your Name Sir: ')
if name.isalpha() or name.isspace():
print('Hello Mr.' + name)
select_mmenu('main-menu.txt')
I've tried combining .isalpha and .isspace but it seems not to be working. Need the most simple way to solve this trick
isalpha tests that each member of the string is a letter. isspace tests that each member of the string is a whitespace character. Neither of those is what you want.
Instead you could do:
if all(lett.isalpha() or lett.isspace() for lett in name):
which will pass if every letter is EITHER a letter or a space. Alternatively you can match a regular expression:
import re # at the top of your module
if re.match(r"[\s\w]+$", name):
which is arguably cleaner, and certainly more powerful. The square brackets denote a character class, \s is all whitespaces and \w is all word character, the + means "matches 1 or more times," and the $ is the end of string. [\s\w]+$ then means "one or more characters that are either whitespace or word characters, and nothing afterwards.
It will certainly give you an error because the method isalpha() checks whether the string consists of alphabetic characters only. So if you put a space, the result will return false instead of true, and you will get an error.
Thankyou for the answers. I got it solved without using all() function. I just solved it with simplest basic Python loops
Thankyou Adam Smith because of your answer i got this idea to solve it through that method
con = False
while con!=True:
l=0
strs = input('Enter your Name: ')
for i in strs:
if i.isalpha() or i.isspace():
l += 1
if l == len(strs):
con = True
break
else:
print('Wrong Input')
if con==True:
print(strs)
In this code its basically counting the input lenght and alphabets and space lenght if it match it works. else the while loop continue.

Python - Validation to ensure input only contains characters A-Z

I'm creating a program in Python 3.x where it asks the user for their first name and then last name and stores these in variables which are then concatenated into one variable:
firstName = input("What's your first name? ")
lastName = input("What's your first name? ")
name = firstName + " " + lastName
I tried:
while True:
try:
firstName = input("What's your first name? ")
lastName = input("What's your first name? ")
name = firstName + " " + lastName
break
except ValueError:
print("That's invalid, please try again.")
which ensures that a string is inputted, but inputting 'bob38', '74' or '][;p/' all count as string values, so these would be accepted, which is not what I want to happen.
I want valid input to only contain the letters A-Z/a-z (both uppercase and lowercase), and if the input contains anything else, an error message is outputted (e.g. 'That's invalid, try again.') and the user is asked the question again. How would I do this?
What you want to do is actually check if your string is not isalpha() and output an error and continue your loop until you get a valid entry.
So, to give you an idea, here is a simple example:
while True:
name = input("input name")
if name.isalpha():
break
print("Please enter characters A-Z only")
print(name)
Note, that as mentioned in the comments to this question, this is limited to only names that contain letters. There are several valid names that will contain ' and - that should probably be considered when wanting to validate names.
There is another solution. It's not as efficient as using re or isalpha but allows you to easily customize the characters you allow:
valid_characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
# Just insert other characters into that string if you want to accept anything else.
while True:
firstName = input("What's your first name? ")
if all(char in valid_characters for char in firstName):
break
print("That's invalid, please try again.")
The all checks if all characters from firstName are contained in the valid_characters string and returns False if any of them is not in it.
So to add whitespace and minus - you can alter it slightly:
valid_characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ -'
# whitespace is here ------------------------------^
assert all('a'<=letter<='z' or 'A'<= letter <= 'Z' for letter in name)
This will throw an error if name contains a non alphabet letter.
You can use a simple regular expression for this -
import re
is_valid_name = r'[a-zA-Z]+'
if bool(re.match(firstName, is_valid_name)) and bool(re.match(lastName, is_valid_name)):
name = firstName + lastName
else:
print('thats invalid')

Python : Another Name Error

I have two sets of code that essentially have the same goal but neither work and come up with the same name error. I'm trying to make it so they only letters are accept as answers, not numbers. When a number is entered as the input the program works fine but letters do not. Pleases also note that I am still new to python and am looking for basic commands if possible. I know their are many other questions like this one but none that I found answered my question. The error that comes up specifically points out the Name = input("What's your name?\n") line. Thank you in advance!
1
LetterCheck = True
while LetterCheck == True:
Name = input("What's your name?\n")
if "0" or "1" or "2" or "3" or "4" or "5" or "6" or "7" or "8" or "9" in str(Name):
print('Your name must NOT include numbers.')
else:
LetterCheck = False
print(Name)
2
LetterCheck = True
while LetterCheck == True:
Name = input("What's your name?\n")
global Name
try:
Name = int(Name)
except ValueError:
Name = str(Name)
LetterCheck = False
else:
print("Your name must NOT include numbers")
print(Name)
The Error
What's your name?
45
Your name must NOT include numbers
What's your name?
Will
Traceback (most recent call last):
File "C:/Users/Will/Documents/Python/Task 1 Debugging.py", line 3, in <module>
Name = input("What's your name?\n")
File "<string>", line 1, in <module>
NameError: name 'Will' is not defined
if "0" or "1" or "2" or "3" or "4" or "5" or "6" or "7" or "8" or "9" in str(Name):
This will always tell you there is a number in your name, because "0" is a non-zero length string and therefore truthy. Python sees if "0" or and stops there because it already knows the whole thing must be true.
What you probably want is something more like:
if any(digit in Name for digit in "0123456789"):
Or, arguably better:
if any(char.isdigit() for char in Name):
The other one where you're trying to convert the name to an integer will only succeed in the conversion if the name is all digits, not if it contains a digit. That's not what you want so you shouldn't do it that way.
You're running this in Python2. In Python2, input evaluates the user's input AS CODE. This means when you do:
>>> input("Name: ")
Name: Will
It tries to evaluate to some variable named Will. There is no such variable, so it throws a NameError. You can test this by entering "Will" (note the quotes). Now it evaluates it as a string and should work properly. But of course you could also write import os; os.listdir() and get a list of the current directory followed by what will likely be a TypeError. input is not safe in Python2.
Instead (in Python2), use raw_input.
I would just like to point out a few things:
First, "1" or "2" or "3" or "4" will evaluate "1" or "2" which is true and stop. You have to write out "1" in name or "2" in name, etc. That's highly inefficient and you should look at the posted function for has_int() as that would be a better way to implement it.
Also a name may have digits and still won't probably be parsed as an int() and raise an error so the second check is not effective at determining if a string has any numbers, only if the string is only numbers
Finally, it's not necessary but it is good practice to name your variables with lowercase letters.
Also, your name error could be because of input if you python version is not 3. Try using raw_input() if that is the case.
The goal here is to check if a string contains numbers.
if it does, ask again.
else, quit
# return true if given string does not have any numbers in them.
def has_int(s):
return any(char.isdigit() for char in s)
# ask what the name is
name = input('What is your name?')
# check if this user input has int
while has_int(name):
# if it does, re-prompt
print('Name cannot include numbers')
name = input('What is your name?')
# finally, say the name
print('Your name is {}'.format(name))
Very glad that you have decided to reach out.
I think regular expressions (python module re) (more info here: https://docs.python.org/2/library/re.html) are right up your alley. Regular expressions will allow you to determine if your string matches a "mold" or a pattern, which you can define by yourself
Regular expressions are a very broad and deep subject that take a bit of time to get used to, but I think they're absolutely worth your time. Take this introductory, friendly tutorial: http://regexone.com/
Then, in python, you can try this:
import re
input_str = raw_input(">?") #reads user input
if re.match('[0-9]+', input_str): #if the input matches the pattern "one or more numbers in the string"
print "Only letters a-z allowed!" #error out of the program
sys.exit()
The thing of importance here is the part with [0-9]+, which means "one or more numbers, any of them from 0 to 9".
Alright, I know I messed up with my previous code but to make up for it I present a working alternative, OP can refactor their program a bit like the following:
import re
while True:
input_str = raw_input("What's your name? ") #reads user input
if ( re.match('[0-9]+', input_str) ): # while the input doesn't match the pattern "one or more numbers in the string"
print "Your name must NOT include numbers." #error out of the program
else:
break
print "if you see this, the entered name fullfilled the logical condition"
Good luck!

Categories

Resources