FAQ: Learn Python: Inheritance and Polymorphism - Exceptions

This community-built FAQ covers the “Exceptions” exercise from the lesson “Learn Python: Inheritance and Polymorphism”.

Paths and Courses
This exercise can be found in the following Codecademy content:

Computer Science

FAQs on the exercise Exceptions

Join the Discussion. Help a fellow learner on their journey.

Ask or answer a question about this exercise by clicking reply (reply) below!

Agree with a comment or answer? Like (like) to up-vote the contribution!

Need broader help or resources? Head here.

Looking for motivation to keep learning? Join our wider discussions.

Learn more about how to use this guide.

Found a bug? Report it!

Have a question about your account or billing? Reach out to our customer support team!

None of the above? Find out where to ask other questions here!

4 posts were split to a new topic: How can I catch a raised exception and pass the lesson?

A post was split to a new topic: What’s wrong with my code?

A post was split to a new topic: I’m trying to practice the example but it isn’t working?

3 posts were split to a new topic: How can I print the name in the class?

# Define your exception up here:
class OutOfStock(Exception):
  pass

# Update the class below to raise OutOfStock
class CandleShop:
  name = "Here's a Hot Tip: Buy Drip Candles"
  def __init__(self, stock):
    self.stock = stock
    
  def buy(self, color):
    if self.stock[color] > 0:
      self.stock[color] = self.stock[color] - 1
    else:
      raise OutOfStock

candle_shop = CandleShop({'blue': 6, 'red': 2, 'green': 0})
candle_shop.buy('blue')

# This should raise OutOfStock:
candle_shop.buy('green')

I don’t understand why this keeps getting refused as an answer for the second step in this exercise. I’m stuck now and can’t progress in the course because of this nonsense. I even tried swapping the order to first raise the exception if stock equals zero, else do the buy method, but also doesn’t get accepted.

2.

Have CandleShop raise your OutOfStock exception when CandleShop.buy() tries to buy a candle that’s out of stock.

This is what it shows when I run this code, and I can’t make any sense out of it. Adding dunder main. in front of the exception name makes no difference whatsoever:

Traceback (most recent call last):
  File "script.py", line 22, in <module>
    candle_shop.buy('green')
  File "script.py", line 13, in buy
    raise OutOfStock
__main__.OutOfStock

The following is the given solution to the exercise. Why is this accepted, and not my code?

# Define your exception up here:
class OutOfStock(Exception):
  pass

# Update the class below to raise OutOfStock
class CandleShop:
  name = "Here's a Hot Tip: Buy Drip Candles"
  def __init__(self, stock):
    self.stock = stock
    
  def buy(self, color):
    if self.stock[color] < 1:
      raise OutOfStock
    self.stock[color] = self.stock[color] - 1

candle_shop = CandleShop({'blue': 6, 'red': 2, 'green': 0})
candle_shop.buy('blue')

# This should raise OutOfStock:
# candle_shop.buy('green')
2 Likes

Your ‘buy’ method looks correct, but look again at the comment toward the bottom. When you comment out the last line (candle_shop.buy(‘green’)), this is the line of the program were we want to use a try/except clause to call the Exception class.

I had the same problem, even if I write the same solution given by the exercise with the only change is giving the command candle_shop.buy(‘green’), instead of hiding it with the # sign. So the only way to pass this exercise is just by hiding the last command line as the sln gives.

When we raise/ throw an exception should we place a return keyword afterwards? Or will control flow always be sent back to the place at which the function was called?

Many thanks for any help :slight_smile:

It would depend upon whether you want to handle the exception or throw it. No return would be needed in the former case if you let Python return None to the caller.

1 Like

Great - thanks,
and in the case of the exception being thrown, would this exit/ halt execution of the program thus not requiring any returns?

1 Like

If it is thrown, the program terminates immediately.

1 Like

As I am understanding, any Exception class will throw a Traceback error when it or any of its sub classes is raised? If so, why might this be useful?

