Python Forum
Detecting float or int in a string
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Detecting float or int in a string
#1
The str.isnumeric() function is lacking when it comes to detecting floats.
Several sites say to use a try/except to attempt the conversion. I was taught not to depend on try except in the regular program flow, and that it should only be used in the case of real exceptions, like catching runtime errors.
To that end, I made the function below.
Is there a better way?
Would you change anything about this?
def is_number(string):
    if string.isnumeric():
        return True
    if string.count('.') == 1:
        if string.replace('.', '').isnumeric():
            return True
    return False
Thanks for looking.
Reply
#2
(May-23-2022, 08:39 PM)Clunk_Head Wrote: I was taught not to depend on try except in the regular program flow, and that it should only be used in the case of real exceptions, like catching runtime errors.
I disagree completely with this philosophy. Exceptions must be raised and sometimes (often) caught in regular Python program flow. Their role goes far beyond signaling errors.
Reply
#3
(May-23-2022, 08:44 PM)Gribouillis Wrote: I disagree completely with this philosophy

Can you please provide an example where an exception must be used in place of anything else? I'd like to expand my understanding of it. A link to reading is fine.
Reply
#4
I don't see anything wrong with using a try/except for handling an attempt to see if something is or is not compatible with float().

Float will handle exponential notation while yours will not. Up to you if that's a problem. Yours will not handle negative numbers or numbers with an explicit plus sign.

>>> [float(x) for x in ("1e3", "-12", "+3.5")]
[1000.0, -12.0, 3.5]
Reply
#5
(May-23-2022, 09:01 PM)bowlofred Wrote: I don't see anything wrong with using a try/except for handling an attempt to see if something is or is not compatible with float().

How much memory does it use? That's part of the reasoning behind not relying on it.
While the topic of this thread is for general use, I've found that try blocks in circuitpython are memory hogs.

(May-23-2022, 09:01 PM)bowlofred Wrote: exponential notation while yours will not. Up to you if that's a problem. Yours will not handle negative numbers or numbers with an explicit plus sign.

That's what I was looking for. Thanks a bunch.
Still have a bit of work to do.
Reply
#6
Clunk_Head Wrote:Can you please provide an example where an exception must be used in place of anything else?
Exceptions free intermediary code from checking all the obstacles that can occur for completing a task. For example
def get_cup_of_coffee():
    go_to_recreation_room()
    open_the_door()
    go_to_coffee_machine()
    insert_coin()
    push_button()
    cup = take_coffee()
    return cup
Many things can go wrong. The door could be locked, the machine could be in maintenance, the coin could be rejected, etc. All these events, which are not errors should raise an exception when the corresponding function is called. But the logic of get_cup_of_coffee() does not need to handle these exceptions. It lets them propagate and they all result in get_cup_of_coffee() sending an exception.

Now the code that uses this function can freely decide to catch the exceptions or not, for example
def ten_o_clock_routine():
    try:
        coffee = get_cup_of_coffee()
    except RecreationRoomLocked:
        # take appropriate action
    except Exception:
        # other errors
    else:
        coffee.drink()
The main gain is to choose at which level we catch the exceptions in the code (if they are caught).

In a language without exceptions, such as C, get_cup_of_coffee() would have the responsibility to handle all the exceptional cases that can happen in the functions that it calls. In some other languages, we would need to declare all the exception types that are thrown by the function, which is tedious. But not in Python.
Reply
#7
(May-23-2022, 09:01 PM)bowlofred Wrote: Float will handle exponential notation while yours will not. Up to you if that's a problem. Yours will not handle negative numbers or numbers with an explicit plus sign.

Think I've got it fixed:
def is_number(string):
    if string.isnumeric():
        return True
    if string[0] == '-' or string[0] == '+':
        return is_number(string[1: ])
    if string.count('.') == 1:
        return is_number(string.replace('.', '')
    elif string.count('e') == 1:
        index = string.find('e')
        return is_number(string[ :index]) and is_number(string[index+1: ])
    return False
There's probably another case that I've missed. Please let me know if you see one.
Reply
#8
A more classical way to implement your parsing strategy would be to use regular expressions.
Reply
#9
All depends on how much you care to make it identical. You're doing recursive function calls. Would need to test, but I'd worry that would have a bigger impact on memory than a try block.

I believe your function will pass the strings ++-+3 and 3e, while float() will not.
Reply
#10
(May-23-2022, 09:45 PM)Gribouillis Wrote: regular expressions

I understand that python has a fast regex engine. I haven't timed it since python 2 though, but then I found regex to be slower than replace() by at least a factor of 10. I never timed it against count or find.

Sounds like it's worth investigating it again, as I could probably consolidate it using regex.
I will also look into using translate.

Good advice, thank you.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  python calculate float plus float is incorrect? sirocawa 6 309 Apr-16-2024, 01:45 PM
Last Post: DeaD_EyE
  convert string to float in list jacklee26 6 1,929 Feb-13-2023, 01:14 AM
Last Post: jacklee26
  iterating and detecting the last Skaperen 3 1,089 Oct-01-2022, 05:23 AM
Last Post: Gribouillis
  TypeError: float() argument must be a string or a number, not 'list' Anldra12 2 4,888 Jul-01-2022, 01:23 PM
Last Post: deanhystad
  Convert string to float problem vasik006 8 3,425 Jun-03-2022, 06:41 PM
Last Post: deanhystad
  module detecting if imported vs not Skaperen 1 1,683 Nov-19-2021, 07:43 AM
Last Post: Yoriz
  detecting a generstor passed to a funtion Skaperen 9 3,634 Sep-23-2021, 01:29 AM
Last Post: Skaperen
  Python BLE Scanner not detecting device alexanderDennisEnviro500 0 2,015 Aug-01-2021, 02:29 AM
Last Post: alexanderDennisEnviro500
  Detecting power plug Narayan 2 2,727 Aug-01-2020, 04:29 AM
Last Post: bowlofred
  ValueError: could not convert string to float: RandomCoder 3 5,776 Jul-27-2020, 07:38 AM
Last Post: ndc85430

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020