I'm trying to write a program to calculate densities, and I have tried to create a while loop the prevents the user from entering nothing or a non-number for the volume.
But when I run the program the it just loops "You have to type a value" forever. I've tried the same code in a for loop and it does work after inputing 2 numbers.
def GetVolume():
print("How many cublic cm of water does the item displace")
Volume = input()
while Volume == ("") or type(Volume) != int:
print("You have to type a value")
Volume = input()
return float(Volume)
This solution is written assuming you are using Python 3. The problem in your code is that you are assuming that if you type in a number, the input method will return a type int. This is incorrect. You will always get a string back from your input.
Furthermore, if you try to cast int around your input to force an int, your code will raise if you enter a string, with:
ValueError: invalid literal for int() with base 10:
So, what I suggest you do to make your implementation easier is to make use of try/exceptinstead to attempt to convert your value to a float. If it does not work, you prompt the user to keep entering a value until they do. Then you simply break your loop and return your number, type casted to a float.
Furthermore, because of the use of the try/except, you no longer need to put in a conditional check in your while loop. You simply can set your loop to while True and then break once you have satisfied your condition in your code.
Observe the code below re-written with what I mentioned above:
def GetVolume():
print("How many cublic cm of water does the item displace")
Volume = input()
while True:
try:
Volume = float(Volume)
break
except:
print("You have to type a value")
Volume = input()
return Volume
def GetVolume():
Volume = input("How many cublic cm of water does the item displace")
while not Volume.replace('.', '').replace(',', '').isdigit():
Volume = input("You have to type a value")
return float(Volume)
x = GetVolume()
print(x)
You have to modify your while because is validating that is str or different than int. An input will always be an str by default unless you modified the type with int() or float() in your case.
You can use 'try' instead to check for this:
while True:
x = input("How many cubic cm of water does the item displace")
try:
x = float(x)
break
except ValueError:
pass
print('out of loop')
Related
Im currently working on a project for my coding class. The prompt is to make an atm interface.
All of my code is currently working but when it comes to the function of deposit() it asks for a whole number to be entered where I use int(input) say someone inputs a float like 45346.4 it comes up with an error. Is there a fix to this?
here is my code currently for the deposit function. The balance is already given outside of this function.
def deposit():
balanced = balance
print(f'Your current balance is ${balanced}\n------------------------------')
print('How much money would you like to deposit?\n---------------------------\n You can only deposit in whole numbers')
deposit_amount = int(input('Enter here:'))
if deposit_amount.is_integer():
balance_a_d = balanced + deposit_amount
print(f'You Current Balance is ${balance_a_d}\n-------------------------------\nHave a great day!')
quit()
else:
print('----------------------------\nThat is not a whole number please try again\n----------------------------')
deposit()
You could use a while loop and a try block to keep asking for input until ValueError is no longer raised.
Something like this:
number = None
while number == None:
try:
number = int(input('Enter here:'))
except ValueError as e:
print('Please enter a whole number.')
I have a general purpose input function which is simple to use and saves a lot of repeated code.
def getInput(prompt, t=str):
while True:
v = input(f'{prompt}: ')
try:
return t(v)
except ValueError:
print('Invalid input')
If I just want text input then:
getInput('Enter some text')
Of course, for plain text, this isn't really necessary.
If I want a float then:
getInput('Enter a float', float)
Or int:
getInput('Enter an integer', int)
This saves you from having to "wrap" all your inputs in try/except as it's all handled for you
I have this function below, which I have done something wrong in somewhere.
def quantityFunction(product):
valid = False
while True:
if product is not None:
quantity = input("Please enter the amount of this item you would like to purchase: ")
for i in quantity:
try:
int(i)
return int(quantity)
valid = True
except ValueError:
print("We didn't recognise that number. Please try again.")
#If I get here, I want to loop back to the start of this function
return True
return False
To run through, the function is called from the main part of the program like so: quantity = quantityFunction(product)
The return False at the bottom of the code is to do with if product is None, which is needed after a bit of code in another function but has had to go in this function.
If the user input for quantity is a number, all works fine. If it is anything else, the Value Error is printed and you can enter another input. If you put another letter etc in, it repeats again, if you put a number in, it accepts it.
However, it does not return the number you inputted after the letters. It just returns 0.
I suspect this is something to do with how I am repeating the code, i.e. the code should loop back to the start of the function if it hits the Value Error.
Any Ideas?
You said:
the code should loop back to the start of the function if it hits the Value Error.
Then you should not use return statements, otherwise the function will terminate, returning True or False.
Few issue:
1) return statement returns control to the calling function.
2) You are looping over the input, which is wrong.
3) valid=True isn't executed at all.
def quantityFunction(product):
valid = False
while True:
if product is not None:
quantity = raw_input("Please enter the amount of this item you would like to purchase: ")
try:
return int(quantity)
#valid = True (since it is never run)
except ValueError:
print("We didn't recognise that number. Please try again.")
#If I get here, I want to loop back to the start of this function
#return True
return False
quantityFunction("val")
Note : Use raw_input() in case of Python 2.7 and input() in case of 3.x
Try this (some formatting included too, but the functionality should be the same):
def determine_quantity(product): # descriptive function name
if not product: # avoiding nesting
return False
while True:
quantity = input("Please enter the amount of this item you would like to purchase: ")
try:
return int(quantity) # try to convert quantity straight away
except ValueError:
print("We didn't recognise that number. Please try again.")
# nothing here means we simply continue in the while loop
Ideally, you'd take product out. A function should do as little as possible, and this check is better off somewhere else.
def determine_quantity():
while True:
quantity = input("Please enter the amount of this item you would like to purchase: ")
try:
return int(quantity)
except ValueError:
print("We didn't recognise that number. Please try again.")
First, let's address the code. Simply stated, you want a function that will loop until the user enters a legal quantity.
product doesn't do much for the function; check it in the calling program, not here. Let the function have a single purpose: fetch a valid quantity.
Let's work from there in the standard recipe for "loop until good input". Very simply, it looks like:
Get first input
Until input is valid
... print warning message and get a new value.
In code, it looks like this.
def get_quantity():
quantity_str = input("Please enter the amount of this item you would like to purchase: ")
while not quantity_str.isdigit():
print("We didn't recognise that number. Please try again.")
quantity_str = input("Please enter the amount of this item you would like to purchase: ")
return quantity
As for coding practice ...
Develop incrementally: write a few lines of code to add one feature to what you have. Debug that. Get it working before you add more.
Learn your language features. In the code you've posted, you misuse for, in, return, and a function call.
Look up how to solve simple problems. try/except is a more difficult concept to handle than the simple isdigit.
You should try this..
def quantityFunction(product):
valid = False
while True:
if product is not None:
quantity = raw_input("Please enter the amount of this item you would like to purchase: ")
if quantity.isdigit():
return int(quantity)
valid = True
else:
print("We didn't recognise that number. Please try again.")
continue
return False
quantity = quantityFunction("myproduct")
I am very new to Python (started 2 days ago). I was trying to validate positive integers. The code does validate the numbers but it asks twice after a wrong input is entered. For example if I enter the word Python, it says: This is not an integer! like is supposed to but if I enter 20 afterwards, it also says it is not an integer and if I enter 20 again it reads it.
def is_positive_integer(input):
#error: when a non-integer is input and then an integer is input it takes two tries to read the integer
flag = 0
while flag != 1:
try:
input = int(input)
if input <= 0:
print "This is not a positive integer!"
input = raw_input("Enter the number again:")
except ValueError:
print "This is not an integer!"
input = raw_input("Enter the number again: ")
if isinstance(input, int):
flag = 1
return input
number = raw_input("Enter the number to be expanded: ")
is_positive_integer(number)
number = int(is_positive_integer(number))
Any help is appreciated.
The main bug is that you call is_positive_integer(number) twice with the same input (the first thing you enter).
The first time you call is_positive_integer(number), you throw away the return value. Only the second time do you assign the result to number.
You can "fix" your program by removing the line with just is_positive_integer(number) on its own.
However, your code is a little messy, and the name is_positive_integer does not describe what the function actually does.
I would refactor a little like this:
def input_positive_integer(prompt):
input = raw_input(prompt)
while True:
try:
input = int(input)
if input <= 0:
print "This is not a positive integer!"
else:
return input
except ValueError:
print "This is not an integer!"
input = raw_input("Enter the number again: ")
number = input_positive_integer("Enter the number to be expanded: ")
The problem stems from the fact that you're calling is_positive_integer twice. So, the first time it's called, you send it a string like 'hello', then it says it's not an integer and tells you to try again. Then you enter '20', which parses fine, and it's returned.
But then you don't save a reference to that, so it goes nowhere.
Then you call the function again, this time saving a reference to it, and it first tries the original bad string, which was still there in number. Then it complains that it's a bad input, asks you for a new one, and you provide it, terminating the program.
While using the following code:
url = None
print("For 'The Survey of Cornwall,' press 1")
print("For 'The Adventures of Sherlock Holmes,' press 2")
print("For 'Pride and Prejudice,' press 3")
n = input("Which do you choose?")
if n==1:
url = 'http://www.gutenberg.org/cache/epub/9878/pg9878.txt' #cornwall
print("cornwall")
elif n==2:
url = 'http://www.gutenberg.org/cache/epub/1661/pg1661.txt' #holmes
print("holmes)
elif n==3:
url = 'http://www.gutenberg.org/cache/epub/1342/pg1342.txt' #pap
print("PaP")
else:
print("That was not one of the choices")
I'm only getting the "else" case returned, why might that be??
input() returns a string in py3x. So, you need to convert it to int first.
n = int(input("Which do you choose?"))
Demo:
>>> '1' == 1
False
>>> int('1') == 1
True
input() returns a string, but you are comparing it to integers. You can convert the result from input to an integer with the int() function.
You should convert the input with int()
n = input("Which do you choose?") should be n = int(input("Which do you choose?"))
This is due to the fact that input returns strings for all input since it should almost always work.
I'm guessing you are using Python 3, in which input behaves like raw_input did in Python 2, that is, it returns the input value as a string. In Python, '1' does not equal 1. You'll have to convert the input string to an int using n = int(n), then go through your succession of elifs.
input() returns a string type. So, you need to convert your input into an integer using int(), or else you can compare the inputs to characters instead of integers, like '1', '2'.
While the other answers correctly identify the reason you're getting the else block in your current code, I want to suggest an alternative implementation that is a bit more "Pythonic". Rather than a bunch of nested if/elif statements, use a dictionary lookup, which can support arbitrary keys (including perhaps more meaningful ones than integers):
book_urls = {'cornwall': 'http://www.gutenberg.org/cache/epub/9878/pg9878.txt',
'holmes': 'http://www.gutenberg.org/cache/epub/1661/pg1661.txt',
'p and p': 'http://www.gutenberg.org/cache/epub/1342/pg1342.txt'}
print("For 'The Survey of Cornwall,' type 'cornwall'")
print("For 'The Adventures of Sherlock Holmes,' type 'holmes'")
print("For 'Pride and Prejudice,' type 'p and p'")
choice = input("Which do you choose?") # no conversion, we want a string!
try:
url = book_urls[choice]
except KeyError:
print("That was not one of the choices")
url = None
You could make the whole thing data-driven if you wanted, with the book names and urls being provided as an argument to a function that would ask the user to pick one (without knowing what they were ahead of time).
The purpose of this program is to display the sum, average, max, and min of use based input.
count=0.0
Sum=0.0
average=0.0
data=float(input("Enter a number or just ENTER to quit:"))
Min=data
Max=data
while data!="":
count+=1
number=float(data)
Sum+=number
average=Sum/count
if data<Min:
Min=data
if data>Max:
Max=data
data=float(input("Enter a number or just ENTER to quit:"))
print(count,("numbers entered."))
print("Sum:",Sum)
print("Average:",average)
print("Min:",Min)
print("Max:",Max)
The problem is with line 20:
data=float(input("Enter a number or just ENTER to quit:"))
When i press ENTER to end the loop it says that it was unable to convert string to float and errors. What am I doing wrong ?????
Well, you shouldn't convert to float immediately. Also, this is not how you do do..while loop in Python.
while True:
data = input('Enter a number or ENTER to quit: ')
if not data: break
data = float(data)
# ...
This way you don't have to duplicate code, or to prolong the life of data name unnecessarily.
By default, the data type of input is string. Pressing ENTER will return an empty string which cannot be casted into a float, since the string is empty and there is nothing to be casted, which is generating the error. Here are two solutions to handle this error.
Solution 1
Do not cast input into float directly, but cast it when assigning the value of input to any variable.
data=input("Enter a number or just ENTER to quit:")
Add the following statement before the loop to handle the condition when the user wants to exit without entering any number.
if not data: # If user wants to exit without entering any number
Max = 0
Min = 0
else: # Cast the inputs by user to float
Max = float(data)
Min = float(data)
Lastly add the following line at the beginning inside the loop.
data = float(data)
Complete Code
count=0.0
Sum=0.0
average=0.0
data=input("Enter a number or just ENTER to quit:")
if not data:
Max = 0
Min = 0
else:
Max = float(data)
Min = float(data)
while data!='':
data = float(data)
count+=1
number=float(data)
Sum+=number
average=Sum/count
if data<Min:
Min=data
if data>Max:
Max=data
data=input("Enter a number or just ENTER to quit:")
print(count,("numbers entered."))
print("Sum:",Sum)
print("Average:",average)
print("Min:",Min)
print("Max:",Max)
Solution 2
What you can also do is set a default value for empty inputs. Here since you are casting input into a float, you can set any number as the default value for empty inputs. However, I will not prefer this because if the user enters the same number as the default value, the loop will be terminated. In the following example I've only modified two lines of your code and set the default value for empty inputs as 0.
count=0.0
Sum=0.0
average=0.0
data=float(input("Enter a number or just ENTER to quit:") or 0)
Min=data
Max=data
while data!=0:
count+=1
number=float(data)
Sum+=number
average=Sum/count
if data<Min:
Min=data
if data>Max:
Max=data
data=float(input("Enter a number or just ENTER to quit:") or 0)
print(count,("numbers entered."))
print("Sum:",Sum)
print("Average:",average)
print("Min:",Min)
print("Max:",Max)
The float() function raises an exception for blank inputs. You must catch this exception for your loop to work as intended. Here is the simplest fix:
In Python 2.x, it is actually the input() call that raises the exception, not float(). So, if you are using Python 2.x, my solution is the only one here that works.
while True:
count+=1
Sum+=data
average=Sum/count
if data<Min:
Min=data
if data>Max:
Max=data
try:
data=float(input("Enter a number or just ENTER to quit:"))
except:
break
Your variable names are incorrect, because sum, min, and max are all functions. Change them to different names such as "datasum", "datamin", and "datamax", so that the program does not confuse them with the functions.
Python by default takes input in the string format only. Don't do direct type casting in python like string to float. It will give an error immediately.
The best way to conversion of type string to float is::
string_data = input("enter the data")
enter the data 123
string_data '123'
float_data = float(string_data)
float_data 123.0