Coding roles: Software Engineer, Machine Learning Engineer
Create a shipping-fee calculator for an e-commerce service. It must determine an order's overall shipping charge using pricing schemes that can vary by destination country and product.
The task advances through three stages, with each stage adding more behavior:
Two primary structures are provided:
Order Object: Holds a country identifier along with the ordered items.
{
"country": "GB",
"items": [
{"product": "keyboard", "quantity": 12},
{"product": "monitor", "quantity": 3}
]
}
Shipping Cost Configuration: A nested dictionary that describes product-specific pricing by country.
The configuration format changes as you move through the three stages.
Write compute_shipping_cost(order, shipping_cost) to return the complete shipping charge when every product has one constant per-unit fee.
Input:
order_gb = {
"country": "GB",
"items": [
{"product": "keyboard", "quantity": 12},
{"product": "monitor", "quantity": 3}
]
}
order_de = {
"country": "DE",
"items": [
{"product": "keyboard", "quantity": 12},
{"product": "monitor", "quantity": 3}
]
}
shipping_cost = {
"GB": [
{"product": "keyboard", "cost": 420},
{"product": "monitor", "cost": 850}
],
"DE": [
{"product": "keyboard", "cost": 510},
{"product": "monitor", "cost": 920}
]
}
Output:
compute_shipping_cost(order_gb, shipping_cost) == 7590
# Calculation: (12 × 420) + (3 × 850) = 5040 + 2550 = 7590
compute_shipping_cost(order_de, shipping_cost) == 8880
# Calculation: (12 × 510) + (3 × 920) = 6120 + 2760 = 8880
Enhance the implementation to support quantity-based price tiers, where the per-unit amount is determined by the item's quantity bracket. Every tier provides a lower bound, upper bound, and unit charge for that interval.
This resembles volume discounting: units that land in larger quantity bands can have a cheaper individual rate.
Input:
# The orders are unchanged from Part 1
shipping_cost = {
"GB": [
{
"product": "keyboard",
"costs": [
{"minQuantity": 0, "maxQuantity": None, "cost": 420}
]
},
{
"product": "monitor",
"costs": [
{"minQuantity": 0, "maxQuantity": 1, "cost": 850},
{"minQuantity": 1, "maxQuantity": None, "cost": 760}
]
}
],
"DE": [
{
"product": "keyboard",
"costs": [
{"minQuantity": 0, "maxQuantity": None, "cost": 510}
]
},
{
"product": "monitor",
"costs": [
{"minQuantity": 0, "maxQuantity": 1, "cost": 920},
{"minQuantity": 1, "maxQuantity": None, "cost": 830}
]
}
]
}
Output:
compute_shipping_cost(order_gb, shipping_cost) == 7410
# Calculation:
# keyboard: 12 × 420 = 5040 (every unit has the same rate)
# monitor: (1 × 850) + (2 × 760) = 850 + 1520 = 2370
# Total: 5040 + 2370 = 7410
compute_shipping_cost(order_de, shipping_cost) == 8700
# Calculation:
# keyboard: 12 × 510 = 6120
# monitor: (1 × 920) + (2 × 830) = 920 + 1660 = 2580
# Total: 6120 + 2580 = 8700
maxQuantity value of None means that the tier has no upper limit.minQuantity?Further extend the implementation so that tiers can use either of two pricing methods within one tier list:
incremental: Apply a per-item charge, as in Part 2 (quantity × cost).fixed: Apply one flat charge, independent of the number of units covered by that tier.One product's tiers may alternate between fixed and incremental pricing.
Input:
# The orders are unchanged
shipping_cost = {
"GB": [
{
"product": "keyboard",
"costs": [
{
"type": "incremental",
"minQuantity": 0,
"maxQuantity": None,
"cost": 420
}
]
},
{
"product": "monitor",
"costs": [
{
"type": "fixed",
"minQuantity": 0,
"maxQuantity": 1,
"cost": 850
},
{
"type": "incremental",
"minQuantity": 1,
"maxQuantity": None,
"cost": 760
}
]
}
],
"DE": [
{
"product": "keyboard",
"costs": [
{
"type": "incremental",
"minQuantity": 0,
"maxQuantity": None,
"cost": 510
}
]
},
{
"product": "monitor",
"costs": [
{
"type": "fixed",
"minQuantity": 0,
"maxQuantity": 1,
"cost": 920
},
{
"type": "incremental",
"minQuantity": 1,
"maxQuantity": None,
"cost": 830
}
]
}
]
}
Output:
compute_shipping_cost(order_gb, shipping_cost) == 7410
# Calculation:
# keyboard: 12 × 420 = 5040 (incremental)
# monitor: 850 (fixed for the first 1) + (2 × 760) = 850 + 1520 = 2370
# Total: 5040 + 2370 = 7410
compute_shipping_cost(order_de, shipping_cost) == 8700
# Calculation:
# keyboard: 12 × 510 = 6120 (incremental)
# monitor: 920 (fixed for the first 1) + (2 × 830) = 920 + 1660 = 2580
# Total: 6120 + 2580 = 8700
cost once whenever quantity reaches that tier.cost, as in Part 2.Question: If this implementation were going into production, what changes would you make to improve its clarity and long-term maintainability?
Considerations: