PracHub
QuestionsPremiumCoachesLearningGuidesInterview Prep

Quick Overview

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.

  • Medium
  • Stripe
  • Coding & Algorithms
  • Software Engineer

Implement multi-part cost calculator

Company: Stripe

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: Medium

Interview Round: Technical Screen

You are given a price catalog and a list of orders. Implement the following in any language (Python examples acceptable): Inputs - price_catalog: mapping from sku (string) -> unit_price (float). - orders: list of orders; each order has: - order_id (string) - items: list of { sku: string, qty: integer } Part 1 — Basic totals - For each order, compute total_cost = sum(qty * unit_price) over its valid items. - Validations and corner cases: - If an item's sku is not in price_catalog, skip that item and record it in a per-order "missing_skus" list. - If qty is non-numeric, non-integer, <= 0, or overflows type limits, treat it as invalid; skip and record in a per-order "invalid_items" list. - Do not crash on malformed input; return both results and an "errors" structure. - Output: list of { order_id, total_cost } sorted by order_id ascending. In Python, show the lambda used for sorting; in other languages, provide the equivalent. Part 2 — Discounts and tax - Extend inputs to support optional per-item discounts: discounts: mapping sku -> discount_rate (0.0–1. 0), and optional per-order tax_rate (0.0–1. 0). - Compute total_cost = (sum over items of qty * unit_price * (1 - discount_rate))) * (1 + tax_rate). - Validate numeric ranges for discount_rate and tax_rate; out-of-range values should be treated as invalid and reported. - Allow the caller to choose sorting: by "order_id" or by "total_cost", ascending or descending (demonstrate the sort key/compare function; in Python show the lambda). Part 3 — Multi-currency and rounding - Extend orders with optional currency code (e.g., "USD", "EUR"). Given a rates mapping base->target (e.g., usd_per_unit: mapping currency -> rate), convert each order’s total into a target_currency parameter (default "USD"). - Validate that required conversion rates exist and are numeric; report missing or invalid rates. - Round monetary outputs to two decimals with banker's rounding (or specify the rounding mode you choose and apply it consistently). Complexity and robustness - State the time and space complexity of your implementation for each part, and discuss how you would handle very large inputs (streaming, batching, or memory constraints). - Provide a brief test plan that covers normal cases, missing_skus, invalid qty, extreme numeric values, discount/tax edge cases, sorting correctness, and currency conversion failures.

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

Given a price catalog mapping SKU strings to unit prices and a list of orders, compute the total cost of each order. Each order has an order_id and an items list. Each item has a sku and qty. Only valid items contribute to the total. If an item SKU is missing from the catalog, skip it and report it in that order's missing_skus list. If qty is non-numeric, non-integer, <= 0, boolean, or greater than 10^12, skip it and report it in invalid_items. Return totals sorted by order_id ascending. The intended Python sort is results.sort(key=lambda row: row['order_id']).

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.

Input: ({'A': 3.0}, [{'order_id': 'solo', 'items': []}])

Expected Output: {'results': [{'order_id': 'solo', 'total_cost': 0.0}], 'errors': {}}

Explanation: An order with no items has total 0.

Input: ({'A': 1.0}, [{'order_id': 'o1', 'items': [{'sku': 'A', 'qty': 1000000000000}, {'sku': 'A', 'qty': 1000000000001}, {'sku': 'A', 'qty': 1.5}, {'sku': 'A', 'qty': True}]}])

Expected Output: {'results': [{'order_id': 'o1', 'total_cost': 1000000000000.0}], 'errors': {'o1': {'invalid_items': [{'sku': 'A', 'qty': 1000000000001, 'reason': 'invalid_qty'}, {'sku': 'A', 'qty': 1.5, 'reason': 'invalid_qty'}, {'sku': 'A', 'qty': True, 'reason': 'invalid_qty'}]}}}

Explanation: The maximum allowed qty is valid. Overflow-like, fractional, and boolean quantities are invalid.

Solution

