I have a python program where it prompts a user input for position or index and deletes the element in the list based on the position or index. The python program works but I'm having issues with the condition where if no user input is given, it automatically deletes the whole line in the list.
Example:
lst = [1,2,3,4,5]
enter position: 2
output: [1,2,4,5]
enter position: #user just pressed enter without giving any input
output: []
I'm writing the function within a class whereby:
def delete(self,index):
"""
This function deletes an item based on the index
:param self: the array
:param index: the index of an item in the array
:return: the array is updated
:raises: IndexError if out of range
"""
if not index:
self.__init__()
if index<0:
index = index + self.count
for i in range(index, self.count -1):
self._array[i] = self._array[i+1]
self.count-=1
and prompting the user input is as such:
position = int(input("Enter position:"))
it's not possible to just press 'enter' without receiving an error due to the position only receiving integers hence I'm looking for a method where if the user doesn't give any position, it registers it and prints just an empty list instead of an error message.
What you're looking for is the try-except block. See the following for an example:
input_invalid = true
while input_invalid:
user_input = input("Enter position: ")
try:
user_input = int(user_input)
input_invalid = false
except ValueError:
print("Please enter a valid integer!")
Here, the try-except block catches any errors (of the type specified
in except) thrown within the code block. In this case, the error results from trying to call int() on a string that does not contain an integer (ValueError). You can use this to explicitly prevent the error and control the logic flow of your program like shown above.
An alternate solution without using try-except is to use the .isdigit() method to validate the data beforehand. If you were to use .isdigit() (which I personally think is better), your code would look something like this:
input_invalid = true
while input_invalid:
user_input = input("Enter position: ")
if user_input.isdigit():
input_invalid = false
else:
print("Please enter a valid integer!")
Hope this helped!
Related
I have simple code:
def simpleMethod():
try:
list_to_app = []
number_of_a = input('\nHow many a you want to create? ')
number_of_a = int(number_of_a)
for i in range(number_of_a):
user_a = input('\nPlease type here some track: ')
list_to_app.append(user_a.lower())
except ValueError:
stderr.write('Type error - please provide an integer character')
simpleMethod()
I do not want to use something like while True:...
How to make some loop (I think while will be fine in this case) for this kind of flow:
user types non-integer
program shows Type error - please provide an integer character
program goes back to 1. step
This is simple method but I'm stuck.
Add a while True loop to repeat the try block until it can successfully break. You probably also want to return the list you're building so that the caller can access it:
def simpleMethod():
list_to_app = []
while True:
try:
number_of_a = input('\nHow many a you want to create? ')
number_of_a = int(number_of_a)
break
except ValueError:
stderr.write('Type error - please provide an integer character')
for i in range(number_of_a):
user_a = input('\nPlease type here some track: ')
list_to_app.append(user_a.lower())
return list_to_app # no point building a list you don't return!
tracks = simpleMethod()
A simpler way to build a list is a comprehension -- you can actually put almost the entire function in a single comprehension statement within that while, since the exception will raise to the outer loop. You might also want to make the function name more descriptive:
from typing import List
def get_user_tracks() -> List[str]:
"""Prompt the user for a list of tracks."""
while True:
try:
return [
input('\nPlease type here some track: ')
for _ in range(int(input('\nHow many a you want to create? ')))
]
except ValueError:
stderr.write('Type error - please provide an integer character')
tracks = get_user_tracks()
I am new to python and came around a scenario explained below-:
This is one from the .pdf I am referring to learn. Would be great if anyone could guide or share some other resources.
A program which repeatedly reads numbers until the user enters “done”. Once “done” is entered, print out the total, count, and average of the numbers. If the user enters anything other than a number, detect their mistake using try and except and print an error message and skip to the next number.
Enter a number: 4
Enter a number: 5
Enter a number: bad data
Invalid input
Enter a number: 7
Enter a number: done
16 3 5.333333333333333*
I am unable to store the values into list.
Tried going with this logic-:
while True:
line = input('Enter Number-: ')
if type(line) == int():
continue
if line == 'done':
break
print(line)
print('Done!')
Just need to know how to store into lists without using spaces or commas,
The user should be able to enter the value as shown in example above and those should get stored in a list.
Thanks in advance.
In Python 2.7, input will evalulate any entry and will fail if the input is not a correct Python type to begin with. It's better to use raw_input here as any entry will be considered a string. If you move to Python 3, raw_input was removed and input acts how raw_input did. So your example expects you to give it '45' or 'done' instead of 45 or done.
But the reason you're unable to store any values into a list is because you're not adding them to a list in the first place. But since we've also switched to raw_input, we don't know if the entry is a valid number or not. So we need to try to convert it to a number and if it isn't one, then check to see if it's the keyword telling the code to stop.
values = [] # make an empty list
while True:
line = raw_input('Enter Number-: ') # all entries here are considered strings
try:
num = int(line) # convert to an integer
values.append(num) # add to list
continue # return to input query
except: # int(line) threw an error, so not a valid number input
if line == 'done': # check if should stop
break # get out of loop
else: # anything else
print 'bad data, invalid input'
continue # return to input query
print 'Done!\n'
print 'total:', sum(values)
print 'count:', len(values)
print 'average:', sum(values) / float(len(values))
If you're entering more than just integers, you may wish to change num = int(line) to num = float(line) to handle decimal inputs, as int only accepts integers.
Enter Number-: 4
Enter Number-: 5
Enter Number-:
bad data, invalid input
Enter Number-: 7
Enter Number-: done
Done!
total: 16
count: 3
average: 5.33333333333
The Tutorial may also be helpful in learning Python.
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'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')
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.