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
andbonds
. - Each list contains multiple objects of the
Stock
andBond
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!