Closing Bell
A medium Python interview practice problem on DataDriven. Write the Python and run it against test cases, with instant feedback.
- Domain
- Python
- Difficulty
- medium
- Seniority
- L6
- Asked in
- Amazon
Problem
A brokerage export gives you prices, a dict keyed by ISO date string mapping to that day's close, and purchases, a list of [date, quantity] buy records where quantity is a whole number of shares. Mark every lot to the price on the latest date in the history and return the portfolio's total gain, where each buy contributes its quantity times how far the price has moved since the day it was bought.
Every share you own, priced at today's close. Tally the gains.
Example 1
Input:
prices = {"2024-01-01":100,"2024-01-15":110,"2024-02-01":120}, purchases = [["2024-01-01",10],["2024-01-15",5]]Output:
250
Example 2
Input:
prices = {"2024-03-01":50,"2024-03-15":45}, purchases = [["2024-03-01",20]]Output:
-100
Worked solution and explanation
The trap hiding in a friendly dict
Strip the finance costume off and this is a per-record accumulation against one derived reference value: mark every lot to the latest price, then add up quantity times the move. The whole problem hinges on where 'latest' comes from. Modern Python dicts remember insertion order, so it is tempting to grab the last entry or a variable you kept updating as you looped. But a price feed can land out of order, and the moment it does, insertion order lies. The latest price is prices[max(prices)], full stop. Get that one lookup wrong and every lot is marked to the wrong number, so the entire portfolio total is off, not just one row.
Walking it
Step 1: Anchor to the latest price
The current value of any share is the close on the most recent date. Pull it once, before the loop, as prices[max(prices)]. Do it once, not per purchase.
Step 2: Price each lot individually
Each [date, quantity] buy paid prices[date] per share and those same shares are now worth the latest price. The gain on that lot is quantity times the difference, and it can be negative.
Step 3: Sum and return a float
Accumulate every lot's gain into a running total seeded at 0.0 and return it. Seeding with a float means a whole-number result still comes back as a float.
The solution
def portfolio_profit_calculator(prices, purchases):
latest_date = max(prices)
latest_price = prices[latest_date]
total_profit = 0.0
for date, quantity in purchases:
buy_price = prices[date]
total_profit += quantity * (latest_price - buy_price)
return total_profitCommon follow-up questions
- What if you needed a per-date profit breakdown? (Tests returning a dict of profit per purchase date instead of a single total.)
- How would you fold dividends into the P&L? (Tests adding a dividend income stream alongside capital gains.)
- What if you need historical P&L at every date instead of just the latest? (Tests computing unrealized P&L at each date point using the corresponding price.)
- What about short positions? (Tests handling negative quantities and the reversed profit logic.)