# Initialized list of cities
CitiesInMichigan = ["Acme", "Albion", "Detroit", "Watervliet", "Coloma", "Saginaw", "Richland", "Glenn", "Midland",
"Brooklyn"]
# Get user input
inCity = input("Enter name of city: ")
# Write your test statement here to see if there is a match.
for i in range(len(CitiesInMichigan)):
if CitiesInMichigan[i] == inCity:
while CitiesInMichigan is True:
print("City found. ")
break
else:
print("Not a city in Michigan. ")
input("Enter name of city: ")
# If the city is found, print "City found."
# Otherwise, "Not a city in Michigan" message should be printed.
So what I am trying to go for was to have the input case insensitive so (Acme, ACME, acMe, etc.) would work
and to have it break if input matches or try again if input is false.
Instead I have been receiving that all inputs are not a city of Michigan.
What am I doing wrong?
P.S I am studying python for school and as a passion, I am still new and wrapping my head around it please criticize anything I do wrong to further improve my codings.
Thank you
Your while loop is unnecessary and your else clause should simply be moved outside of the loop. You also need to loop all the way back to your initial input if a city is not found.
cityFound = False
while not cityFound:
inCity = input("Enter name of city: ")
for i in range(len(CitiesInMichigan)):
if CitiesInMichigan[i] == inCity:
print("City found. ")
cityFound = True
break
if not cityFound:
print("Not a city in Michigan. ")
To do case insensitive matching you should use the string upper method on both the input and the value in your CitiesInMichigan list before you check for equality.
Other notes:
You don't need to use an index in your for loop, you can just use for city in CitiesInMichigan
Generally variable names begin with lower case letters (citiesInMichigan instead of CitiesInMichigan). Class names start with upper case letters
as others have mentioned, the while loop is unnecessary. below code is longer than it needs to be, but it explains itself well.
# Initialized list of cities
CitiesInMichigan = ["Acme", "Albion", "Detroit", "Watervliet", "Coloma", "Saginaw", "Richland", "Glenn", "Midland",
"Brooklyn"]
def get_input():
'''Get user input and capitalize it'''
inCity = input("Enter name of city: ")
inCity = inCity.capitalize()
check_against_list(name=inCity)
def check_against_list(name):
'''check if the item is in the list. if yes, print. if not, print and start over'''
if name in CitiesInMichigan:
print("City found. ")
else:
print("Not a city in Michigan. ")
get_input()
get_input()
CitiesInMichigan = ["Acme", "Albion", "Detroit", "Watervliet", "Coloma", "Saginaw", "Richland", "Glenn", "Midland",
"Brooklyn"]
CitiesInMichigan_casefold = [i.casefold() for i in CitiesInMichigan ]
inCity = input("Enter name of city: ")
while True:
if inCity.casefold() in CitiesInMichigan_casefold:
print("city found",inCity)
break
else:
print("city not found")
inCity = input("Enter name of city again: ")
Try this. you have to compare case fold strings both in input and as well as from the mentioned list.
if the city is found, it prints city name and breaks the loop.
else it continues until the city is matched.
Related
Currently I have this, but when entering a name with a surname, but it does not validate it accordingly
name = input("Enter your name: ")
if True == name.isalnum():
print("Correct, it's a name")
else:
print("Error")
You can try to split the input by space symbols first and then check each part. The code will be something like that:
name = input("Enter your name: ")
if all(part.isalnum for part in name.split()):
print("Correct, it's a name")
else:
print("Error")
Btw, I guess you should use isalpha instead of isalnum, because '123' not seems to be a valid name.
I think you should change your code checking for if all are digits
False == name.isdigit():
I have a problem in which users can input spaces or nothing and still pass through the program, how do I go about preventing this? I am still a beginner at python.
def orderFunction(): # The function which allows the customer to choose delivery or pickup
global deliveryPickup
deliveryPickup = input("Please input delivery or pickup: d for delivery p for pickup")
if deliveryPickup == "d":
global customerName
while True:
try:
customerName = (input("Please input your name"))
if customerName == (""):
print("Please input a valid name")
else:
break
global customerAddress
while True:
try:
customerAddress = (input("Please input your name"))
if customerAddress == (""):
print("Please input a valid Address")
else:
break
global customerPhnum
while True:
try:
customerPhnum = int(input("Please input your phone number"))
except ValueError:
print("Please input a valid phone number")
else:
break
print("There will also be a $3 delivery surcharge")
elif deliveryPickup == "p":
customerName = (input("Please input your name"))
if customerName == (""):
print("Please input a valid name")
orderFunction()
else:
print("Please ensure that you have chosen d for Delivery or p for Pickup")
orderFunction()
orderFunction()
Here is my attempt at doing this but I get all kinds of unindent and indent errors at the moment and I think my while loops are probably wrong.
Essentially if I input a space or hit enter into one of the customer inputs (customerName for instance) it gets stored. This needs to prevented and I have tried to fix it by using while loops which obviously haven't worked.
Hopefully someone has a solution to this problem
Many Thanks.
.strip() removes all tabs or spaces before and after a string.
Meaning all spaces == empty string. All tabs == empty string. So all you have to check if the length of that string != 0 or the string is not empty. Just use an infinite loop to keep on forcing the right input.
Also as a tip, you don't have to limit yourself into one function.
Here's a working code below.
def getNonBlankInput(message, error_message):
x = input(message)
while len(x.strip()) == 0:
x = input(error_message)
return x
def getValidIntegerInput(message, error_message):
msg = message
while(True):
try:
x = int(input(msg))
break
except ValueError:
msg = error_message
return x
def orderFunction(): # The function which allows the customer to choose delivery or pickup
global deliveryPickup
global customerName
global customerAddress
global customerPhnum
deliveryPickup = input("Please input delivery or pickup: d for delivery p for pickup")
if deliveryPickup == "d":
customerName = getNonBlankInput("Please input your name: ", "Please input a valid name: ")
customerAddress = getNonBlankInput("Please input your address: ", "Please input a valid address: ")
customerPhnum = getValidIntegerInput("Please input your phone number: ", "Please input a valid phone number: ")
print("There will also be a $3 delivery surcharge")
elif deliveryPickup == "p":
customerName = getNonBlankInput("Please input your name: ", "Please input a valid name: ")
else:
print("Please ensure that you have chosen d for Delivery or p for Pickup")
orderFunction()
orderFunction()
Try using a regular expression that checks if any character between "A-Z" has been inserted, if not, give an error
The while loops are a decent solution, you just need to add more checks to your if statements.
First, you don't need a try statement on the top two loops. Don't use a try statement unless you're expecting an error, which you need to handle with an except statement, like you do in the bottom while loop.
Then you just need to add more conditions to your top two loops, I don't know exactly what you want to prevent, but you could try checking the length of the input, also see this answer for an interesting method:
https://stackoverflow.com/a/2405300/8201979
Instead of using input right away you can make a function similar to this one that will only allow valid inputs.
You can use this valid_input function instead of input.
def valid_input(text):
not_valid = True
res = ''
while not_valid:
res = input(text)
if res.split(): # if text is empty or only spaces, this creates an empty list evaluated at False
not_valid = False
return res
here the check is pretty simple: every text made out of nothing or spaces won't be allowed and we will keep asking for the same input until a valid information is given.
I made this code simple just so you get a general idea. But you can change the validation test to your liking and maybe also output a warning saying why the input wasn't allowed so the person knows what to do. You can do more advanced validation with regex, and maybe you need a minimum text length etc...
You have indent error because you have a try statement without the corresponding except.
You need both to make it work (as you did in the Phone number section).
Here is a link to the try/except: docs
Also, you can check if a string is empty as detailed in this answer.
So for example you want to write:
try:
customerName = input("Please input your name")
if not customerName:
print("Please input a valid name")
else:
break
except ValueError:
print("Please input a valid name")
Although the above seems a bit redundant, so you might want to raise an exception if the customer name is empty, catch the exception in the except block, print the warning and return error (or something else).
try:
customerName = input("Please input your name")
if not customerName:
raise ValueError
except ValueError:
print("Please input a valid name")
else:
break
Try adding another while true for pick and delivery option so that it can prevent taking other inputs
you don't need any of those try/excepts (which are broken anyway).
Its difficult to figure out what you're trying to do, are you trying to raise an exception if an empty string is passed, or request another input from the user? You seem to be half implementing both at the moment.
If its the latter, something like this would work.
def func(fieldname):
while True:
val = input("Please input your {}".format(fieldname))
if val.strip() != "":
break
else:
print("Please input a valid {}".format(fieldname))
return val
delivery_pickup = input("Please input delivery or pickup: d for delivery p for pickup")
if delivery_pickup == "d":
customer_name = func("name")
address = func("address")
phone_number = func("phone number")
What you are looking for is the str.strip method that remove trailing whitespace in strings.
Also I think try is not particularly suited for your needs here.
customerName = input("Please input your name")
while not customerName.strip():
customerName = input("Please input a valid name")
for the phone number I would not convert to integer because if the phone number starts with zeros, they will not be stored.
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.
Just started venturing into arrays using python 2.7.5. My objective is to ask the user for input and store the input in multiple arrays.
So far this is what I have, as far as storing multiple arrays with input. I run into an error when trying to print the input at the end.
Here is the code I have so far.
# want user to enter a list of employee names, error occurs when trying to recall user entry
emp_name = [0]
emp_name = raw_input("please enter employee name")
while emp_name !="neg":
emp_name = raw_input("please enter employee name,enter neg to exit")
print "employee 2 is:", emp_name[1] #I want the 2nd name entered to appear
Then you are going to want to:
Change the names of your variables so that you don't have the list be the same name as the input.
Append each name you get to the list.
This should be what you want:
employees = []
name = raw_input("Please enter an employee name: ")
while name != "neg":
# Append the previous name.
employees.append(name)
# Get a new name.
name = raw_input("Please enter an employee name or 'neg' to exit: ")
# You need a try/except here in case there is no second employee.
# This can happen if the user types in "neg" to begin with or only 1 name.
try:
print "Employee 2 is: ", employees[1]
except IndexError:
print None
Also, I slightly changed your input prompts to make them cleaner and more user-friendly.
Below is a sample of the script in action:
Please enter an employee name: Bob
Please enter an employee name or 'neg' to exit: Joe
Please enter an employee name or 'neg' to exit: neg
Employee 2 is: Joe
And here is one without a second employee:
Please enter an employee name: Joe
Please enter an employee name or 'neg' to exit: neg
Employee 2 is: None
Your first line declares emp_name as an array.
Your second line raw_input("please enter employee name") re-assigns it as a string.
So when you tell it to print emp_name[1], it has no idea what emp_name[1] is because it sees a string at that point.
If you write, instead:
emp_name[0] = raw_input("please enter employee name")
That means you're assigning that employee name to element 0 of array emp_name.
Then you want to add index entries inside the while, rather than re-assigning them (you see, it doesn't automatically accumulate entries, you have to tell it to).
Happy Coding!
You can add to a list with list.append(), but you need to capture user input into a separate variable:
employees = []
emp_name = raw_input("Please enter employee name, enter neg to exit")
while emp_name != "neg":
emp_name = raw_input("Please enter employee name, enter neg to exit")
employees.append(emp_name)
print "employee 2 is:", employees[1]
Apart from using separate variables for the list of names and for the name the user has just entered, I also started the list entirely empty.
You can avoid using two raw_input() calls by changing the while loop to an infinite loop and instead break out of the loop when 'neg' has been entered:
employees = []
while True:
emp_name = raw_input("Please enter employee name, enter neg to exit")
if emp_name == 'neg':
break
employees.append(emp_name)
You may also need to test if there are enough employees entered before you print the second employee:
if len(employees) > 1:
print "Employee 2 is:", employees[1]
else:
print "You didn't enter enough employees!"
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.