19

So I'm creating a program to show number systems, however I've run into issues at the first hurdle. The program will take a number from the user and then use that number throughout the program in order to explain several computer science concepts.

When explaining my first section, number systems, the program will say what type of number it is. I'm doing this by converting the string into a float number. If the float number only has '.0' after it then it converts it into a integer.

Currently I'm using this code

while CorrectNumber == False:
try:
    Number = float(NumberString) - 0
    print (Number)
except:
    print ("Error! Not a number!")

This is useful as it shows if the user has entered a number or not. However I am unsure how to now check the value after the decimal place to check if I should convert it into a integer or not. Any tips?

Brad Solomon
  • 34,372
  • 28
  • 129
  • 206

8 Answers8

14

If the string is convertable to integer, it should be digits only. It should be noted that this approach, as @cwallenpoole said, does NOT work with negative inputs beacuse of the '-' character. You could do:

if NumberString.isdigit():
    Number = int(NumberString)
else:
    Number = float(NumberString)

If you already have Number confirmed as a float, you can always use is_integer (works with negatives):

if Number.is_integer():
    Number = int(Number)
francisco sollima
  • 7,352
  • 3
  • 21
  • 37
7

Here is the method to check,

a = '10'
if a.isdigit():
   print "Yes it is Integer"
elif a.replace('.','',1).isdigit() and a.count('.') < 2:
   print "Its Float"
else:
   print "Its is Neither Integer Nor Float! Something else"
Mohideen bin Mohammed
  • 16,635
  • 8
  • 97
  • 110
6

Not sure I follow the question but here is an idea:

test = ['1.1', '2.1', '3.0', '4', '5', '6.12']

for number in test:
    try:
        print(int(number))
    except ValueError:
        print(float(number))

Returns:

1.1
2.1
3.0
4
5
6.12
kjmerf
  • 4,125
  • 2
  • 18
  • 28
3

This checks if the fractional-part has any non-zero digits.

def is_int(n):
    try:
        float_n = float(n)
        int_n = int(float_n)
    except ValueError:
        return False
    else:
        return float_n == int_n

def is_float(n):
    try:
        float_n = float(n)
    except ValueError:
        return False
    else:
        return True

Testing the functions:

nums = ['12', '12.3', '12.0', '123.002']

for num in nums:
    if is_int(num):
        print(num, 'can be safely converted to an integer.')
    elif is_float(num):
        print(num, 'is a float with non-zero digit(s) in the fractional-part.')

It prints:

12 can be safely converted to an integer.
12.3 is a float with non-zero digit(s) in the fractional-part.
12.0 can be safely converted to an integer.
123.002 is a float with non-zero digit(s) in the fractional-part.
srikavineehari
  • 2,344
  • 1
  • 10
  • 21
0
x=input("Enter a value to check it's  type: ")
def checknumber(a):
    try:
        a=float(a)
        if int(a)/a==1:
            print("This is Integer")
            return a
        elif a/int(a)>1:
            print("This is Float")
            return a
    except ValueError:
        print("This value is String")
        return str(a)
