Put a Python Boundary Around the Database · capstone
Capstone project: Project: Complete the Catalog Database Module
One caller can now complete a checkout-and-return journey through a small, honest database
Available before checkout: ['IT-100', 'IT-200', 'IT-400', 'IT-500']
checkout_item(...) -> 9001
Available after checkout: ['IT-200', 'IT-400', 'IT-500']
return_loan(connection, 9001, '2026-08-27') -> True
Available after return: ['IT-100', 'IT-200', 'IT-400', 'IT-500']
Your final task is to complete return_loan(connection, loan_id, returned_on) in catalog_db.py. It identifies a loan by its own ID, not by item ID, and changes only an active loan:
UPDATE loans
SET returned_on = ?
WHERE id = ? AND returned_on IS NULL;
Run that parameterized update inside with connection:. Bind (returned_on, loan_id) in placeholder order. Before leaving the block, turn the affected-row evidence into a result.rowcount == 1; return that boolean after the context has committed.
The first call for an active loan returns True. A repeated call returns False and must not overwrite the first return date. A missing loan also returns False. This operation does not catch or translate
Keep the other three public
open_database(database_path)returns a configured live connection.list_available_items(connection)returns plainin asset-tag order. checkout_item(connection, loan_id, item_id, member_id, checked_out_on)commits one guarded checkout or raises one of the three exactValueErrormessages.return_loan(connection, loan_id, returned_on)commits one active-loan update and returns a boolean.
The module should only define these operations when imported. Do not open a fixed database, create tables, print output, or run a demonstration at import time. A calling operation owns the lifetime: it opens once, makes several calls, then closes once in finally.
Press Run. The visible call sequence checks availability, checks out item 1, checks availability again, returns loan 9001, repeats that return to show False, and 2026-08-27 remains stored, then the caller closes its connection.
Submit repeats the whole flow with different records and tests all four public contracts together.
Task
Complete return_loan(connection, loan_id, returned_on) in catalog_db.py.
Inside one connection context, run the exact parameterized update for id = ? AND returned_on IS NULL, bind (returned_on, loan_id), and return whether result.rowcount == 1 after commit. A successful first return is True; a repeated or missing loan is False. Preserve the other three public