Implement multi-part cost calculator
Company: Stripe
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Quick Answer: This question evaluates a candidate's ability to implement robust data-processing and numeric computation logic for a multi-part cost calculator, covering input validation, per-item discounts and tax, sorting semantics, multi-currency conversion, and precise monetary rounding.
Part 1: Basic Order Totals with Validation
Constraints
- 0 <= number of orders <= 100000
- 0 <= total number of items across all orders <= 500000
- SKU and order_id values are strings in well-formed inputs
- A valid qty is an int or integer-valued float in the range [1, 10^12]; bool is invalid
- Unit prices should be finite numeric values; invalid catalog prices are reported as invalid_price items
Examples
Input: ({'A': 10.0, 'B': 2.5}, [{'order_id': 'o2', 'items': [{'sku': 'A', 'qty': 2}, {'sku': 'X', 'qty': 5}]}, {'order_id': 'o1', 'items': [{'sku': 'B', 'qty': 4}, {'sku': 'A', 'qty': 0}, {'sku': 'B', 'qty': '3'}]}])
Expected Output: {'results': [{'order_id': 'o1', 'total_cost': 10.0}, {'order_id': 'o2', 'total_cost': 20.0}], 'errors': {'o2': {'missing_skus': ['X']}, 'o1': {'invalid_items': [{'sku': 'A', 'qty': 0, 'reason': 'invalid_qty'}, {'sku': 'B', 'qty': '3', 'reason': 'invalid_qty'}]}}}
Explanation: o1 totals only 4 * 2.5. o2 totals only 2 * 10.0. Results are sorted by order_id.
Input: ({'A': 1.0}, [])
Expected Output: {'results': [], 'errors': {}}
Explanation: Edge case: no orders produces no results and no errors.
Hints
- Separate validation from arithmetic so invalid data never reaches the multiplication step.
- Collect per-order errors while scanning items, then sort only the final results list.
Part 2: Order Totals with Discounts, Tax, and Custom Sorting
Constraints
- 0 <= number of orders <= 100000
- 0 <= total number of items across all orders <= 500000
- Valid qty is an int or integer-valued float in the range [1, 10^12]; bool is invalid
- Valid discount_rate and tax_rate values are finite numbers in [0.0, 1.0]
- sort_by must be order_id or total_cost; otherwise order_id is used
Examples
Input: ({'A': 10.0, 'B': 5.0}, [{'order_id': 'o2', 'tax_rate': 0.1, 'items': [{'sku': 'A', 'qty': 2}]}, {'order_id': 'o1', 'items': [{'sku': 'B', 'qty': 4}]}], {'A': 0.2}, 'order_id', False)
Expected Output: {'results': [{'order_id': 'o1', 'total_cost': 20.0}, {'order_id': 'o2', 'total_cost': 17.6}], 'errors': {}}
Explanation: o2 gets a 20 percent discount on A before 10 percent tax. Results are sorted by order_id.
Input: ({'A': 100.0, 'B': 50.0}, [{'order_id': 'o1', 'tax_rate': -0.1, 'items': [{'sku': 'A', 'qty': 1}, {'sku': 'B', 'qty': 2}, {'sku': 'X', 'qty': 1}]}, {'order_id': 'o2', 'tax_rate': 0.2, 'items': [{'sku': 'B', 'qty': '2'}, {'sku': 'A', 'qty': 1}]}], {'A': 1.2, 'B': 0.5}, 'total_cost', True)
Expected Output: {'results': [{'order_id': 'o1', 'total_cost': 150.0}, {'order_id': 'o2', 'total_cost': 120.0}], 'errors': {'o1': {'missing_skus': ['X'], 'invalid_discounts': [{'sku': 'A', 'discount_rate': 1.2}], 'invalid_tax_rate': -0.1}, 'o2': {'invalid_items': [{'sku': 'B', 'qty': '2', 'reason': 'invalid_qty'}], 'invalid_discounts': [{'sku': 'A', 'discount_rate': 1.2}]}}}
Explanation: Invalid discount on A is ignored. Invalid tax on o1 is treated as 0. Results are sorted by total_cost descending.
Hints
- Apply discounts before tax, and apply tax once to the order subtotal.
- For deterministic sorting by total_cost, include order_id as a secondary key.
Part 3: Multi-Currency Order Totals with Banker's Rounding
Constraints
- 0 <= number of orders <= 100000
- 0 <= total number of items across all orders <= 500000
- Valid qty is an int or integer-valued float in the range [1, 10^12]; bool is invalid
- Valid discount_rate and tax_rate values are finite numbers in [0.0, 1.0]
- Required currency rates must be finite positive numbers
- Rounded outputs must use ROUND_HALF_EVEN to two decimal places
Examples
Input: ({'A': 10.0, 'B': 5.0}, [{'order_id': 'e1', 'currency': 'EUR', 'items': [{'sku': 'A', 'qty': 1}, {'sku': 'B', 'qty': 2}]}, {'order_id': 'u1', 'currency': 'USD', 'items': [{'sku': 'A', 'qty': 3}]}], {'USD': 1.0, 'EUR': 1.2}, 'USD')
Expected Output: {'results': [{'order_id': 'e1', 'total_cost': 24.0, 'currency': 'USD'}, {'order_id': 'u1', 'total_cost': 30.0, 'currency': 'USD'}], 'errors': {}}
Explanation: e1 totals 20 EUR, converted to 24 USD. u1 is already in USD.
Input: ({'A': 10.0}, [{'order_id': 'd1', 'currency': 'EUR', 'tax_rate': 0.1, 'items': [{'sku': 'A', 'qty': 3}]}], {'USD': 1.0, 'EUR': 1.2}, 'USD', {'A': 0.1})
Expected Output: {'results': [{'order_id': 'd1', 'total_cost': 35.64, 'currency': 'USD'}], 'errors': {}}
Explanation: 3 * 10 with 10 percent discount is 27 EUR. After 10 percent tax it is 29.7 EUR, converted to 35.64 USD.
Hints
- Use decimal arithmetic or carefully specified rounding; binary float round-off can change half-cent cases.
- Compute in this order: validate items, apply discounts, apply tax, convert currency, then round.