-3

Actual Question

Why something like:

#Converting float to integer
a = 1.0
int(a)  # a is now 1

# Converting String to float to integer
b = '1.0'
b = float(b)  # b is now 1.0
b = int(b)  # b is now 1

works but:

a = '1.0'
a = int(a)  # this throws a ValueError (invalid literal for int() with base 10: "1.0")

Context for question

The reason I ask is because I had a problem with getting two numbers, p and q, as input and depending on:

  1. if both are integers, return p//q
  2. if at least one is a float, return p/q
  3. print a warning if either is not a valid number.

The method I used was:

p, q = input("Enter two numbers: ").split()

try:
    p = int(p)
    q = int(q)
    print("P//Q = ", p//q)
except ValueError:
    try:
        p = float(p)
        q = float(q)
        print("P/Q = ", p/q)
    except ValueError:
        print("Invalid entries for p or q.")

This seems to work, but I was surprised when entering '1.0' for one of the values threw a value error when calling int('1.0').

I did try .isdigit() and .isdecimal() methods, however both fail on the string "0.5" etc.

Edited the question for clarity on what I was actually asking. I apologize for how the problem was posted

6
  • "0.5".isdigit() is False as this is not an int but "50".isdigit() is True or is the issue that you want "1.0" to be considered and int rather than a float? Commented Mar 9, 2023 at 15:20
  • @JonSG part of my question was why int(1.0) is valid but int("1.0") isnt. "1.0" seems like it should be able to easily be represented as an integer, but converting doesnt work Commented Mar 9, 2023 at 15:34
  • 2
    So is the question "Technically, why does int() not like strings with decimal places?" or is your question "How do I alter my code to account for that fact?" Commented Mar 9, 2023 at 15:41
  • 1
    Suppose there are two types, f and g, that can both parse a string x into different values. What, then, should int(x) produce, int(f(x)) or int(g(x))? int should not have to worry about deciding which type is better by looking at x; it should simply assume that either x is either an integer literal, or raise an error and let the caller parse x first. Commented Mar 9, 2023 at 15:49
  • 1
    @JonSG yeah I mainly wanted to know why int("1.0") can't convert to an integer Commented Mar 9, 2023 at 16:00

2 Answers 2

0
def get_number(input_string):
    try:
        num = int(input_string)
    except ValueError:
        try:
            num = float(input_string)
        except ValueError:
            print("Invalid input: {}".format(input_string))
            return None

        if num.is_integer():
            num = int(num)

    return num


p, q = input("Enter two numbers: ").split()

p = get_number(p)
q = get_number(q)

if p is not None and q is not None:
    if isinstance(p, int) and isinstance(q, int):
        print("P//Q = ", p // q)
    else:
        print("P/Q = ", p / q)
Sign up to request clarification or add additional context in comments.

4 Comments

That's an interesting way to check. I wanted to avoid string parsing as it seemed like it would be a pain, but checking before and after the decimal to see if both are digits is clever. I guess you could also check to see if int(parts[1])==0 to determine if the number is a float version of an integer
@SeaBacon That's already a built-in feature..... float.is_integer()
@Tomerikoo oh you're right, it's so much better
Wouldn't it be simpler to check for float first? i.e. try to convert to float. If it errored, the input is surely bad. If not, check if it is_integer and convert to int if possible
-2
p, q = "0.5", "0.5"
def parse_to_number(n):
    try:
        return int(n)
    except:
        return float(n)
try:
    p = parse_to_number(p)
    q = parse_to_number(q)

    if isinstance(p, int) and isinstance(q, int):
        print("P//Q = ", p//q)
    else:
        print("P/Q = ", p/q)
except ValueError:
    print("Invalid entries for p or q.")

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.