isNumber? check

Peter Otten __peter__ at web.de
Tue Sep 30 03:44:48 EDT 2003


Tony Meyer wrote:

> Rob> I don't like that solution for this particular project because, as
> Rob> you say yourself, if it says yes to the second question, it only
> Rob> *may* be a number.  I want to know for sure.
> 
> This also works, although it may not be best for your situation (only does
> int and float for brevity):
> 
> """
> def isInt(s):
>     try:
>         i = int(s)
>     except ValueError:
>         i = None
>     return i
> def isFloat(s):
>     try:
>         i = float(s)
>     except ValueError:
>         i = None
>     return i
> def isNumber(s):
>     return isInt(s) or isFloat(s)
> """
> 
> One advantage is that it returns the number (as an int (preferable) or
> float) rather than just True/False (None is returned if it is not able to
> be
> turned into a number).  You're probably going to want to turn it into a
> number at some point anyway, right?, so why not do it in one step.

Made-up use-case:

s = "123"
value = isNumber(s)
if value is not None:
    value *= 2
else:
    raise ValueError, "%s is not a number" % s

To me this looks like a deliberate attempt to obfuscate. Nobody would guess
that you have to test the result of isNumber() against None and cannot
reliably treat it as a boolean value. You should at least change the
function name to something like stringToNumber().

The program flow is redundant: 
- convert to number 
- "convert" exception into special return value
- check for special return value
- throw exception

I can think of very few situations where None could actually be *used*
instead of a numerical value.

> Note that "0" will come back as 0.0, though, because it evaluates as
> False. It would be easy enough to special case that, if necessary.

This is a bug that demonstrates that your isInt()/isFloat() implementation
is not even well suited to implement isNumber().

Peter




More information about the Python-list mailing list