I have a piece of code that asks for an input. The input must not contain any numbers:
def main():
invalid = []
foo = ""
foo = str(input("Enter a word: ") )
invalid = ["1","2","3","4","5","6","7","8","9","0"]
for eachInvalid in invalid:
if eachInvalid in foo:
print("Not a real word!")
main()
else:
pass
main()
So far, it works but I am not proud of it. What would be the better way of doing this be? For example, a word does not contain things like ~@: so I would have to add those to that list. How would I avoid this but keep the code rather clean and readable?
Also, another error, if I run the code and type something in like hello, that is valid but if I type something invalid it takes me back to the start but when I type a valid word it still says invalid? For example:
Enter a word: hello
>>> ================================ RESTART ================================
>>>
Enter a word: 123
Not a real word!
Enter a word: hello
Not a real word!
How would I fix this error and what would be the best way of looking for invalid characters in an input?
edit: nevermind, regular expression is fine.
3 Answers 3
While a more complex validation is an appropriate use case for a regular expression, in this simple case there is a built in function isalpha() which checks whether a string only contains alphabetic characters.
foo.isalpha()
Returns True or False.
Note that in Python 3 this will deal with all unicode characters defined as "letters".
1 Comment
You could use a simpler method to test for a digit in the whole string, rather than testing each letter individually.
if any(x.isdigit() for x in foo):
print("Invalid Word")
else:
print("valid word")
Comments
You could reverse the way you are doing, instead of having a list of invalids, it is better to have a list of valids. Then check every character of your string :
valids = ['a', 'b', 'c', 'd']
for letter in foo:
if (not letter in valids):
print("Not a real word!")
It is even easier with regex as it is easier to list all valids options :
import re
if (not re.match("^[a-zA-Z_ ]*$", foo)):
print("Not a real word!")
The regex ^[a-zA-Z_ ]*$ meaning a word that contain only symbols in [a-zA-Z_ ]
If you want to stay with a list of invalids, use negated regular expression :
if (re.match("[^0-9@]", foo)):
print("Not a real word!")
where [^0-9@] means anything but the characters defined between the brackets
1 Comment
^[a-zA-Z_ ]*$ might be more clear if it includes \s instead of whitespace (though i think it should be excluded since it would mean more than 1 word is given). Also, [^0-9@] wouldn't work since it matches characters like ,.!?- etc.
if any(char.isdigit() for char in foo):? Also, have a look at stackoverflow.com/q/23294658/3001761invalidandfooare totally redundant.