Python Python Basics All Together Now Handle Exceptions

"Was never assigned" after try block was inserted??

I understand after the try block was inserted that num_tickets was assigned "blue"

I don't understand why the code within the try block was simply skipped.

It should have TRIED to coerce num_tickets into an integer thus creating the ValueError

Instead, it was just skipped altogether and continued to multiply the string instead, I know that. But why.

Edit: I went back to the video and found I can simplify my question a little more He says "This is where the error happened and the assignment never happened" after adding the try block

My question is why did the assignment not happen and instead got skipped while within the try block?

1 Answer

Jeff Muday
MOD
Jeff Muday
Treehouse Moderator 21,715 Points

Rudy,

@craigdennis is teaching a common design pattern of error catching. It is important to understand this to isolate specific points where we can encounter errors.

Here's my best explanation of what is going on.

The nature of how the error was raised is this.

# suppose
num_tickets = "blue" # num_tickets is assigned a string here
# On the next line, the type "coersion" to int() causes an error
# and DOES NOT assign a value into num_tickets, it stays "blue"
num_tickets = int(num_tickets)  

An example below:

The conversion of a string to an int can only succeed if the string follows numeric pattern otherwise throws a ValueError.

PS C:\Users\jeff> C:\Python36\python
Python 3.6.2 (v3.6.2:5fd33b5, Jul  8 2017, 04:14:34) [MSC v.1900 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> num_tickets = input("How many tickets would you like? ")
How many tickets would you like? 5
>>> type(num_tickets)
<class 'str'>
>>> int(num_tickets)
5
>>> num_tickets = input("How many tickets would you like? ")
How many tickets would you like? Hey dude, gimme 2 tickets in the front.
>>> num_tickets
'Hey dude, gimme 2 tickets in the front.'
>>> type(num_tickets)
<class 'str'>
>>> int(num_tickets)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'Hey dude, gimme 2 tickets in the front.'

So... you can see Python is NOT smart enough in the INPUT statement to parse out the 2, but will throw a nice ValueError with the message "invalid literal for int() with base 10:..."

We can fix this with the try/except/else block

# suppose
num_tickets = "blue" # num_tickets is assigned a string here
try: # our saftey error catcher begins here...
    num_tickets = int(num_tickets) # an error could occur here, but we will catch it.
except ValueError: # here is where we process the error
    print("Oh no, something bad happened")
else:
    # the coersion to int succeeded, so process the ticket sale

BUT!!!! we also needed to check the logical error of OVERSELLING tickets. This is where the "custom ValueError" is raised.

# suppose
num_tickets = "blue" # num_tickets is assigned a string here
try:
    num_tickets = int(num_tickets)
    if num_tickets > num_tickets_available:
        # when we raise an error, we jump out of the block to the ValueError part of the block.
        raise ValueError("Not enough tickets available")
except ValueError as custom_error:  # here we "capture the error object as "custom_error"
    print( "Oh no, something bad happened.  Error message: " + str(custom_error) )  # print out error message caused.
    # do any error recovery
else:
    # the coersion to int succeeded, so process the ticket sale

I hope this helps. Python error trapping is pretty powerful and you will use it quite a bit in your future programming of Python.