def solution(price_catalog, orders):
    import math

    MAX_QTY = 10**12

    def valid_qty(q):
        if isinstance(q, bool):
            return False
        if isinstance(q, int):
            return 1 <= q <= MAX_QTY
        if isinstance(q, float):
            return math.isfinite(q) and q.is_integer() and 1 <= q <= MAX_QTY
        return False

    def valid_price(p):
        return isinstance(p, (int, float)) and not isinstance(p, bool) and math.isfinite(p)

    if not isinstance(price_catalog, dict):
        price_catalog = {}
    if not isinstance(orders, list):
        return {'results': [], 'errors': {'__global__': {'invalid_orders': True}}}

    results = []
    errors = {}

    for idx, order in enumerate(orders):
        if isinstance(order, dict):
            order_id = order.get('order_id', f'__missing_order_id_{idx}')
            items = order.get('items', [])
        else:
            order_id = f'__malformed_order_{idx}'
            items = []

        total = 0.0
        missing_skus = []
        invalid_items = []

        if not isinstance(items, list):
            invalid_items.append({'sku': None, 'qty': None, 'reason': 'items_not_list'})
            items = []

        for item in items:
            if not isinstance(item, dict):
                invalid_items.append({'sku': None, 'qty': None, 'reason': 'malformed_item'})
                continue

            sku = item.get('sku')
            qty = item.get('qty')

            if not valid_qty(qty):
                invalid_items.append({'sku': sku, 'qty': qty, 'reason': 'invalid_qty'})
                continue

            if sku not in price_catalog:
                missing_skus.append(sku)
                continue

            price = price_catalog[sku]
            if not valid_price(price):
                invalid_items.append({'sku': sku, 'qty': qty, 'reason': 'invalid_price'})
                continue

            total += int(qty) * float(price)

        results.append({'order_id': order_id, 'total_cost': total})

        order_errors = {}
        if missing_skus:
            order_errors['missing_skus'] = missing_skus
        if invalid_items:
            order_errors['invalid_items'] = invalid_items
        if order_errors:
            errors[order_id] = order_errors

    results.sort(key=lambda row: row['order_id'])
    return {'results': results, 'errors': errors}

Time complexity: O(N + O log O), where N is the total number of items and O is the number of orders. The O log O term is from sorting results by order_id.. Space complexity: O(O + E), where O is the number of result rows and E is the total number of reported errors. For very large inputs, orders can be processed in batches and externally sorted by order_id..

Hints

  1. Separate validation from arithmetic so invalid data never reaches the multiplication step.
  2. Collect per-order errors while scanning items, then sort only the final results list.

Part 2: Order Totals with Discounts, Tax, and Custom Sorting

Extend the basic order total calculator with optional per-item discounts and optional per-order tax. discounts maps SKU to discount_rate, where a valid rate is in [0.0, 1.0]. Each order may include tax_rate, also valid only in [0.0, 1.0]. The pre-tax item cost is qty * unit_price * (1 - discount_rate). Invalid discounts are reported and ignored, meaning the item is charged with no discount. Invalid tax rates are reported and treated as 0 tax. The caller chooses sorting by order_id or total_cost and ascending or descending order.

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.

Input: ({'A': 1.0}, [], None, 'order_id', False)

Expected Output: {'results': [], 'errors': {}}

Explanation: Edge case: empty order list.

Input: ({'A': 10.0, 'B': 20.0}, [{'order_id': 'edge', 'tax_rate': 1.0, 'items': [{'sku': 'A', 'qty': 3}, {'sku': 'B', 'qty': 1}]}], {'A': 1.0, 'B': 0.0}, 'total_cost', False)

Expected Output: {'results': [{'order_id': 'edge', 'total_cost': 40.0}], 'errors': {}}

Explanation: A has a full discount, B has no discount, and 100 percent tax doubles the remaining subtotal.

Input: ({'A': 2.0}, [{'order_id': 'b', 'items': [{'sku': 'A', 'qty': 1}]}, {'order_id': 'a', 'items': [{'sku': 'A', 'qty': 3}]}], {}, 'sku', False)

Expected Output: {'results': [{'order_id': 'a', 'total_cost': 6.0}, {'order_id': 'b', 'total_cost': 2.0}], 'errors': {'__global__': {'invalid_sort_by': 'sku'}}}

Explanation: Invalid sort_by is reported and sorting falls back to order_id ascending.

Solution

