つくる:入力できるおこづかい帳
このレッスンで作るもの — 第 2 章の総仕上げとして、渡された品名と金額でレシートを組み立てる
make_receiptに作り替えます。
つくる — 入力できるおこづかい帳
第 1 章の最後に作った make_receipt は、こうでした。
def make_receipt():
# 合計 200 は りんご 120 と みかん 80 の和
return "=== おこづかい帳 ===" + "\n" + "りんご 120円" + "\n" + "みかん 80円" + "\n" + "合計 200円"引数を取らず、いつ呼んでも同じ 4 行を返す関数でした。あのときは変数も型変換もまだ習っていなかったので、全部を決め打ちにするしかありませんでした。
今日はこれを make_receipt(name, price) に進化させます。品名と金額を外から受け取り、その値でレシートを作ります。
4 行から 3 行へ
第 1 章では、りんごとみかんの 2 件が書いてありました。今回受け取るのは 1 件ぶんの品名と金額です。そこで行の構成をこう変えます。
=== おこづかい帳 ===
りんご 120円
合計 120円見出し、品物 1 行、合計の 3 行です。件数が 2 から 1 に減ったぶん、行も 4 から 3 になりました。
品物が 1 件しかないので、合計は金額そのものです。第 1 章では 120 + 80 を人が計算して 200 と書いていましたが、今回は計算そのものがいりません。同じ price を 2 か所で使うだけです。
何件でも受け取れるようにするには、リストと繰り返しが必要です。それは第 5 章の課題になります。まずは 1 件を確実に扱えるようにします。
組み立て方
前のレッスンの receipt_line がそのまま使えます。
def make_receipt(name, price):
line = f"{name} {price}円"
total = f"合計 {price}円"
return f"=== おこづかい帳 ===\n{line}\n{total}"品物の行と合計の行をそれぞれ変数に入れ、最後に f-string でまとめています。{line} と {total} の中身がそのまま埋め込まれ、\n が行を区切ります。
変数に入れずに 1 本で書くこともできます。
def make_receipt(name, price):
return f"=== おこづかい帳 ===\n{name} {price}円\n合計 {price}円"結果はまったく同じです。行数が増えてきたら前者、短いうちは後者、くらいの使い分けで構いません。
第 1 章の + だらけの書き方と見比べると、どこに何が入るのかが一目で分かるようになりました。使った道具は、変数と f-string の 2 つだけです。
手元で動かしてみる
kakeibo.py を下記のように書き換えると、自分で打ち込めるおこづかい帳になります。第 2 章の全部が 1 本につながる形です。
def parse_input(text):
name, price_text = text.split(" ")
return [name, int(price_text)]
def make_receipt(name, price):
return f"=== おこづかい帳 ===\n{name} {price}円\n合計 {price}円"
text = input("品名と金額を入力してください ")
record = parse_input(text)
print(make_receipt(record[0], record[1]))実行して 牛乳 198 と打つと、下記が表示されます。
=== おこづかい帳 ===
牛乳 198円
合計 198円打ち込んだ内容がそのままレシートになりました。第 1 章では書き換えないと中身が変わらなかったものが、実行するたびに変わる道具になっています。
record[0] と record[1] は、parse_input が返した 2 つの値を取り出す書き方です。角かっこの中の番号は 0 から数えます。詳しくは第 7 章で扱うので、今は「そう書くと取り出せる」で構いません。
採点に出すのは
make_receiptだけです。inputの行は手元で動かすためのもので、採点環境では動きません。前のレッスンで説明したとおりの理由です。
金額はなぜ int で持つのか
make_receipt に渡す price は数値です。文字列のまま渡しても、f-string なら表示だけはできてしまいます。それでも数値で持つのには理由があります。
第 3 章では check_budget(total, budget) を作ります。合計と予算を比べて、予算オーバーかどうかを判定する関数です。比べるには数値である必要があります。"1200" と "800" を文字として比べると、辞書の並び順で比較されて、金額の大小とは違う答えが出ます。
表示は最後の一瞬だけ。それまではずっと数値で持つ。この方針を今のうちに固めておくと、第 3 章から先で迷いません。
よくある間違い
- 合計の行を書き忘れる — 3 行目の
合計 ...円が必要です。品物 1 件なので金額は同じですが、行としては別に用意します。 - 金額を文字列のまま連結する — f-string を使わずに
+で書く場合はstr(price)が必要です。忘れるとTypeErrorになります。 - 末尾に改行を付ける —
合計 120円のうしろに\nを足すと、見た目では分からない差でテストが落ちます。改行は行と行の間だけです。
やってみよう
関数 make_receipt を実装してください。引数は品名 name と数値の金額 price の 2 つです。
1 行目は === おこづかい帳 ===、2 行目は 品名 金額円、3 行目は 合計 金額円 です。3 つの行を \n でつなぎ、末尾に改行は付けません。make_receipt("りんご", 120) の戻り値は下記のとおりです。
=== おこづかい帳 ===
りんご 120円
合計 120円金額が 0 のときも同じ形で、合計 0円 と出ます。書けたら手元の kakeibo.py にも反映して、input から通しで動かしてみてください。第 3 章では、ここで作った合計を予算と比べる check_budget を足していきます。
要件
- 関数名は make_receipt で、引数は name と price の2つ
- 1行目は "= おこづかい帳 ="、2行目は "品名 金額円"、3行目は "合計 金額円"
- 行の区切りは \n を使い、末尾には改行を付けない
- 金額は数値で渡ってくるので f-string か str で文字列にする
入出力例
make_receipt("りんご", 120) → "=== おこづかい帳 ===
りんご 120円
合計 120円"
make_receipt("牛乳", 198) → "=== おこづかい帳 ===
牛乳 198円
合計 198円"
make_receipt("ノート", 0) → "=== おこづかい帳 ===
ノート 0円
合計 0円"
make_receipt("チョコレートアイス", 1200) → "=== おこづかい帳 ===
チョコレートアイス 1200円
合計 1200円"
make_receipt("", 50) → "=== おこづかい帳 ===
50円
合計 50円"