いつの間にか4月ですね。
この時期はだんだん暑くなっていくのもあってあまり春らしさを意識せずに過ぎていってしまいます。
私はお店の支払いはクレジットか電子マネーですることがほとんどなんですが、
何にいくら使ったのかの感覚が残りづらいため、出費を意識できるものが必要だと常々考えていました。
(家計簿とか書くのはめんどくさいので無し)
そこでpythonで簡単な集計ツール作れないかなーと思い、ちょっとやってみました。
私はクレジットの支払いはvisaでやっているのですが、
管理サイトから月次で支払いの詳細がダウンロードできるのでこれを加工したいと思います。
結論: pythonだけじゃ厳しかった
csvモジュールと演算でできるかもと思っていたのですが、うまいこと集計できませんでした。
支払いの明細と金額を辞書に入れてcountとかで集計できそうな感じでしたが、加算されずに金額のみアップデートされてしまってできませんでした。
ダウンロードしたファイルのフォーマットや私の技術不足もあると思います。
おとなしくデータベースを使います
python勉強中ですが、これだけにこだわる必要はないので、おとなしく便利なデータベースを使って集計します。
サクッと集計が今回の目標なのでDBのデーモンは使わず、sqliteでチャレンジします。
- データベースはsqlite3を使う
メインマシンであるUbuntu 16.04LTS Desktopにはデフォルトでsqlite3がインストールされていました。
sqliteとの違いがいまいちわかりませんが、とりあえずこれでいいでしょう。
- データベースを作ります
credit.dbという名前でデータベースファイルを作ります。
ちなみに環境はvenvで仮想環境作ってます。
(python3) masashi@PC-ubuntu:~/python3/work$ sqlite3 credit.db SQLite version 3.11.0 2016-02-15 17:29:24 Enter ".help" for usage hints.
支払い一覧はcsvでダウンロードできます。
デフォルトの形式だといろいろ面倒なので、集計用に成形してます。
日付と明細と金額のみ記載しています。
sqlite> .mode csv sqlite> sqlite> .import 201801_02.csv 201801 Error: near "201801": syntax error
あれ、インポートできない。
数字のみなのがダメなのかな。
sqlite> .import 201801_02.csv t_201801
頭にt_(tableの意)をつけたら行けました。
- 確認
わー文字化けしてる。
ファイルを調べたら文字コードはCP932となっている様です。
sqlite> select * from t_201801; 2017/11/30,"���t�[�W���p��",498 2017/12/01,"�i�F�b�n�l�@�Q�T�|�r�X�p�b�N���p��",5431 2017/12/03,"�i�b�v�X�@���t�k�C���^�[�X",10022 2017/12/03,"�C�I�����e�[��",3419
カラムで絞れるか確認。
sqlite> select name from t_201801; Error: no such column: name sqlite>
このままじゃ絞れませんでした。
文字化けしてるからダメなのかな。
- 文字コードを修正して再挑戦
インポート時に変換できないか調べましたが、すぐ出てこなそうなのでGUIで修正して保存しなおし。
テーブルを削除して、再インポートします。
sqlite> drop table t_201801; sqlite> sqlite> .import 201801_02.csv t_201801 201801_02.csv:37: expected 3 columns but found 1 - filling the rest with NULL sqlite> sqlite> select * from t_201801; date,name,cost #これがヘッダ 2017/11/30,"インターネットイニシアティブ",1796 2017/11/30,"ヤフージャパン",498 …
お、行けました!
37行目でエラーはいてますが、一旦勧めます。
sqlite> select name from t_201801; name "インターネットイニシアティブ" "ヤフージャパン" …
カラムで絞っても大丈夫そうですね。
pythonからつつけるようにする
都度sql叩いて集計してもいいですが、せっかくなのでpython経由で出力できるようにします。
とはいってもこっちもsql叩くだけなんだけど…
#!/usr/bin/env python3 import sqlite3 database = 'credit.db' connection = sqlite3.connect(database) cursor = connection.cursor() for row in cursor.execute('select name, sum(cost) from t_201801 group by name'): print(row[0], row[1])
とりあえず簡単なコードです。
sqliteにアクセスしてname(明細)毎に金額を集計するだけです、
(python3) masashi@PC-ubuntu:~/python3/work$ python credit.py None None イオンリテール xxxx イトーヨーカ堂 (サインレス) xxxx インターネットイニシアティブ xxxx サンフエイス xxxx スウイ―ト カヴアカヴア xxxx スマートEX(JR東海) xxxx ツクモパソコン本店 xxxx ツダヌマ パルコ xxxx ナップス 千葉北インター店 xxxx ヤフージャパン xxxx 千石電商 秋葉原本店 1F xxxx 11月分 au電話利用料 xxxx Bar Vie Lembranca xxxx J:COM 2サ-ビスパック利用料 xxxx JR東日本モバイルSuica xxxx JR西日本 xxxx NETFLIX.COM xxxx
できました〜!
1月支払い分の明細の集計ができましたよ。
恥ずかしいので金額は隠します。
基本機能はできましたね。
もう少し改良して使い勝手を良くしていきたいと思います。
やりたいことメモ
- インポートするcsvファイル成形
- 今回は手動で修正しましたが、自動でやらせたい
- 固定費とそうでない出費を分ける
- 文字列判定でできそう
- Noneの行をスキップする判定を入れる
- 出力結果のカラムを綺麗にする
- 月ごとに出力できるようにする
- これは引数でできそう
あと、これからインポートファイルを増やしていくにしたがってテーブルの設計も考えないとですね。
(追加か別テーブルか)