def solution(price_catalog, orders, discounts=None, sort_by='order_id', descending=False):
    import math

    MAX_QTY = 10**12

    def valid_qty(q):
        if isinstance(q, bool):
            return False
        if isinstance(q, int):
            return 1 <= q <= MAX_QTY
        if isinstance(q, float):
            return math.isfinite(q) and q.is_integer() and 1 <= q <= MAX_QTY
        return False

    def valid_number(x):
        return isinstance(x, (int, float)) and not isinstance(x, bool) and math.isfinite(x)

    def valid_rate(x):
        return valid_number(x) and 0.0 <= float(x) <= 1.0

    if not isinstance(price_catalog, dict):
        price_catalog = {}
    if not isinstance(discounts, dict):
        discounts = {}
    if not isinstance(orders, list):
        return {'results': [], 'errors': {'__global__': {'invalid_orders': True}}}

    results = []
    errors = {}

    for idx, order in enumerate(orders):
        if isinstance(order, dict):
            order_id = order.get('order_id', f'__missing_order_id_{idx}')
            items = order.get('items', [])
        else:
            order_id = f'__malformed_order_{idx}'
            items = []

        subtotal = 0.0
        missing_skus = []
        invalid_items = []
        invalid_discounts = []
        seen_bad_discounts = set()
        invalid_tax_marker = None

        tax_rate = 0.0
        if isinstance(order, dict) and 'tax_rate' in order:
            raw_tax = order.get('tax_rate')
            if valid_rate(raw_tax):
                tax_rate = float(raw_tax)
            else:
                invalid_tax_marker = raw_tax

        if not isinstance(items, list):
            invalid_items.append({'sku': None, 'qty': None, 'reason': 'items_not_list'})
            items = []

        for item in items:
            if not isinstance(item, dict):
                invalid_items.append({'sku': None, 'qty': None, 'reason': 'malformed_item'})
                continue

            sku = item.get('sku')
            qty = item.get('qty')

            if not valid_qty(qty):
                invalid_items.append({'sku': sku, 'qty': qty, 'reason': 'invalid_qty'})
                continue

            if sku not in price_catalog:
                missing_skus.append(sku)
                continue

            price = price_catalog[sku]
            if not valid_number(price):
                invalid_items.append({'sku': sku, 'qty': qty, 'reason': 'invalid_price'})
                continue

            discount_rate = 0.0
            if sku in discounts:
                raw_discount = discounts[sku]
                if valid_rate(raw_discount):
                    discount_rate = float(raw_discount)
                else:
                    if sku not in seen_bad_discounts:
                        invalid_discounts.append({'sku': sku, 'discount_rate': raw_discount})
                        seen_bad_discounts.add(sku)

            subtotal += int(qty) * float(price) * (1.0 - discount_rate)

        total = subtotal * (1.0 + tax_rate)
        results.append({'order_id': order_id, 'total_cost': total})

        order_errors = {}
        if missing_skus:
            order_errors['missing_skus'] = missing_skus
        if invalid_items:
            order_errors['invalid_items'] = invalid_items
        if invalid_discounts:
            order_errors['invalid_discounts'] = invalid_discounts
        if invalid_tax_marker is not None:
            order_errors['invalid_tax_rate'] = invalid_tax_marker
        if order_errors:
            errors[order_id] = order_errors

    if sort_by not in ('order_id', 'total_cost'):
        errors.setdefault('__global__', {})['invalid_sort_by'] = sort_by
        sort_by = 'order_id'

    if sort_by == 'order_id':
        results.sort(key=lambda row: row['order_id'], reverse=bool(descending))
    else:
        results.sort(key=lambda row: (row['total_cost'], row['order_id']), reverse=bool(descending))

    return {'results': results, 'errors': errors}

Time complexity: O(N + O log O), where N is the total number of items and O is the number of orders. Sorting dominates after the item scan.. Space complexity: O(O + E), where O is the number of result rows and E is the number of reported errors. With very large inputs, process orders in streaming batches and use an external merge sort for the selected sort key..

Hints

  1. Apply discounts before tax, and apply tax once to the order subtotal.
  2. For deterministic sorting by total_cost, include order_id as a secondary key.

Part 3: Multi-Currency Order Totals with Banker's Rounding

Extend the order calculator to support order currencies and conversion to a requested target currency. Each order may include currency; missing currency defaults to USD. rates maps a currency code to the value of one unit of that currency in a common base currency, such as USD per unit. To convert an amount from source currency to target currency, use amount * rates[source] / rates[target]. If source and target are the same, no conversion rate is required. Apply optional per-SKU discounts and optional per-order tax as in Part 2, then convert, then round monetary outputs to two decimals using banker's rounding, also called ROUND_HALF_EVEN. If a required rate is missing or invalid, that order's total_cost is None and the rate problem is reported.

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.

Input: ({'P': 2.685}, [{'order_id': 'r1', 'currency': 'USD', 'items': [{'sku': 'P', 'qty': 1}]}], {'USD': 1.0}, 'USD')

Expected Output: {'results': [{'order_id': 'r1', 'total_cost': 2.68, 'currency': 'USD'}], 'errors': {}}

Explanation: Banker's rounding sends 2.685 to 2.68 because the hundredths digit 8 is even.

Input: ({'A': 10.0}, [{'order_id': 'e', 'currency': 'EUR', 'items': [{'sku': 'A', 'qty': 1}]}, {'order_id': 'g', 'currency': 'GBP', 'items': [{'sku': 'A', 'qty': 1}]}, {'order_id': 'u', 'currency': 'USD', 'items': [{'sku': 'A', 'qty': 1}]}], {'USD': 1.0, 'EUR': 'bad'}, 'USD')

Expected Output: {'results': [{'order_id': 'e', 'total_cost': None, 'currency': 'USD'}, {'order_id': 'g', 'total_cost': None, 'currency': 'USD'}, {'order_id': 'u', 'total_cost': 10.0, 'currency': 'USD'}], 'errors': {'e': {'invalid_rates': [{'currency': 'EUR', 'rate': 'bad'}]}, 'g': {'missing_rates': ['GBP']}}}

Explanation: EUR has an invalid rate, GBP is missing, and USD needs no conversion.

Input: ({'A': 10.0}, [{'order_id': 'x', 'currency': 'USD', 'tax_rate': 1.5, 'items': [{'sku': 'A', 'qty': 1}, {'sku': 'Z', 'qty': 1}, {'sku': 'A', 'qty': 0}]}], {'USD': 1.0}, 'USD', {'A': -0.2})

Expected Output: {'results': [{'order_id': 'x', 'total_cost': 10.0, 'currency': 'USD'}], 'errors': {'x': {'missing_skus': ['Z'], 'invalid_items': [{'sku': 'A', 'qty': 0, 'reason': 'invalid_qty'}], 'invalid_discounts': [{'sku': 'A', 'discount_rate': -0.2}], 'invalid_tax_rate': 1.5}}}

Explanation: The valid A item is charged without discount or tax because both rates are invalid. Missing SKU and invalid qty are reported.

Solution

