月間レポート機能
4 つの数字を、どの順で作るか
run_kakeibo で追加と削除ができるようになりました。ただ、記録が溜まっただけでは何も分かりません。「今月は何にいくら使ったのか」を一目で分かる形にするのが今回の仕事です。
レポートに載せるのは 4 つです。合計の total、カテゴリごとの合計を入れた by_category、いちばん高かった支出の品名 top、予算からの残り remaining。この 4 つをキーに持つ辞書を返します。
このうち total は第 6 章、by_category は第 7 章ですでに作りました。remaining は予算から合計を引くだけです。本当に新しいのは top だけなので、そこに時間を使います。完成間近のアプリに機能を足すとき、ゼロから考えることはめったにありません。
進め方としては、まず total だけを返す形で通し、次に by_category を足し、最後に top を足します。1 つ足すごとに結果を見れば、どこで崩れたのかがすぐ分かります。
4 つとも同じ記録を見るので、ループは 1 周で足ります。分けて 3 周してもかまいませんが、1 周にまとめるほうが素直です。remaining の引き算だけはループの外に置きます。中で引くと、最後の 1 件を足す前の値が残ります。
最高額の初期値を、どこに置くか
top を求めるには、「今までで一番高い金額」を覚えておく変数が要ります。この初期値が地味な勘所です。
0 から始めると、0 円の記録しかない月に 1 件も選ばれず、top が空文字のまま返ります。金額は 0 以上なので、必ずそれより小さい値、たとえば -1 から始めれば 1 件目で必ず入れ替わります。
同じ金額が 2 件並んだときの扱いも決めておきます。比較を「より大きい」にすれば先に出てきたほうが残り、「以上」にすれば後のほうへ入れ替わります。今回は先に出てきたほうを採用します。どちらでもよい仕様ですが、決めていないコードはいつか必ず食い違います。
なお top に入れるのは品名の文字列です。金額を覚えておく変数は探すための作業用で、戻り値には入れません。
記録が 0 件のときを、先に確かめる
初回起動や月が変わった直後は、記録が空です。ここを最初に通しておくと、あとが楽になります。
Python
monthly_report([], 3000)期待する戻り値は {"total": 0, "by_category": {}, "top": "", "remaining": 3000} です。ループが 1 度も回らないので、それぞれの初期値がそのまま返ります。初期値を素直に置いておけば、空リスト用の場合分けは要りません。
逆に、予算を超えた月も確かめます。remaining は 0 で止めず、負の数のまま返します。-1300 と出るからこそ、いくら超えたのかが分かります。
やってみよう
関数 monthly_report(records, budget) を実装してください。records は支出の辞書のリスト、budget は予算の整数です。
{"total": 合計金額, "by_category": カテゴリ別の合計の辞書, "top": 最高額の品名, "remaining": 予算から合計を引いた値} の辞書を返します。同じ金額が並んだときは先に出てきたほうを top にします。記録が空のときは top を ""、by_category を {}、remaining を budget にしてください。
要件
- 関数名は monthly_report で、引数は records と budget の2つ
- 戻り値は total と by_category と top と remaining の4つのキーを持つ辞書
- by_category は同じカテゴリの金額を足し合わせた辞書にする
- top は最高額の品名。同額なら先に出てきたほうを採用する
- 記録が空のときは top を空文字、by_category を空の辞書、remaining を budget にする
- 予算を超えたときも remaining は負の数のまま返す