isNumber? check
Peter Otten
__peter__ at web.de
Tue Sep 30 08:26:19 EDT 2003
Tony Meyer wrote:
> I would think that:
> """
> s = "123"
> value = isNumber(s)
> if value is None:
> # do something that shows it's not a number.
> # (obviously not raise a ValueError, because
> # then there's no point using the function at
> # all)
> # continue program, with value in value, if needed.
> """
> Would be a more logical way to do it.
I would still prefer
try:
value = toNumber(s)
except ValueError:
# handle error
> It's not. It was an example case showing that there isn't any need to
> bother with regexs and the like if you don't want to - Python will do the
> work for you. Assuming you trust the Python developers, you can trust
> that it will correctly check that the value is convertible into a number,
> and don't need to worry that you missed something in the regex (or
> whatever).
I wouldn't use regexes here, too.
> A real function would have a docstring...this is only c.l.p...
Everything that can be conveyed by the function name makes the code more
readable. Consider
def killTheBeast(beast):
""" Does not actually kill the beast, but shows a grim face
while hugging it
"""
(Sorry, couldn't resist)
> The OP asked for a function called isNumber. I posted an example of one.
If a suggested improvement changes the functionality, you could explain the
name change to the OP.
> The program snippet doesn't throw an exception at the end; your example
> usage did. If the code was going to raise a ValueError if it couldn't be
> converted, then it would be written differently; the OP didn't say that
> that
> was the case. The program flow is really:
> - convert to number and return
> - if an exception was raised then return None, signifying that no number
> can be created
>
> Lots of the stuff written about Python talks about using exceptions for
> code
> control, as this does. This isn't C++.
No, this isn't C, and one advantage, I think, is that you no longer need to
check for special error values. (OK, I'm simplifying...)
>> I can think of very few situations where None could actually
>> be *used* instead of a numerical value.
>
> Why would you want to *use* None? It's simply the function signifying
> that it couldn't convert the number.
>
>> > 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().
>
> Rubbish. This is me not taking care of every little detail in example
> code,
> for the sake of brevity, but warning that that is the case. In any case,
> it still correctly determines if the object can be converted to a number,
> and
> still correctly returns the number it is converted to. The only thing
> that
> is possibly incorrect is that it's a float instead of an int. As I said,
> easily fixed.
It is easily fixed in this trivial example. However, when you use a special
value to signal an error in a sufficiently complex calling hierarchy, you
end up testing for it too often for my taste.
> You seem to have missed the whole point of the code snippet. The idea is
> that you can use the conversion built into Python to check if a number can
> be converted, without having to write code that checks yourself. Perhaps
Maybe I stressed the points I did *not* like too much. Again, I agree with
your no regexes policy. (Localization is a different story)
> you would like this more?
>
> """
> def isNumber(s):
> for f in [int, float,]:
> try:
> return f(s)
> except ValueError:
> pass
> raise ValueError("Cannot convert to a number")
> """
You're right, I like that. Now give it a decent name (e.g. strToNumber())
and we have finally reached consensus :-)
> To me this doesn't seem as clear in explaining the concept, although it's
> more like code I would actually use. This does return "0" as 0, and
> raises
> a ValueError is no conversion is possible. The point is that the concept,
> which is what I was trying to convey, is the same. If you really don't
> want the value returned, then you could just use:
>
> """
> def isNumber(s):
> for f in [int, float,]:
> try:
> f(s)
> except ValueError:
> continue
> return True
> return False
> """
I think I would build on previous work here:
def isNumber(s):
try:
strToNumber(s)
except ValueError:
return False
return True
Peter
More information about the Python-list
mailing list