x=checknumber(x)```
AHMAD ZIA
  • 1
  • 1
  • Code-only answers like this are often down-voted here. Please [edit](https://stackoverflow.com/posts/65099721/edit) your answer and explain what you changed or how it works or something. – Arthur Pereira Dec 02 '20 at 23:30
0

Regular expressions are nice for this as they can be custom tailored in case you have some edge-cases. For example:

  • How do you want to handle padded numbers (numbers with leading zeros). My example here includes this consideration.
  • Do you need to handle exponents, e.g. 2.3E12 or 2.3e12. This is not handled here.

...in other words, if your implementation doesn't agree with an assumption mine makes, you can change it.

Regular expressions work in all versions of Python (and other languages). They can be compiled for reuse, so should be pretty quick.

# Int is:
#  - Only numbers that do NOT start with 0 (protect padded number strings)
#  - Exactly 0
re_int = re.compile(r"(^[1-9]+\d*$|^0$)")

# Float is:
#  - Only numbers but with exactly 1 dot.
#  - The dot must always be followed number numbers
re_float = re.compile(r"(^\d+\.\d+$|^\.\d+$)")

These tests all pass:

def test_re_int(self):
    self.assertTrue(re_int.match("1"))
    self.assertTrue(re_int.match("1543"))
    self.assertTrue(re_int.match("0"))  # Exactly 0 is good

    self.assertFalse(re_int.match("1.54"))
    self.assertFalse(re_int.match("1a4"))
    self.assertFalse(re_int.match("14a"))
    self.assertFalse(re_int.match("a14"))
    self.assertFalse(re_int.match("00"))  # Ambiguous
    self.assertFalse(re_int.match("0012"))  # Protect padding

def test_re_float(self):

    self.assertTrue(re_float.match("1.0"))
    self.assertTrue(re_float.match("1.456"))
    self.assertTrue(re_float.match("567.456"))
    self.assertTrue(re_float.match("0.10"))
    self.assertTrue(re_float.match(".10"))

    self.assertFalse(re_float.match("1.0.0"))  # Too many dots
    self.assertFalse(re_float.match(".10.0"))
    self.assertFalse(re_float.match("..034"))

    self.assertFalse(re_float.match("1"))
    self.assertFalse(re_float.match("0"))
    self.assertFalse(re_float.match("1a4"))
    self.assertFalse(re_float.match("14a"))
    self.assertFalse(re_float.match("a14"))

    self.assertFalse(re_float.match("1.a4"))
    self.assertFalse(re_float.match("1.4a"))
    self.assertFalse(re_float.match(".a14"))

Please comment if there are any caveats, missing details or regular expression improvements I can make.

Rafe
  • 1,679
  • 19
  • 31
-1

Here's my gist that not only checks for positive & negative ints, but also checks for positive & negative floats. It also checks if the string is just a normal non-number.

def int_float_or_string(string):
    try:
        int(string)  # strict and nice
    except ValueError:
        if is_strictly_float(string): # float() is too permissive, this is better
            return "float"
        else:
            return "string"
    else:
        return "int"

def is_strictly_float(string):
    if string.startswith("-"):
        string = string[1:]
    return "." in string and string.replace(".", "", 1).isdecimal()

int() is great for checking an integer, but float() has a problem of being too laid back in what it calls a float.

jaquinocode
  • 174
  • 3
  • 8
-1

I rewrite bin Mohammed's answer as follows (number also may be negative):

from numpy import nan, isnan

def is_valid_number(s):
    if (s.find('-') <= 0) and s.replace('-', '', 1).isdigit():
        if (s.count('-') == 0):
            s_type = 'Positive Integer'
        else:
            s_type = 'Negative Integer'
    elif (s.find('-') <= 0) and (s.count('.') < 2) and \
         (s.replace('-', '', 1).replace('.', '', 1).isdigit()):
        if (s.count('-') == 0):
            s_type = 'Positive Float'
        else:
            s_type = 'Negative Float'
    else:
        s_type = "Not alphanumeric!"
    return('{}\t is {}'.format(s, s_type))

example:

nums = ['12', '-34', '12.3', '-12.0', '123.0-02', '12!','5-6', '3.45.67']
for num in nums:
    print(is_valid_number(num))

result:

12   is Positive Integer
-34  is Negative Integer
12.3     is Positive Float
-12.0    is Negative Float
123.0-02     is Not alphanumeric!
12!  is Not alphanumeric!
5-6  is Not alphanumeric!
3.45.67  is Not alphanumeric!

minimal code:

from numpy import nan, isnan

def str2num(s):
    if (s.find('-') <= 0) and s.replace('-', '', 1).isdigit():
        return(int(s))
    elif (s.find('-') <= 0) and (s.count('.') < 2) and \
         (s.replace('-', '', 1).replace('.', '', 1).isdigit()):
        return(float(s))
    else:
        return(nan)

example:

nums = ['12', '-34', '12.3', '-12.0', '123.0-02', '12!','5-6', '3.45.67']
for num in nums:
    x = str2num(num)
    if not isnan(x):
        print('x =', x) # .... or do something else

result:

x = 12
x = -34
x = 12.3
x = -12.0
Morteza
  • 1
  • 2
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/31171035) – aaossa Mar 03 '22 at 15:36