Try/Except handling

Question:

Today i made this function to try and understand the try/except.
If i run this code it should ask for a positive integer x, to roll a dice function x times.
I made the code below but it seems to never get in the "ValueError". I’d like to check if the input (n) is first an integer (digit in the string) and secondly if the integer is positive. if one of these occur, raise the exception.

How can i fix it that it works correctly?

def userInput():
    while True:
        try:
            n=input("How many times do you want to roll the dice? ")
            if not n.isdigit():
                raise TypeError
            
            n = int(n)
            if n < 0:
                raise ValueError
            else:
                break

        except ValueError:
            #if type is integer but not a positive integer
            print("Please enter a positive integer")
    
        except TypeError:
            #if type is not an integer
            print("Only positive integers allowed")
    
return n
Asked By: itzMeep

||

Answers:

Your code works perfectly for positive numbers, to handle negative numbers, you need to modify at one place

if not n.lstrip('-').isdigit():

I hope this solves your problem

Answered By: Ajay A

Stripping out the - doesn’t address the issue of some digits not actually being integers, as Matthias’s link describes. You would be much better off trying to convert to int without checking isdigit(). If the input can’t be converted to an integer, this raises a ValueError with the message "invalid literal for int() with base 10: '...'".

If you want to raise a ValueError with a custom message for your positive number check, you can do raise ValueError("Please enter a positive integer")

Then, in the except block, you can access this message through the .args attribute of the exception:

def userInput():
    while True:
        try:
            n = int(input("How many times do you want to roll the dice? "))
            if n < 0:
                raise ValueError("Please enter a positive integer")
            else:
                return n # You probably want to do this instead of just break out of the loop

        except ValueError as ex:
            print(ex.args[0])

Calling the function gives:

How many times do you want to roll the dice? -5
Please enter a positive integer

How many times do you want to roll the dice? abc
invalid literal for int() with base 10: 'abc'

How many times do you want to roll the dice? 1

To be clear, it would be cheaper to simply print the error message for non-positive integers instead of raising an error only to catch it immediately. That way, you can modify the message that is printed when the int() conversion fails. Consider:

def userInput():
    while True:
        try:
            n = input("How many times do you want to roll the dice? ")
            n = int(n)
            if n < 0:
                print("Please enter a positive integer")
            else:
                return n # You probably want to do this instead of just break out of the loop

        except ValueError as ex:
            print(f"Hey, {n} is not a valid integer!")

which would print:

How many times do you want to roll the dice? abc
Hey, abc is not a valid integer!

How many times do you want to roll the dice? 10.5
Hey, 10.5 is not a valid integer!

How many times do you want to roll the dice? -100
Please enter a positive integer

How many times do you want to roll the dice? 100
Answered By: Pranav Hosangadi
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.