itzMeep
itzMeep

Reputation: 13

Try/Except handling

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

Upvotes: 1

Views: 408

Answers (2)

pho
pho

Reputation: 25489

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

Upvotes: 1

Ajay A
Ajay A

Reputation: 1068

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

Upvotes: 0

Related Questions