Start learning free

LESSON 559 OF 569 · OBJECT-ORIENTED PROGRAMMING - CHALLENGES

Shipping Options in Python: Overriding Methods

Practice O(1) Read the full explanation

An online shop offers three ways to ship a parcel. Standard shipping is the basic one. Express and Economy are kinds of shipping too: they answer the same two questions, what the option is called and what it costs, but each in its own way. So each one overrides the parent's methods with its own versions.

Implement the class Shipping, the standard option:

  • name() returns "Standard".
  • cost(weight) returns 5 + weight: a base price of 5, plus 1 for each kilogram.

and two classes that inherit from Shipping and override both methods:

  • Express: name() returns "Express", and cost(weight) returns 10 + 2 * weight.
  • Economy: name() returns "Economy", and cost(weight) returns 3 plus half the weight, rounded down to a whole number: half of 7 is 3.

The input lists parcels, one per line: the option (standard, express or economy) and the weight. For each line, the code that tests your classes creates that option and prints <name>: <cost> from its name() and cost(weight). The two calls are the same for every option (where variables have types, through a variable of the parent type Shipping); because the methods are overridden, each option answers with its own version. The starter code spells these names the way your language does.

 

Example 1:

Input:
    standard 4
    express 4
    economy 4
Output:
    Standard: 9
    Express: 18
    Economy: 5
Explanation: The same parcel of 4 kilograms costs 5 + 4 = 9 with Standard, 10 + 2 × 4 = 18 with Express
and 3 + 2 = 5 with Economy (half of 4 is 2).

Example 2:

Input:
    standard 0
    express 0
    economy 0
Output:
    Standard: 5
    Express: 10
    Economy: 3
Explanation: With a weight of 0, only the base prices are left.

Example 3:

Input:
    economy 7
    economy 1
    standard 7
    express 7
Output:
    Economy: 6
    Economy: 3
    Standard: 12
    Express: 24
Explanation: Economy halves the weight and rounds down: half of 7 is 3, so 3 + 3 = 6, and half of 1 is 0, so 3 + 0 = 3.

 

Constraints:

  • 0 <= weight <= 1000, a whole number of kilograms.
  • At most 100 parcels per test case.
STEP 1 OF 6
    Ctrl + Enter to check

    PYTHON · OBJECT-ORIENTED PROGRAMMING - CHALLENGES

    Shipping Options in Python, explained

    Problem overview

    The lesson asks for three classes. Shipping is the standard option, and Express and Economy inherit from it. Every option answers the same two questions: name() returns its name, and cost(weight) returns the price of a parcel of that many kilograms.

    • Shipping: the name is "Standard" and the cost is 5 + weight.
    • Express: the name is "Express" and the cost is 10 + 2 * weight.
    • Economy: the name is "Economy" and the cost is 3 + weight // 2, with the division rounding down.

    For a parcel of 4 kilograms the three options cost 9, 18 and 5.

    Approach: one parent, two overrides

    The code that uses these classes calls name() and cost(weight) on an option without knowing which kind it holds. That works because every option has both methods. Express and Economy write class Express(Shipping):, which makes them subclasses of Shipping, and each defines methods with the same names as the parent's. This is called overriding.

    When you call a method on an object, Python looks for it in the object's own class first and only then in the parent. An Express object finds Express.cost straight away, so the parent's version never runs for it. Each class overrides only for itself: changing Express has no effect on Economy or Shipping.

    Step by step

    1. Write Shipping.name so it returns the text "Standard".
    2. Write Shipping.cost so it returns 5 + weight: a base price plus 1 for each kilogram.
    3. Override name in Express with the same header and the text "Express".
    4. Override cost in Express: 10 + 2 * weight. If you left this out, an express parcel would silently get the parent's price.
    5. Override name in Economy with "Economy".
    6. Override cost in Economy with 3 + weight // 2. The // operator divides and drops the remainder.

    The solution in Python

    class Shipping:
        def name(self):
            return "Standard"
    
        def cost(self, weight):
            return 5 + weight
    
    
    class Express(Shipping):
        def name(self):
            return "Express"
    
        def cost(self, weight):
            return 10 + 2 * weight
    
    
    class Economy(Shipping):
        def name(self):
            return "Economy"
    
        def cost(self, weight):
            return 3 + weight // 2
    

    Here is the same parcel of 4 kilograms sent through each option:

    for option in (Shipping(), Express(), Economy()):
        print(f"{option.name()}: {option.cost(4)}")
    
    Standard: 9
    Express: 18
    Economy: 5
    

    The loop body is identical for all three objects, yet each one answers with its own version of the methods.

    Why // and not /

    In Python, / always gives a float and // gives the rounded-down result. With a weight of 7, 7 / 2 is 3.5 and 7 // 2 is 3. The lesson wants a whole price, so Economy's cost for 7 kilograms is 3 + 3 = 6. With / the method would return 6.5.

    Edge cases and common mistakes

    • Weight 0. Only the base prices are left: 5 for Standard, 10 for Express and 3 for Economy. Economy's 0 // 2 is 0, so the formula needs no special case.
    • Weight 1 on Economy. 1 // 2 is 0, so the cost is 3, the same as for an empty parcel.
    • Overriding only one method. A subclass that defines cost but not name inherits the parent's name, so it would call itself "Standard". Override both.
    • Misspelling a method name. A method called Name or costs is a new method, not an override, and the parent's version runs instead. The names and parameters must match the parent's.
    • Forgetting self. Every method in a class takes self as its first parameter, including cost(self, weight).
    • Forgetting the parent in the class line. class Express: makes an unrelated class. Write class Express(Shipping):.

    Key takeaways

    • A subclass overrides a method by defining one with the same name in its own class.
    • Python runs the version belonging to the object's own class, so code written for the parent works with every subclass.
    • Use // when the result must be a whole number rounded down.
    Keep going with Python500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free