Day 84:最終プロジェクト設計 ― 「ここから“作品づくり”が始まる」
Day 84は、90日コースの中でも特別な日です。 いよいよ 最終プロジェクトの設計 に入ります。
ここまで積み上げてきた Python の知識を、 ひとつの“形”としてまとめていく―― そんなワクワクする瞬間です。
今回の例として扱うのは、
売上管理・分析システム
という、実務でもよく使われるテーマ。 CSV、データベース、API、Excelレポートなど、 Pythonの強みをフル活用できる構成になっています。
プロジェクトの全体像を描く
「まずは、どんなシステムにしたいかを言葉にする」
売上管理・分析システムの機能は次のとおりです。
- CSVアップロード
- データチェック
- データベース保存
- 売上集計
- API提供
- Excelレポート出力
これらをひとつずつ、 初心者でも迷わないように丁寧に分解していきます。
CSVアップロード
「外からデータを受け取る入り口を作る」
CSVアップロードは、 システムにとって “外界との接点” です。
FastAPI を使う場合、 CSVファイルを受け取るエンドポイントを作ります。
# app/routes.py
from fastapi import APIRouter, UploadFile, File
from services.csv_service import process_csv
router = APIRouter()
@router.post("/upload")
async def upload_csv(file: UploadFile = File(...)):
"""
CSVファイルをアップロードして処理するエンドポイント。
"""
content = await file.read()
return process_csv(content)
Pythonここでのポイントは、
UploadFileを使うと、CSVをそのまま受け取れるprocess_csvに処理を委ねることで、役割が分かれる
というところです。
データチェック
「壊れたデータを入れないための“門番”」
CSVには、 時々「欠損」「型違い」「空欄」などの問題が含まれます。
これをそのままデータベースに入れてしまうと、 後で集計が壊れたり、APIがエラーになったりします。
そこで データチェック(バリデーション) が必要になります。
# services/csv_service.py
import csv
from io import StringIO
def process_csv(content: bytes) -> list[dict]:
"""
CSVの内容を読み込み、データチェックを行う。
"""
text = content.decode("utf-8")
reader = csv.DictReader(StringIO(text))
rows = []
for row in reader:
# 売上金額が空ならエラー
if row["amount"] == "":
raise ValueError("売上金額が空です")
# 数値に変換できるかチェック
try:
row["amount"] = int(row["amount"])
except ValueError:
raise ValueError("売上金額が整数ではありません")
rows.append(row)
return rows
Python重要ポイント:
- データチェックは「システムの安全性」を守る
- バリデーションは services 層に置くと整理しやすい
- エラーは例外で返し、API側でメッセージ化する
データベース保存
「データを“資産”として蓄積する場所」
売上データは、 毎日・毎月・毎年と積み重なっていくものです。
SQLite を使えば、 軽量で扱いやすいデータベースを簡単に導入できます。
# repositories/sales_repository.py
import sqlite3
def save_sales(rows: list[dict]) -> None:
"""
売上データをSQLiteに保存する。
"""
conn = sqlite3.connect("sales.db")
cur = conn.cursor()
for row in rows:
cur.execute(
"INSERT INTO sales (date, item, amount) VALUES (?, ?, ?)",
(row["date"], row["item"], row["amount"])
)
conn.commit()
conn.close()
Pythonポイント:
- repositories 層は「データの出し入れ専用」
- services → repositories の流れが美しい構造になる
売上集計
「データを“意味のある情報”に変える瞬間」
集計は、 システムの価値を決める大事な機能です。
# services/report_service.py
import sqlite3
def get_total_sales() -> int:
"""
売上の合計を返す。
"""
conn = sqlite3.connect("sales.db")
cur = conn.cursor()
cur.execute("SELECT SUM(amount) FROM sales")
total = cur.fetchone()[0]
conn.close()
return total or 0
Pythonここでのポイントは、
- 集計は services 層に置く
- データベースの生データは repositories に任せる
- services は「意味のある値」を返す
という役割分担です。
API提供
「集計結果を外部に公開する“窓口”」
FastAPI を使えば、 集計結果を簡単にAPIとして公開できます。
# app/routes.py
from services.report_service import get_total_sales
@router.get("/report/total")
def report_total():
"""
売上合計を返すAPI。
"""
return {"total_sales": get_total_sales()}
Pythonこれで、
- Webブラウザ
- 他のシステム
- スマホアプリ
などから売上データを取得できるようになります。
Excelレポート出力
「人が読める“成果物”としてまとめる」
Excelレポートは、 実務でとても喜ばれる機能です。
pandas を使えば、 簡単にExcelファイルを生成できます。
# services/excel_service.py
import pandas as pd
def export_excel(path: str) -> None:
"""
売上データをExcelレポートとして出力する。
"""
conn = sqlite3.connect("sales.db")
df = pd.read_sql_query("SELECT * FROM sales", conn)
conn.close()
# Excelに書き出し
df.to_excel(path, index=False)
Pythonポイント:
- pandas は Excel出力が得意
- データベース → DataFrame → Excel の流れが自然
Day 84ミニテンプレート
「このまま使えるプロジェクト構成」
project/
├── app
│ └── routes.py
├── services
│ ├── csv_service.py
│ ├── report_service.py
│ └── excel_service.py
├── repositories
│ └── sales_repository.py
├── models
│ └── sales.py
├── config
│ └── settings.py
├── tests
│ └── test_sales.py
└── main.py
Day 84のまとめ
「設計は、作品の“骨格”をつくる大事な時間」
今日の主役は、
- CSVアップロード
- データチェック
- データベース保存
- 売上集計
- API提供
- Excelレポート出力
でした。
これらを組み合わせることで、
「実務でも使える本格的な売上管理・分析システム」
が完成します。
Day 84は、 コードを書く前の“設計”に集中する日。
設計がしっかりしていると、 この先の実装が驚くほどスムーズになります。