Why is the Traceback useful? Is that your question?

Yeah, I suppose I just assumed trace back errors are something to avoid because they stop the execution of the rest of your code. Wouldn’t a try except statement be better in this case as you could avoid a trace back?

Custom exception handling is a way to prevent fatal errors, but it is probably best to let the errors happen so we can identify them and their cause. Anticipating all the possible things that can go wrong could derail our creative focus. Write code that works in a best case scenario, then tighten the screws on each edge case with one’s own error handling. In many cases we don’t need to use try..except if our own handing of errors is successful and there are no edge cases sneaking past.

When we can anticipate edge cases that will raise an exception and cannot handle it ourselves without code bloat then except that specific error, and let the Exception class handle all the others. We can still echo the error message without killing the program. Eventually we will come to trust the debugged code once we address all the possible errors that can be raised. Use exceptions as both a learning tool and a programming tool.

1 Like

Codecademy accepts my following answer, but for my curiosity, I commented the last line for Green purchasing and still the error is raised. Isn’t the exception error supposed to be raised only for items out of stock?

class OutOfStock(Exception):
  print("We ran out of stock.")

# Update the class below to raise OutOfStock
class CandleShop:
  name = "Here's a Hot Tip: Buy Drip Candles"
  def __init__(self, stock):
    self.stock = stock
    
  def buy(self, color):
    print(self.stock[color],color)
    if self.stock[color]<=0:
      raise OutOfStock
    else:
      self.stock[color] = self.stock[color] - 1
    print(self.stock[color],color)
 

candle_shop = CandleShop({'blue': 6, 'red': 2, 'green': 0})
candle_shop.buy('blue')

# This should raise OutOfStock:
#candle_shop.buy('green')

#Output:
#We ran out of stock.
#6 blue
#5 blue

I’m a little mystified by that class.

1 Like

Hi,
I am stuck in example problem of Refrigerator. Below is the program:

class KitchenException(Exception):
  """
  Exception that gets thrown when a kitchen appliance isn't working
  """

class MicrowaveException(KitchenException):
  """
  Exception for when the microwave stops working
  """

class RefrigeratorException(KitchenException):
  """
  Exception for when the refrigerator stops working
  """
def get_food_from_fridge():
    if refrigerator.cooling == False:
        raise RefrigeratorException
    else:
        return food
  
def heat_food(food):
    if microwave.working == False:
        raise MicrowaveException
    else:
        microwave.cook(food)
    return food

try:
    food = get_food_from_fridge()
    food = heat_food(food)
except KitchenException:
    food = order_takeout()

I am finding difficulty in understanding this program execution.
When I am running this program in my own console, showing below error -

if refrigerator.cooling == False:

NameError: name 'refrigerator' is not defined

What is expected? and I feel this program is incomplete.
Eagerly waiting for inputs.
Thanks

Hi,
I am continuing to my own message. Done some modifications to the program.

class KitchenException(Exception):
    pass

class MicrowaveException(KitchenException):
    pass

class RefrigeratorException(KitchenException):
    pass  

class refrigerator:
    cooling = True
    
    
class microwave:
    working = True
  
def cook(food):
    return [item for item in food]
    
def get_food_from_fridge(food = []):
    if refrigerator.cooling == False:
        raise RefrigeratorException
    else:
        return food
  
def heat_food(food):
    if microwave.working == False:
        raise MicrowaveException
    else:
          microwave.cook(food)
          return food

food = get_food_from_fridge(['spinach', 'tomato'])
food = heat_food(food) 
print(food)
#food = order_takeout()

I am getting below error and also does not know how to utilize order_takeout(). Please help.

File "E:\Python_Classes\kitchen_exception.py", line 70, in <module>
    food = heat_food(food)

  File "E:\Python_Classes\kitchen_exception.py", line 66, in heat_food
    microwave.cook(food)

AttributeError: type object 'microwave' has no attribute 'cook'

Eagerly waiting for any reply/inputs.
Many thanks in advance.