🤖
pythonをチャッピー(ChatGPT)に教えてもらう (Excel自動化ツール) #3
はじめに
しばらく実務でコーディングの機会がなかったので、定期的にChatGPTから課題をもらって、それを解くことでコーディングの習慣を取り戻したいと思います。
チャッピー(ChatGPT)から与えられた課題
課題: Excel自動化ツール
課題概要: 売上データが格納されたExcelファイルを読み込み、月ごとに集計を行う
ステップ:
1. openpyxlライブラリを使ってExcelファイルを読み込み。
2. 月ごとにデータを集計し、売上額を計算。
3. 加工したデータを新しいExcelファイルとして保存。
難易度: 中級
使用するライブラリ: openpyxl, pandas
追加のヒント:
データの集計には、pandasを併用すると効率的に処理できます。
自分で書いたソースコード
import openpyxl
import pandas as pd
from pandas import DataFrame
from openpyxl.workbook import Workbook
def read_excel(file_path: str) -> DataFrame:
# Excelファイルを読み込む
return pd.read_excel(file_path)
def aggregate_sales(data: DataFrame) -> DataFrame:
# 月ごとに売上を集計
data['月'] = data['Date'].dt.to_period('M')
monthly_sales = data.groupby(['月'])['Total Sales'].sum().reset_index()
return monthly_sales
def save_to_excel(workbook: Workbook, output_path: str) -> None:
# 新しいExcelファイルとして保存
workbook.save(output_path)
def main(input_file: str, output_file: str) -> None:
# メイン処理
data = read_excel(input_file)
monthly_sales = aggregate_sales(data)
# 新しいExcelワークブックを作成
workbook = openpyxl.Workbook()
sheet = workbook.active
sheet.title = "月ごとの売上"
# ヘッダーを追加
sheet.append(['月', '売上額'])
for index, row in monthly_sales.iterrows():
sheet.append([row['月'].strftime('%Y-%m'), row['Total Sales']])
save_to_excel(workbook, output_file)
if __name__ == "__main__":
input_file = 'daily_sales_with_products.xlsx' # 入力ファイル名
output_file = '集計結果.xlsx' # 出力ファイル名
main(input_file, output_file)
チャッピー(ChatGPT)の評価
90点程度/100点
このコードをさらに改善して実務レベルでの利用に近づけるには、上記の改善案を取り入れるとより高い完成度が期待できます。また、エラーハンドリングやデータフォーマットの強化を行うことで、利用者に優しいツールになります。
リファクタリング
リファクタリングの主なポイント
-
エラー処理
ファイルの存在確認や列名のチェックを追加。
日付変換に失敗した場合に対処。 -
柔軟性
列名やフォーマットエラーに対応。 -
フォーマット調整
列幅自動調整やセルの中央揃え。
ヘッダー行を太字に設定。 -
再利用性の向上
Excelフォーマット部分を関数化。
修正後のソースコード
import pandas as pd
from pandas import DataFrame
from openpyxl import Workbook
from openpyxl.styles import Alignment, Font
def read_excel(file_path: str) -> DataFrame:
"""
Excelファイルを読み込む
"""
try:
data = pd.read_excel(file_path)
if 'Date' not in data.columns or 'Total Sales' not in data.columns:
raise KeyError("必要な列('Date', 'Total Sales')が存在しません。")
if not pd.api.types.is_datetime64_any_dtype(data['Date']):
data['Date'] = pd.to_datetime(data['Date'], errors='coerce')
return data
except FileNotFoundError:
raise FileNotFoundError(f"ファイルが見つかりません: {file_path}")
except Exception as e:
raise Exception(f"エラーが発生しました: {e}")
def aggregate_sales(data: DataFrame) -> DataFrame:
"""
月ごとに売上を集計
"""
data['月'] = data['Date'].dt.to_period('M')
monthly_sales = data.groupby(['月'])['Total Sales'].sum().reset_index()
return monthly_sales
def format_excel_sheet(sheet) -> None:
"""
Excelシートのフォーマットを調整
"""
for col in sheet.columns:
max_length = max(len(str(cell.value)) if cell.value else 0 for cell in col)
sheet.column_dimensions[col[0].column_letter].width = max_length + 2
for row in sheet.iter_rows():
for cell in row:
cell.alignment = Alignment(horizontal='center', vertical='center')
if row[0] == sheet[1]:
cell.font = Font(bold=True)
def save_to_excel(data: DataFrame, output_path: str) -> None:
"""
集計データをExcelファイルとして保存
"""
workbook = Workbook()
sheet = workbook.active
sheet.title = "月ごとの売上"
# ヘッダーとデータを追加
sheet.append(['月', '売上額'])
for _, row in data.iterrows():
sheet.append([row['月'].strftime('%Y-%m'), row['Total Sales']])
# フォーマット調整
format_excel_sheet(sheet)
workbook.save(output_path)
def main(input_file: str, output_file: str) -> None:
"""
メイン処理
"""
try:
data = read_excel(input_file)
monthly_sales = aggregate_sales(data)
save_to_excel(monthly_sales, output_file)
print(f"集計結果を保存しました: {output_file}")
except Exception as e:
print(f"エラー: {e}")
if __name__ == "__main__":
input_file = 'daily_sales_with_products.xlsx' # 入力ファイル名
output_file = 'monthly_sales_summary.xlsx' # 出力ファイル名
main(input_file, output_file)
学んだポイント
- 忘れがちなエラーハンドリングを意識しよう
- excelのフォーマット調整など、人に親切な成果物を意識して書く習慣を身に着けたい
Discussion