make_invoice_line from yesterday formats one client's line from a stats dict. But sometimes you want a quick portfolio summary — all clients combined. What if one function handled both modes with a single parameter?
A default argument? If I pass a name it filters to that client; if I pass nothing it uses all of them?
Exactly. name: str = "all" defaults to "all" when no argument is given. Inside the function, check if name == "all" to use the full client list. The return value is a tuple — three numbers at once, unpacked by the caller:
def summarize_client(clients: list, name: str = "all") -> tuple:
if name == "all":
subset = clients
else:
subset = [c for c in clients if c["name"] == name]
total_hours = sum(c.get("hours", 0) for c in subset)
total_revenue = sum(c.get("rate", 0) * c.get("hours", 0) for c in subset)
avg_rate = round(total_revenue / total_hours, 2) if total_hours > 0 else 0.0
return total_hours, total_revenue, avg_rateWhat does "unpacking" mean? The function returns three values but the caller gets one return statement?
return a, b, c returns a tuple (a, b, c). The caller unpacks it: hours, revenue, rate = summarize_client(clients). Three variables assigned in one line. Or access by index: result[0] for hours.
So I can call it with no name for the portfolio dashboard and with a specific name for a client breakdown. One function, two modes.
One function. Two modes. Zero duplication. The default argument is the switch:
def summarize_client(clients: list, name: str = "all") -> tuple:
if name == "all":
subset = clients
else:
subset = [c for c in clients if c.get("name") == name]
total_hours = sum(c.get("hours", 0) for c in subset)
total_revenue = sum(c.get("rate", 0) * c.get("hours", 0) for c in subset)
avg_rate = round(total_revenue / total_hours, 2) if total_hours > 0 else 0.0
print(f"Summary for '{name}': {total_hours}hrs, ${total_revenue:.2f}")
return (total_hours, total_revenue, avg_rate)This is the portfolio overview I have been building manually every quarter.
And you can extend it: add a currency default, a tax_rate default. Defaults keep the common case simple while the function stays flexible.
Default argument: name='all' makes the parameter optional:
def summarize_client(clients: list, name: str = 'all') -> tuple:
if name != 'all':
clients = [c for c in clients if c['name'] == name]Tuple return: return (total_hours, total_revenue, avg_rate) returns three values at once. The caller unpacks them with:
hours, revenue, rate = summarize_client(clients)Why a tuple? Tuples are the idiomatic Python way to return multiple related values from one function — no dict overhead, no named attribute access required. The caller can unpack or index as needed.
make_invoice_line from yesterday formats one client's line from a stats dict. But sometimes you want a quick portfolio summary — all clients combined. What if one function handled both modes with a single parameter?
A default argument? If I pass a name it filters to that client; if I pass nothing it uses all of them?
Exactly. name: str = "all" defaults to "all" when no argument is given. Inside the function, check if name == "all" to use the full client list. The return value is a tuple — three numbers at once, unpacked by the caller:
def summarize_client(clients: list, name: str = "all") -> tuple:
if name == "all":
subset = clients
else:
subset = [c for c in clients if c["name"] == name]
total_hours = sum(c.get("hours", 0) for c in subset)
total_revenue = sum(c.get("rate", 0) * c.get("hours", 0) for c in subset)
avg_rate = round(total_revenue / total_hours, 2) if total_hours > 0 else 0.0
return total_hours, total_revenue, avg_rateWhat does "unpacking" mean? The function returns three values but the caller gets one return statement?
return a, b, c returns a tuple (a, b, c). The caller unpacks it: hours, revenue, rate = summarize_client(clients). Three variables assigned in one line. Or access by index: result[0] for hours.
So I can call it with no name for the portfolio dashboard and with a specific name for a client breakdown. One function, two modes.
One function. Two modes. Zero duplication. The default argument is the switch:
def summarize_client(clients: list, name: str = "all") -> tuple:
if name == "all":
subset = clients
else:
subset = [c for c in clients if c.get("name") == name]
total_hours = sum(c.get("hours", 0) for c in subset)
total_revenue = sum(c.get("rate", 0) * c.get("hours", 0) for c in subset)
avg_rate = round(total_revenue / total_hours, 2) if total_hours > 0 else 0.0
print(f"Summary for '{name}': {total_hours}hrs, ${total_revenue:.2f}")
return (total_hours, total_revenue, avg_rate)This is the portfolio overview I have been building manually every quarter.
And you can extend it: add a currency default, a tax_rate default. Defaults keep the common case simple while the function stays flexible.
Default argument: name='all' makes the parameter optional:
def summarize_client(clients: list, name: str = 'all') -> tuple:
if name != 'all':
clients = [c for c in clients if c['name'] == name]Tuple return: return (total_hours, total_revenue, avg_rate) returns three values at once. The caller unpacks them with:
hours, revenue, rate = summarize_client(clients)Why a tuple? Tuples are the idiomatic Python way to return multiple related values from one function — no dict overhead, no named attribute access required. The caller can unpack or index as needed.
Carlos needs a function that can either summarise his entire client portfolio or drill down to one specific client — using the same call signature. Write `summarize_client(clients, name='all')` that returns a tuple `(total_hours, total_revenue, avg_rate)`. When `name` is `'all'`, use all clients; otherwise filter to the matching name. Client dicts have `name`, `rate`, and `hours` keys.
Tap each step for scaffolded hints.
No blank-editor panic.