On Sat, Apr 25, 2015 at 09:18:53PM -0700, Jim Mooney Py3winXP wrote: > It seems odd to me that there are three tests to see if user input is > digits - isdecimal, isdigit, isnumeric, but nothing to test for a float > unless you use a try - except. Or did I miss something?
Yes -- the string tests don't specifically test for valid numbers, only digit characters. If we go back deep into the mists of time, when dinosaurs ruled the earth, Python ints were not unlimited in size. If you tried to create an integer that was too big, you would get an exception, either an OverflowError or a ValueError depending on what you tried to do. Even today, just because a string is all digits doesn't mean that you can successfully turn it into an int. You may run out of memory, if you have millions of digits. The right way to check is a string is numeric is to try to convert it into a number and see what happens. The string methods are too strict, and will prohibit perfectly good numeric strings: py> s = ' -123 ' py> s.isdigit() False py> int(s) -123 (In my experience, the isdigit etc. methods are really only useful for testing individual characters.) Instead: try: n = int(s) except ValueError: print("failed") or similar. Do you know the difference in meaning between isdigit, isnumeric, and isdecimal? > Anyway, I tried a > try - except, but I don't see why my output is all integer when I only > convert to integer if it passes the is_integer test: That's what you *intended* to do, but it isn't what you did :-) > user_values = [] > while True: > user_input = input("Give me a number: ") > if user_input.lower() == 'done': break > try: > user_input = float(user_input) > if user_input.is_integer: user_input = int(user_input) At the interactive interpreter: py> x = 23.1 py> x.is_integer # no brackets <built-in method is_integer of float object at 0xb7aef950> py> x.is_integer() # with brackets False Built-in methods and functions are consider "truthy" values, so your test user_input.is_integer (without the brackets) is always true and the number will always be converted to an int. Personally, I would not do the conversion like that. The big problem is that for sufficiently large integers, floats lose precision: py> s = '123456789012345678901' py> int(s) 123456789012345678901 py> int(float(s)) 123456789012345683968 Instead, I'd create a helper function that first tries to convert to an int, and only if that fails, converts to a float: def make_number(astring): if not isinstance(astring, str): raise TypeError('not a string') for kind in (int, float): try: return kind(astring) except ValueError: pass raise ValueError( 'String {0} is not a supported number.'.format(astring) ) You could support more formats if you like, e.g. 0x123 for hex ints, complex, fractions, percentages, whatever you wanted. But as a simpler string-to-int-or-float function, this works well. -- Steve _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor