Python · Errors and Exceptions
Else - Finally
The full text of this chapter, to read or revisit. To practise, do the exercises.
▶ Do the exercisesExercise 1 — Introduction to the else Clause
We saw
try
and
except
for handling errors. Now let's learn about the
else
clause!
The
else
clause in a try/except block is an optional part that runs only when no exception occurs in the try block.
try:
# Code that might raise an exception
risky_operation()
except SomeError:
# Runs if exception occurs
print("Error occurred")
else:
# Runs ONLY if no exception occurred
print("Success! No errors.")
Let's see it in action with a Codémon example:
def train_codemon(codemon_name, training_hours):
try:
if training_hours < 0:
raise ValueError("Training hours cannot be negative")
power_increase = training_hours * 10
except ValueError as e:
print(f"Training failed: {e}")
else:
print("else print")
print(f"{codemon_name} trained successfully!")
print(f"Power increased by {power_increase}")
train_codemon("Aquachu", 3)
print("---")
train_codemon("Pyrochu", -1)
Why use else instead of putting code at the end of try?
The else clause makes your code clearer by separating the risky operation (in try) from the success actions (in else). It also ensures that only exceptions from the try block are caught, not from your success code.
Exercise 2 — When Does else Execute?
Given the following code, when will the
else
block execute?
try:
codemon_level = int(input("Enter level: "))
if codemon_level > 100:
raise ValueError("Level too high")
except ValueError:
print("Invalid level")
else:
print(f"Level set to {codemon_level}")
Options
• Only when no exception occurs in the try block
• Only when a ValueError occurs
• Always, regardless of exceptions
• When the except block finishes executing
Hint : Think about what makes else special - it only runs in the success case.
Exercise 3 — Introduction to the finally Clause
The
finally
clause is an optional part of try/except that always executes, whether an exception occurred or not. It's perfect for cleanup operations.
try:
# Code that might raise an exception
risky_operation()
except SomeError:
# Runs if exception occurs
print("Error occurred")
finally:
# ALWAYS runs, no matter what
print("Cleanup code")
def battle_codemon(attacker, defender):
print(f"Battle started: {attacker} vs {defender}")
try:
if defender == "":
raise ValueError("Defender cannot be empty")
print(f"{attacker} attacks {defender}!")
except ValueError as e:
print(f"Battle error: {e}")
finally:
print("Battle arena is now closed")
print("---")
battle_codemon("Aquachu", "Pyrochu")
battle_codemon("Florachu", "")
Common uses for finally
The finally clause is commonly used for:
- Closing files
- Releasing resources (database connections, network sockets)
- Cleaning up temporary data
- Logging operations
Anything that must happen regardless of success or failure should go in finally.
Exercise 4 — Understanding finally Execution
What will be printed when this code runs with a valid Codémon name?
try:
codemon_name = "Aquachu"
print(f"Caught {codemon_name}!")
except Exception:
print("Catch failed")
finally:
print("Pokéball returned to bag")
Options
• Both "Caught Aquachu!" and "Pokéball returned to bag"
• Only "Caught Aquachu!"
• Only "Pokéball returned to bag"
• Only "Catch failed"
Hint : Remember that finally always executes, whether there's an exception or not.
Exercise 5 — Complete the try/except/else Structure
Complete the code to add an else clause that only runs when the Codémon evolution succeeds (no exception):
def evolve_codemon(codemon_name, level):
try:
if level < 16:
raise ValueError("Level too low to evolve")
print(f"{codemon_name} is evolving...")
except ValueError as e:
print(f"Evolution failed: {e}")
____:
# Success! Evolution completed
print(f"{codemon_name} evolved successfully!")
print(f"New level: {level}")
evolve_codemon("Florachu", 20)
print('---')
evolve_codemon("Pyrochu", 10)
Options: else finally except then success if
Hint : Think about which clause runs only when no exception occurs in the try block.
Exercise 6 — Complete Structure: try/except/else/finally
Now let's see how all four parts work together. Here's the complete structure:
try:
# Code that might raise an exception
risky_operation()
except SomeError:
# Runs if exception occurs
handle_error()
else:
# Runs ONLY if NO exception occurred
success_actions()
finally:
# ALWAYS runs, no matter what
cleanup()
Execution order:
1.
try
block always runs first
2. If exception occurs →
except
block runs
3. If NO exception occurs →
else
block runs
4.
finally
block ALWAYS runs last
Let's see a complete example:
def calculate_item_price(item_name, quantity):
print(f"Processing order: {quantity}x {item_name}")
try:
# Risky operations - converting string to int
quantity_int = int(quantity)
base_price = 100
total = base_price * quantity_int
except ValueError as e:
# Runs if exception occurs
print(f"Error: Invalid quantity '{quantity}'")
print("Order cancelled")
else:
# Runs ONLY if no exception
print(f"Total price: {total} coins")
print("Order confirmed!")
finally:
# ALWAYS runs
print("Transaction logged")
print("---")
# Test with valid quantity
calculate_item_price("Potion", "5")
# Test with invalid quantity - watch the flow!
calculate_item_price("Revive", "three")
Key Points to Remember
• else and finally are both optional
• else runs only on success (no exception)
• finally runs always (success or failure)
• Order: try → except/else → finally
• You can use else without finally, or finally without else, or both together
Exercise 7 — Match Clauses with Their Purpose
Match each clause with its correct execution condition:
Items to match
• try
• except
• else
• finally
Definitions
• Always executes first, contains risky code
• Executes only when an exception occurs
• Executes only when NO exception occurs
• Always executes, used for cleanup
Exercise 8 — Complete the Full Structure
Complete this Codémon healing code with the appropriate clauses. The healing center should always close at the end (cleanup), and success message should only show if healing succeeds:
def heal_codemon(codemon_name, hp):
print(f"Healing center opened for {codemon_name}")
____:
restored_hp = 100
____ ValueError as e:
print(f"Healing failed: {e}")
____:
print(f"{codemon_name} fully healed!")
print(f"HP restored to {restored_hp}")
____:
print("Healing center closed")
heal_codemon("Aquachu", 50)
Options: try except else finally catch always success cleanup
Hint : Think about: which clause contains risky code? Which handles errors? Which runs on success? Which always runs for cleanup?
Exercise 9 — Understanding Execution Order
In what order will the print statements execute if NO exception occurs?
try:
print("A")
except ValueError:
print("B")
else:
print("C")
finally:
print("D")
Options
• A, C, D
• A, B, D
• A, D
• A, B, C, D
Hint : Trace through the execution: try runs first, then since there's no exception, else runs, then finally always runs.
Exercise 10 — Codémon Power Calculator
Create a Codémon power calculator that uses
else
and
finally
properly!
Create a function called
calculate_power
that:
1. Takes two parameters:
-
name
(string): Codémon name
-
level
(string): Level as a string to convert
2. In the
try
block:
- Convert
level
to integer
3. In the
except
block:
- Handle
ValueError
and set power to 0
4. In the
else
block:
- Calculate power (level * 10) - only if conversion worked
5. In the
finally
block:
- Display the final result (always runs)
Test with the provided cases!
Starter code
# Create the calculate_power function with try/except/else/finally
# Test with valid level
calculate_power("Aquachu", "50")
# Test with invalid level
calculate_power("Pyrochu", "fifty")
Back to the course