Python Python Basics All Together Now Handle Exceptions

Except, task isn't done yet. One of the errors isn't user friendly at all.

So here we have my version of Craig's code, minor changes to naming only, objects are all the same.

TICKET_PRICE = 10
tickets_remaining = 100

while tickets_remaining >= 1:
    print("There are {} tickets left for sale.\n".format(tickets_remaining))
    name = input("What is your name?  ")
    num_tickets = input("Hello {}, how many tickets would you like to buy?  ".format(name))
    # Expect a ValueError to happen and handle it appropriately... remember to test it out!
    try:
        num_tickets = int(num_tickets)
        if num_tickets > tickets_remaining:
            raise ValueError("There are only {} tickets remaining".format(tickets_remaining))
        # Raise a ValueError if the request is for more tickets than are available
    except ValueError as err:
        # Include the error text in the output
        print("Oh no, we ran into an issue. {}. Please try again".format(err))
    else:
        amount_due = num_tickets * TICKET_PRICE                         
        print("Total due is ${}".format(amount_due))
        should_proceed = input("Do you want to proceed? Y/N  ")
        if should_proceed.lower() == "y":
            # TODO: Gather credit card information and process it.
            print("SOLD!")
            tickets_remaining -= num_tickets
        else:
            print("Thank you for your time, {}".format(name))
print("Tickets are sold out, sorry!")

And after I run it I get the following on console:

There are 100 tickets left for sale.                                                                                                                                                                             

What is your name?  Nuno Martins                                                                                                                                                                                 
Hello Nuno Martins, how many tickets would you like to buy?  oranges                                                                                                                                             
Oh no, we ran into an issue. invalid literal for int() with base 10: 'oranges'. Please try again                                                                                                                 
There are 100 tickets left for sale.

How to solve this one? I'm a newbie still :S

3 Answers

Hi..

to fix this I just added this "if" statement after "try" block.

try:
    if not num_tickets.isdigit():
        raise ValueError("Please enter a valid whole number between 1 and {}".format(tickets_remaining))

    num_tickets = int(num_tickets)

    if num_tickets > tickets_remaining:
        raise ValueError("There are only {} tickets remaining".format(tickets_remaining))

str.isdigit(): This is a string method. Return true if all characters in the string are digits and there is at least one character, false otherwise. in other words, A string is considered a digit string if all characters in the string are digits and there is at least one character in the string.

Here, we want to check for error: if the user input is a normal string like "blue" which is not a digit string, so we can output error message telling him that his input is invalid and he must enter a valid number

So, I used not keyword here after if to get the opposite value from the check ... which is False .. you could write it like this and it still work:

if num_tickets.isdigit() == False:
        raise ValueError("Please enter a valid whole number between 1 and {}".format(tickets_remaining))

Hope that helps... and sorry if my English isn't that clear :)

Jennifer Nordell
MOD
Jennifer Nordell
Treehouse Moderator

Hi there, Nuno Martins! You are entirely correct. That error isn't user-friendly at all, but it's not really meant to be, I don't think. Part of that error is generated by the Python interpreter. What it's saying is that you entered a string that cannot be converted to a number. For instance, Python can convert the string "42" to an integer, but it cannot convert "Treehouse" to an integer. This is when we get a ValueError. A string is a valid data type for the int() function, but not all strings can successfully be converted to an integer. The word "oranges" is one of them. When we pass in a value that is of the correct data type, but it still cannot be done, we encounter a ValueError.

In this line here, we're taking care of that ValueError and printing something to the user:

print("Oh no, we ran into an issue. {}. Please try again".format(err))

See that err there? It contains this string invalid literal for int() with base 10: 'oranges' which simply means that something was put in that it cannot convert to an integer. But it's this part that's not entirely user-friendly. You could decide to not print Python's error message at all and do a more generic error message like this:

print("Oh no, we ran into an issue. Could not convert your input into a number. Please try again")

Hope this helps and you're doing great! :sparkles:

Hi Jen~

I was stuck with the .format(err) as well and I happened to came across your explanation. Thanks for your explanation, its simple and succinct! Problem resolved!!

Thank you!!

Thanks for the fast reply, you really did help me!

Cheers.

You are welcome :)