# /// script # requires-python = ">=3.12" # dependencies = [ # "polars>=1.32,<2", # ] # [tool.uv] # exclude-newer = "2026-08-07T00:00:00Z" # /// """Work through working capital and the current ratio in readable Python. Run the downloaded file directly with uv; do not insert ``python``: uv run working-capital-analysis.py Try a different supplier payment with ``--payable-payment 10000``. Zero and 30,000 exercise the permitted boundaries; values outside them fail explicitly. The program keeps the accounting visible: named inputs first, two short formulas next, and a labeled comparison table last. """ from __future__ import annotations import argparse from pathlib import Path import polars as pl # Step 1: state the balances. These are the yellow input cells in the workbook. NORTHSTAR = { "cash": 30_000.0, "accounts_receivable": 50_000.0, "inventory": 40_000.0, "accounts_payable": 50_000.0, "short_term_debt": 30_000.0, } SMALLER_PEER = { "cash": 20_000.0, "accounts_receivable": 25_000.0, "inventory": 15_000.0, "accounts_payable": 15_000.0, "short_term_debt": 5_000.0, } def calculate_position(name: str, balances: dict[str, float]) -> dict[str, float | str]: """Apply the two liquidity formulas to one classified position.""" current_assets = balances["cash"] + balances["accounts_receivable"] + balances["inventory"] current_liabilities = balances["accounts_payable"] + balances["short_term_debt"] # Step 2: compute a dollar difference and a unitless ratio. working_capital = current_assets - current_liabilities current_ratio = current_assets / current_liabilities return { "position": name, "current_assets": current_assets, "current_liabilities": current_liabilities, "working_capital": working_capital, "current_ratio": current_ratio, } def pay_supplier(balances: dict[str, float], amount: float) -> dict[str, float]: """Return a new position after Cash settles Accounts Payable dollar for dollar.""" if amount < 0: raise ValueError("the payable payment cannot be negative") if amount > balances["cash"]: raise ValueError("the payment cannot exceed available Cash in this model") if amount > balances["accounts_payable"]: raise ValueError("the payment cannot exceed Accounts Payable") after_payment = balances.copy() after_payment["cash"] -= amount after_payment["accounts_payable"] -= amount return after_payment def build_comparison(payable_payment: float = 20_000.0) -> pl.DataFrame: """Build the three-row comparison used in the worked example.""" northstar_after_payment = pay_supplier(NORTHSTAR, payable_payment) rows = [ calculate_position("Northstar — reported", NORTHSTAR), calculate_position("Northstar — after payment", northstar_after_payment), calculate_position("Smaller peer", SMALLER_PEER), ] return pl.DataFrame(rows) def verify_comparison(table: pl.DataFrame, payable_payment: float) -> None: """Reconcile every learner-selected payment, plus the published seed.""" reported = table.row(0, named=True) after_payment = table.row(1, named=True) if reported["working_capital"] != after_payment["working_capital"]: raise AssertionError("an equal Cash/payable reduction must preserve working capital") if reported["current_assets"] - after_payment["current_assets"] != payable_payment: raise AssertionError("current assets must fall by the Cash payment") if reported["current_liabilities"] - after_payment["current_liabilities"] != payable_payment: raise AssertionError("current liabilities must fall by the payable payment") if payable_payment == 20_000: expected_working_capital = [40_000.0, 40_000.0, 40_000.0] expected_current_ratios = [1.5, 100_000 / 60_000, 3.0] if table["working_capital"].to_list() != expected_working_capital: raise AssertionError("the published working-capital results must be $40,000") for actual, expected in zip( table["current_ratio"].to_list(), expected_current_ratios, strict=True ): if abs(actual - expected) > 1e-9: raise AssertionError("a published current-ratio result does not reconcile") def arguments() -> argparse.Namespace: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "--payable-payment", type=float, default=20_000, help="Cash paid to reduce Accounts Payable (default: 20000)", ) parser.add_argument("--csv", type=Path, help="optional path for the comparison table") return parser.parse_args() def main() -> int: args = arguments() table = build_comparison(args.payable_payment) verify_comparison(table, args.payable_payment) print("Working capital = current assets - current liabilities") print("Current ratio = current assets / current liabilities\n") # Display financial amounts with thousands separators and two decimals. # The DataFrame and optional CSV retain their original numeric precision. with pl.Config(thousands_separator=",", float_precision=2): print(table) print( "\nInterpretation: paying a current payable with Cash can leave working " "capital unchanged while increasing the current ratio. Neither metric " "proves liquidity on its own." ) if args.csv: args.csv.parent.mkdir(parents=True, exist_ok=True) table.write_csv(args.csv) print(f"Saved table: {args.csv}") return 0 if __name__ == "__main__": raise SystemExit(main())