Python お金の健康

Pythonで1年間の家計簿を自動処理するプログラムを作った話【プログラム付き】

こんにちは、ウチダです。

休日に趣味でプログラミングを独学し、
家計簿や顧客リストの作成、ブログでの
データ分析に役立てています。
 
副業ではFXの自動売買プログラムを販売しています。

家計簿を1年間つけたのはいいけど、

「1年間でいくら貯金できたの?」

「生活費にいくら使っているんだろう?」

と悩んでいませんか?

実はPythonで1年間の家計簿

自動処理できるんです。

なぜこんなことが言えるかといえば

私が実際にPythonで家計簿の処理を自動化しているからです。

この記事では1年間の家計簿を自動で処理して

1年間の収支や各項目の費用をまとめる方法を紹介します。

この記事を読み終えると、

Pythonでデータ処理する方法の基本が分かり、

仕事や投資にも応用できるようになります。

Pythonで1年間の家計簿を自動処理しよう

Pythonで1年間の家計簿を自動処理しよう

これまでの記事では、

Pythonで毎月の家計簿を自動で

処理する方法を紹介しました。

参考↓

さらに、前回はプログラムを改良し、

家計簿の処理結果をメールで送るようにしました↓

ただ、これでは毎月の家計簿のデータが溜まっていくだけで、

1年間の収支が分かりませんよね。

そこで、今回は毎月の家計簿のデータを

とりまとめ、1年間の収支を計算する

プログラムを作成します。

Pythonで1年間の家計簿をまとめる

#ライブラリのインポート
import glob
import pandas as pd

#家計簿ファイルをまとめて選択
files=glob.glob('2020*.xlsx')

#家計簿ファイルを1箇所に集める
list = []
for file in files:
    list.append(pd.read_excel(file))

#家計簿を1つのファイルにまとめる
df = pd.concat(list)
df.to_excel('total.xlsx', index=False) #保存

まず1年分の家計簿を1つのファイルにまとめます。

globメソッドを使って

ファイル名が「2020」から始まっており、

かつ拡張子が.xlsxのファイルを読み込みました。

こちらをappendメソッドを使って

空のリストにまとめました。

そしてpandasのconcatで1つのエクセルファイルに結合し、

「total.xlsx」という名前で保存しています。

これで1年分の家計簿が1つのファイルにまとまりました。

こんな短いコードでできるので、

Pythonは人気なんです。

次に分析していきます。

Pythonで1年間の収支を計算する

#収入
get_df = df.loc[df['収入/支出'] == '収入']
get_money = get_df['合計'].sum()

#支出
pay_df = df.loc[df['収入/支出'] == '支出']
pay_money = pay_df['合計'].sum()

#収入、支出、収支の表示
print('収入の合計:'+ str(get_money))
print('支出の合計:' + str(pay_money))
print('2020年の収支:' + str(get_money + pay_money))

#ひろの収入
hiroget_df = get_df.loc[get_df['payer'] == 'hiro']
hiroget_money = hiroget_df['合計'].sum()

#みさの収入
misaget_df = get_df.loc[get_df['payer'] == 'misa']
misaget_money = misaget_df['合計'].sum()

収入と支出を計算して

収支を計算しました。

さらにpayerを絞り込むことで

夫婦それぞれの収入も確認できます。

.loc[条件]と書けば、条件を満たすデータだけ

抽出できるんです。

さらに.sum()で合計額を計算しています。

Pythonで家計簿の各項目を調べる

#調べたい項目
list = ['食費','日用','治療','交通','教育','葬祭','家賃','水光熱','ローン','通信','投資']

#各項目の支出を調べる
each_data = []
for i in list:
    each_df = df.loc[df['メモ'].str.contains(i)]
    print(each_df)
    each_data.append(each_df)
    each_data.append('-' * 10)
    each_sum = i + 'の小計:'+str(each_df['合計'].sum())
    print(each_sum)
    each_data.append(each_sum)
    each_data.append('-' * 10)
    print('-' * 10)

#メールの本文に使うデータ
kekka3 = ''
for j in each_data:
    kekka3 += str(j) + '\n'

次に.loc[条件]を使って、

食費や日用雑貨費、交通費などの各項目の

支出を調べます。

.contains(特定の文字)は、特定の文字を含む

データを抽出できます。

そして、各項目の支出の合計額を

.sum()で計算しています。

Pythonで1年間の家計簿の処理結果をメールで送信する

import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
import base64
from email.mime.text import MIMEText
from apiclient import errors

# 1. Gmail APIのスコープを設定
SCOPES = ['https://www.googleapis.com/auth/gmail.send']

# 2. メール本文の作成
def create_message(sender, to, subject, message_text):
    message = MIMEText(message_text)
    message['to'] = to
    message['from'] = sender
    message['subject'] = subject
    encode_message = base64.urlsafe_b64encode(message.as_bytes())
    return {'raw': encode_message.decode()}

# 3. メール送信の実行
def send_message(service, user_id, message):
    try:
        message = (service.users().messages().send(userId=user_id, body=message)
                   .execute())
        print('Message Id: %s' % message['id'])
        return message
    except errors.HttpError as error:
        print('An error occurred: %s' % error)

# 4. メインとなる処理
def main(i,mess,sbj):
    # 5. アクセストークンの取得
    creds = None
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                    'credentials.json', SCOPES)
            creds = flow.run_local_server()
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)
    service = build('gmail', 'v1', credentials=creds)
    
       # 6. メール本文の作成
    sender = '<送り主のメールアドレス>'
    to = i
    subject = sbj
    message_text = mess
    message = create_message(sender, to, subject, message_text)
    # 7. Gmail APIを呼び出してメール送信
    send_message(service, 'me', message)

# 8. プログラム実行!
if __name__ == '__main__':
    sbj = '''
    2020年の家計簿
    '''
    
    mess = '''
    2020年の家計簿\n
    収入:{0}\n
    支出:{1}\n
    2020年の収支:{2}\n
    ---------
    hiroの収入:{3}\n
    misaの収入:{4}\n
    ----------
    各項目\n
    {5}
    
    '''.format(str(get_money), #収入
              str(pay_money), #支出
               str(get_money + pay_money), #収支
               str(hiroget_money), #ヒロの収入
               str(misaget_money), #ミサの収入
               kekka3 #各項目の家計簿
              )
    to_list = ['<送り先のメールアドレス>']
    for i in to_list:
        main(i,mess,sbj)   

最後にPythonで家計簿の処理が完了したら

Gメールで私と妻に連絡します。

PythonでGmailを送信する時は

GmailAPIを有効化させる必要があります。

(参考:Gmail APIとPythonを使ってメール送信を自動化する方法

そして、メールの本文に家計簿の処理結果をのせて

送信させます。

送られた結果がこちらです。

Pythonで家計簿を自動で処理した結果
Pythonで家計簿を自動で処理した結果

警告文があり、怪しいメールになってしまいましたが、

無事にPythonで家計簿の処理結果をメールできました。


Pythonはデータ処理に強みがある

プログラミング言語です。

中でも家計簿は最も身近で、

かつ生活に役立つ教材です。

ぜひプログラミング言語Pythonに挑戦してみませんか?

これからの習い事は家でプログラミングですね。

ここまで読んでくださり、ありがとうございました。^^

-Python, お金の健康
-