Design a Defensive Function Contract
Separate validation, computation and failure handling.
By BizAIPro Learning · Prerequisites: Summarize a Collection with a Loop
What you will learn
- Describe accepted input
- Raise a meaningful error
- Test zero and invalid values locally
Define a narrow contract
This function accepts a non-negative integer quantity. It rejects bool even though Python bool is a subclass of int, because True is not a useful quantity for this product. A clear contract makes surprising inputs easier to handle consistently.
Separate the checks
Check the type before comparing the value. If validation fails, raise ValueError with a message explaining what is needed. This makes failure visible to the caller. Avoid catching every possible exception and returning 0, which could disguise a programming mistake as a valid price.
Test defined boundaries
The example checks an ordinary quantity and zero. Add local tests for -1, True and the string "3". The expected result for these inputs is a validation error. Write tests using the standard library unittest module when the project grows beyond a small exploratory script.
Keep evidence reproducible
A portfolio project should include its Python version requirement, command to run, sample input and test command. Do not include private client data in examples. Use invented non-sensitive amounts. A repository with readable code and tests lets a reviewer evaluate your engineering decisions.
Project checkpoint
Finish the expense summary by separating parsing, validation and reporting. Handle an unreadable file, empty input and invalid amount without dropping the user’s original record. Document what the script does not support. These are engineering habits; completing this small course is not a professional qualification.
Read the example
def item_count(quantity):
if type(quantity) is not int or quantity < 0:
raise ValueError("quantity must be a non-negative integer")
return quantity
assert item_count(3) == 3
assert item_count(0) == 0
print("Checks passed")Line-by-line explanation
- def introduces the function.
- type(quantity) is not int rejects bool and text.
- raise reports a violated contract.
- The assertions document two accepted examples.
Expected output
Checks passed
Common mistakes to avoid
- Returning 0 for every exception
- Accepting True as a business quantity unintentionally
- Claiming a small example covers all production cases
Run this script on your computer
Python is not executed in this browser. Install Python 3 from the official Python website, save the script and run python bizaipro-lesson.py or python3 bizaipro-lesson.py.
def item_count(quantity):
if type(quantity) is not int or quantity < 0:
raise ValueError("quantity must be a non-negative integer")
return quantity
assert item_count(3) == 3
assert item_count(0) == 0
print("Checks passed")Check the expected output in the lesson, then complete the output-prediction assessment below.
Recognize a validation failure
The defensive function raises ValueError for a negative integer. Enter the exception class raised by item_count(-1). This is a knowledge assessment, not remote Python execution.
What should item_count(-1) do?
Summary & next step
- Can you now describe accepted input?
- Can you now raise a meaningful error?
- Can you now test zero and invalid values locally?
Complete the exercise and pass the knowledge check to complete this lesson. Guest progress stays on this browser and does not sync across devices.

