Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Python Basics All Together Now Handle Exceptions

Not very user friendly message for non-INT number Exception

Hi, I saw this question has been asked before, but I'm hoping for a more clear answer. The error message for a non-INT input is not very user friendly. Why not use two distinctive exception names (ValueError and Exception for example) for two scenarios ("non-INT number" and "num_tickets > tickets_remaining" and then show two separate error messages to the user? This is also how it was done in the video when Exceptions were taught in this course originally (two exceptions, two separate messages).

3 Answers

Hi Niusha!

This is probably overkill, but I hope it can answer your question.

First, go here (and look at point/example 3. "Handling multiple exceptions with one except block"):

https://www.techbeamers.com/use-try-except-python/

One thing about inputs is that they return string values only.

So if a user inputs 123, the value stored in the variable will actually be '123' (a number string) and not 123

So you can't test for (not being a number value) using something like this:

res = isinstance(test_string, str)

becaue ANY response from an input would evaluate to TRUE.

So notice my reverse-logic work-around to do a workable test for number-ness.

(And make sure your indents are precisely 4/8/12/16/20/etc... spaces only - don't use tabs.)

Here is a version of my solution (which goes beyond the challenge) with error handling:

TICKET_PRICE = 10

tickets_remaining = 100  

while tickets_remaining >= 1:
    if tickets_remaining > 1:
        verb = "are"
        remaining_s = "s"
    else:
        verb = "is"
        remaining_s = ""
    print("There {} {} ticket{} remaning (at $10.00 per ticket).".format(verb, tickets_remaining, remaining_s))
    valid = False
    while valid != True:
        client_name = input("What is your name? ")
        if (len(client_name) == 0):
            print("*** INVALID SELECTION ***")
        else:
            try:
                val = int(client_name) ###  IF THIS FAILS, client_name is a string - the desired value type  ###
            except ValueError: ###  BACKWORDS LOGIC HERE  ###
                valid = True ### Only valid on the exception!?! ###
            else:
                print("*** INVALID SELECTION ***")
    valid = False
    while valid != True:
        num_ticket = input("{}, how many tickets do you want to purchase? ".format(client_name))
        try:
            val = int(num_ticket)
        except ValueError:
            print("*** INVALID SELECTION ***")
            continue
        if val <= tickets_remaining:
            valid = True
        else:
            print("*** ERROR ***: There {} only {} ticket{} remaining. Try again.".format(verb, tickets_remaining, remaining_s))
    num_ticket = int(num_ticket)
    if num_ticket > 1:
        num_s = "s"
    else:
        num_s = ""
    amount_due = num_ticket * TICKET_PRICE
    print("The total amout due is ${}.00 for {} ticket{}.".format(amount_due, num_ticket, num_s))
    user_info = input("Do you want to procced Y/N? ").lower()
    if user_info == "y":
        print("SOLD!!!")
        tickets_remaining -= num_ticket
    else :
        print("Thanks anyways, {}".format(client_name))
print("Tickets soldout! :( ")

If you notice, in one section (the first try/except/else block) I sort of use ValueError backwards, but it makes it work. - I try to cast clientName to an int, and when it errors, I know it's a string (and therefore valid when it errors!?!) Again, kind of backwards logic, but sometimes you have to think outside-the-box!?! LOL

I had to do a lot of research and testing to figure that out.

Notice also that although I could have used raise ValueError in places, but opted not to and it still has workable/correct logic.

From this thread:

https://teamtreehouse.com/community/can-someone-help-me-with-this-python-script

You can test it here:

https://www.katacoda.com/courses/python/playground (run it with python3 app.py)

I hope this all helps.

Stay safe and happy coding!

Hi Peter,

Thanks for your answer, I really enjoyed your outside the box backward logic after I could figure it out (I'm a beginner in Python). Your reply answered a couple of other questions I had but since I deemed them to be minor I was delaying asking them for now(e.g. how to make sure the user input name is actually valid). But my question was simpler :) and I realize I may not have worded it accurately. I wanted to know why Craig in the video chose to handle both exceptions with one except block. Because he uses {} in his error message to the user, when the message is for a non-INT input, it is not very user friendly. He could've raised an "Exception" and then handle it in a separate block so he could have a more user friendly error message.