def solution(price_catalog, orders, rates, target_currency='USD', discounts=None):
    import math
    from decimal import Decimal, ROUND_HALF_EVEN

    MAX_QTY = 10**12
    CENT = Decimal('0.01')
    ZERO = Decimal('0')
    ONE = Decimal('1')

    def to_decimal(value):
        if isinstance(value, bool):
            return None
        if isinstance(value, Decimal):
            return value if value.is_finite() else None
        if isinstance(value, int):
            return Decimal(value)
        if isinstance(value, float):
            if not math.isfinite(value):
                return None
            return Decimal(str(value))
        return None

    def valid_qty(q):
        if isinstance(q, bool):
            return False
        if isinstance(q, int):
            return 1 <= q <= MAX_QTY
        if isinstance(q, float):
            return math.isfinite(q) and q.is_integer() and 1 <= q <= MAX_QTY
        return False

    def valid_fraction(value):
        d = to_decimal(value)
        return d is not None and ZERO <= d <= ONE

    def positive_rate(value):
        d = to_decimal(value)
        if d is None or d <= ZERO:
            return None
        return d

    if not isinstance(price_catalog, dict):
        price_catalog = {}
    if not isinstance(orders, list):
        return {'results': [], 'errors': {'__global__': {'invalid_orders': True}}}
    if not isinstance(rates, dict):
        rates = {}
    if not isinstance(discounts, dict):
        discounts = {}
    if not isinstance(target_currency, str) or not target_currency:
        target_currency = 'USD'

    results = []
    errors = {}

    for idx, order in enumerate(orders):
        if isinstance(order, dict):
            order_id = order.get('order_id', f'__missing_order_id_{idx}')
            items = order.get('items', [])
            source_currency = order.get('currency', 'USD')
        else:
            order_id = f'__malformed_order_{idx}'
            items = []
            source_currency = 'USD'

        if not isinstance(source_currency, str) or not source_currency:
            source_currency = 'USD'

        subtotal = Decimal('0')
        missing_skus = []
        invalid_items = []
        invalid_discounts = []
        seen_bad_discounts = set()
        invalid_tax_marker = None

        tax_rate = Decimal('0')
        if isinstance(order, dict) and 'tax_rate' in order:
            raw_tax = order.get('tax_rate')
            if valid_fraction(raw_tax):
                tax_rate = to_decimal(raw_tax)
            else:
                invalid_tax_marker = raw_tax

        if not isinstance(items, list):
            invalid_items.append({'sku': None, 'qty': None, 'reason': 'items_not_list'})
            items = []

        for item in items:
            if not isinstance(item, dict):
                invalid_items.append({'sku': None, 'qty': None, 'reason': 'malformed_item'})
                continue

            sku = item.get('sku')
            qty = item.get('qty')

            if not valid_qty(qty):
                invalid_items.append({'sku': sku, 'qty': qty, 'reason': 'invalid_qty'})
                continue

            if sku not in price_catalog:
                missing_skus.append(sku)
                continue

            price = to_decimal(price_catalog[sku])
            if price is None:
                invalid_items.append({'sku': sku, 'qty': qty, 'reason': 'invalid_price'})
                continue

            discount_rate = Decimal('0')
            if sku in discounts:
                raw_discount = discounts[sku]
                if valid_fraction(raw_discount):
                    discount_rate = to_decimal(raw_discount)
                else:
                    if sku not in seen_bad_discounts:
                        invalid_discounts.append({'sku': sku, 'discount_rate': raw_discount})
                        seen_bad_discounts.add(sku)

            subtotal += Decimal(int(qty)) * price * (ONE - discount_rate)

        local_total = subtotal * (ONE + tax_rate)

        missing_rates = []
        invalid_rates = []
        converted = None

        if source_currency == target_currency:
            converted = local_total
        else:
            source_rate = None
            target_rate = None

            if source_currency not in rates:
                missing_rates.append(source_currency)
            else:
                source_rate = positive_rate(rates[source_currency])
                if source_rate is None:
                    invalid_rates.append({'currency': source_currency, 'rate': rates[source_currency]})

            if target_currency not in rates:
                missing_rates.append(target_currency)
            else:
                target_rate = positive_rate(rates[target_currency])
                if target_rate is None:
                    invalid_rates.append({'currency': target_currency, 'rate': rates[target_currency]})

            if not missing_rates and not invalid_rates:
                converted = local_total * source_rate / target_rate

        if converted is None:
            total_value = None
        else:
            total_value = float(converted.quantize(CENT, rounding=ROUND_HALF_EVEN))

        results.append({'order_id': order_id, 'total_cost': total_value, 'currency': target_currency})

        order_errors = {}
        if missing_skus:
            order_errors['missing_skus'] = missing_skus
        if invalid_items:
            order_errors['invalid_items'] = invalid_items
        if invalid_discounts:
            order_errors['invalid_discounts'] = invalid_discounts
        if invalid_tax_marker is not None:
            order_errors['invalid_tax_rate'] = invalid_tax_marker
        if missing_rates:
            order_errors['missing_rates'] = missing_rates
        if invalid_rates:
            order_errors['invalid_rates'] = invalid_rates
        if order_errors:
            errors[order_id] = order_errors

    results.sort(key=lambda row: row['order_id'])
    return {'results': results, 'errors': errors}

Time complexity: O(N + O log O), where N is the total number of items and O is the number of orders. Each item is scanned once, and each order performs O(1) currency-rate lookups.. Space complexity: O(O + E), where O is the number of result rows and E is the number of reported errors. For very large data, stream item validation/order aggregation, write intermediate results to disk, and externally sort by order_id..

Hints

  1. Use decimal arithmetic or carefully specified rounding; binary float round-off can change half-cent cases.
  2. Compute in this order: validate items, apply discounts, apply tax, convert currency, then round.
Last updated: Jun 22, 2026

Loading coding console...

PracHub

Master your tech interviews with 8,000+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities
  • Student Access

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.

Related Coding Questions

  • Assign Reviewers from Changed Files - Stripe (medium)
  • Generate Account Email Notifications - Stripe (medium)
  • Calculate Transaction Fees - Stripe (medium)
  • Build an Account Transfer Ledger - Stripe (medium)
  • Implement Validation and String Compression - Stripe (hard)