How to convert a float string to an integer in python 3 [duplicate]
Asked Answered
H

4

28

I'm new to the whole coding thing...so here goes. Just trying to write a simple number guess game, but also do input validation. So that only integers are accepted as input. I've figured out how to weed out alphabetic characters, so I can convert the numbers into an integer. I'm having trouble when I put in a float number. I can't get it to convert the float number over to an integer. Any help is appreciated. As I said I'm on about day 3 of this coding thing so try to be understanding of my little knowledge. Thanks in advance.

Here's the function from my main program.

def validateInput():
    while True:
        global userGuess
        userGuess = input("Please enter a number from 1 to 100. ")
        if userGuess.isalpha() == False:
            userGuess = int(userGuess)
            print(type(userGuess), "at 'isalpha() == False'")
            break
        elif userGuess.isalpha() == True:
            print("Please enter whole numbers only, no words.")
            print(type(userGuess), "at 'isalpha() == True'")
    return userGuess

Here's the error I'm getting if I use 4.3 (or any float) as input.

Traceback (most recent call last):
File "C:\\*******.py\line 58, in <module>
validateInput()
File "C:\\*******.py\line 28, in validateInput
userGuess = int(userGuess)
ValueError: invalid literal for int() with base 10: '4.3'
Halfassed answered 20/11, 2014 at 20:11 Comment(2)
You could try to chain your conversions using try-except. If your int() conversion generates a ValueError exception, you could try to convert input using float() and then round or truncate your float value to integer.Yarmouth
A few side notes: You almost never want to check if spam == False:, just if not spam:. In an elif, you don't need to recheck the opposite of the if test—you already know isalpha is true, because you know it isn't false. So, just use else:. If you're returning userGuess from this function, you almost certainly don't need it to be global. And finally, you don't need to break just to hit the return; you can just return userGuess right there in the if block.Faiyum
A
50

Actually int() function expects an integer string or a float, but not a float string. If a float string is given you need to convert it to float first then to int as:

int(float(userGuess))
Addington answered 20/11, 2014 at 20:17 Comment(2)
This does not work for large numbers; for example int(float('8304305552891322054.0')) returns wrong 8304305552891322368 value while int('8304305552891322054') returns 8304305552891322054Collywobbles
@JalilHamdollahiOskouei This is not a float() issue at all but a fundamental limitation of floats with limited precision for large numbers, a core concept of Computer Science. See docs.python.org/3/tutorial/floatingpoint.html. If you need precision of such levels, go with something like decimal.DecimalPentad
M
1

Don't use isalpha to screen the output. EAFP -- convert it and handle that exception. Either the ValueError is exactly what you want, in that you can handle it and tell the user to correct their input. Or for some odd reason you want to silently correct their input from "4.3" to "4".

def validateInput():
    while True:
        global userGuess
        userGuess = input("Please enter a number from 1 to 100. ")
        try:
            int(userGuess)
            return userGuess # you shouldn't really keep this string...
        except ValueError as e:
            print("Please enter whole numbers only, no words.")
Misfile answered 20/11, 2014 at 20:28 Comment(0)
F
0

First, why do you want to convert the float string to an integer? Do you want to treat 4.7 as meaning the user has guessed 4? Or 5? Or a legal but automatically-invalid guess? Or as actually the value 4.7 (in which case you don't want integers at all)? Or…?


Second, the way you're approaching this is wrong. userGuess.isalpha() only tells you that the guess is made entirely of letters. That means you're still going to treat, say, "Hello!" as a number, because it has at least one non-letter.

If you want to know if a string is a valid integer, just call int on it, and use a try/except to handle the case where it isn't:

def validateInput():
    while True:
        global userGuess
        userGuess = input("Please enter a number from 1 to 100. ")
        try:
            userGuess = int(userGuess)
            print(type(userGuess), "after int succeeeded")
            break
        except ValueError:
            print("Please enter whole numbers only, no words.")
            print(type(userGuess), "after int failed")
    return userGuess

If you want to handle actual words differently from other kinds of failure, e.g., so you can print a more specific error message, then you can check isalpha inside the except clause.

If you want to handle check whether it's a float so you can give a different error, do the same thing—try to call float(userGuess)—inside the except clause. Or, if you want to truncate floats, change that int(userGuess) to int(float(userGuess)).

You may also want some other checks even inside the try part. For example, what if they type -23 or 178? Those are integers, but they're not numbers between 1 and 100.

Obviously, the more validation you want, the more code it takes, because each test is another line of code. So, you may want to consider moving the validation out to a separate function from the looping over input, to make it more readable.

Faiyum answered 20/11, 2014 at 20:25 Comment(0)
C
-1

You could use string manipulation and typecasting.

int(userGuess.split('.')[0])
Comeuppance answered 20/4, 2018 at 8:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.