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.
Related
I wrote a function, which returns the value to the main code only when the input is given in the correct format, to add in my school project but I am facing a small problem and I can't understand the reason why.
This is the code -
def xinput(text, pattern):
myinput = input(text)
match = re.search(pattern,myinput)
if match is None:
print("\nError. \nPlease give input in correct format.\n")
xinput(text, pattern)
else:
return myinput
val = xinput("Enter a number : ", pattern=r"^[\d]+$")
print(val)
Entering the correct value the first time works but if a wrong input is given the first time and the correct input the second time, it returns None.
Here is the output -
Enter a number : q
Error.
Please give input in correct format.
Enter a number : 1
None
I've checked it and myinput remains 1 till just before returning it.
You need to return the value returned by your recursive calls:
if match is None:
print("\nError. \nPlease give input in correct format.\n")
return xinput(text, pattern) # added return here
else:
return myinput
Since you don't return it in your code, when your function completes it comes inside your if statement and does nothing with the result hence returns None.
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!
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 troubling handling input in python. I have a program that request from the user the number of recommendations to be calculated.He can enter any positive integer and blank(""). I tried using the "try: , except: " commands,but then i leave out the possibility of blank input. By the way blank means that the recommendations are going to be 10.
I tried using the ascii module,but my program ends up being completely confusing. I would be glad if anyone could get me on the idea or give me an example of how to handle this matter.
My program for this input is :
while input_ok==False:
try:
print "Enter the number of the recommendations you want to be displayed.\
You can leave blank for the default number of recommendations(10)",
number_of_recs=input()
input_ok=True
except:
input_ok=False
P.S. Just to make sure thenumber_of_recs , can either be positive integer or blank. Letters and negative numbers should be ignored cause they create errors or infinite loops in the rest of the program.
while True:
print ("Enter the number of the recommendations you want to " +
"be displayed. You can leave blank for the " +
"default number of recommendations(10)"),
number_of_recs = 10 # we set the default value
user_input = raw_input()
if user_input.strip() == '':
break # we leave default value as it is
try:
# we try to convert string from user to int
# if it fails, ValueError occurs:
number_of_recs = int(user_input)
# *we* raise error 'manually' if we don't like value:
if number_of_recs < 0:
raise ValueError
else:
break # if value was OK, we break out of the loop
except ValueError:
print "You must enter a positive integer"
continue
print number_of_recs
So I have a finished program that accepts an input file with bank account information and parses it up and allows for a few different utilities.
One such utility is adding a transaction to the "database" (just a log file).
The program prompts the user to enter 'w' or 'd' and then an amount (float). This represents a deposit or withdrawal of X amount of money.
I was wondering how to go about making sure that the user entered either 'w' or 'd' AND a correct amount (number).
So, I decided that a while loop with the above condition would work, however I am having trouble getting it work 100%
I initially had:
while input1 is not ("w" or "d")
where input1 would be the first input (w or d) the user enters
However, I also want to check that a number exists.
I had the idea of casting the string input to a float, then checking that but I wouldn't know how to checking if that is right since casting and checking the type wouldn't tell me much.
How would I also check that the user entered in some sort of number.
So to reiterate, I would like the program to re-prompt for input if the user did not enter either:
A) A w or d
B) A number (int/float)
Thanks
the expression ("w" or "d") will always evaluate to "w". Generally, here you want an in:
while input1 not in ("w", "d"):
...
As far as handling the case where the input is a number, this is a job for a helper function:
def string_is_number(s):
try:
float(s)
return True
except ValueError:
return False
Now you can use that with the above to put the whole thing together:
while (not string_is_number(input1)) and (input1 not in ("w", "d")): ...
Which can actually be simplified a little more:
while not (string_is_number(input1) or (input1 in ("w", "d"))): ...
And now a completely different approach, You can actually use a recursive function for this sort of thing. Combine that with python's exception handling and we could probably put together a pretty elegant solution in just a few lines:
def prog_loop():
# prompt for user's input here:
input1 = raw_input("Enter a number, or 'w' or 'd':")
# See if we got a number
try:
number = float(input1)
except ValueError:
# Nope, wasn't a number. Check to see if it was in our
# whitelisted strings. If so, break early.
if input1 in ('w', 'd'):
return function_handle_w_d(input1)
else:
# Yes, we got a number. Use the number and exit early
return function_handle_number(number)
# haven't exited yet, so we didn't get a whitelisted string or a number
# I guess we need to try again...
return prog_loop()
This will work as long as your user doesn't enter bad input 1000 times.
Try this:
while True:
if input1 == 'w':
withdraw()
elif input1 == 'd':
deposite()
else:
continue()