Python Exceptions and Error Handling Study Guide
Syntax Errors vs. Runtime Errors
- Exceptions represent errors or problems in code execution where something has gone wrong that ideally requires a programmatic solution.
- Syntax Errors:
- Occur when typed code violates the grammatical rules of the Python language.
- Example: Running
hello.PyinVersus Codewith the codeprint("hello, worldresults inSyntaxError: unterminated string literal. - An unterminated string literal means a sequence of text (
stror literal string) was started with a quotation mark but was not terminated before the end of the line. - Syntax errors cannot be caught or handled at runtime by defensive code; they must be manually fixed directly in the source code file before execution.
- Runtime Errors:
- Errors that occur dynamically while the program is running.
- Arise due to unpredictable user input, requiring defensive programming to anticipate mistakes or malicious input.
Handling Input Errors with Try and Except
- Input conversion behavior in
number.Py:- Basic code structure to prompt for an integer :
python x = int(input("what's x? ")) print(f"x is {x}") - Testing corner cases:
- Positive integer: Inputting prints
x is 50. - Zero: Inputting prints
x is 0. - Negative integer: Inputting prints
x is -1. - Non-numeric string: Inputting
catcauses a runtime error.
- Basic code structure to prompt for an integer :
- Understanding
ValueError:- Output message:
ValueError: invalid literal for int() with base 10: 'cat'. - Invalid literal: The supplied text string literally cannot be converted to an integer.
- Base 10: Refers to the standard decimal number system used by
int()by default.
- Output message:
- Exception handling using
tryandexcept:try: Block used to attempt executing code that might raise an exception.except: Block used to catch and respond to specific exceptions.- Capitalization rule: Exception class names are case-sensitive (e.g.,
ValueErrorrequires capitalVand capitalE). - Indentation rule: Code inside
tryandexceptblocks must be indented by spaces. - Basic implementation catching
ValueError:python try: x = int(input("what's x? ")) print(f"x is {x}") except ValueError: print("x is not an integer")
Variable Scope, Name Errors, and the Else Block
- Best practice for
tryblocks:- Minimize code within the
tryblock to only include lines capable of raising the specific target exception. - Printing does not raise a
ValueError, so it should reside outside thetryblock.
- Minimize code within the
- Cause of
NameError:- Moving
print(f"x is {x}")belowexceptwithout anelseblock:python try: x = int(input("what's x? ")) except ValueError: print("x is not an integer") print(f"x is {x}") - Entering
catproducesNameError: name 'x' is not definedon line - Assignment order of operations:
- In
x = int(input(...)), the right-hand side of the=operator evaluates first. int()fails and raises aValueErrorbefore completing assignment to the left-hand side variablex.- Control jumps straight to
except, leaving completely undefined when line attempts to reference it.
- Moving
- Utilizing the
elseblock:else: Executes only if the precedingtryblock completes successfully without raising exceptions.- Refactored code structure using
else:python try: x = int(input("what's x? ")) except ValueError: print("x is not an integer") else: print(f"x is {x}")
Reprompting with Loops and Break Statements
- Continually prompting users using loops:
- Replacing immediate exit behavior with an infinite loop (
while True) to re-prompt until valid input is given.
- Replacing immediate exit behavior with an infinite loop (
- Using
breakinsideelse:
while True:
try:
x = int(input("what's x? "))
except ValueError:
print("x is not an integer")
else:
break
print(f"x is {x}")
```
* Alternative loop design placing `break` directly inside `try`:
python while True: try: x = int(input("what's x? ")) break except ValueError: print("x is not an integer")
print(f"x is {x}") ```
- Execution logic: If
int()succeeds, line execution continues tobreakto exit the loop. Ifint()raises aValueError, execution jumps immediately toexcept, skippingbreakentirely.
Modularizing Code with Custom Functions and Return Values
- Encapsulating input logic into a reusable function
get_int():
def main():
x = get_int()
print(f"x is {x}")
def get_int():
while True:
try:
x = int(input("what's x? "))
except ValueError:
print("x is not an integer")
else:
return x
main()
```
* `return` vs. `break` behavior:
* `return` exits the function entirely and handed back a value, automatically terminating any active loops in the process.
* Tightening implementation by eliminating intermediate variables:
python def get_int(): while True: try: return int(input("what's x? ")) except ValueError: print("x is not an integer") ```
Ignoring Exceptions with Pass and Adding Function Parameters
Silencing errors with
pass:pass: Keyword used to catch an exception silently without printing messages or interrupting loop execution.- Silent re-prompt implementation:
python def get_int(): while True: try: return int(input("what's x? ")) except ValueError: pass
Parameterizing prompts for reusability:
- Avoid hardcoding prompt strings like
"what's x?"inside generic helper functions. - Definitions:
- Caller: The function making a call to another function (e.g.,
main()). - Callee: The function being invoked (e.g.,
get_int()). - Dynamic function implementation: ```python def main(): x = get_int("what's x? ") print(f"x is {x}")
def get_int(prompt): while True: try: return int(input(prompt)) except ValueError: pass
main() ```
- Avoid hardcoding prompt strings like
Questions & Discussion
- Question: What is an interpreter? When coding in an integrated IDE, can we code in an interpreter? What if the user types something that is not an integer?
- Response: Programs must be written defensively because attempting to convert invalid non-integer string input using
int()causes runtime errors. Corner cases such as positive integers, zero (), negative numbers (), and non-numeric strings (cat) should be tested routinely.
- Response: Programs must be written defensively because attempting to convert invalid non-integer string input using
- Question: To use the
exceptblock, do you need to know the type of error in advance? What if you cannot anticipate the specific type of error?- Response: Omitting the specific error type (e.g., writing bare
except:) catches all exceptions. However, this is bad practice and lazy because it hides bugs and makes proper error resolution difficult. Although official documentation does not always explicitly list every error a function can raise, identifying explicit exceptions becomes easier with experience.
- Response: Omitting the specific error type (e.g., writing bare
- Question: Is the scope of variable restricted strictly between the
tryblock?- Response: Scope refers to the region of code where a variable exists. Unlike languages like C, C++, or Java (where curly braces strictly define local block scope), Python variables assigned inside
tryblocks remain defined outside the block once assigned. TheNameErroroccurs because the assignment operator failed to evaluate due to the error, not because of block scope rules.
- Response: Scope refers to the region of code where a variable exists. Unlike languages like C, C++, or Java (where curly braces strictly define local block scope), Python variables assigned inside
- Question: Can the explanation of
NameErrorbe repeated?- Response: In
x = int(input(...)), the right side evaluates first. Ifint()raisesValueError, control jumps immediately toexcept, skipping assignment to . Calling later fails withNameErrorbecause was never assigned a value.
- Response: In
- Question: Can
breakbe used insideexceptorelseblocks, or only in loops?- Response:
breakcan be used inside any loop, including insideif,elif,else, ortry/exceptstatements nested within a loop.
- Response:
- Question: Can you elaborate on Python indentation rules?
- Response: Indentation in Python syntactically defines logical block relationships. Statements indented under
def,while,try, orexceptbelong exclusively to that parent block. Indentation standardly uses spaces per nesting level (e.g., , , spaces).
- Response: Indentation in Python syntactically defines logical block relationships. Statements indented under
- Question: Once
passis executed, can the caller still learn about the error through a system variable?- Response: No, using
passsuppresses the exception entirely, so calling routines likemain()remain completely unaware that an error occurred.
- Response: No, using
- Question: Is using string methods like
isnumeric()different from usingtry/except?- Response:
isnumeric()allows pre-checking strings with conditionals (if/else) before conversion. While valid, the traditional "Pythonic" design philosophy prefers attempting the operation inside atryblock and handling exceptions if they occur.
- Response: