Exceptions
Try-Except
Handling Exceptions
Your program divides user input. If they enter zero, it crashes. Try-except lets you catch the error and respond gracefully - show a message, ask again, or use a default value. Your program keeps running.
Basic try-except
Catch and handle an exception.
# Basic try-except for division by zero
def main():
# Without exception handling (crashes)
print("Without try-except:")
# This would crash: result = 10 / 0
# With exception handling
print("\nWith try-except:")
try:
result = 10 / 0
print(f"Result: {result}")
except ZeroDivisionError:
print("Error: Cannot divide by zero")
result = None
print(f"Program continues, result = {result}")
# Safe division function
print("\nSafe division:")
numerator = 20
denominator = 4
try:
answer = numerator / denominator
print(f"{numerator} / {denominator} = {answer}")
except ZeroDivisionError:
print("Cannot divide by zero")
answer = 0
# Another example with zero
print("\nWith zero denominator:")
a = 15
b = 0
try:
quotient = a / b
print(f"{a} / {b} = {quotient}")
except ZeroDivisionError:
print(f"Cannot divide {a} by zero, using default value")
quotient = float('inf') # infinity
print(f"Final quotient: {quotient}")
if __name__ == "__main__":
main()
# Basic try-except for division by zero
def main():
# Without exception handling (crashes)
print("Without try-except:")
# This would crash: result = 10 / 0
# With exception handling
print("\nWith try-except:")
try:
result = 10 / 0
print(f"Result: {result}")
except ZeroDivisionError:
print("Error: Cannot divide by zero")
result = None
print(f"Program continues, result = {result}")
# Safe division function
print("\nSafe division:")
numerator = 10
denominator = 4
try:
answer = numerator / denominator
print(f"{numerator} / {denominator} = {answer}")
except ZeroDivisionError:
print("Cannot divide by zero")
answer = 0
# Another example with zero
print("\nWith zero denominator:")
a = 15
b = 0
try:
quotient = a / b
print(f"{a} / {b} = {quotient}")
except ZeroDivisionError:
print(f"Cannot divide {a} by zero, using default value")
quotient = float('inf') # infinity
print(f"Final quotient: {quotient}")
if __name__ == "__main__":
main()
# Basic try-except for division by zero
def main():
# Without exception handling (crashes)
print("Without try-except:")
# This would crash: result = 10 / 0
# With exception handling
print("\nWith try-except:")
try:
result = 10 / 0
print(f"Result: {result}")
except ZeroDivisionError:
print("Error: Cannot divide by zero")
result = None
print(f"Program continues, result = {result}")
# Safe division function
print("\nSafe division:")
numerator = 30
denominator = 4
try:
answer = numerator / denominator
print(f"{numerator} / {denominator} = {answer}")
except ZeroDivisionError:
print("Cannot divide by zero")
answer = 0
# Another example with zero
print("\nWith zero denominator:")
a = 15
b = 0
try:
quotient = a / b
print(f"{a} / {b} = {quotient}")
except ZeroDivisionError:
print(f"Cannot divide {a} by zero, using default value")
quotient = float('inf') # infinity
print(f"Final quotient: {quotient}")
if __name__ == "__main__":
main()
# Basic try-except for division by zero
def main():
# Without exception handling (crashes)
print("Without try-except:")
# This would crash: result = 10 / 0
# With exception handling
print("\nWith try-except:")
try:
result = 10 / 0
print(f"Result: {result}")
except ZeroDivisionError:
print("Error: Cannot divide by zero")
result = None
print(f"Program continues, result = {result}")
# Safe division function
print("\nSafe division:")
numerator = 50
denominator = 4
try:
answer = numerator / denominator
print(f"{numerator} / {denominator} = {answer}")
except ZeroDivisionError:
print("Cannot divide by zero")
answer = 0
# Another example with zero
print("\nWith zero denominator:")
a = 15
b = 0
try:
quotient = a / b
print(f"{a} / {b} = {quotient}")
except ZeroDivisionError:
print(f"Cannot divide {a} by zero, using default value")
quotient = float('inf') # infinity
print(f"Final quotient: {quotient}")
if __name__ == "__main__":
main()
# Basic try-except for division by zero
def main():
# Without exception handling (crashes)
print("Without try-except:")
# This would crash: result = 10 / 0
# With exception handling
print("\nWith try-except:")
try:
result = 10 / 0
print(f"Result: {result}")
except ZeroDivisionError:
print("Error: Cannot divide by zero")
result = None
print(f"Program continues, result = {result}")
# Safe division function
print("\nSafe division:")
numerator = 20
denominator = 0
try:
answer = numerator / denominator
print(f"{numerator} / {denominator} = {answer}")
except ZeroDivisionError:
print("Cannot divide by zero")
answer = 0
# Another example with zero
print("\nWith zero denominator:")
a = 15
b = 0
try:
quotient = a / b
print(f"{a} / {b} = {quotient}")
except ZeroDivisionError:
print(f"Cannot divide {a} by zero, using default value")
quotient = float('inf') # infinity
print(f"Final quotient: {quotient}")
if __name__ == "__main__":
main()
# Basic try-except for division by zero
def main():
# Without exception handling (crashes)
print("Without try-except:")
# This would crash: result = 10 / 0
# With exception handling
print("\nWith try-except:")
try:
result = 10 / 0
print(f"Result: {result}")
except ZeroDivisionError:
print("Error: Cannot divide by zero")
result = None
print(f"Program continues, result = {result}")
# Safe division function
print("\nSafe division:")
numerator = 20
denominator = 2
try:
answer = numerator / denominator
print(f"{numerator} / {denominator} = {answer}")
except ZeroDivisionError:
print("Cannot divide by zero")
answer = 0
# Another example with zero
print("\nWith zero denominator:")
a = 15
b = 0
try:
quotient = a / b
print(f"{a} / {b} = {quotient}")
except ZeroDivisionError:
print(f"Cannot divide {a} by zero, using default value")
quotient = float('inf') # infinity
print(f"Final quotient: {quotient}")
if __name__ == "__main__":
main()
# Basic try-except for division by zero
def main():
# Without exception handling (crashes)
print("Without try-except:")
# This would crash: result = 10 / 0
# With exception handling
print("\nWith try-except:")
try:
result = 10 / 0
print(f"Result: {result}")
except ZeroDivisionError:
print("Error: Cannot divide by zero")
result = None
print(f"Program continues, result = {result}")
# Safe division function
print("\nSafe division:")
numerator = 20
denominator = 5
try:
answer = numerator / denominator
print(f"{numerator} / {denominator} = {answer}")
except ZeroDivisionError:
print("Cannot divide by zero")
answer = 0
# Another example with zero
print("\nWith zero denominator:")
a = 15
b = 0
try:
quotient = a / b
print(f"{a} / {b} = {quotient}")
except ZeroDivisionError:
print(f"Cannot divide {a} by zero, using default value")
quotient = float('inf') # infinity
print(f"Final quotient: {quotient}")
if __name__ == "__main__":
main()
def main(): # Without exception handling (crashes)
3def main():4 # Without exception handling (crashes)5 print("Without try-except:")6 # This would crash: result = 10 / 07 8 # With exception handling9 print("\nWith try-except:")10 try:outputWithout try-except: With try-except:result ← None
12 print(f"Result: {result}")13except ZeroDivisionError:14 print("Error: Cannot divide by zero")15 result→ None = NoneoutputError: Cannot divide by zeronumerator ← 20, denominator ← 4
17print(f"Program continues, result = {resultNone}")1819#@help h120# Without try-except, program crashes at division by zero21# With try-except, we catch the error and program continues22# The except block runs only when that specific error occurs23#@end2425# Safe division function26print("\nSafe division:")27numerator→ 20 = 2028#@numerator=10, 30, 5029denominator→ 4 = 430#@denominator=0, 2, 5outputProgram continues, result = None Safe division:answer ← 5.0
32try:33 answer→ 5.0 = numerator20 / denominator434 print(f"{numerator20} / {denominator4} = {answer5.0}")35except ZeroDivisionError:output20 / 4 = 5.0a ← 15, b ← 0
39# Another example with zero40print("\nWith zero denominator:")41a→ 15 = 1542b→ 0 = 0output With zero denominator:try:
44try:45 quotient = a15 / b046 print(f"{a} / {b} = {quotient}")quotient ← inf
46 print(f"{a} / {b} = {quotient}")47except ZeroDivisionError:48 print(f"Cannot divide {a15} by zero, using default value")49 quotient→ inf = float('inf') # infinity5051print(f"Final quotient: {quotient}")outputCannot divide 15 by zero, using default valueprint(f"Final quotient: {quotient}")
51print(f"Final quotient: {quotientinf}")outputFinal quotient: infmain()
53if __name__ == "__main__":54 main()
def main(): # Without exception handling (crashes)
3def main():4 # Without exception handling (crashes)5 print("Without try-except:")6 # This would crash: result = 10 / 07 8 # With exception handling9 print("\nWith try-except:")10 try:outputWithout try-except: With try-except:result ← None
12 print(f"Result: {result}")13except ZeroDivisionError:14 print("Error: Cannot divide by zero")15 result→ None = NoneoutputError: Cannot divide by zeronumerator ← 10, denominator ← 4
17print(f"Program continues, result = {resultNone}")181920# Safe division function21print("\nSafe division:")22numerator→ 10 = 1023denominator→ 4 = 4outputProgram continues, result = None Safe division:answer ← 2.5
25try:26 answer→ 2.5 = numerator10 / denominator427 print(f"{numerator10} / {denominator4} = {answer2.5}")28except ZeroDivisionError:output10 / 4 = 2.5a ← 15, b ← 0
32# Another example with zero33print("\nWith zero denominator:")34a→ 15 = 1535b→ 0 = 0output With zero denominator:try:
37try:38 quotient = a15 / b039 print(f"{a} / {b} = {quotient}")quotient ← inf
39 print(f"{a} / {b} = {quotient}")40except ZeroDivisionError:41 print(f"Cannot divide {a15} by zero, using default value")42 quotient→ inf = float('inf') # infinity4344print(f"Final quotient: {quotient}")outputCannot divide 15 by zero, using default valueprint(f"Final quotient: {quotient}")
44print(f"Final quotient: {quotientinf}")outputFinal quotient: infmain()
46if __name__ == "__main__":47 main()
def main(): # Without exception handling (crashes)
3def main():4 # Without exception handling (crashes)5 print("Without try-except:")6 # This would crash: result = 10 / 07 8 # With exception handling9 print("\nWith try-except:")10 try:outputWithout try-except: With try-except:result ← None
12 print(f"Result: {result}")13except ZeroDivisionError:14 print("Error: Cannot divide by zero")15 result→ None = NoneoutputError: Cannot divide by zeronumerator ← 30, denominator ← 4
17print(f"Program continues, result = {resultNone}")181920# Safe division function21print("\nSafe division:")22numerator→ 30 = 3023denominator→ 4 = 4outputProgram continues, result = None Safe division:answer ← 7.5
25try:26 answer→ 7.5 = numerator30 / denominator427 print(f"{numerator30} / {denominator4} = {answer7.5}")28except ZeroDivisionError:output30 / 4 = 7.5a ← 15, b ← 0
32# Another example with zero33print("\nWith zero denominator:")34a→ 15 = 1535b→ 0 = 0output With zero denominator:try:
37try:38 quotient = a15 / b039 print(f"{a} / {b} = {quotient}")quotient ← inf
39 print(f"{a} / {b} = {quotient}")40except ZeroDivisionError:41 print(f"Cannot divide {a15} by zero, using default value")42 quotient→ inf = float('inf') # infinity4344print(f"Final quotient: {quotient}")outputCannot divide 15 by zero, using default valueprint(f"Final quotient: {quotient}")
44print(f"Final quotient: {quotientinf}")outputFinal quotient: infmain()
46if __name__ == "__main__":47 main()
def main(): # Without exception handling (crashes)
3def main():4 # Without exception handling (crashes)5 print("Without try-except:")6 # This would crash: result = 10 / 07 8 # With exception handling9 print("\nWith try-except:")10 try:outputWithout try-except: With try-except:result ← None
12 print(f"Result: {result}")13except ZeroDivisionError:14 print("Error: Cannot divide by zero")15 result→ None = NoneoutputError: Cannot divide by zeronumerator ← 50, denominator ← 4
17print(f"Program continues, result = {resultNone}")181920# Safe division function21print("\nSafe division:")22numerator→ 50 = 5023denominator→ 4 = 4outputProgram continues, result = None Safe division:answer ← 12.5
25try:26 answer→ 12.5 = numerator50 / denominator427 print(f"{numerator50} / {denominator4} = {answer12.5}")28except ZeroDivisionError:output50 / 4 = 12.5a ← 15, b ← 0
32# Another example with zero33print("\nWith zero denominator:")34a→ 15 = 1535b→ 0 = 0output With zero denominator:try:
37try:38 quotient = a15 / b039 print(f"{a} / {b} = {quotient}")quotient ← inf
39 print(f"{a} / {b} = {quotient}")40except ZeroDivisionError:41 print(f"Cannot divide {a15} by zero, using default value")42 quotient→ inf = float('inf') # infinity4344print(f"Final quotient: {quotient}")outputCannot divide 15 by zero, using default valueprint(f"Final quotient: {quotient}")
44print(f"Final quotient: {quotientinf}")outputFinal quotient: infmain()
46if __name__ == "__main__":47 main()
def main(): # Without exception handling (crashes)
3def main():4 # Without exception handling (crashes)5 print("Without try-except:")6 # This would crash: result = 10 / 07 8 # With exception handling9 print("\nWith try-except:")10 try:outputWithout try-except: With try-except:result ← None
12 print(f"Result: {result}")13except ZeroDivisionError:14 print("Error: Cannot divide by zero")15 result→ None = NoneoutputError: Cannot divide by zeronumerator ← 20, denominator ← 0
17print(f"Program continues, result = {resultNone}")181920# Safe division function21print("\nSafe division:")22numerator→ 20 = 2023denominator→ 0 = 0outputProgram continues, result = None Safe division:try:
25try:26 answer = numerator20 / denominator027 print(f"{numerator} / {denominator} = {answer}")answer ← 0
27 print(f"{numerator} / {denominator} = {answer}")28except ZeroDivisionError:29 print("Cannot divide by zero")30 answer→ 0 = 0outputCannot divide by zeroa ← 15, b ← 0
32# Another example with zero33print("\nWith zero denominator:")34a→ 15 = 1535b→ 0 = 0output With zero denominator:try:
37try:38 quotient = a15 / b039 print(f"{a} / {b} = {quotient}")quotient ← inf
39 print(f"{a} / {b} = {quotient}")40except ZeroDivisionError:41 print(f"Cannot divide {a15} by zero, using default value")42 quotient→ inf = float('inf') # infinity4344print(f"Final quotient: {quotient}")outputCannot divide 15 by zero, using default valueprint(f"Final quotient: {quotient}")
44print(f"Final quotient: {quotientinf}")outputFinal quotient: infmain()
46if __name__ == "__main__":47 main()
def main(): # Without exception handling (crashes)
3def main():4 # Without exception handling (crashes)5 print("Without try-except:")6 # This would crash: result = 10 / 07 8 # With exception handling9 print("\nWith try-except:")10 try:outputWithout try-except: With try-except:result ← None
12 print(f"Result: {result}")13except ZeroDivisionError:14 print("Error: Cannot divide by zero")15 result→ None = NoneoutputError: Cannot divide by zeronumerator ← 20, denominator ← 2
17print(f"Program continues, result = {resultNone}")181920# Safe division function21print("\nSafe division:")22numerator→ 20 = 2023denominator→ 2 = 2outputProgram continues, result = None Safe division:answer ← 10.0
25try:26 answer→ 10.0 = numerator20 / denominator227 print(f"{numerator20} / {denominator2} = {answer10.0}")28except ZeroDivisionError:output20 / 2 = 10.0a ← 15, b ← 0
32# Another example with zero33print("\nWith zero denominator:")34a→ 15 = 1535b→ 0 = 0output With zero denominator:try:
37try:38 quotient = a15 / b039 print(f"{a} / {b} = {quotient}")quotient ← inf
39 print(f"{a} / {b} = {quotient}")40except ZeroDivisionError:41 print(f"Cannot divide {a15} by zero, using default value")42 quotient→ inf = float('inf') # infinity4344print(f"Final quotient: {quotient}")outputCannot divide 15 by zero, using default valueprint(f"Final quotient: {quotient}")
44print(f"Final quotient: {quotientinf}")outputFinal quotient: infmain()
46if __name__ == "__main__":47 main()
def main(): # Without exception handling (crashes)
3def main():4 # Without exception handling (crashes)5 print("Without try-except:")6 # This would crash: result = 10 / 07 8 # With exception handling9 print("\nWith try-except:")10 try:outputWithout try-except: With try-except:result ← None
12 print(f"Result: {result}")13except ZeroDivisionError:14 print("Error: Cannot divide by zero")15 result→ None = NoneoutputError: Cannot divide by zeronumerator ← 20, denominator ← 5
17print(f"Program continues, result = {resultNone}")181920# Safe division function21print("\nSafe division:")22numerator→ 20 = 2023denominator→ 5 = 5outputProgram continues, result = None Safe division:answer ← 4.0
25try:26 answer→ 4.0 = numerator20 / denominator527 print(f"{numerator20} / {denominator5} = {answer4.0}")28except ZeroDivisionError:output20 / 5 = 4.0a ← 15, b ← 0
32# Another example with zero33print("\nWith zero denominator:")34a→ 15 = 1535b→ 0 = 0output With zero denominator:try:
37try:38 quotient = a15 / b039 print(f"{a} / {b} = {quotient}")quotient ← inf
39 print(f"{a} / {b} = {quotient}")40except ZeroDivisionError:41 print(f"Cannot divide {a15} by zero, using default value")42 quotient→ inf = float('inf') # infinity4344print(f"Final quotient: {quotient}")outputCannot divide 15 by zero, using default valueprint(f"Final quotient: {quotient}")
44print(f"Final quotient: {quotientinf}")outputFinal quotient: infmain()
46if __name__ == "__main__":47 main()
Code that might fail goes in try. Error handling goes in except.
See Exception Flow
An exception changes the path through the program. These diagrams pin the exact division and parsing examples from this lesson.
Catch index errors
Handle accessing invalid list indices.
# Catching IndexError when accessing list elements
def main():
# Safe list access
scores = [85, 92, 78, 90, 88]
print("Scores:", scores)
print(f"Total scores: {len(scores)}")
# Access valid index
try:
first = scores[0]
print(f"\nFirst score: {first}")
except IndexError:
print("Index out of range")
first = None
# Access invalid index
print("\nAccessing index 10:")
try:
value = scores[10]
print(f"Value: {value}")
except IndexError:
print("Error: Index 10 doesn't exist")
value = None
# Safe get function
def safe_get(lst, index, default=0):
try:
return lst[index]
except IndexError:
return default
print("\nUsing safe_get:")
print(f"Index 2: {safe_get(scores, 2)}")
print(f"Index 99: {safe_get(scores, 99, default=-1)}")
# Multiple attempts
indices = [0, 2, 5, 3, 10]
print("\nAccessing multiple indices:")
for i in indices:
try:
score = scores[i]
print(f" scores[{i}] = {score}")
except IndexError:
print(f" scores[{i}] = OUT OF RANGE")
if __name__ == "__main__":
main()
# Catching IndexError when accessing list elements
def main():
# Safe list access
scores = [95, 88, 92]
print("Scores:", scores)
print(f"Total scores: {len(scores)}")
# Access valid index
try:
first = scores[0]
print(f"\nFirst score: {first}")
except IndexError:
print("Index out of range")
first = None
# Access invalid index
print("\nAccessing index 10:")
try:
value = scores[10]
print(f"Value: {value}")
except IndexError:
print("Error: Index 10 doesn't exist")
value = None
# Safe get function
def safe_get(lst, index, default=0):
try:
return lst[index]
except IndexError:
return default
print("\nUsing safe_get:")
print(f"Index 2: {safe_get(scores, 2)}")
print(f"Index 99: {safe_get(scores, 99, default=-1)}")
# Multiple attempts
indices = [0, 2, 5, 3, 10]
print("\nAccessing multiple indices:")
for i in indices:
try:
score = scores[i]
print(f" scores[{i}] = {score}")
except IndexError:
print(f" scores[{i}] = OUT OF RANGE")
if __name__ == "__main__":
main()
# Catching IndexError when accessing list elements
def main():
# Safe list access
scores = [100, 75, 80, 85, 90]
print("Scores:", scores)
print(f"Total scores: {len(scores)}")
# Access valid index
try:
first = scores[0]
print(f"\nFirst score: {first}")
except IndexError:
print("Index out of range")
first = None
# Access invalid index
print("\nAccessing index 10:")
try:
value = scores[10]
print(f"Value: {value}")
except IndexError:
print("Error: Index 10 doesn't exist")
value = None
# Safe get function
def safe_get(lst, index, default=0):
try:
return lst[index]
except IndexError:
return default
print("\nUsing safe_get:")
print(f"Index 2: {safe_get(scores, 2)}")
print(f"Index 99: {safe_get(scores, 99, default=-1)}")
# Multiple attempts
indices = [0, 2, 5, 3, 10]
print("\nAccessing multiple indices:")
for i in indices:
try:
score = scores[i]
print(f" scores[{i}] = {score}")
except IndexError:
print(f" scores[{i}] = OUT OF RANGE")
if __name__ == "__main__":
main()
scores ← [85, 92, 78, 90, 88]
3def main():4 # Safe list access5 scores→ [85, 92, 78, 90, 88] = [85, 92, 78, 90, 88]6 #@scores=[95, 88, 92], [100, 75, 80, 85, 90]7 8 print("Scores:", scores[85, 92, 78, 90, 88])9 print(f"Total scores: {len(scores[85, 92, 78, 90, 88])}")outputScores: [85, 92, 78, 90, 88] Total scores: 5first ← 85
11# Access valid index12try:13 first→ 85 = scores[0]8514 print(f"\nFirst score: {first85}")15except IndexError:output First score: 85print(" Accessing index 10:")
19# Access invalid index20print("\nAccessing index 10:")21try:output Accessing index 10:try:
20print("\nAccessing index 10:")21try:22 value = scores[10](empty)23 print(f"Value: {value}")value ← None
23 print(f"Value: {value}")24except IndexError:25 print("Error: Index 10 doesn't exist")26 value→ None = NoneoutputError: Index 10 doesn't existprint(f"Index 2: {safe_get(scores, 2)}")
41print("\nUsing safe_get:")42print(f"Index 2: {safe_get(scores[85, 92, 78, 90, 88], 2)}")43print(f"Index 99: {safe_get(scores, 99, default=-1)}")output Using safe_get:def safe_get(lst, index, default=0):
pass 1 of 234# Safe get function35def safe_get(lst[85, 92, 78, 90, 88], index2, default0=0):36 try:37 return lst[index]try:
pass 1 of 235def safe_get(lst, index, default=0):36 try:37 return lst[index]7838 except IndexError:print(f"Index 2: {safe_get(scores, 2)}")
41print("\nUsing safe_get:")42print(f"Index 2: {safe_get(scores[85, 92, 78, 90, 88], 2)}")43print(f"Index 99: {safe_get(scores[85, 92, 78, 90, 88], 99, default=-1)}")outputIndex 2: 78def safe_get(lst, index, default=0):
pass 2 of 234# Safe get function35def safe_get(lst[85, 92, 78, 90, 88], index99, default-1=0):36 try:37 return lst[index]try:
pass 2 of 235def safe_get(lst, index, default=0):36 try:37 return lst[index](empty)38 except IndexError:except IndexError:
37 return lst[index]38except IndexError:39 return default-1indices ← [0, 2, 5, 3, 10]
42print(f"Index 2: {safe_get(scores, 2)}")43print(f"Index 99: {safe_get(scores[85, 92, 78, 90, 88], 99, default=-1)}")4445# Multiple attempts46indices→ [0, 2, 5, 3, 10] = [0, 2, 5, 3, 10]47print("\nAccessing multiple indices:")48for i in indices:outputIndex 99: -1 Accessing multiple indices:for i in indices:
pass 1 of 547print("\nAccessing multiple indices:")48for i0 in indices[0, 2, 5, 3, 10]:49 try:50 score = scores[i]All 5 passes — pass 1 is the card above pass i1 0 2 2 3 5 4 3 5 10 score ← 85
pass 1 of 548for i in indices:49 try:50 score→ 85 = scores[i]8551 print(f" scores[{i0}] = {score85}")52 except IndexError:output scores[0] = 85All 5 passes — pass 1 is the card above pass scores[i]iscore1 85 0 85 2 78 2 78 3 (empty) 5 — 4 90 3 90 5 (empty) 10 — except IndexError:
pass 1 of 251 print(f" scores[{i}] = {score}")52except IndexError:53 print(f" scores[{i5}] = OUT OF RANGE")output scores[5] = OUT OF RANGE scores[5] = OUT OF RANGEexcept IndexError:
pass 2 of 251 print(f" scores[{i}] = {score}")52except IndexError:53 print(f" scores[{i10}] = OUT OF RANGE")output scores[10] = OUT OF RANGE scores[10] = OUT OF RANGEmain()
55if __name__ == "__main__":56 main()
scores ← [95, 88, 92]
3def main():4 # Safe list access5 scores→ [95, 88, 92] = [95, 88, 92]6 7 print("Scores:", scores[95, 88, 92])8 print(f"Total scores: {len(scores[95, 88, 92])}")outputScores: [95, 88, 92] Total scores: 3first ← 95
10# Access valid index11try:12 first→ 95 = scores[0]9513 print(f"\nFirst score: {first95}")14except IndexError:output First score: 95print(" Accessing index 10:")
18# Access invalid index19print("\nAccessing index 10:")20try:output Accessing index 10:try:
19print("\nAccessing index 10:")20try:21 value = scores[10](empty)22 print(f"Value: {value}")value ← None
22 print(f"Value: {value}")23except IndexError:24 print("Error: Index 10 doesn't exist")25 value→ None = NoneoutputError: Index 10 doesn't existprint(f"Index 2: {safe_get(scores, 2)}")
35print("\nUsing safe_get:")36print(f"Index 2: {safe_get(scores[95, 88, 92], 2)}")37print(f"Index 99: {safe_get(scores, 99, default=-1)}")output Using safe_get:def safe_get(lst, index, default=0):
pass 1 of 228# Safe get function29def safe_get(lst[95, 88, 92], index2, default0=0):30 try:31 return lst[index]try:
pass 1 of 229def safe_get(lst, index, default=0):30 try:31 return lst[index]9232 except IndexError:print(f"Index 2: {safe_get(scores, 2)}")
35print("\nUsing safe_get:")36print(f"Index 2: {safe_get(scores[95, 88, 92], 2)}")37print(f"Index 99: {safe_get(scores[95, 88, 92], 99, default=-1)}")outputIndex 2: 92def safe_get(lst, index, default=0):
pass 2 of 228# Safe get function29def safe_get(lst[95, 88, 92], index99, default-1=0):30 try:31 return lst[index]try:
pass 2 of 229def safe_get(lst, index, default=0):30 try:31 return lst[index](empty)32 except IndexError:except IndexError:
31 return lst[index]32except IndexError:33 return default-1indices ← [0, 2, 5, 3, 10]
36print(f"Index 2: {safe_get(scores, 2)}")37print(f"Index 99: {safe_get(scores[95, 88, 92], 99, default=-1)}")3839# Multiple attempts40indices→ [0, 2, 5, 3, 10] = [0, 2, 5, 3, 10]41print("\nAccessing multiple indices:")42for i in indices:outputIndex 99: -1 Accessing multiple indices:for i in indices:
pass 1 of 541print("\nAccessing multiple indices:")42for i0 in indices[0, 2, 5, 3, 10]:43 try:44 score = scores[i]All 5 passes — pass 1 is the card above pass i1 0 2 2 3 5 4 3 5 10 score ← 95
pass 1 of 542for i in indices:43 try:44 score→ 95 = scores[i]9545 print(f" scores[{i0}] = {score95}")46 except IndexError:output scores[0] = 95All 5 passes — pass 1 is the card above pass scores[i]iscore1 95 0 95 2 92 2 92 3 (empty) — — 4 (empty) — — 5 (empty) — — except IndexError:
pass 1 of 345 print(f" scores[{i}] = {score}")46except IndexError:47 print(f" scores[{i5}] = OUT OF RANGE")output scores[5] = OUT OF RANGE scores[5] = OUT OF RANGEAll 3 passes — pass 1 is the card above pass i1 5 2 3 3 10 main()
49if __name__ == "__main__":50 main()
scores ← [100, 75, 80, 85, 90]
3def main():4 # Safe list access5 scores→ [100, 75, 80, 85, 90] = [100, 75, 80, 85, 90]6 7 print("Scores:", scores[100, 75, 80, 85, 90])8 print(f"Total scores: {len(scores[100, 75, 80, 85, 90])}")outputScores: [100, 75, 80, 85, 90] Total scores: 5first ← 100
10# Access valid index11try:12 first→ 100 = scores[0]10013 print(f"\nFirst score: {first100}")14except IndexError:output First score: 100print(" Accessing index 10:")
18# Access invalid index19print("\nAccessing index 10:")20try:output Accessing index 10:try:
19print("\nAccessing index 10:")20try:21 value = scores[10](empty)22 print(f"Value: {value}")value ← None
22 print(f"Value: {value}")23except IndexError:24 print("Error: Index 10 doesn't exist")25 value→ None = NoneoutputError: Index 10 doesn't existprint(f"Index 2: {safe_get(scores, 2)}")
35print("\nUsing safe_get:")36print(f"Index 2: {safe_get(scores[100, 75, 80, 85, 90], 2)}")37print(f"Index 99: {safe_get(scores, 99, default=-1)}")output Using safe_get:def safe_get(lst, index, default=0):
pass 1 of 228# Safe get function29def safe_get(lst[100, 75, 80, 85, 90], index2, default0=0):30 try:31 return lst[index]try:
pass 1 of 229def safe_get(lst, index, default=0):30 try:31 return lst[index]8032 except IndexError:print(f"Index 2: {safe_get(scores, 2)}")
35print("\nUsing safe_get:")36print(f"Index 2: {safe_get(scores[100, 75, 80, 85, 90], 2)}")37print(f"Index 99: {safe_get(scores[100, 75, 80, 85, 90], 99, default=-1)}")outputIndex 2: 80def safe_get(lst, index, default=0):
pass 2 of 228# Safe get function29def safe_get(lst[100, 75, 80, 85, 90], index99, default-1=0):30 try:31 return lst[index]try:
pass 2 of 229def safe_get(lst, index, default=0):30 try:31 return lst[index](empty)32 except IndexError:except IndexError:
31 return lst[index]32except IndexError:33 return default-1indices ← [0, 2, 5, 3, 10]
36print(f"Index 2: {safe_get(scores, 2)}")37print(f"Index 99: {safe_get(scores[100, 75, 80, 85, 90], 99, default=-1)}")3839# Multiple attempts40indices→ [0, 2, 5, 3, 10] = [0, 2, 5, 3, 10]41print("\nAccessing multiple indices:")42for i in indices:outputIndex 99: -1 Accessing multiple indices:for i in indices:
pass 1 of 541print("\nAccessing multiple indices:")42for i0 in indices[0, 2, 5, 3, 10]:43 try:44 score = scores[i]All 5 passes — pass 1 is the card above pass i1 0 2 2 3 5 4 3 5 10 score ← 100
pass 1 of 542for i in indices:43 try:44 score→ 100 = scores[i]10045 print(f" scores[{i0}] = {score100}")46 except IndexError:output scores[0] = 100All 5 passes — pass 1 is the card above pass scores[i]iscore1 100 0 100 2 80 2 80 3 (empty) 5 — 4 85 3 85 5 (empty) 10 — except IndexError:
pass 1 of 245 print(f" scores[{i}] = {score}")46except IndexError:47 print(f" scores[{i5}] = OUT OF RANGE")output scores[5] = OUT OF RANGE scores[5] = OUT OF RANGEexcept IndexError:
pass 2 of 245 print(f" scores[{i}] = {score}")46except IndexError:47 print(f" scores[{i10}] = OUT OF RANGE")output scores[10] = OUT OF RANGE scores[10] = OUT OF RANGEmain()
49if __name__ == "__main__":50 main()
IndexError when accessing index outside list range.
Multiple except blocks
Handle different exceptions differently.
# Multiple except blocks for different errors
def main():
# Parse user input (multiple error types)
print("Input parsing with multiple exceptions:\n")
data = {
"name": "Alice",
"age": "25",
"scores": [85, 90, 78]
}
# Catch ValueError (bad conversion)
try:
age_str = "not a number"
age = int(age_str)
print(f"Age: {age}")
except ValueError:
print("ValueError: Cannot convert to integer")
age = 0
# Catch KeyError (missing key)
try:
email = data["email"] # key doesn't exist
print(f"Email: {email}")
except KeyError:
print("KeyError: 'email' key not found")
email = "unknown@example.com"
# Multiple exceptions in one try block
print("\nProcessing with multiple potential errors:")
try:
# Could raise KeyError
score_str = data["score"] # missing key
# Could raise ValueError
score = int(score_str)
# Could raise IndexError
first_score = data["scores"][10]
print(f"Score: {score}, First: {first_score}")
except KeyError as e:
print(f"Missing key: {e}")
except ValueError as e:
print(f"Invalid value: {e}")
except IndexError as e:
print(f"Index error: {e}")
# Catch parent exception
print("\nUsing generic Exception:")
try:
result = data["count"] / 0
except ZeroDivisionError:
print("Specific: Division by zero")
except Exception as e:
print(f"Generic: {type(e).__name__}: {e}")
# Process list of operations
operations = [
("parse", "123"),
("parse", "abc"),
("divide", 10, 0),
("access", [1, 2], 5)
]
print("\nProcessing operations:")
for op in operations:
try:
if op[0] == "parse":
result = int(op[1])
print(f" Parsed: {result}")
elif op[0] == "divide":
result = op[1] / op[2]
print(f" Divided: {result}")
elif op[0] == "access":
result = op[1][op[2]]
print(f" Accessed: {result}")
except ValueError:
print(f" ValueError in {op}")
except ZeroDivisionError:
print(f" ZeroDivisionError in {op}")
except IndexError:
print(f" IndexError in {op}")
if __name__ == "__main__":
main()
# Multiple except blocks for different errors
def main():
# Parse user input (multiple error types)
print("Input parsing with multiple exceptions:\n")
data = {
"name": "Alice",
"age": "25",
"scores": [85, 90, 78]
}
# Catch ValueError (bad conversion)
try:
age_str = "30"
age = int(age_str)
print(f"Age: {age}")
except ValueError:
print("ValueError: Cannot convert to integer")
age = 0
# Catch KeyError (missing key)
try:
email = data["email"] # key doesn't exist
print(f"Email: {email}")
except KeyError:
print("KeyError: 'email' key not found")
email = "unknown@example.com"
# Multiple exceptions in one try block
print("\nProcessing with multiple potential errors:")
try:
# Could raise KeyError
score_str = data["score"] # missing key
# Could raise ValueError
score = int(score_str)
# Could raise IndexError
first_score = data["scores"][10]
print(f"Score: {score}, First: {first_score}")
except KeyError as e:
print(f"Missing key: {e}")
except ValueError as e:
print(f"Invalid value: {e}")
except IndexError as e:
print(f"Index error: {e}")
# Catch parent exception
print("\nUsing generic Exception:")
try:
result = data["count"] / 0
except ZeroDivisionError:
print("Specific: Division by zero")
except Exception as e:
print(f"Generic: {type(e).__name__}: {e}")
# Process list of operations
operations = [
("parse", "123"),
("parse", "abc"),
("divide", 10, 0),
("access", [1, 2], 5)
]
print("\nProcessing operations:")
for op in operations:
try:
if op[0] == "parse":
result = int(op[1])
print(f" Parsed: {result}")
elif op[0] == "divide":
result = op[1] / op[2]
print(f" Divided: {result}")
elif op[0] == "access":
result = op[1][op[2]]
print(f" Accessed: {result}")
except ValueError:
print(f" ValueError in {op}")
except ZeroDivisionError:
print(f" ZeroDivisionError in {op}")
except IndexError:
print(f" IndexError in {op}")
if __name__ == "__main__":
main()
# Multiple except blocks for different errors
def main():
# Parse user input (multiple error types)
print("Input parsing with multiple exceptions:\n")
data = {
"name": "Alice",
"age": "25",
"scores": [85, 90, 78]
}
# Catch ValueError (bad conversion)
try:
age_str = "invalid"
age = int(age_str)
print(f"Age: {age}")
except ValueError:
print("ValueError: Cannot convert to integer")
age = 0
# Catch KeyError (missing key)
try:
email = data["email"] # key doesn't exist
print(f"Email: {email}")
except KeyError:
print("KeyError: 'email' key not found")
email = "unknown@example.com"
# Multiple exceptions in one try block
print("\nProcessing with multiple potential errors:")
try:
# Could raise KeyError
score_str = data["score"] # missing key
# Could raise ValueError
score = int(score_str)
# Could raise IndexError
first_score = data["scores"][10]
print(f"Score: {score}, First: {first_score}")
except KeyError as e:
print(f"Missing key: {e}")
except ValueError as e:
print(f"Invalid value: {e}")
except IndexError as e:
print(f"Index error: {e}")
# Catch parent exception
print("\nUsing generic Exception:")
try:
result = data["count"] / 0
except ZeroDivisionError:
print("Specific: Division by zero")
except Exception as e:
print(f"Generic: {type(e).__name__}: {e}")
# Process list of operations
operations = [
("parse", "123"),
("parse", "abc"),
("divide", 10, 0),
("access", [1, 2], 5)
]
print("\nProcessing operations:")
for op in operations:
try:
if op[0] == "parse":
result = int(op[1])
print(f" Parsed: {result}")
elif op[0] == "divide":
result = op[1] / op[2]
print(f" Divided: {result}")
elif op[0] == "access":
result = op[1][op[2]]
print(f" Accessed: {result}")
except ValueError:
print(f" ValueError in {op}")
except ZeroDivisionError:
print(f" ZeroDivisionError in {op}")
except IndexError:
print(f" IndexError in {op}")
if __name__ == "__main__":
main()
data ← {'name': 'Alice', 'age': '25', 'scores': [85, 90, 78]}
3def main():4 # Parse user input (multiple error types)5 print("Input parsing with multiple exceptions:\n")6 7 data→ {'name': 'Alice', 'age': '25', 'scores': [85, 90, 78]} = {8 "name": "Alice",9 "age": "25",10 "scores": [85, 90, 78]11 }outputInput parsing with multiple exceptions:age_str ← not a number
13# Catch ValueError (bad conversion)14try:15 age_str→ not a number = "not a number"16 #@age_str="30", "invalid"17 age = int(age_strnot a number)18 print(f"Age: {age}")age ← 0
18 print(f"Age: {age}")19except ValueError:20 print("ValueError: Cannot convert to integer")21 age→ 0 = 0outputValueError: Cannot convert to integertry:
23# Catch KeyError (missing key)24try:25 email = data["email"](empty) # key doesn't exist26 print(f"Email: {email}")email ← unknown@example.com
26 print(f"Email: {email}")27except KeyError:28 print("KeyError: 'email' key not found")29 email→ unknown@example.com = "unknown@example.com"outputKeyError: 'email' key not foundprint(" Processing with multiple potential errors:")
37# Multiple exceptions in one try block38print("\nProcessing with multiple potential errors:")output Processing with multiple potential errors:try: # Could raise KeyError
40try:41 # Could raise KeyError42 score_str = data["score"](empty) # missing key43 # Could raise ValueErrorexcept KeyError as e:
50except KeyError as e:51 print(f"Missing key: {e'score'}")52except ValueError as e:outputMissing key: 'score'print(" Using generic Exception:")
57# Catch parent exception58print("\nUsing generic Exception:")output Using generic Exception:try:
60try:61 result = data["count"](empty) / 062except ZeroDivisionError:except Exception as e:
63 print("Specific: Division by zero")64except Exception as e:65 print(f"Generic: {type(e'count').__name__}: {e}")6667# Process list of operationsoutputGeneric: KeyError: 'count' Generic: KeyError: 'count'operations ← [('parse', '123'), ('parse', 'abc'), ('divide', 10, 0), ('access', [1, 2], 5)]
67# Process list of operations68operations→ [('parse', '123'), ('parse', 'abc'), ('divide', 10, 0), ('access', [1, 2], 5)] = [69 ("parse", "123"),70 ("parse", "abc"),71 ("divide", 10, 0),72 ("access", [1, 2], 5)73]7475print("\nProcessing operations:")76for op in operations:output Processing operations:for op in operations:
pass 1 of 475print("\nProcessing operations:")76for op('parse', '123') in operations[('parse', '123'), ('parse', 'abc'), ('divide', 10, 0), ('access', [1, 2], 5)]:77 try:78 if op[0] == "parse":All 4 passes — pass 1 is the card above pass opop[0]op[1]op[2]op[1][op[2]]result1 ('parse', '123') parse 123 — — 123 2 ('parse', 'abc') parse abc — — — 3 ('divide', 10, 0) divide 10 0 — — 4 ('access', [1, 2], 5) access — — (empty) — try:
pass 1 of 476for op in operations:77 try:78 if op[0] == "parse":79 result = int(op[1])All 4 passes — pass 1 is the card above pass op[0]op[1]opop[2]op[1][op[2]]result1 parse 123 — — — 123 2 parse abc ('parse', 'abc') — — — 3 divide 10 ('divide', 10, 0) 0 — — 4 access — ('access', [1, 2], 5) — (empty) — result ← 123
pass 1 of 277try:78 if op[0]parse == "parse":79 result→ 123 = int(op[1]123)80 print(f" Parsed: {result123}")81 elif op[0] == "divide":output Parsed: 123if op[0] == "parse":
pass 2 of 277try:78 if op[0]parse == "parse":79 result = int(op[1]abc)80 print(f" Parsed: {result}")except ValueError:
86 print(f" Accessed: {result}")87except ValueError:88 print(f" ValueError in {op('parse', 'abc')}")89except ZeroDivisionError:output ValueError in ('parse', 'abc')elif op[0] == "divide":
80 print(f" Parsed: {result}")81elif op[0]divide == "divide":82 result = op[1]10 / op[2]083 print(f" Divided: {result}")except ZeroDivisionError:
88 print(f" ValueError in {op}")89except ZeroDivisionError:90 print(f" ZeroDivisionError in {op('divide', 10, 0)}")91except IndexError:output ZeroDivisionError in ('divide', 10, 0)elif op[0] == "access":
83 print(f" Divided: {result}")84elif op[0]access == "access":85 result = op[1][op[2]](empty)86 print(f" Accessed: {result}")except IndexError:
90 print(f" ZeroDivisionError in {op}")91except IndexError:92 print(f" IndexError in {op('access', [1, 2], 5)}")output IndexError in ('access', [1, 2], 5) IndexError in ('access', [1, 2], 5)main()
94if __name__ == "__main__":95 main()
data ← {'name': 'Alice', 'age': '25', 'scores': [85, 90, 78]}
3def main():4 # Parse user input (multiple error types)5 print("Input parsing with multiple exceptions:\n")6 7 data→ {'name': 'Alice', 'age': '25', 'scores': [85, 90, 78]} = {8 "name": "Alice",9 "age": "25",10 "scores": [85, 90, 78]11 }outputInput parsing with multiple exceptions:age_str ← 30, age ← 30
13# Catch ValueError (bad conversion)14try:15 age_str→ 30 = "30"16 age→ 30 = int(age_str30)17 print(f"Age: {age30}")18except ValueError:outputAge: 30try:
22# Catch KeyError (missing key)23try:24 email = data["email"](empty) # key doesn't exist25 print(f"Email: {email}")email ← unknown@example.com
25 print(f"Email: {email}")26except KeyError:27 print("KeyError: 'email' key not found")28 email→ unknown@example.com = "unknown@example.com"outputKeyError: 'email' key not foundprint(" Processing with multiple potential errors:")
31# Multiple exceptions in one try block32print("\nProcessing with multiple potential errors:")output Processing with multiple potential errors:try: # Could raise KeyError
34try:35 # Could raise KeyError36 score_str = data["score"](empty) # missing key37 # Could raise ValueErrorexcept KeyError as e:
44except KeyError as e:45 print(f"Missing key: {e'score'}")46except ValueError as e:outputMissing key: 'score'print(" Using generic Exception:")
51# Catch parent exception52print("\nUsing generic Exception:")output Using generic Exception:try:
54try:55 result = data["count"](empty) / 056except ZeroDivisionError:except Exception as e:
57 print("Specific: Division by zero")58except Exception as e:59 print(f"Generic: {type(e'count').__name__}: {e}")6061# Process list of operationsoutputGeneric: KeyError: 'count' Generic: KeyError: 'count'operations ← [('parse', '123'), ('parse', 'abc'), ('divide', 10, 0), ('access', [1, 2], 5)]
61# Process list of operations62operations→ [('parse', '123'), ('parse', 'abc'), ('divide', 10, 0), ('access', [1, 2], 5)] = [63 ("parse", "123"),64 ("parse", "abc"),65 ("divide", 10, 0),66 ("access", [1, 2], 5)67]6869print("\nProcessing operations:")70for op in operations:output Processing operations:for op in operations:
pass 1 of 469print("\nProcessing operations:")70for op('parse', '123') in operations[('parse', '123'), ('parse', 'abc'), ('divide', 10, 0), ('access', [1, 2], 5)]:71 try:72 if op[0] == "parse":All 4 passes — pass 1 is the card above pass opop[0]op[1]op[2]op[1][op[2]]result1 ('parse', '123') parse 123 — — 123 2 ('parse', 'abc') parse abc — — — 3 ('divide', 10, 0) divide 10 0 — — 4 ('access', [1, 2], 5) access — — (empty) — try:
pass 1 of 470for op in operations:71 try:72 if op[0] == "parse":73 result = int(op[1])All 4 passes — pass 1 is the card above pass op[0]op[1]opop[2]op[1][op[2]]result1 parse 123 — — — 123 2 parse abc ('parse', 'abc') — — — 3 divide 10 ('divide', 10, 0) 0 — — 4 access — ('access', [1, 2], 5) — (empty) — result ← 123
pass 1 of 271try:72 if op[0]parse == "parse":73 result→ 123 = int(op[1]123)74 print(f" Parsed: {result123}")75 elif op[0] == "divide":output Parsed: 123if op[0] == "parse":
pass 2 of 271try:72 if op[0]parse == "parse":73 result = int(op[1]abc)74 print(f" Parsed: {result}")except ValueError:
80 print(f" Accessed: {result}")81except ValueError:82 print(f" ValueError in {op('parse', 'abc')}")83except ZeroDivisionError:output ValueError in ('parse', 'abc')elif op[0] == "divide":
74 print(f" Parsed: {result}")75elif op[0]divide == "divide":76 result = op[1]10 / op[2]077 print(f" Divided: {result}")except ZeroDivisionError:
82 print(f" ValueError in {op}")83except ZeroDivisionError:84 print(f" ZeroDivisionError in {op('divide', 10, 0)}")85except IndexError:output ZeroDivisionError in ('divide', 10, 0)elif op[0] == "access":
77 print(f" Divided: {result}")78elif op[0]access == "access":79 result = op[1][op[2]](empty)80 print(f" Accessed: {result}")except IndexError:
84 print(f" ZeroDivisionError in {op}")85except IndexError:86 print(f" IndexError in {op('access', [1, 2], 5)}")output IndexError in ('access', [1, 2], 5) IndexError in ('access', [1, 2], 5)main()
88if __name__ == "__main__":89 main()
data ← {'name': 'Alice', 'age': '25', 'scores': [85, 90, 78]}
3def main():4 # Parse user input (multiple error types)5 print("Input parsing with multiple exceptions:\n")6 7 data→ {'name': 'Alice', 'age': '25', 'scores': [85, 90, 78]} = {8 "name": "Alice",9 "age": "25",10 "scores": [85, 90, 78]11 }outputInput parsing with multiple exceptions:age_str ← invalid
13# Catch ValueError (bad conversion)14try:15 age_str→ invalid = "invalid"16 age = int(age_strinvalid)17 print(f"Age: {age}")age ← 0
17 print(f"Age: {age}")18except ValueError:19 print("ValueError: Cannot convert to integer")20 age→ 0 = 0outputValueError: Cannot convert to integertry:
22# Catch KeyError (missing key)23try:24 email = data["email"](empty) # key doesn't exist25 print(f"Email: {email}")email ← unknown@example.com
25 print(f"Email: {email}")26except KeyError:27 print("KeyError: 'email' key not found")28 email→ unknown@example.com = "unknown@example.com"outputKeyError: 'email' key not foundprint(" Processing with multiple potential errors:")
31# Multiple exceptions in one try block32print("\nProcessing with multiple potential errors:")output Processing with multiple potential errors:try: # Could raise KeyError
34try:35 # Could raise KeyError36 score_str = data["score"](empty) # missing key37 # Could raise ValueErrorexcept KeyError as e:
44except KeyError as e:45 print(f"Missing key: {e'score'}")46except ValueError as e:outputMissing key: 'score'print(" Using generic Exception:")
51# Catch parent exception52print("\nUsing generic Exception:")output Using generic Exception:try:
54try:55 result = data["count"](empty) / 056except ZeroDivisionError:except Exception as e:
57 print("Specific: Division by zero")58except Exception as e:59 print(f"Generic: {type(e'count').__name__}: {e}")6061# Process list of operationsoutputGeneric: KeyError: 'count' Generic: KeyError: 'count'operations ← [('parse', '123'), ('parse', 'abc'), ('divide', 10, 0), ('access', [1, 2], 5)]
61# Process list of operations62operations→ [('parse', '123'), ('parse', 'abc'), ('divide', 10, 0), ('access', [1, 2], 5)] = [63 ("parse", "123"),64 ("parse", "abc"),65 ("divide", 10, 0),66 ("access", [1, 2], 5)67]6869print("\nProcessing operations:")70for op in operations:output Processing operations:for op in operations:
pass 1 of 469print("\nProcessing operations:")70for op('parse', '123') in operations[('parse', '123'), ('parse', 'abc'), ('divide', 10, 0), ('access', [1, 2], 5)]:71 try:72 if op[0] == "parse":All 4 passes — pass 1 is the card above pass opop[0]op[1]op[2]op[1][op[2]]result1 ('parse', '123') parse 123 — — 123 2 ('parse', 'abc') parse abc — — — 3 ('divide', 10, 0) divide 10 0 — — 4 ('access', [1, 2], 5) access — — (empty) — try:
pass 1 of 470for op in operations:71 try:72 if op[0] == "parse":73 result = int(op[1])All 4 passes — pass 1 is the card above pass op[0]op[1]opop[2]op[1][op[2]]result1 parse 123 — — — 123 2 parse abc ('parse', 'abc') — — — 3 divide 10 ('divide', 10, 0) 0 — — 4 access — ('access', [1, 2], 5) — (empty) — result ← 123
pass 1 of 271try:72 if op[0]parse == "parse":73 result→ 123 = int(op[1]123)74 print(f" Parsed: {result123}")75 elif op[0] == "divide":output Parsed: 123if op[0] == "parse":
pass 2 of 271try:72 if op[0]parse == "parse":73 result = int(op[1]abc)74 print(f" Parsed: {result}")except ValueError:
80 print(f" Accessed: {result}")81except ValueError:82 print(f" ValueError in {op('parse', 'abc')}")83except ZeroDivisionError:output ValueError in ('parse', 'abc')elif op[0] == "divide":
74 print(f" Parsed: {result}")75elif op[0]divide == "divide":76 result = op[1]10 / op[2]077 print(f" Divided: {result}")except ZeroDivisionError:
82 print(f" ValueError in {op}")83except ZeroDivisionError:84 print(f" ZeroDivisionError in {op('divide', 10, 0)}")85except IndexError:output ZeroDivisionError in ('divide', 10, 0)elif op[0] == "access":
77 print(f" Divided: {result}")78elif op[0]access == "access":79 result = op[1][op[2]](empty)80 print(f" Accessed: {result}")except IndexError:
84 print(f" ZeroDivisionError in {op}")85except IndexError:86 print(f" IndexError in {op('access', [1, 2], 5)}")output IndexError in ('access', [1, 2], 5) IndexError in ('access', [1, 2], 5)main()
88if __name__ == "__main__":89 main()
Specific exceptions first, general Exception last. Order matters.
Catch parent exception
Catch parent type to handle all subtypes.
# Catching parent exception types
def main():
# Catch general Exception
print("Catching general Exception:\n")
numbers = [10, 20, 30]
try:
# Could be any type of error
index = 5
value = numbers[index]
result = value / 0
except Exception as e:
# Catches ANY exception
print(f"Caught: {type(e).__name__}")
print(f"Message: {e}")
# Specific vs general order matters
print("\nException handling order:")
data = {"x": "not_a_number"}
try:
num = int(data["y"])
except KeyError:
print("Specific: Missing key")
except ValueError:
print("Specific: Bad value")
except Exception as e:
print(f"General: {type(e).__name__}")
# Access exception details
print("\nException details:")
items = [1, 2, 3]
try:
value = items[10]
except Exception as e:
print(f"Type: {type(e).__name__}")
print(f"Message: {str(e)}")
print(f"Args: {e.args}")
# Multiple operations with general catch
def safe_operate(operation, a, b):
try:
if operation == "divide":
return a / b
elif operation == "get":
return a[b]
elif operation == "parse":
return int(a)
else:
return None
except Exception as e:
print(f" Error in {operation}: {type(e).__name__}")
return None
print("\nSafe operations:")
print(f"divide 10/2: {safe_operate('divide', 10, 2)}")
print(f"divide 10/0: {safe_operate('divide', 10, 0)}")
print(f"get [1,2,3][5]: {safe_operate('get', [1,2,3], 5)}")
print(f"parse 'abc': {safe_operate('parse', 'abc', None)}")
# Catch and re-raise pattern
print("\nLogging then re-raising:")
try:
try:
result = 100 / 0
except ZeroDivisionError as e:
print(f"Logging: {e}")
# Could log to file here
# Then let it propagate
except Exception:
print("Outer handler caught it")
if __name__ == "__main__":
main()
# Catching parent exception types
def main():
# Catch general Exception
print("Catching general Exception:\n")
numbers = [10, 20, 30]
try:
# Could be any type of error
index = 2
value = numbers[index]
result = value / 0
except Exception as e:
# Catches ANY exception
print(f"Caught: {type(e).__name__}")
print(f"Message: {e}")
# Specific vs general order matters
print("\nException handling order:")
data = {"x": "not_a_number"}
try:
num = int(data["y"])
except KeyError:
print("Specific: Missing key")
except ValueError:
print("Specific: Bad value")
except Exception as e:
print(f"General: {type(e).__name__}")
# Access exception details
print("\nException details:")
items = [1, 2, 3]
try:
value = items[10]
except Exception as e:
print(f"Type: {type(e).__name__}")
print(f"Message: {str(e)}")
print(f"Args: {e.args}")
# Multiple operations with general catch
def safe_operate(operation, a, b):
try:
if operation == "divide":
return a / b
elif operation == "get":
return a[b]
elif operation == "parse":
return int(a)
else:
return None
except Exception as e:
print(f" Error in {operation}: {type(e).__name__}")
return None
print("\nSafe operations:")
print(f"divide 10/2: {safe_operate('divide', 10, 2)}")
print(f"divide 10/0: {safe_operate('divide', 10, 0)}")
print(f"get [1,2,3][5]: {safe_operate('get', [1,2,3], 5)}")
print(f"parse 'abc': {safe_operate('parse', 'abc', None)}")
# Catch and re-raise pattern
print("\nLogging then re-raising:")
try:
try:
result = 100 / 0
except ZeroDivisionError as e:
print(f"Logging: {e}")
# Could log to file here
# Then let it propagate
except Exception:
print("Outer handler caught it")
if __name__ == "__main__":
main()
# Catching parent exception types
def main():
# Catch general Exception
print("Catching general Exception:\n")
numbers = [10, 20, 30]
try:
# Could be any type of error
index = 10
value = numbers[index]
result = value / 0
except Exception as e:
# Catches ANY exception
print(f"Caught: {type(e).__name__}")
print(f"Message: {e}")
# Specific vs general order matters
print("\nException handling order:")
data = {"x": "not_a_number"}
try:
num = int(data["y"])
except KeyError:
print("Specific: Missing key")
except ValueError:
print("Specific: Bad value")
except Exception as e:
print(f"General: {type(e).__name__}")
# Access exception details
print("\nException details:")
items = [1, 2, 3]
try:
value = items[10]
except Exception as e:
print(f"Type: {type(e).__name__}")
print(f"Message: {str(e)}")
print(f"Args: {e.args}")
# Multiple operations with general catch
def safe_operate(operation, a, b):
try:
if operation == "divide":
return a / b
elif operation == "get":
return a[b]
elif operation == "parse":
return int(a)
else:
return None
except Exception as e:
print(f" Error in {operation}: {type(e).__name__}")
return None
print("\nSafe operations:")
print(f"divide 10/2: {safe_operate('divide', 10, 2)}")
print(f"divide 10/0: {safe_operate('divide', 10, 0)}")
print(f"get [1,2,3][5]: {safe_operate('get', [1,2,3], 5)}")
print(f"parse 'abc': {safe_operate('parse', 'abc', None)}")
# Catch and re-raise pattern
print("\nLogging then re-raising:")
try:
try:
result = 100 / 0
except ZeroDivisionError as e:
print(f"Logging: {e}")
# Could log to file here
# Then let it propagate
except Exception:
print("Outer handler caught it")
if __name__ == "__main__":
main()
# Catching parent exception types
def main():
# Catch general Exception
print("Catching general Exception:\n")
numbers = [10, 20, 30]
try:
# Could be any type of error
index = 15
value = numbers[index]
result = value / 0
except Exception as e:
# Catches ANY exception
print(f"Caught: {type(e).__name__}")
print(f"Message: {e}")
# Specific vs general order matters
print("\nException handling order:")
data = {"x": "not_a_number"}
try:
num = int(data["y"])
except KeyError:
print("Specific: Missing key")
except ValueError:
print("Specific: Bad value")
except Exception as e:
print(f"General: {type(e).__name__}")
# Access exception details
print("\nException details:")
items = [1, 2, 3]
try:
value = items[10]
except Exception as e:
print(f"Type: {type(e).__name__}")
print(f"Message: {str(e)}")
print(f"Args: {e.args}")
# Multiple operations with general catch
def safe_operate(operation, a, b):
try:
if operation == "divide":
return a / b
elif operation == "get":
return a[b]
elif operation == "parse":
return int(a)
else:
return None
except Exception as e:
print(f" Error in {operation}: {type(e).__name__}")
return None
print("\nSafe operations:")
print(f"divide 10/2: {safe_operate('divide', 10, 2)}")
print(f"divide 10/0: {safe_operate('divide', 10, 0)}")
print(f"get [1,2,3][5]: {safe_operate('get', [1,2,3], 5)}")
print(f"parse 'abc': {safe_operate('parse', 'abc', None)}")
# Catch and re-raise pattern
print("\nLogging then re-raising:")
try:
try:
result = 100 / 0
except ZeroDivisionError as e:
print(f"Logging: {e}")
# Could log to file here
# Then let it propagate
except Exception:
print("Outer handler caught it")
if __name__ == "__main__":
main()
numbers ← [10, 20, 30]
3def main():4 # Catch general Exception5 print("Catching general Exception:\n")6 7 numbers→ [10, 20, 30] = [10, 20, 30]outputCatching general Exception:index ← 5
9try:10 # Could be any type of error11 index→ 5 = 512 #@index=2, 10, 1513 value = numbers[index](empty)14 result = value / 0except Exception as e: # Catches ANY exception
14 result = value / 015except Exception as e:16 # Catches ANY exception17 print(f"Caught: {type(elist index out of range).__name__}")18 print(f"Message: {elist index out of range}")1920#@help h1outputCaught: IndexError Message: list index out of range Message: list index out of rangedata ← {'x': 'not_a_number'}
26# Specific vs general order matters27print("\nException handling order:")2829data→ {'x': 'not_a_number'} = {"x": "not_a_number"}output Exception handling order:try:
31try:32 num = int(data["y"](empty))33except KeyError:except KeyError:
32 num = int(data["y"])33except KeyError:34 print("Specific: Missing key")35except ValueError:outputSpecific: Missing keyitems ← [1, 2, 3]
40# Access exception details41print("\nException details:")4243items→ [1, 2, 3] = [1, 2, 3]output Exception details:try:
45try:46 value = items[10](empty)47except Exception as e:except Exception as e:
46 value = items[10]47except Exception as e:48 print(f"Type: {type(elist index out of range).__name__}")49 print(f"Message: {str(elist index out of range)}")50 print(f"Args: {e.args('list index out of range',)}")5152# Multiple operations with general catchoutputType: IndexError Message: list index out of range Args: ('list index out of range',) Args: ('list index out of range',)print(" Safe operations:")
67print("\nSafe operations:")68print(f"divide 10/2: {safe_operate('divide', 10, 2)}")69print(f"divide 10/0: {safe_operate('divide', 10, 0)}")output Safe operations:def safe_operate(operation, a, b):
pass 1 of 452# Multiple operations with general catch53def safe_operate(operationdivide, a10, b2):54 try:55 if operation == "divide":All 4 passes — pass 1 is the card above pass operationaba[b]1 divide 10 2 — 2 divide 10 0 — 3 get [1, 2, 3] 5 (empty) 4 parse abc None — try:
pass 1 of 453def safe_operate(operation, a, b):54 try:55 if operation == "divide":56 return a / bAll 4 passes — pass 1 is the card above pass operationaba[b]1 divide 10 2 — 2 divide 10 0 — 3 get — — (empty) 4 parse abc — — if operation == "divide":
pass 1 of 254try:55 if operationdivide == "divide":56 return a10 / b257 elif operation == "get":print(f"divide 10/2: {safe_operate('divide', 10, 2)}")
67print("\nSafe operations:")68print(f"divide 10/2: {safe_operate('divide', 10, 2)}")69print(f"divide 10/0: {safe_operate('divide', 10, 0)}")70print(f"get [1,2,3][5]: {safe_operate('get', [1,2,3], 5)}")outputdivide 10/2: 5.0if operation == "divide":
pass 2 of 254try:55 if operationdivide == "divide":56 return a10 / b057 elif operation == "get":except Exception as e:
pass 1 of 362 return None63except Exception as e:64 print(f" Error in {operationdivide}: {type(edivision by zero).__name__}")65 return Noneoutput Error in divide: ZeroDivisionErrorAll 3 passes — pass 1 is the card above pass operatione1 divide division by zero 2 get list index out of range 3 parse invalid literal for int() with base 10: 'abc' print(f"divide 10/0: {safe_operate('divide', 10, 0)}")
68print(f"divide 10/2: {safe_operate('divide', 10, 2)}")69print(f"divide 10/0: {safe_operate('divide', 10, 0)}")70print(f"get [1,2,3][5]: {safe_operate('get', [1,2,3], 5)}")71print(f"parse 'abc': {safe_operate('parse', 'abc', None)}")outputdivide 10/0: Noneelif operation == "get":
56 return a / b57elif operationget == "get":58 return a[b](empty)59elif operation == "parse":print(f"get [1,2,3][5]: {safe_operate('get', [1,2,3], 5)}")
69print(f"divide 10/0: {safe_operate('divide', 10, 0)}")70print(f"get [1,2,3][5]: {safe_operate('get', [1,2,3], 5)}")71print(f"parse 'abc': {safe_operate('parse', 'abc', None)}")outputget [1,2,3][5]: Noneelif operation == "parse":
58 return a[b]59elif operationparse == "parse":60 return int(aabc)61else:print(f"parse 'abc': {safe_operate('parse', 'abc', None)}")
70print(f"get [1,2,3][5]: {safe_operate('get', [1,2,3], 5)}")71print(f"parse 'abc': {safe_operate('parse', 'abc', None)}")7273# Catch and re-raise pattern74print("\nLogging then re-raising:")outputparse 'abc': None Logging then re-raising:except ZeroDivisionError as e:
78 result = 100 / 079except ZeroDivisionError as e:80 print(f"Logging: {edivision by zero}")81 # Could log to file hereoutputLogging: division by zero Logging: division by zeromain()
86if __name__ == "__main__":87 main()
numbers ← [10, 20, 30]
3def main():4 # Catch general Exception5 print("Catching general Exception:\n")6 7 numbers→ [10, 20, 30] = [10, 20, 30]outputCatching general Exception:index ← 2, value ← 30
9try:10 # Could be any type of error11 index→ 2 = 212 value→ 30 = numbers[index]3013 result = value30 / 014except Exception as e:except Exception as e: # Catches ANY exception
13 result = value / 014except Exception as e:15 # Catches ANY exception16 print(f"Caught: {type(edivision by zero).__name__}")17 print(f"Message: {edivision by zero}")18outputCaught: ZeroDivisionError Message: division by zero Message: division by zerodata ← {'x': 'not_a_number'}
20# Specific vs general order matters21print("\nException handling order:")2223data→ {'x': 'not_a_number'} = {"x": "not_a_number"}output Exception handling order:try:
25try:26 num = int(data["y"](empty))27except KeyError:except KeyError:
26 num = int(data["y"])27except KeyError:28 print("Specific: Missing key")29except ValueError:outputSpecific: Missing keyitems ← [1, 2, 3]
34# Access exception details35print("\nException details:")3637items→ [1, 2, 3] = [1, 2, 3]output Exception details:try:
39try:40 value = items[10](empty)41except Exception as e:except Exception as e:
40 value = items[10]41except Exception as e:42 print(f"Type: {type(elist index out of range).__name__}")43 print(f"Message: {str(elist index out of range)}")44 print(f"Args: {e.args('list index out of range',)}")4546# Multiple operations with general catchoutputType: IndexError Message: list index out of range Args: ('list index out of range',) Args: ('list index out of range',)print(" Safe operations:")
61print("\nSafe operations:")62print(f"divide 10/2: {safe_operate('divide', 10, 2)}")63print(f"divide 10/0: {safe_operate('divide', 10, 0)}")output Safe operations:def safe_operate(operation, a, b):
pass 1 of 446# Multiple operations with general catch47def safe_operate(operationdivide, a10, b2):48 try:49 if operation == "divide":All 4 passes — pass 1 is the card above pass operationaba[b]1 divide 10 2 — 2 divide 10 0 — 3 get [1, 2, 3] 5 (empty) 4 parse abc None — try:
pass 1 of 447def safe_operate(operation, a, b):48 try:49 if operation == "divide":50 return a / bAll 4 passes — pass 1 is the card above pass operationaba[b]1 divide 10 2 — 2 divide 10 0 — 3 get — — (empty) 4 parse abc — — if operation == "divide":
pass 1 of 248try:49 if operationdivide == "divide":50 return a10 / b251 elif operation == "get":print(f"divide 10/2: {safe_operate('divide', 10, 2)}")
61print("\nSafe operations:")62print(f"divide 10/2: {safe_operate('divide', 10, 2)}")63print(f"divide 10/0: {safe_operate('divide', 10, 0)}")64print(f"get [1,2,3][5]: {safe_operate('get', [1,2,3], 5)}")outputdivide 10/2: 5.0if operation == "divide":
pass 2 of 248try:49 if operationdivide == "divide":50 return a10 / b051 elif operation == "get":except Exception as e:
pass 1 of 356 return None57except Exception as e:58 print(f" Error in {operationdivide}: {type(edivision by zero).__name__}")59 return Noneoutput Error in divide: ZeroDivisionErrorAll 3 passes — pass 1 is the card above pass operatione1 divide division by zero 2 get list index out of range 3 parse invalid literal for int() with base 10: 'abc' print(f"divide 10/0: {safe_operate('divide', 10, 0)}")
62print(f"divide 10/2: {safe_operate('divide', 10, 2)}")63print(f"divide 10/0: {safe_operate('divide', 10, 0)}")64print(f"get [1,2,3][5]: {safe_operate('get', [1,2,3], 5)}")65print(f"parse 'abc': {safe_operate('parse', 'abc', None)}")outputdivide 10/0: Noneelif operation == "get":
50 return a / b51elif operationget == "get":52 return a[b](empty)53elif operation == "parse":print(f"get [1,2,3][5]: {safe_operate('get', [1,2,3], 5)}")
63print(f"divide 10/0: {safe_operate('divide', 10, 0)}")64print(f"get [1,2,3][5]: {safe_operate('get', [1,2,3], 5)}")65print(f"parse 'abc': {safe_operate('parse', 'abc', None)}")outputget [1,2,3][5]: Noneelif operation == "parse":
52 return a[b]53elif operationparse == "parse":54 return int(aabc)55else:print(f"parse 'abc': {safe_operate('parse', 'abc', None)}")
64print(f"get [1,2,3][5]: {safe_operate('get', [1,2,3], 5)}")65print(f"parse 'abc': {safe_operate('parse', 'abc', None)}")6667# Catch and re-raise pattern68print("\nLogging then re-raising:")outputparse 'abc': None Logging then re-raising:except ZeroDivisionError as e:
72 result = 100 / 073except ZeroDivisionError as e:74 print(f"Logging: {edivision by zero}")75 # Could log to file hereoutputLogging: division by zero Logging: division by zeromain()
80if __name__ == "__main__":81 main()
numbers ← [10, 20, 30]
3def main():4 # Catch general Exception5 print("Catching general Exception:\n")6 7 numbers→ [10, 20, 30] = [10, 20, 30]outputCatching general Exception:index ← 10
9try:10 # Could be any type of error11 index→ 10 = 1012 value = numbers[index](empty)13 result = value / 0except Exception as e: # Catches ANY exception
13 result = value / 014except Exception as e:15 # Catches ANY exception16 print(f"Caught: {type(elist index out of range).__name__}")17 print(f"Message: {elist index out of range}")18outputCaught: IndexError Message: list index out of range Message: list index out of rangedata ← {'x': 'not_a_number'}
20# Specific vs general order matters21print("\nException handling order:")2223data→ {'x': 'not_a_number'} = {"x": "not_a_number"}output Exception handling order:try:
25try:26 num = int(data["y"](empty))27except KeyError:except KeyError:
26 num = int(data["y"])27except KeyError:28 print("Specific: Missing key")29except ValueError:outputSpecific: Missing keyitems ← [1, 2, 3]
34# Access exception details35print("\nException details:")3637items→ [1, 2, 3] = [1, 2, 3]output Exception details:try:
39try:40 value = items[10](empty)41except Exception as e:except Exception as e:
40 value = items[10]41except Exception as e:42 print(f"Type: {type(elist index out of range).__name__}")43 print(f"Message: {str(elist index out of range)}")44 print(f"Args: {e.args('list index out of range',)}")4546# Multiple operations with general catchoutputType: IndexError Message: list index out of range Args: ('list index out of range',) Args: ('list index out of range',)print(" Safe operations:")
61print("\nSafe operations:")62print(f"divide 10/2: {safe_operate('divide', 10, 2)}")63print(f"divide 10/0: {safe_operate('divide', 10, 0)}")output Safe operations:def safe_operate(operation, a, b):
pass 1 of 446# Multiple operations with general catch47def safe_operate(operationdivide, a10, b2):48 try:49 if operation == "divide":All 4 passes — pass 1 is the card above pass operationaba[b]1 divide 10 2 — 2 divide 10 0 — 3 get [1, 2, 3] 5 (empty) 4 parse abc None — try:
pass 1 of 447def safe_operate(operation, a, b):48 try:49 if operation == "divide":50 return a / bAll 4 passes — pass 1 is the card above pass operationaba[b]1 divide 10 2 — 2 divide 10 0 — 3 get — — (empty) 4 parse abc — — if operation == "divide":
pass 1 of 248try:49 if operationdivide == "divide":50 return a10 / b251 elif operation == "get":print(f"divide 10/2: {safe_operate('divide', 10, 2)}")
61print("\nSafe operations:")62print(f"divide 10/2: {safe_operate('divide', 10, 2)}")63print(f"divide 10/0: {safe_operate('divide', 10, 0)}")64print(f"get [1,2,3][5]: {safe_operate('get', [1,2,3], 5)}")outputdivide 10/2: 5.0if operation == "divide":
pass 2 of 248try:49 if operationdivide == "divide":50 return a10 / b051 elif operation == "get":except Exception as e:
pass 1 of 356 return None57except Exception as e:58 print(f" Error in {operationdivide}: {type(edivision by zero).__name__}")59 return Noneoutput Error in divide: ZeroDivisionErrorAll 3 passes — pass 1 is the card above pass operatione1 divide division by zero 2 get list index out of range 3 parse invalid literal for int() with base 10: 'abc' print(f"divide 10/0: {safe_operate('divide', 10, 0)}")
62print(f"divide 10/2: {safe_operate('divide', 10, 2)}")63print(f"divide 10/0: {safe_operate('divide', 10, 0)}")64print(f"get [1,2,3][5]: {safe_operate('get', [1,2,3], 5)}")65print(f"parse 'abc': {safe_operate('parse', 'abc', None)}")outputdivide 10/0: Noneelif operation == "get":
50 return a / b51elif operationget == "get":52 return a[b](empty)53elif operation == "parse":print(f"get [1,2,3][5]: {safe_operate('get', [1,2,3], 5)}")
63print(f"divide 10/0: {safe_operate('divide', 10, 0)}")64print(f"get [1,2,3][5]: {safe_operate('get', [1,2,3], 5)}")65print(f"parse 'abc': {safe_operate('parse', 'abc', None)}")outputget [1,2,3][5]: Noneelif operation == "parse":
52 return a[b]53elif operationparse == "parse":54 return int(aabc)55else:print(f"parse 'abc': {safe_operate('parse', 'abc', None)}")
64print(f"get [1,2,3][5]: {safe_operate('get', [1,2,3], 5)}")65print(f"parse 'abc': {safe_operate('parse', 'abc', None)}")6667# Catch and re-raise pattern68print("\nLogging then re-raising:")outputparse 'abc': None Logging then re-raising:except ZeroDivisionError as e:
72 result = 100 / 073except ZeroDivisionError as e:74 print(f"Logging: {edivision by zero}")75 # Could log to file hereoutputLogging: division by zero Logging: division by zeromain()
80if __name__ == "__main__":81 main()
numbers ← [10, 20, 30]
3def main():4 # Catch general Exception5 print("Catching general Exception:\n")6 7 numbers→ [10, 20, 30] = [10, 20, 30]outputCatching general Exception:index ← 15
9try:10 # Could be any type of error11 index→ 15 = 1512 value = numbers[index](empty)13 result = value / 0except Exception as e: # Catches ANY exception
13 result = value / 014except Exception as e:15 # Catches ANY exception16 print(f"Caught: {type(elist index out of range).__name__}")17 print(f"Message: {elist index out of range}")18outputCaught: IndexError Message: list index out of range Message: list index out of rangedata ← {'x': 'not_a_number'}
20# Specific vs general order matters21print("\nException handling order:")2223data→ {'x': 'not_a_number'} = {"x": "not_a_number"}output Exception handling order:try:
25try:26 num = int(data["y"](empty))27except KeyError:except KeyError:
26 num = int(data["y"])27except KeyError:28 print("Specific: Missing key")29except ValueError:outputSpecific: Missing keyitems ← [1, 2, 3]
34# Access exception details35print("\nException details:")3637items→ [1, 2, 3] = [1, 2, 3]output Exception details:try:
39try:40 value = items[10](empty)41except Exception as e:except Exception as e:
40 value = items[10]41except Exception as e:42 print(f"Type: {type(elist index out of range).__name__}")43 print(f"Message: {str(elist index out of range)}")44 print(f"Args: {e.args('list index out of range',)}")4546# Multiple operations with general catchoutputType: IndexError Message: list index out of range Args: ('list index out of range',) Args: ('list index out of range',)print(" Safe operations:")
61print("\nSafe operations:")62print(f"divide 10/2: {safe_operate('divide', 10, 2)}")63print(f"divide 10/0: {safe_operate('divide', 10, 0)}")output Safe operations:def safe_operate(operation, a, b):
pass 1 of 446# Multiple operations with general catch47def safe_operate(operationdivide, a10, b2):48 try:49 if operation == "divide":All 4 passes — pass 1 is the card above pass operationaba[b]1 divide 10 2 — 2 divide 10 0 — 3 get [1, 2, 3] 5 (empty) 4 parse abc None — try:
pass 1 of 447def safe_operate(operation, a, b):48 try:49 if operation == "divide":50 return a / bAll 4 passes — pass 1 is the card above pass operationaba[b]1 divide 10 2 — 2 divide 10 0 — 3 get — — (empty) 4 parse abc — — if operation == "divide":
pass 1 of 248try:49 if operationdivide == "divide":50 return a10 / b251 elif operation == "get":print(f"divide 10/2: {safe_operate('divide', 10, 2)}")
61print("\nSafe operations:")62print(f"divide 10/2: {safe_operate('divide', 10, 2)}")63print(f"divide 10/0: {safe_operate('divide', 10, 0)}")64print(f"get [1,2,3][5]: {safe_operate('get', [1,2,3], 5)}")outputdivide 10/2: 5.0if operation == "divide":
pass 2 of 248try:49 if operationdivide == "divide":50 return a10 / b051 elif operation == "get":except Exception as e:
pass 1 of 356 return None57except Exception as e:58 print(f" Error in {operationdivide}: {type(edivision by zero).__name__}")59 return Noneoutput Error in divide: ZeroDivisionErrorAll 3 passes — pass 1 is the card above pass operatione1 divide division by zero 2 get list index out of range 3 parse invalid literal for int() with base 10: 'abc' print(f"divide 10/0: {safe_operate('divide', 10, 0)}")
62print(f"divide 10/2: {safe_operate('divide', 10, 2)}")63print(f"divide 10/0: {safe_operate('divide', 10, 0)}")64print(f"get [1,2,3][5]: {safe_operate('get', [1,2,3], 5)}")65print(f"parse 'abc': {safe_operate('parse', 'abc', None)}")outputdivide 10/0: Noneelif operation == "get":
50 return a / b51elif operationget == "get":52 return a[b](empty)53elif operation == "parse":print(f"get [1,2,3][5]: {safe_operate('get', [1,2,3], 5)}")
63print(f"divide 10/0: {safe_operate('divide', 10, 0)}")64print(f"get [1,2,3][5]: {safe_operate('get', [1,2,3], 5)}")65print(f"parse 'abc': {safe_operate('parse', 'abc', None)}")outputget [1,2,3][5]: Noneelif operation == "parse":
52 return a[b]53elif operationparse == "parse":54 return int(aabc)55else:print(f"parse 'abc': {safe_operate('parse', 'abc', None)}")
64print(f"get [1,2,3][5]: {safe_operate('get', [1,2,3], 5)}")65print(f"parse 'abc': {safe_operate('parse', 'abc', None)}")6667# Catch and re-raise pattern68print("\nLogging then re-raising:")outputparse 'abc': None Logging then re-raising:except ZeroDivisionError as e:
72 result = 100 / 073except ZeroDivisionError as e:74 print(f"Logging: {edivision by zero}")75 # Could log to file hereoutputLogging: division by zero Logging: division by zeromain()
80if __name__ == "__main__":81 main()
Catching Exception catches (almost) everything. Be specific when possible.
Finally block
Code that always runs, even after exception.
# Finally block for cleanup
def main():
# Finally always executes
print("Finally block basics:\n")
try:
print("In try block")
result = 10 / 2
print(f"Result: {result}")
except ZeroDivisionError:
print("In except block")
finally:
print("In finally block (always runs)")
# Finally runs even with exception
print("\nWith exception:")
try:
print("In try block")
result = 10 / 0 # raises error
print("This won't print")
except ZeroDivisionError:
print("In except block")
finally:
print("In finally block (runs despite error)")
# Simulated file handling
def process_file(filename):
file_handle = None
try:
print(f"\nOpening {filename}")
file_handle = f"<handle:{filename}>"
if "error" in filename:
raise ValueError("Simulated read error")
print(f"Processing {filename}")
return "SUCCESS"
except ValueError as e:
print(f"Error: {e}")
return "FAILED"
finally:
if file_handle:
print(f"Closing {file_handle}")
result1 = process_file("data.txt")
print(f"Result: {result1}")
result2 = process_file("error.txt")
print(f"Result: {result2}")
# Try-except-else-finally (complete form)
print("\nComplete form:")
value = "123"
try:
num = int(value)
except ValueError:
print("Conversion failed")
num = 0
else:
# Runs only if NO exception
print(f"Conversion succeeded: {num}")
finally:
print("Cleanup complete")
# Resource tracking
class Resource:
def __init__(self, name):
self.name = name
print(f" Acquired: {name}")
def close(self):
print(f" Released: {self.name}")
print("\nResource management:")
resource = None
try:
resource = Resource("Database")
# Simulate work
items = [1, 2, 3]
value = items[5] # Error!
except IndexError:
print(" Error during processing")
finally:
if resource:
resource.close()
if __name__ == "__main__":
main()
# Finally block for cleanup
def main():
# Finally always executes
print("Finally block basics:\n")
try:
print("In try block")
result = 10 / 2
print(f"Result: {result}")
except ZeroDivisionError:
print("In except block")
finally:
print("In finally block (always runs)")
# Finally runs even with exception
print("\nWith exception:")
try:
print("In try block")
result = 10 / 0 # raises error
print("This won't print")
except ZeroDivisionError:
print("In except block")
finally:
print("In finally block (runs despite error)")
# Simulated file handling
def process_file(filename):
file_handle = None
try:
print(f"\nOpening {filename}")
file_handle = f"<handle:{filename}>"
if "error" in filename:
raise ValueError("Simulated read error")
print(f"Processing {filename}")
return "SUCCESS"
except ValueError as e:
print(f"Error: {e}")
return "FAILED"
finally:
if file_handle:
print(f"Closing {file_handle}")
result1 = process_file("data.txt")
print(f"Result: {result1}")
result2 = process_file("error.txt")
print(f"Result: {result2}")
# Try-except-else-finally (complete form)
print("\nComplete form:")
value = "456"
try:
num = int(value)
except ValueError:
print("Conversion failed")
num = 0
else:
# Runs only if NO exception
print(f"Conversion succeeded: {num}")
finally:
print("Cleanup complete")
# Resource tracking
class Resource:
def __init__(self, name):
self.name = name
print(f" Acquired: {name}")
def close(self):
print(f" Released: {self.name}")
print("\nResource management:")
resource = None
try:
resource = Resource("Database")
# Simulate work
items = [1, 2, 3]
value = items[5] # Error!
except IndexError:
print(" Error during processing")
finally:
if resource:
resource.close()
if __name__ == "__main__":
main()
# Finally block for cleanup
def main():
# Finally always executes
print("Finally block basics:\n")
try:
print("In try block")
result = 10 / 2
print(f"Result: {result}")
except ZeroDivisionError:
print("In except block")
finally:
print("In finally block (always runs)")
# Finally runs even with exception
print("\nWith exception:")
try:
print("In try block")
result = 10 / 0 # raises error
print("This won't print")
except ZeroDivisionError:
print("In except block")
finally:
print("In finally block (runs despite error)")
# Simulated file handling
def process_file(filename):
file_handle = None
try:
print(f"\nOpening {filename}")
file_handle = f"<handle:{filename}>"
if "error" in filename:
raise ValueError("Simulated read error")
print(f"Processing {filename}")
return "SUCCESS"
except ValueError as e:
print(f"Error: {e}")
return "FAILED"
finally:
if file_handle:
print(f"Closing {file_handle}")
result1 = process_file("data.txt")
print(f"Result: {result1}")
result2 = process_file("error.txt")
print(f"Result: {result2}")
# Try-except-else-finally (complete form)
print("\nComplete form:")
value = "abc"
try:
num = int(value)
except ValueError:
print("Conversion failed")
num = 0
else:
# Runs only if NO exception
print(f"Conversion succeeded: {num}")
finally:
print("Cleanup complete")
# Resource tracking
class Resource:
def __init__(self, name):
self.name = name
print(f" Acquired: {name}")
def close(self):
print(f" Released: {self.name}")
print("\nResource management:")
resource = None
try:
resource = Resource("Database")
# Simulate work
items = [1, 2, 3]
value = items[5] # Error!
except IndexError:
print(" Error during processing")
finally:
if resource:
resource.close()
if __name__ == "__main__":
main()
def main(): # Finally always executes
3def main():4 # Finally always executes5 print("Finally block basics:\n")outputFinally block basics:result ← 5.0
7try:8 print("In try block")9 result→ 5.0 = 10 / 210 print(f"Result: {result5.0}")11except ZeroDivisionError:outputIn try block Result: 5.0finally:
11except ZeroDivisionError:12 print("In except block")13finally:14 print("In finally block (always runs)")1516# Finally runs even with exceptionoutputIn finally block (always runs) In finally block (always runs)print(" With exception:")
16# Finally runs even with exception17print("\nWith exception:")output With exception:try:
19try:20 print("In try block")21 result = 10 / 0 # raises error22 print("This won't print")outputIn try blockexcept ZeroDivisionError:
22 print("This won't print")23except ZeroDivisionError:24 print("In except block")25finally:outputIn except blockfinally:
23except ZeroDivisionError:24 print("In except block")25finally:26 print("In finally block (runs despite error)")2728#@help h1outputIn finally block (runs despite error) In finally block (runs despite error)result1 = process_file("data.txt")
54result1 = process_file("data.txt")55print(f"Result: {result1}")file_handle ← None
pass 1 of 234# Simulated file handling35def process_file(filenamedata.txt):36 file_handle→ None = None37 try:file_handle ← <handle:data.txt>
pass 1 of 236file_handle = None37try:38 print(f"\nOpening {filenamedata.txt}")39 file_handle→ <handle:data.txt> = f"<handle:{filenamedata.txt}>"40 41 if "error" in filename:42 raise ValueError("Simulated read error")43 44 print(f"Processing {filenamedata.txt}")45 return "SUCCESS"output Opening data.txt Processing data.txtif file_handle:
pass 1 of 250finally:51 if file_handle<handle:data.txt>:52 print(f"Closing {file_handle<handle:data.txt>}")outputClosing <handle:data.txt> Closing <handle:data.txt>result1 ← SUCCESS
54result1→ SUCCESS = process_file("data.txt")55print(f"Result: {result1SUCCESS}")5657result2 = process_file("error.txt")58print(f"Result: {result2}")outputResult: SUCCESSfile_handle ← None
pass 2 of 234# Simulated file handling35def process_file(filenameerror.txt):36 file_handle→ None = None37 try:file_handle ← <handle:error.txt>
pass 2 of 236file_handle = None37try:38 print(f"\nOpening {filenameerror.txt}")39 file_handle→ <handle:error.txt> = f"<handle:{filenameerror.txt}>"output Opening error.txtif "error" in filename:
41if "error" in filenameerror.txt:42 raise ValueError("Simulated read error")except ValueError as e:
47except ValueError as e:48 print(f"Error: {eSimulated read error}")49 return "FAILED"50finally:outputError: Simulated read errorif file_handle:
pass 2 of 250finally:51 if file_handle<handle:error.txt>:52 print(f"Closing {file_handle<handle:error.txt>}")outputClosing <handle:error.txt> Closing <handle:error.txt>result2 ← FAILED, value ← 123
57result2→ FAILED = process_file("error.txt")58print(f"Result: {result2FAILED}")5960# Try-except-else-finally (complete form)61print("\nComplete form:")6263value→ 123 = "123"64#@value="456", "abc"outputResult: FAILED Complete form:num ← 123
66try:67 num→ 123 = int(value123)68except ValueError:else: # Runs only if NO exception
69 print("Conversion failed")70 num = 071else:72 # Runs only if NO exception73 print(f"Conversion succeeded: {num123}")74finally:outputConversion succeeded: 123finally:
72 # Runs only if NO exception73 print(f"Conversion succeeded: {num}")74finally:75 print("Cleanup complete")7677# Resource trackingoutputCleanup complete Cleanup completeresource ← None
77# Resource tracking78class Resource:79 def __init__(self, name):80 self.name = name81 print(f" Acquired: {name}")82 83 def close(self):84 print(f" Released: {self.name}")8586print("\nResource management:")8788resource→ None = None89try:output Resource management:self.name ← Database
78class Resource:79 def __init__(self<__main__.main.<locals>.Resource object at ⟨addr A⟩>, nameDatabase):80 self.name→ Database = nameDatabase81 print(f" Acquired: {nameDatabase}")output Acquired: Databaseresource ← <__main__.main.<locals>.Resource object at ⟨addr A⟩>
89try:90 resource→ <__main__.main.<locals>.Resource object at ⟨addr A⟩> = Resource("Database")91 # Simulate work92 items→ [1, 2, 3] = [1, 2, 3]93 value = items[5](empty) # Error!94except IndexError:except IndexError:
93 value = items[5] # Error!94except IndexError:95 print(" Error during processing")96finally:output Error during processingif resource:
96finally:97 if resource<__main__.main.<locals>.Resource object at ⟨addr A⟩>:98 resource<__main__.main.<locals>.Resource object at ⟨addr A⟩>.close()def close(self):
83def close(self<__main__.main.<locals>.Resource object at ⟨addr A⟩>):84 print(f" Released: {self.nameDatabase}")output Released: Databaseresource.close()
97if resource:98 resource<__main__.main.<locals>.Resource object at ⟨addr A⟩>.close()main()
100if __name__ == "__main__":101 main()
def main(): # Finally always executes
3def main():4 # Finally always executes5 print("Finally block basics:\n")outputFinally block basics:result ← 5.0
7try:8 print("In try block")9 result→ 5.0 = 10 / 210 print(f"Result: {result5.0}")11except ZeroDivisionError:outputIn try block Result: 5.0finally:
11except ZeroDivisionError:12 print("In except block")13finally:14 print("In finally block (always runs)")1516# Finally runs even with exceptionoutputIn finally block (always runs) In finally block (always runs)print(" With exception:")
16# Finally runs even with exception17print("\nWith exception:")output With exception:try:
19try:20 print("In try block")21 result = 10 / 0 # raises error22 print("This won't print")outputIn try blockexcept ZeroDivisionError:
22 print("This won't print")23except ZeroDivisionError:24 print("In except block")25finally:outputIn except blockfinally:
23except ZeroDivisionError:24 print("In except block")25finally:26 print("In finally block (runs despite error)")27outputIn finally block (runs despite error) In finally block (runs despite error)result1 = process_file("data.txt")
49result1 = process_file("data.txt")50print(f"Result: {result1}")file_handle ← None
pass 1 of 229# Simulated file handling30def process_file(filenamedata.txt):31 file_handle→ None = None32 try:file_handle ← <handle:data.txt>
pass 1 of 231file_handle = None32try:33 print(f"\nOpening {filenamedata.txt}")34 file_handle→ <handle:data.txt> = f"<handle:{filenamedata.txt}>"35 36 if "error" in filename:37 raise ValueError("Simulated read error")38 39 print(f"Processing {filenamedata.txt}")40 return "SUCCESS"output Opening data.txt Processing data.txtif file_handle:
pass 1 of 245finally:46 if file_handle<handle:data.txt>:47 print(f"Closing {file_handle<handle:data.txt>}")outputClosing <handle:data.txt> Closing <handle:data.txt>result1 ← SUCCESS
49result1→ SUCCESS = process_file("data.txt")50print(f"Result: {result1SUCCESS}")5152result2 = process_file("error.txt")53print(f"Result: {result2}")outputResult: SUCCESSfile_handle ← None
pass 2 of 229# Simulated file handling30def process_file(filenameerror.txt):31 file_handle→ None = None32 try:file_handle ← <handle:error.txt>
pass 2 of 231file_handle = None32try:33 print(f"\nOpening {filenameerror.txt}")34 file_handle→ <handle:error.txt> = f"<handle:{filenameerror.txt}>"output Opening error.txtif "error" in filename:
36if "error" in filenameerror.txt:37 raise ValueError("Simulated read error")except ValueError as e:
42except ValueError as e:43 print(f"Error: {eSimulated read error}")44 return "FAILED"45finally:outputError: Simulated read errorif file_handle:
pass 2 of 245finally:46 if file_handle<handle:error.txt>:47 print(f"Closing {file_handle<handle:error.txt>}")outputClosing <handle:error.txt> Closing <handle:error.txt>result2 ← FAILED, value ← 456
52result2→ FAILED = process_file("error.txt")53print(f"Result: {result2FAILED}")5455# Try-except-else-finally (complete form)56print("\nComplete form:")5758value→ 456 = "456"outputResult: FAILED Complete form:num ← 456
60try:61 num→ 456 = int(value456)62except ValueError:else: # Runs only if NO exception
63 print("Conversion failed")64 num = 065else:66 # Runs only if NO exception67 print(f"Conversion succeeded: {num456}")68finally:outputConversion succeeded: 456finally:
66 # Runs only if NO exception67 print(f"Conversion succeeded: {num}")68finally:69 print("Cleanup complete")7071# Resource trackingoutputCleanup complete Cleanup completeresource ← None
71# Resource tracking72class Resource:73 def __init__(self, name):74 self.name = name75 print(f" Acquired: {name}")76 77 def close(self):78 print(f" Released: {self.name}")7980print("\nResource management:")8182resource→ None = None83try:output Resource management:self.name ← Database
72class Resource:73 def __init__(self<__main__.main.<locals>.Resource object at ⟨addr A⟩>, nameDatabase):74 self.name→ Database = nameDatabase75 print(f" Acquired: {nameDatabase}")output Acquired: Databaseresource ← <__main__.main.<locals>.Resource object at ⟨addr A⟩>
83try:84 resource→ <__main__.main.<locals>.Resource object at ⟨addr A⟩> = Resource("Database")85 # Simulate work86 items→ [1, 2, 3] = [1, 2, 3]87 value = items[5](empty) # Error!88except IndexError:except IndexError:
87 value = items[5] # Error!88except IndexError:89 print(" Error during processing")90finally:output Error during processingif resource:
90finally:91 if resource<__main__.main.<locals>.Resource object at ⟨addr A⟩>:92 resource<__main__.main.<locals>.Resource object at ⟨addr A⟩>.close()def close(self):
77def close(self<__main__.main.<locals>.Resource object at ⟨addr A⟩>):78 print(f" Released: {self.nameDatabase}")output Released: Databaseresource.close()
91if resource:92 resource<__main__.main.<locals>.Resource object at ⟨addr A⟩>.close()main()
94if __name__ == "__main__":95 main()
def main(): # Finally always executes
3def main():4 # Finally always executes5 print("Finally block basics:\n")outputFinally block basics:result ← 5.0
7try:8 print("In try block")9 result→ 5.0 = 10 / 210 print(f"Result: {result5.0}")11except ZeroDivisionError:outputIn try block Result: 5.0finally:
11except ZeroDivisionError:12 print("In except block")13finally:14 print("In finally block (always runs)")1516# Finally runs even with exceptionoutputIn finally block (always runs) In finally block (always runs)print(" With exception:")
16# Finally runs even with exception17print("\nWith exception:")output With exception:try:
19try:20 print("In try block")21 result = 10 / 0 # raises error22 print("This won't print")outputIn try blockexcept ZeroDivisionError:
22 print("This won't print")23except ZeroDivisionError:24 print("In except block")25finally:outputIn except blockfinally:
23except ZeroDivisionError:24 print("In except block")25finally:26 print("In finally block (runs despite error)")27outputIn finally block (runs despite error) In finally block (runs despite error)result1 = process_file("data.txt")
49result1 = process_file("data.txt")50print(f"Result: {result1}")file_handle ← None
pass 1 of 229# Simulated file handling30def process_file(filenamedata.txt):31 file_handle→ None = None32 try:file_handle ← <handle:data.txt>
pass 1 of 231file_handle = None32try:33 print(f"\nOpening {filenamedata.txt}")34 file_handle→ <handle:data.txt> = f"<handle:{filenamedata.txt}>"35 36 if "error" in filename:37 raise ValueError("Simulated read error")38 39 print(f"Processing {filenamedata.txt}")40 return "SUCCESS"output Opening data.txt Processing data.txtif file_handle:
pass 1 of 245finally:46 if file_handle<handle:data.txt>:47 print(f"Closing {file_handle<handle:data.txt>}")outputClosing <handle:data.txt> Closing <handle:data.txt>result1 ← SUCCESS
49result1→ SUCCESS = process_file("data.txt")50print(f"Result: {result1SUCCESS}")5152result2 = process_file("error.txt")53print(f"Result: {result2}")outputResult: SUCCESSfile_handle ← None
pass 2 of 229# Simulated file handling30def process_file(filenameerror.txt):31 file_handle→ None = None32 try:file_handle ← <handle:error.txt>
pass 2 of 231file_handle = None32try:33 print(f"\nOpening {filenameerror.txt}")34 file_handle→ <handle:error.txt> = f"<handle:{filenameerror.txt}>"output Opening error.txtif "error" in filename:
36if "error" in filenameerror.txt:37 raise ValueError("Simulated read error")except ValueError as e:
42except ValueError as e:43 print(f"Error: {eSimulated read error}")44 return "FAILED"45finally:outputError: Simulated read errorif file_handle:
pass 2 of 245finally:46 if file_handle<handle:error.txt>:47 print(f"Closing {file_handle<handle:error.txt>}")outputClosing <handle:error.txt> Closing <handle:error.txt>result2 ← FAILED, value ← abc
52result2→ FAILED = process_file("error.txt")53print(f"Result: {result2FAILED}")5455# Try-except-else-finally (complete form)56print("\nComplete form:")5758value→ abc = "abc"outputResult: FAILED Complete form:try:
60try:61 num = int(valueabc)62except ValueError:num ← 0
61 num = int(value)62except ValueError:63 print("Conversion failed")64 num→ 0 = 065else:outputConversion failedfinally:
66 # Runs only if NO exception67 print(f"Conversion succeeded: {num}")68finally:69 print("Cleanup complete")7071# Resource trackingoutputCleanup complete Cleanup completeresource ← None
71# Resource tracking72class Resource:73 def __init__(self, name):74 self.name = name75 print(f" Acquired: {name}")76 77 def close(self):78 print(f" Released: {self.name}")7980print("\nResource management:")8182resource→ None = None83try:output Resource management:self.name ← Database
72class Resource:73 def __init__(self<__main__.main.<locals>.Resource object at ⟨addr A⟩>, nameDatabase):74 self.name→ Database = nameDatabase75 print(f" Acquired: {nameDatabase}")output Acquired: Databaseresource ← <__main__.main.<locals>.Resource object at ⟨addr A⟩>
83try:84 resource→ <__main__.main.<locals>.Resource object at ⟨addr A⟩> = Resource("Database")85 # Simulate work86 items→ [1, 2, 3] = [1, 2, 3]87 value = items[5](empty) # Error!88except IndexError:except IndexError:
87 value = items[5] # Error!88except IndexError:89 print(" Error during processing")90finally:output Error during processingif resource:
90finally:91 if resource<__main__.main.<locals>.Resource object at ⟨addr A⟩>:92 resource<__main__.main.<locals>.Resource object at ⟨addr A⟩>.close()def close(self):
77def close(self<__main__.main.<locals>.Resource object at ⟨addr A⟩>):78 print(f" Released: {self.nameDatabase}")output Released: Databaseresource.close()
91if resource:92 resource<__main__.main.<locals>.Resource object at ⟨addr A⟩>.close()main()
94if __name__ == "__main__":95 main()
finally: runs whether exception occurred or not. Good for cleanup.
Exercise: practical.py
Build a robust input parser with complete exception handling