-2

In the following code, is_number is False for the value "foo", but this still prints is a number for that string. Why? And how do I fix it?

def string_is_number(a_string):
    pattern = re.compile(r'[0-9]+')
    if pattern.search(a_string):
        return("True")
    else:
        return("False")
 
for value in 42, 0.5, "foo":
    the_string = str(value)
    is_number = string_is_number(the_string)
    print(the_string, is_number)
    if is_number:
        print(the_string, "is a number")

Output:

42 True
42 is a number
0.5 True
0.5 is a number
foo False
foo is a number
oguz ismail
  • 1
  • 16
  • 47
  • 69
code_to_joy
  • 569
  • 1
  • 9
  • 27

3 Answers3

4

Return a bool, not a str:

if pattern.search(a_string):
    return True
else:
    return False 

Any non-empty string in Python is considered true (or "truthy"), including "False":

>>> bool("False")
True

Then of course, the regex for your number detection is a bit off:

re.match("^\d+([.,]\d+)?$", a_string)

would be a tighter test.

user2390182
  • 72,016
  • 6
  • 67
  • 89
  • I like your answer but part of the fix is to ditch the regex completely because it only tests if the string has a digit, not is a number. `str.isdigit()` is a good replacement. – tdelaney Dec 21 '20 at 16:32
  • It is not really part of the question though. "1,23" or "1.23" should be considered numbers as I take it, so `str.isdigit` won't be enough – user2390182 Dec 21 '20 at 16:34
  • ...except maybe not. Just realized there are commas in there. – tdelaney Dec 21 '20 at 16:34
0

You're trying to return "True" and "False" as string. You need to return them as boolean like this:

def string_is_number(a_string):
    
    pattern = re.compile(r'[0-9]+')
    
    return pattern.search(a_string) # Returns True or False
Gudarzi
  • 486
  • 3
  • 7
  • 22
0

Your function failed because you returned non-empty strings, which are alwaysTrue. A more subtle problem is that you call anything that has at least one digit a number. So "I am not the number 1" is a number. A nice way to check if something is a "number" is to try to convert it. In your case, it looks like you are dealing with integers and floats which both can be converted to float. Because commas are not allowed in string literals, they need to be factored out, but your function could be

def string_is_number(a_string):
    try:
        float(a_string.strip(','))
        return True
    except:
        return False
    
tdelaney
  • 73,364
  • 6
  • 83
  • 116