Implementing a Dynamic Cost Model for Resource Allocation
This challenge focuses on building a flexible and dynamic cost model in Python. You will design a system that can calculate costs based on various resource types and their associated pricing structures. This is a fundamental task in many applications, from cloud computing billing to project management expense tracking.
Problem Description
Your task is to create a Python class, CostModel, that can manage and calculate costs for different types of resources. The cost model should be able to:
- Define pricing tiers: Allow for resources to have different prices based on quantity consumed (e.g., the first 100 units are cheaper than subsequent units).
- Support various resource types: Be able to handle different kinds of resources (e.g., 'CPU', 'RAM', 'Storage', 'Network').
- Calculate costs dynamically: Compute the total cost for a given quantity of a specific resource type.
- Handle unknown resources: Gracefully handle requests for resource types not yet defined in the model.
Key Requirements:
- A
CostModelclass with methods for adding pricing information and calculating costs. - Pricing information should include a resource type (string) and a list of pricing tiers.
- Each pricing tier should define a
limit(the upper bound of units for that tier) and aprice_per_unit. - The
calculate_costmethod should take aresource_type(string) andquantity(integer) as input.
Expected Behavior:
- When a resource type is added with pricing tiers, the model should store this information.
- When
calculate_costis called for a known resource type and quantity, it should sum up the costs based on the defined tiers. - If the quantity exceeds the defined tiers, the cost for units beyond the last tier should be calculated using the price of the last tier.
- If
calculate_costis called for an unknown resource type, it should return 0 or raise a specific exception (you decide which is more appropriate, but clearly document it).
Edge Cases:
- Calculating the cost for zero quantity.
- Calculating the cost for a quantity that falls exactly on a tier boundary.
- Calling
calculate_costfor a resource type with no defined pricing. - Defining pricing tiers in an order that is not sequential (e.g., a tier with a limit of 50 followed by a tier with a limit of 20). The implementation should handle this by sorting the tiers internally.
Examples
Example 1:
Input:
cost_model = CostModel()
cost_model.add_pricing('CPU', [(100, 0.05), (1000, 0.03), (float('inf'), 0.02)])
cost_model.calculate_cost('CPU', 150)
Output:
7.0
Explanation: For 150 CPU units:
- First 100 units cost 100 * 0.05 = 5.0
- Next 50 units (150 - 100) cost 50 * 0.03 = 1.5
- Total cost = 5.0 + 1.5 = 7.0
Example 2:
Input:
cost_model = CostModel()
cost_model.add_pricing('RAM', [(50, 0.10), (200, 0.08)])
cost_model.calculate_cost('RAM', 250)
Output:
17.0
Explanation: For 250 RAM units:
- First 50 units cost 50 * 0.10 = 5.0
- Next 150 units (200 - 50) cost 150 * 0.08 = 12.0
- Remaining 50 units (250 - 200) cost 50 * 0.08 = 4.0 (using the price of the last tier)
- Total cost = 5.0 + 12.0 + 4.0 = 21.0
Example 3: Unknown Resource
Input:
cost_model = CostModel()
cost_model.add_pricing('CPU', [(100, 0.05)])
cost_model.calculate_cost('GPU', 50)
Output:
0.0
Explanation: The 'GPU' resource type has not been added to the cost model, so its cost is 0.
Example 4: Zero Quantity
Input:
cost_model = CostModel()
cost_model.add_pricing('Storage', [(1000, 0.01)])
cost_model.calculate_cost('Storage', 0)
Output:
0.0
Explanation: Calculating the cost for zero quantity should always result in zero.
Constraints
- Pricing tiers for a given resource type will be provided as a list of tuples, where each tuple is
(limit, price_per_unit).limitcan be an integer orfloat('inf'). price_per_unitwill be a non-negative float.quantityforcalculate_costwill be a non-negative integer.- The number of pricing tiers for a single resource type will be at least one.
- Your solution should be efficient enough to handle hundreds of resource types and thousands of cost calculations per second.
Notes
- Consider how you will store the pricing information for each resource type. A dictionary might be a good choice.
- Ensure that the pricing tiers are processed in the correct order when calculating costs. You might want to sort them internally.
- Decide on a clear strategy for handling unknown resource types and document it in your code.
- Floating-point precision might be a consideration for currency calculations. While exact precision isn't strictly mandated here, be mindful of standard practices.