Sorting Stocks and Bonds in Python

Sorting Stocks and Bonds in Python

In this programming challenge, we’re tasked with building on a previously developed codebase, adding new functionality to manage stocks and bonds in a more Pythonic way. Specifically, we’re going to implement sorting logic for these financial assets based on different criteria: stocks will be sorted by their price, and bonds by their yield, both in ascending order.

To make this happen, we’ll make use of Python’s magic methods, which enable us to customize how objects of our classes are represented and compared.

Challenge Overview

The core of this challenge is to refactor an existing class hierarchy for financial assets by:

  • Replacing a custom get_description function with Python’s built-in __str__ method to get a string representation of each asset.
  • Implementing the __lt__ method to enable sorting functionality, based on the price for stocks and the yield for bonds.

Let’s dive into the solution and explore how we can achieve this step by step.

1. Setting Up the Asset Class

We start with an abstract base class called Asset, which represents a financial asset, like stocks and bonds. We need to define the __str__ method, which will return a human-readable string for each asset.

Additionally, we need to implement the __lt__ (less than) magic method to allow sorting based on different attributes depending on whether the asset is a stock or a bond.

				
					from abc import ABC, abstractmethod

class Asset(ABC):
    def __init__(self, name):
        self.name = name

    @abstractmethod
    def __str__(self):
        pass

    @abstractmethod
    def __lt__(self, other):
        pass

				
			

Here, Asset is an abstract base class (ABC), which means that both the __str__ and __lt__ methods must be implemented by subclasses.

2. Defining the Stock Class

The Stock class inherits from Asset and represents a stock. We implement the __str__ method to print out stock information and the __lt__ method to allow sorting by the stock price.

				
					class Stock(Asset):
    def __init__(self, name, price):
        super().__init__(name)
        self.price = price

    def __str__(self):
        return f"Stock: {self.name}, Price: {self.price}"

    def __lt__(self, other):
        return self.price < other.price

				
			

In the __lt__ method, we compare the stock prices. This allows Python’s built-in sort() function to sort a list of Stock objects based on their price.

3. Defining the Bond Class

Similarly, we define the Bond class, which represents a bond. Bonds are sorted by their yield, so we customize the __lt__ method accordingly.

				
					class Bond(Asset):
    def __init__(self, name, yield_amount):
        super().__init__(name)
        self.yield_amount = yield_amount

    def __str__(self):
        return f"Bond: {self.name}, Yield: {self.yield_amount}"

    def __lt__(self, other):
        return self.yield_amount < other.yield_amount

				
			

Here, bonds are compared by their yield amounts in the __lt__ method.

4. Sorting the Stocks and Bonds

Now, let’s move on to sorting a list of stocks and bonds. With the __lt__ method defined, Python will handle the sorting logic when we call sort().

				
					if __name__ == "__main__":
    stocks = [
        Stock("Apple", 150),
        Stock("Google", 100),
        Stock("Amazon", 120)
    ]
    
    bonds = [
        Bond("US Treasury", 2.5),
        Bond("Corporate Bond", 3.0),
        Bond("Municipal Bond", 1.8)
    ]
    
    stocks.sort()
    bonds.sort()

    print("Sorted Stocks:")
    for stock in stocks:
        print(stock)

    print("\nSorted Bonds:")
    for bond in bonds:
        print(bond)

				
			

Explanation:

  • We create two lists: stocks and bonds.
  • Each list contains multiple objects of the Stock and Bond classes.
  • We sort both lists using the sort() method. The __lt__ method for each class takes care of the sorting logic.
  • Finally, we print the sorted stocks and bonds.

5. Running the Code

After running the code, we get the following output:

				
					Sorted Stocks:
Stock: Google, Price: 100
Stock: Amazon, Price: 120
Stock: Apple, Price: 150

Sorted Bonds:
Bond: Municipal Bond, Yield: 1.8
Bond: US Treasury, Yield: 2.5
Bond: Corporate Bond, Yield: 3.0

				
			

As expected, the stocks are sorted by their price in ascending order, and the bonds are sorted by their yield in ascending order.

Conclusion

This challenge is a great way to practice working with Python’s magic methods, especially __str__ and __lt__. By leveraging these, we can enhance our classes to behave more like Python’s built-in types, making them sortable and printable.

Using the sort() function in combination with the __lt__ method helps streamline the sorting of complex objects like stocks and bonds, with minimal extra code.

Now, it’s your turn to try it out! Happy coding!