I'm trying to use while loop in my functions but getting problems when I enter data input string. Below is my code.
search = input('Enter a string to continue or a negative number to exit:')
while True:
if int(search) < 0:
print('its a -ve number')
break
elif type(search) == str:
print('Its a string OK lets run the code and search')
else:
print('Please enter a valid input')
I'm getting a ValueError on entering string;
ValueError: invalid literal for int() with base 10: string value
CodePudding user response:
To transform a string into an integer, the common method is to wrap the logic in a try except block which will handle the value error. To improve readability I would suggest creating a method which handles the value error by returning None
if one occurs.
def parse_int(value):
try:
return int(value)
except ValueError:
return None
Now your loop can look like this:
while True:
int_search = parse_int(search)
if int_search is not None and int(search) < 0:
print('its a -ve number')
break
elif type(search) == str:
print('Its a string OK lets run the code and search')
else:
print('Please enter a valid input')
Also note, that the input
function always returns a string. So checking type(search) == str
will always returns true. Perhaps you meant to exclude positive numbers?
You also construct the input
outside the loop, meaning incorrect options will loop forever, telling you that you have entered incorrect data. Place that input request inside the loop.
while True:
search = input('Enter a string to continue or a negative number to exit:')
int_search = parse_int(search)
if int_search is not None and int(search) < 0:
print('its a -ve number')
break
elif int_search is not None:
print('Please enter a valid input')
else:
print('Its a string OK lets run the code and search')
Yet another option could be to modify the parse_int
method to return the original string value if you receive a value error. In that case the type would be search: Union[str, int]
. The logic could look like this (adding type annotations to show how they can be useful):
from typing import Union
# Type annotations help document code and can be
# used by static analysis tools like mypy to catch bugs!
def parse_int(value: str) -> Union[str, int]:
try:
return int(value)
except ValueError:
return value
prompt = 'Enter a string to continue or a negative number to exit:'
while True:
search = parse_int(input(prompt))
# isinstance is the preferred way to check types.
if isinstance(search, int) and search < 0:
print('its a -ve number')
break
elif isinstance(search, str):
print('Its a string OK lets run the code and search')
else:
print('Please enter a valid input')
# Will bring us back to the start of the loop
# Causing us to get a fresh input value
continue
CodePudding user response:
The first if condition of the while loop converts the input to int
. Meaning if the input wasn't an integer, it would return an error as it is not possible to convert a string to an int. So try this:
search = input('Enter a string to continue or a negative number to exit:')
while True:
if search[0] == "-":
if search[1].isdigit():
print('its a -ve number')
break
elif type(search) == str:
print('Its a string OK lets run the code and search')
break
else:
print('Please enter a valid input')
break
CodePudding user response:
There are many solutions, if you don't want to use try/except
block you can use regex
.
We can use regex to match a negative number re.match('^-\d $', search)
. isnumeric()
will returns False
if it finds string characters in the search
. Keep in mind the while loop is running continuously.
import re
search = input('Enter a string to continue or a negative number to exit: ')
while True:
if re.match('^-\d $', search):
print('its a -ve number')
break
elif search.isnumeric() is False:
print('Its a string OK lets run the code and search')
else:
print('Please enter a valid input')