Hi I just start learning python today and get to apply what I learning on a flash cards program, I want to ask the user for their name, and only accept alphabet without numbers or symbols, I've tried several ways but there is something I am missing in my attempts. Here is what I did so far.
yname = raw_input('Your Name ?: ')
if yname.isdigit():
print ('{0}, can\'t be your name!'.format(yname))
print "Please use alphbetic characters only!."
yname = raw_input("Enter your name:?")
print "Welcome %s !" %yname
but I figured in this one is if the user input any character more than one time it will eventually continue...So I did this instead.
yname = raw_input("EnterName").isalpha()
while yname == True:
if yname == yname.isalpha():
print "Welcome %s " %(yname)
else:
if yname == yname.isdigit():
print ("Name must be alphabetical only!")
yname = raw_input('Enter Name:').isalpha()
This while loop goes on forever, as well as I tried (-) and (+) the raw input variable as I've seen in some tutorials. So I thought of using while loop.
name = raw_input("your name"):
while True:
if name > 0 and name.isalpha():
print "Hi %s " %name
elif name < 0 and name.isdigit():
print "Name must be Alphabet characters only!"
try:
name != name.isalpha():
except (ValueError):
print "Something went wrong"
This will check for both alphabet in the raw_input and check for the length of the name as I see you tried to do in your last try.
import string
import re
name = re.compile(r'[a-zA-Z]+') #This will check for alphabet.
yname = raw_input("Your Name:") #ask the user for input.
while not name.match(yname):
print "invalid characters"
yname = raw_input("Your Name:")
if 5<=len(yname)<=10:
print "Hi,", yname, "!"
elif len(yname)>10:
print "too long!"
elif len(yname)<5:
print "too short!"
You can rearrange your last attempt a bit to get what you want:
while True:
name = raw_input("your name") # ask inside the loop
if name and name.isalpha():
print "Hi %s " %name
break # leave the loop if done
elif name and name.isdigit():
print "Name must be Alphabet characters only!"
else:
print "Please enter something"
Note that if name will be True if name != "".
name = raw_input('Enter your name: ')
while not name.isalpha():
print 'Invaid characters in name'
name = raw_input('Enter your name: ')
Use regexes:
import re
regex = re.compile("^[a-zA-Z]+$")
valid_name = False
while not valid_name:
user_name = raw_input("EnterName")
if not regex.search(user_name):
print "this can't be your name"
else:
print "Hi there, {0}".format(user_name)
valid_name = True
Also, please take note that programmers often make false assumptions about human names
Edit: as an alternative you can skip compiling a regex and just use the pattern in place:
if not re.search("^[a-zA-Z]+$", user_name):
...
However, since you're doing it in a loop compiled version would have slightly better performance, since re.search actually compiles a regex behind the scenes each time invoked.
Also, please note I've changed match to search and slightly modified a regex since there're some differences and it appears tome me that search suits your situation more.
Related
So I've almost finished a program in which the user inputs a name/word and it spits out the Soundex counterpart.
The code runs well and the Soundex methodology is sound, "Get it Sound". What I had issues with were the strings being returned. Things like space before or after the word typed in or having an uppercase and lowercase name being repeated when they shouldn't have been. Those got fixed rather easily.
What I'm having issues with now is when the user inputs something like, "Carl Sagan" it returns the ("Word should only contain characters") elif of my program.
What I'd like to do is respond to the user and say, ("Two words entered at once, Please enter one at a time."). When those instances happen.
Here's a snippet of my code:
#input name
name = input("To start, Please give your name :")
print("\nGreetings,", name.strip().capitalize(), "Your Soundex-name is:", convert_to_soundex(name), "\n" )
#creating dictionary
dicti={}
#convert name to code and store in dictionary
dicti[name]=convert_to_soundex(name)
# keeping asking user for a word or name until user enters 0
while(True):
word=input("Please give a word to convert (0 to exit) :").strip().capitalize()
if word=='0':
break
elif word=="":
print("Please give word with atleast one character.")
elif not word.isalpha():
print("Word should only contain characters.")
else:
if word in dicti:
print("Word already exists")
else:
dicti[word]=convert_to_soundex(word)
#printing formatted data
printData(dicti)
You can add another while..if instead of name input like this:
while True:
name = input("To start, Please give your name :")
if ' ' in name:
print("Two words entered at once, Please enter one at a time.")
else:
break
#input name
name = input("To start, Please give your name :")
print("\nGreetings,", name.strip().capitalize(), "Your Soundex-name is:", convert_to_soundex(name), "\n" )
#creating dictionary
dicti={}
#convert name to code and store in dictionary
dicti[name]=convert_to_soundex(name)
# keeping asking user for a word or name until user enters 0
while(True):
word=input("Please give a word to convert (0 to exit) :").strip().capitalize()
if word=='0':
break
elif ' ' in word:
print("Two words entered at once, Please enter one at a time.")
elif word=="":
print("Please give word with atleast one character.")
elif not word.isalpha():
print("Word should only contain characters.")
else:
if word in dicti:
print("Word already exists")
else:
dicti[word]=convert_to_soundex(word)
#printing formatted data
printData(dicti)
name = input("give name please...")
for nam in name:
if nam == " ":
print('invalid input')
# removes space from input
print(''.join([i for i in name if i != " "]))
I am currently doing the one of the practice projects on Automate the Boring Stuff with Python, specifically the Password Detection project in chapter 7. And I am trying to print out the elements of the password given by the user using findall() function, but it keeps popping up that ('list has no attribute group')
I tried putting the the passPut.group(0) in a variable and printed it with the %s replacement. I tried converting it to a string by doing print(str(passPut.group(0))). And so far, the error keeps popping up
passwordRegex = re.compile(r'''
([a-zA-Z]){1,}
([0-9]){1,}
''', re.VERBOSE)
while False == False:
passPut = str(input("Please input the password you would like to test: "))
if len(passPut) <= 7:
print("Password length too short, please try again.")
input("Press enter to continue: ")
continue
else:
break
passTest = passwordRegex.findall(passPut)
print(passPut, "is your password")
print('[%s]' % ', '.join(map(str, passPut.group())))
print(len(passTest.group(0)))
print(passTest.group(0))
for i in passTest.group(0):
print(i)
AttributeError: 'list' object has no attribute 'group'
That's the thing I keep seeing
re.findall finds all the matches in the string and return a list of all matches and if you are using groups then it will return a list of tuples. so for group 1 in first match you can try passTest[0][0].
Maybe you want something like this:
#!/usr/bin/env python3
import re
passwordRegex = re.compile(
r"""
([a-zA-Z]){1,}
([0-9]){1,}
([a-zA-Z0-9])*
""",
re.VERBOSE,
)
while True:
passwd = input("Please input the password you would like to test: ")
if len(passwd) >= 8:
break
print("Password length too short, please try again.")
input("Press enter to continue... ")
passwd_parts = passwordRegex.match(passwd)
print(passwd, "is your password.")
print("chars:", "[%s]" % ", ".join(map(str, passwd_parts.group())))
print("Length of group 0:", len(passwd_parts.group(0)))
print("Group 0:", passwd_parts.group(0))
for i in passwd_parts.group(0):
print(i)
So I have for example the following while statements and I would like to combine them. Because this can get tiresome if you have 20 of these with all different if statements.
while True:
name = str(raw_input("NAME PLEASE\n"))
if name.isalpha():
break
print("Please chars dude")
while True:
age = raw_input("Please type your age\n")
if age.isdigit():
break
print("Please digits only")
If I combine them and someone types a A-Z character with 'age' then the code restarts all over without having saved the 'name' statement. I would like it to save 'name' if it's correct and only start over from the if statement that was false.
while True:
name = str(raw_input("NAME PLEASE\n"))
if name.isalpha():
break
print("Please chars dude")
age = raw_input("Please type your age\n")
if age.isdigit():
break
print("Please digits only")
Use a function to encapsulate asking for information. You can pass in a validation test function:
def ask(question, validator, errormessage):
while True:
result = raw_input(question)
if not validator(result):
print(errormessage)
continue
return result
name = ask("NAME PLEASE\n", lambda s: s.isalpha(), "Please chars dude")
age = ask("Please type your age\n", lambda s: s.isdigit(), "Please digits only")
This is far more readable then any number of tests to see if the user already entered a correct name and you only need to ask for the age now.
Why not use functions and cut down on some duplication in the process?
def ask_input(prompt, error_msg, validation_fn):
while True:
data = raw_input(prompt)
if validation_fn(data):
return data
print(error_msg)
name = ask_input("NAME PLEASE\n", "Please chars dude", lambda x: x.isalpha())
age = ask_input("Please type your age\n", "Please digits only",
lambda x: x.isdigit())
In this case, the prompt (what to ask the user), an error message (what to provide on invalid input), and a validation function are provided to the ask_input() function. This hides the while loop behind the function call and gives you something more meaningful to read in the code.
The lambda functions are just an easy way to help do the validation. You could do this instead:
def isalpha(x):
return x.isalpha()
def isdigit(x):
return x.isdigit()
name = ask_input("NAME PLEASE\n", "Please chars dude", isalpha)
age = ask_input("Please type your age\n", "Please digits only", isdigit)
You can set the variables to None first, and then check them before assignment:
name, age = None, None
while True:
if name is None:
name = str(raw_input("NAME PLEASE\n"))
if not name.isalpha():
print("Please chars dude")
name = None
continue
if age is None:
age = raw_input("Please type your age\n")
if not age.isdigit():
print("Please digits only")
age = None
continue
print("input is valid")
break
continue will start the loop over again. This fits better in the logic of your code, since break actually stop and exit the loop code.
Just use flags to track weather valid input is given, if given then exit the loop.
name_input_required = True
name = ''
while name_input_required:
name = str(raw_input("NAME PLEASE\n"))
if name.isalpha():
name_input_required = False
else:
print("Please chars dude")
age_input_required = True
age = None
while age_input_required:
age = raw_input("Please type your age\n")
if age.isdigit():
age_input_required = False
else:
print("Please digits only")
Try this:
name = None
age = None
while requires_info:
if name is None:
temp_name = str(raw_input("NAME PLEASE\n"))
if temp_name.isalpha():
name = temp_name
continue
else:
print("Please chars dude")
continue
if age is None:
temp_age = raw_input("Please type your age\n")
if temp_age.isdigit():
age = temp_age
continue
else:
print("Please digits only")
continue
break
What we do here is use a single continuous loop and a few if statements/variables to track what still needs to be done. Note depending on how you want them to enter the data you may also add logic to not ask for age if the name was invalid.
So I have for example the following while statements and I would like to combine them. Because this can get tiresome if you have 20 of these with all different if statements.
I assume the actual problem is "How to reduce tiresome code?" instead of "How to merge two loops into one?". I think keeping two loops is a good idea.
def safe_input(prompt, err_message, validation_fn):
while True:
value = raw_input(prompt)
if validation_fn(value):
return value
print err_message
name = safe_input("NAME PLEASE\n", "Please chars dude", str.isalpha)
age = safe_input("Please type your age\n", "Please digits only", str.isdigit)
If you always want the used to enter text in a separate line, you might want to print prompt before raw_input and to not give an argument to raw_input. That way you don't have to supply "\n" in every call of safe_input.
Yes, you can combine both loops in one loop!
Always try to solve the problem line by line.
You will get to learn the language better and it is the most simple way to solve any problem too.
A line by line solution would look like this:
name = '' # define name outside while loop
while True:
if not name:
name = str(raw_input("NAME PLEASE\n"))
if not name.isalpha(): # validate name
print("Please chars dude")
# reset name
name = ''
else:
age = raw_input("Please type your age\n")
if age.isdigit(): # validate age
"""continue your code here"""
print('name: ' + name + ' and age: ' + age)
print('Ok! Goodbye!')
break # while loop
else:
print("Please digits only")
will print:
NAME PLEASE
Elis
Please type your age
30
name: Elis and age: 30
Ok! Goodbye!
This will help you understand while loop better and how to use it in more difficult cases.
Do not over design using redundant language features. It will make refactoring and debugging difficult.
So I am working on a project and I was wondering if it is possible to reuse an 'if' statement. For example, my code right now is
import re
import string
userinput=''
print "Hello! What is your name?"
userinput = str(raw_input("My name is "))
if not re.search(r'[A-Za-z]', userinput):
print "That isn't a name!"
print str(raw_input("My name is "))
and it prints
Hello! WHat is your name?
My name is 86124674983#
That isn't a name!
My name is 986421674941
986421674941
As you can see, it recognizes anything other than letters as an invalid entrance, but it only does it once. If you input symbols the second time it prompts you for a name, it takes that random input and prints it. I want it to print
Hello! WHat is your name?
My name is 86124674983#
That isn't a name!
My name is 986421674941
That isn't a name!
My name is Eli
Sorry if this confuses anyone. If you need anything clarified don't hesitate to ask. Thanks very much in advance!!
Use a while loop:
print "Hello! What is your name?"
while True:
userinput = raw_input("My name is ")
if not re.search(r'[A-Za-z]', userinput):
print "That isn't a name!"
else:
break
print userinput
Note you don't print a raw_input() - or make it str (it already is). All you need is the raw_input('text') and it will display text.
Use a while-loop:
print "Hello! What is your name?"
while True:
userinput = raw_input("My name is ")
if re.search(r'[A-Za-z]', userinput):
break
print "That isn't a name!"
print userinput
Alright, so I defined a function where the user can input his/her name. I want to make it so that the user is not allowed to input a number like "69" for his/her name. How would I go about doing this? Here is the code I used:
def name():
while True:
name = input("What is your name? "))
try:
return str(name)
break
except TypeError:
print("Make sure to enter your actual name.")
You can use isalpha() to check name:
Return true if all characters in the string are alphabetic and there
is at least one character, false otherwise.
>>> "69".isalpha()
False
>>> "test".isalpha()
True
Here's your code with modifications:
while True:
name = input("What is your name? ")
if name.isalpha():
break
else:
print("Make sure to enter your actual name.")
continue
Or:
name = input("What is your name? ")
while not name.isalpha():
print("Make sure to enter your actual name.")
name = input("What is your name? ")
You can use str.isdigit() method to check if the string contains just digits:
name = input("What is your name? ")
while name.isdigit():
print("Make sure to enter your actual name.")
name = input("What is your name? ")
Note that this will allow names like - "Rohit1234". If you just want to allow alphabetic characters, then you can use str.isalpha() method instead.
Invert your logic:
while True:
name = ...
try:
int(name)
print "Name can't be a number."
except TypeError:
return str(name)
Mind you, this will accept any input that is not a valid integer, including 123abc or so.