I have a function to validate some user input (val
) that begins as string input. I want the input to end up in integer format but I don't want to strip a number like 4.2 to make it 4. Instead, I want to throw an error and explain the problem to the user with a different message for each invalid type.
- The function should first check that the input is not an empty string.
- Then it looks for a minus sign or hypen and throws an error if any are found.
- Next, it should check whether the string is suitable to be cast as an integer (e.g. "42"). I've used
isdigit()
for this.- If suitable, it should skip straight to converting
val
to anint
withval = int(val)
.
- If suitable, it should skip straight to converting
However, if the value is not a whole number in string form, I really want to check whether it's:
- a decimal number that can be converted without causing confusion (4.0)
- a decimal number that should prompt an error message (4.2)
- or a non-numerical string that should prompt an error message ("I am a string").
You can see this attempt in the code:
try:
if val == "":
raise ValueError("customer error 1")
if "-" in val:
raise ValueError("custom error 2")
if not val.isdigit():
try:
val = float(val)
except Exception:
raise ValueError("custom error 3")
else:
if val % 1 != 0:
raise ValueError("custom error 4")
else:
val = int(val)
else:
val = int(val)
if val < 5:
raise ValueError("custom error 5")
except ValueError as e:
print(e)
return False
except TypeError as e:
print(e)
return False
return True
After the few string operations, I'm using a nested try/except to attempt converting val
to a float. If successful, the program should find out whether that float has a remainder when divided by 1. In other words, can it be made a whole number without changing its numerical value (4.0 -> 4). If yes, go ahead an make it an integer.
If the float has a remainder when divided by 1, it must be something like 4.2, rather than 4. In that case, I want to alert the user with a particular error message.
If it can't be made a float, it must be non-numerical string like "I am a string". In that case, I want to alert the user with a different message.
If it's successfully converted to an integer at any stage, I want to ensure it's not less than 5.
The code above conveys all the right error messages, until I enter a float like 7.0
. I thought I'd handled this and it would be converted, but I'm evidently going wrong somewhere. I've re-written it so many times at this stage, I have to concede defeat and hope someone can explain where I going wrong.
I should say, I'm new to Python and to error handling and try/except/else/finally in particular, so simplified responses would be helpful!