0%

Capstone: A Persistent Lending Tool · practice

Print the Lending Activity

A lending activity report has one row per loan, whether that loan is active or returned. It is not a two-event timeline. The report must also show the member email that version 2 added, and it must represent missing values honestly.

The demo calls main(["activity", str(database_path)]) twice: once while loan 501 is active and once after its return. Add display_value(value) exactly as shown, then add activity_command(args). Argparse passes only args.database to that command .

Refuse a missing database, call prepare_database, and open the application connection. Call list_lending_activity(connection) exactly once and store its returned rows. Close the connection in finally before printing. The query returns plain in loan-ID order with exactly loan_id, asset_tag, member_code, member_email, checked_out_on, and returned_on.

def display_value(value):
    if value is None:
        return "NULL"
    return str(value)

Use display_value(value) when rendering nullable values. It returns the literal text NULL for Python None; every other becomes its ordinary . This matters for an active loan’s returned_on and for an older migrated member whose email is SQL NULL. Do not print Python’s None, an empty field, or an invented event row.

Print this header even when no loans exist:

loan_id | asset_tag | member_code | member_email | checked_out_on | returned_on

Then use a for and the six in that exact order. Do not add SQL, query twice, omit returned loans, or sort by asset tag in the . Add the exact branch if args.command == "activity": return activity_command(args) to main.

Press Run to compare the same durable row before and after return:

== activity before return ==
Status: 0
loan_id | asset_tag | member_code | member_email | checked_out_on | returned_on
501 | TL-100 | MB-017 | riley@example.test | 2026-08-26 | NULL
== activity after return ==
Status: 0
loan_id | asset_tag | member_code | member_email | checked_out_on | returned_on
501 | TL-100 | MB-017 | riley@example.test | 2026-08-26 | 2026-08-27
stderr: <empty>

A thorough check supplies several loans in a different insertion order, active and returned rows, Unicode values, and both missing and present email. It checks one row per loan, exact order and columns, no state change, one public query call, and connection closure.

Task

Add the exact display_value(value) from the instructions, add or complete activity_command(args), and add this branch in main:

if args.command == "activity":
    return activity_command(args)

Refuse a missing database, prepare and open it, call list_lending_activity exactly once, and close in finally. Print the exact six-column header and one pipe-delimited row per returned in its existing order. Render every Python None as NULL, including a missing email or return label.