Delivery Cost Dashboard with Effective-Dated Driver Rates and Exact Money Totals
Company: Rippling
Role: Software Engineer
Category: Software Engineering Fundamentals
Difficulty: medium
Interview Round: Technical Screen
A food-delivery platform pays its drivers per delivery. The cost of one delivery is its duration multiplied by the hourly rate of the driver who made it. Build the core of a dashboard whose headline figure is a single number: the total cost of all deliveries recorded so far.
Implement a class that supports these four operations:
```python
class DeliveryCostDashboard:
def add_driver(self, driver_id, hourly_rate): ...
def record_delivery(self, delivery_id, driver_id, start_time, end_time): ...
def update_driver_rate(self, driver_id, new_rate, effective_time): ...
def get_total_cost(self) -> str: ...
```
- `add_driver(driver_id, hourly_rate)` registers a driver with an initial hourly rate in dollars.
- `record_delivery(delivery_id, driver_id, start_time, end_time)` records one delivery made by that driver.
- `update_driver_rate(driver_id, new_rate, effective_time)` changes the driver's hourly rate from `effective_time` onward.
- `get_total_cost()` returns the total cost of every counted delivery in dollars, as a string with exactly two decimal places, such as `"135.30"`.
The round is live coding in an editor with an AI assistant available. Before writing any code, discuss your approach with the interviewer, including the time format you will use. The interviewer is looking for good object-oriented design and expects you to point out, without being asked, every place where your interview solution would differ from a production system.
```hint Rates have a history
A driver's rate is not a single number. Consider what you must keep so that a delivery can be priced at the rate that applied when it started, even when it is recorded after a later rate change has been registered.
```
```hint Round exactly once
Look for a unit in which every per-delivery amount is an exact integer, and postpone the only rounding step to the moment the string is produced.
```
### Constraints and Clarifications
- The time format is your choice; agree on it with the interviewer before coding (for example, integer Unix timestamps in seconds, in UTC).
- `delivery_id` is globally unique. If a delivery whose id is already recorded is submitted again, the new submission is ignored.
- A delivery that lasts longer than 3 hours is ignored and adds nothing to the total.
- A rate change affects only deliveries recorded after the change. Deliveries already recorded keep the cost they were given when they were recorded.
- A delivery is billed in full at the rate in effect at its `start_time`, even when it runs past the moment a rate change takes effect. Do not split it across rates.
- Hourly rates arrive as floating-point numbers. Adding a floating-point cost on every event accumulates rounding error, so the total must stay exact until the single final conversion to dollars and cents.
### Example
Times are integer seconds, and a new rate is assumed to apply to deliveries that start at or after its `effective_time`.
```text
add_driver("d1", 20.00)
record_delivery("a", "d1", 0, 5400) # 1.5 h at 20.00/h -> 30.00
update_driver_rate("d1", 30.00, 7200)
record_delivery("b", "d1", 3600, 9000) # starts before 7200: old rate, 1.5 h -> 30.00
record_delivery("c", "d1", 7200, 8100) # starts at 7200: new rate, 0.25 h -> 7.50
record_delivery("a", "d1", 0, 600) # duplicate delivery_id: ignored
record_delivery("e", "d1", 10000, 20801) # 10,801 s is longer than 3 h: ignored
get_total_cost() # -> "67.50"
```
Delivery `b` runs past 7200 but is billed entirely at the old rate, because it started before the change took effect.
### Clarifying Questions
- In what form will callers pass times, and are they always in UTC?
- Does the rate given to `add_driver` apply to deliveries that started at any time before the driver's first rate change?
- What should happen on invalid input, such as an unknown driver, an `end_time` before `start_time`, a second `add_driver` for the same id, or a negative rate: raise an error or ignore the call?
- If a delivery is ignored because it exceeds 3 hours, is its `delivery_id` used up, or may a corrected submission with the same id be accepted later?
- Can a rate change arrive with an `effective_time` earlier than a change already registered, and what happens if two changes share the same `effective_time`?
- How should the final total be rounded to cents, and can a rate contain a fraction of a cent?
### What a Strong Answer Covers
- Agreement on the time representation, the money representation and the unresolved edge-case policies before coding, with assumptions labeled as such
- An object-oriented decomposition with clear responsibilities (rate history, delivery record, dashboard) and validation kept in one place
- Pricing at the rate in effect at `start_time` through an effective-dated history, including late-recorded deliveries and out-of-order rate changes, without repricing recorded deliveries
- Exact arithmetic with a single, explicitly defined rounding step and correct two-decimal formatting
- Correct duplicate and 3-hour handling, including the boundaries, and the time cost of each operation
- A proactive list of interview-versus-production differences, such as persistence, idempotency, concurrency, audit trail and rounding policy
### Follow-up Questions
- Finance now wants a rate change to reprice already-recorded deliveries that started at or after its effective time. What changes in your data model, and what do `update_driver_rate` and `get_total_cost` cost now?
- How would you bill a delivery that spans a rate change pro rata instead of entirely at its start rate, while keeping the total exact?
- Add a per-driver total and the total cost of deliveries that started within a time window. What would you store or index to answer these quickly?
- Several servers call `record_delivery` concurrently, and the same delivery can be submitted twice at the same moment. How do you keep the total correct and the duplicate ignored?
Overview: Implement a delivery-cost dashboard class that registers drivers with hourly rates, records deliveries, applies effective-dated rate changes without repricing recorded deliveries, and returns the exact total cost as a two-decimal string. It tests object-oriented design, idempotent recording, edge-case policy and exact money arithmetic.
Read the full Rippling Software Engineer interview experience this question came from