はじめに
この実験では、株式保有を表すために設計された Stock クラスを拡張する方法を学びます。このクラスに新しいメソッドと機能を追加し、より汎用的で有用なものにします。
この実験の目的は、既存の Stock クラスに sell メソッドを追加し、CSV ファイルから株式ポートフォリオデータを読み取る関数を作成し、ポートフォリオデータを整形された表形式で表示する別の関数を作成することです。変更するファイルは stock.py です。
Stock クラスに sell メソッドを追加する
このステップでは、新しいメソッドを追加することで Stock クラスを拡張します。メソッドは、クラスに属する特別な関数で、そのクラスから作成されたオブジェクトを操作することができます。sell(nshares) という名前のメソッドを作成し、株式の売却アクションをシミュレートします。株式を売却すると、保有する株式数が減少し、このメソッドがその減少を処理します。
メソッドとは何か?
まず、メソッドが何であるかを理解しましょう。メソッドは、クラスの内部で定義された関数です。そのクラスのインスタンス(個々のコピーのようなもの)を操作するように設計されています。オブジェクトに対してメソッドが呼び出されると、そのオブジェクトのすべての属性(特性)にアクセスすることができます。これは self パラメータを通じて行われます。self パラメータは、メソッドが呼び出されているオブジェクトへの参照です。したがって、メソッドの内部で self を使用するときは、そのメソッドが作用している特定のオブジェクトを参照しています。
実装手順
- まず、エディタで
stock.pyファイルを開く必要があります。これを行うには、コマンドラインを使用します。ターミナルを開き、次のコマンドを実行します。このコマンドは、stock.pyファイルがあるprojectフォルダにディレクトリを変更します。
cd ~/project
stock.pyファイルを開いたら、Stockクラス内の特定のコメントを見つける必要があります。## TODO: Add sell(nshares) method hereというコメントを探します。このコメントは、新しいsellメソッドを追加する場所を示すプレースホルダーです。次に、
sellメソッドを追加しましょう。このメソッドはnsharesというパラメータを受け取り、これは売却したい株式数を表します。このメソッドの主な役割は、Stockオブジェクトのshares属性を売却する株式数だけ減らすことです。
以下は追加する sell メソッドのコードです。
def sell(self, nshares):
self.shares -= nshares
このコードでは、self.shares は Stock オブジェクトの shares 属性を参照しています。-= 演算子は、self.shares の現在の値から nshares の値を減算します。
sellメソッドを追加したら、stock.pyファイルを保存する必要があります。キーボードでCtrl+Sを押すか、エディタのメニューから「ファイル > 保存」を選択して保存できます。sellメソッドが正しく動作することを確認するために、テストスクリプトを作成します。test_sell.pyという名前の新しい Python ファイルを作成し、以下のコードを追加します。
## test_sell.py
from stock import Stock
## Create a stock object
s = Stock('GOOG', 100, 490.10)
print(f"Initial shares: {s.shares}")
## Sell 25 shares
s.sell(25)
print(f"Shares after selling: {s.shares}")
このスクリプトでは、まず stock.py ファイルから Stock クラスをインポートします。次に、株式シンボルが GOOG、株式数が 100、価格が 490.10 の Stock オブジェクト s を作成します。最初の株式数を表示します。その後、s オブジェクトに対して sell メソッドを呼び出して 25 株を売却します。最後に、売却後の株式数を表示します。
- 次に、テストスクリプトを実行して、
sellメソッドが期待通りに動作するかを確認します。再度ターミナルを開き、次のコマンドを実行します。
python3 test_sell.py
すべてが正しく動作している場合、次のような出力が表示されるはずです。
Initial shares: 100
Shares after selling: 75
この出力は、sell メソッドが正しく動作していることを確認します。指定した数量だけ株式数を正常に減らしています。
CSV ファイルからポートフォリオを読み取る
このステップでは、CSV ファイルから株式データを読み取り、Stock オブジェクトのリストを返す関数を作成します。Stock オブジェクトは株式保有を表し、このステップの最後までに、CSV ファイルから株式ポートフォリオを読み取ることができるようになります。
CSV ファイルの理解
CSV は Comma-Separated Values の略で、表形式のデータを保存するための非常に一般的な形式です。簡単なスプレッドシートのようなものと考えてください。CSV ファイルの各行はデータの行を表し、その行内の列はコンマで区切られています。通常、CSV ファイルの最初の行にはヘッダーが含まれています。これらのヘッダーは、各列にどのようなデータが含まれているかを説明します。たとえば、株式ポートフォリオの CSV では、ヘッダーは「Name」、「Shares」、「Price」になるかもしれません。
実装手順
まず、コードエディタで
stock.pyファイルを開きます。すでに開いていれば問題ありません。開いていない場合は、それを見つけて開きます。ここに新しい関数を追加します。stock.pyファイルが開いたら、## TODO: Add read_portfolio(filename) function hereというコメントを探します。このコメントは、新しい関数を配置する場所を示すプレースホルダーです。そのコメントの下に、次の関数を追加します。この関数は
read_portfolioと呼ばれ、ファイル名を引数として受け取ります。この関数の目的は、CSV ファイルを読み取り、株式データを抽出し、Stockオブジェクトのリストを作成することです。
def read_portfolio(filename):
"""
Read a CSV file containing portfolio data and return a list of Stock objects.
Args:
filename (str): Path to the CSV file
Returns:
list: A list of Stock objects
"""
portfolio = []
with open(filename, 'r') as f:
headers = next(f).strip().split(',') ## Skip the header line
for line in f:
row = line.strip().split(',')
name = row[0]
shares = int(row[1])
price = float(row[2])
## Create a Stock object and add it to the portfolio list
stock = Stock(name, shares, price)
portfolio.append(stock)
return portfolio
この関数が何をするかを分解してみましょう。まず、portfolio という空のリストを作成します。次に、CSV ファイルを読み取りモードで開きます。next(f) 文は最初の行(ヘッダー行)をスキップします。その後、ファイルの各行をループします。各行について、その行を値のリストに分割し、名前、株式数、価格を抽出し、Stock オブジェクトを作成し、portfolio リストに追加します。最後に、portfolio リストを返します。
関数を追加したら、
stock.pyファイルを保存します。キーボードでCtrl+Sを押すか、コードエディタのメニューから「ファイル > 保存」を選択して保存できます。ファイルを保存することで、変更が保存されます。次に、
read_portfolio関数をテストする必要があります。test_portfolio.pyという名前の新しい Python スクリプトを作成します。このスクリプトはstock.pyファイルからread_portfolio関数をインポートし、CSV ファイルからポートフォリオを読み取り、ポートフォリオ内の各株式に関する情報を印刷します。
## test_portfolio.py
from stock import read_portfolio
## Read the portfolio from the CSV file
portfolio = read_portfolio('portfolio.csv')
## Print information about each stock
for stock in portfolio:
print(f"Name: {stock.name}, Shares: {stock.shares}, Price: ${stock.price:.2f}")
## Print the total number of stocks in the portfolio
print(f"\nTotal number of stocks in portfolio: {len(portfolio)}")
このスクリプトでは、まず read_portfolio 関数をインポートします。次に、ファイル名 portfolio.csv を指定して関数を呼び出し、Stock オブジェクトのリストを取得します。その後、リストをループして各株式に関する情報を印刷します。最後に、ポートフォリオ内の株式の総数を印刷します。
- テストスクリプトを実行するには、ターミナルまたはコマンドプロンプトを開き、
test_portfolio.pyファイルがあるディレクトリに移動して、次のコマンドを実行します。
python3 test_portfolio.py
すべてが正しく動作している場合、portfolio.csv ファイル内のすべての株式の名前、株式数、価格が一覧表示された出力が表示されるはずです。また、ポートフォリオ内の株式の総数も表示されます。
Name: AA, Shares: 100, Price: $32.20
Name: IBM, Shares: 50, Price: $91.10
Name: CAT, Shares: 150, Price: $83.44
Name: MSFT, Shares: 200, Price: $51.23
Name: GE, Shares: 95, Price: $40.37
Name: MSFT, Shares: 50, Price: $65.10
Name: IBM, Shares: 100, Price: $70.44
Total number of stocks in portfolio: 7
この出力は、read_portfolio 関数が CSV ファイルを正しく読み取り、そのデータから Stock オブジェクトを作成していることを確認します。
ポートフォリオデータの整形と表示
このステップでは、ポートフォリオデータを整然とした表形式で表示する関数を作成します。ポートフォリオは株式の集合であり、このデータを明確かつ読みやすい方法で提示することは重要です。そこで print_portfolio(portfolio) 関数が役立ちます。この関数はポートフォリオを入力として受け取り、ヘッダー付きで適切に整列された表形式で表示します。
Python での文字列整形
Python では、文字列の整形方法が複数あります。文字列整形は、データをより整理された、ユーザーにやさしい方法で提示できるため、重要なスキルです。
%演算子は古い形式の文字列整形方法です。文字列内の特定の場所に値を挿入できるテンプレートのようなものです。str.format()メソッドは別の方法です。文字列の整形において、より柔軟性があり、クリーンな構文を提供します。- f - 文字列は Python 3.6 以降で導入された機能です。文字列リテラル内に式を埋め込むことができるため、非常に便利です。
この演習では % 演算子を使用します。固定幅の列を作成する場合に特に便利で、これはポートフォリオ表に必要な機能です。
実装手順
まず、エディタで
stock.pyファイルを開きます。すでに開いていれば問題ありません。このファイルにprint_portfolio関数を記述します。ファイルを開いたら、
## TODO: Add print_portfolio(portfolio) function hereというコメントを探します。このコメントは、新しい関数を追加する場所を示すマーカーです。そのコメントの下に、次の関数を追加します。
def print_portfolio(portfolio):
"""
Print the portfolio data in a nicely formatted table.
Args:
portfolio (list): A list of Stock objects
"""
## Print the header row
print('%10s %10s %10s' % ('name', 'shares', 'price'))
## Print a separator line
print('-' * 10 + ' ' + '-' * 10 + ' ' + '-' * 10)
## Print each stock in the portfolio
for stock in portfolio:
print('%10s %10d %10.2f' % (stock.name, stock.shares, stock.price))
この関数はまず表のヘッダー行を表示し、次に区切り線を表示し、最後にポートフォリオ内の各株式をループして、その詳細を整形して表示します。
関数を追加したら、ファイルを保存します。
Ctrl+Sを押すか、メニューから「ファイル > 保存」を選択して保存できます。ファイルを保存することで、変更が保存されます。次に、関数をテストする必要があります。
test_print.pyという名前の新しいファイルを作成します。このファイルがテストスクリプトになります。以下のコードを追加します。
## test_print.py
from stock import read_portfolio, print_portfolio
## Read the portfolio from the CSV file
portfolio = read_portfolio('portfolio.csv')
## Print the portfolio as a formatted table
print_portfolio(portfolio)
このスクリプトは stock.py ファイルから read_portfolio と print_portfolio 関数をインポートします。次に、CSV ファイルからポートフォリオデータを読み取り、新しく作成した print_portfolio 関数を使用して表示します。
- 最後に、テストスクリプトを実行します。ターミナルを開き、次のコマンドを入力します。
python3 test_print.py
すべてが正しく動作している場合、次のような出力が表示されるはずです。
name shares price
---------- ---------- ----------
AA 100 32.20
IBM 50 91.10
CAT 150 83.44
MSFT 200 51.23
GE 95 40.37
MSFT 50 65.10
IBM 100 70.44
この出力は、print_portfolio 関数が期待通りに動作していることを確認します。ヘッダー付きで列が整列された表形式でポートフォリオデータを整形して表示し、読みやすくなっています。
文字列整形の理解
print_portfolio 関数での文字列整形がどのように機能するかを詳しく見てみましょう。
%10sは文字列の整形に使用されます。10はフィールドの幅を示し、sは文字列を表します。幅 10 のフィールド内で文字列を右寄せにします。%10dは整数の整形に使用されます。10はフィールドの幅で、dは整数を表します。幅 10 のフィールド内で整数を右寄せにします。%10.2fは浮動小数点数の整形に使用されます。10はフィールドの幅で、.2は浮動小数点数を小数点以下 2 桁で表示することを指定します。幅 10 のフィールド内で浮動小数点数を右寄せにします。
この整形により、表のすべての列が適切に整列され、出力が読みやすく理解しやすくなります。
まとめ
この実験では、Stock クラスに新しい機能を追加する方法を学びました。株式の売却をシミュレートする sell メソッドを追加し、CSV ファイルから株式データを読み取り Stock オブジェクトに変換する read_portfolio 関数を作成し、ポートフォリオデータを整形された表形式で表示する print_portfolio 関数を開発しました。
クラス内でメソッドを定義すること、ファイルを操作しデータを解析すること、出力を読みやすく整形することなどのこれらのスキルは、Python のオブジェクト指向プログラミングにおける基本的な要素です。これらの概念を適用して、Python プログラムでより複雑なクラスやユーティリティを作成することができるようになりました。