実行順序
このレッスンで作るもの — コードが上から順に走ることを、レシート 3 行を組み立てながら体で覚えます。
実行順序
Python はソースコードを 上から下へ、1 行ずつ 実行します。当たり前に聞こえますが、この一点を押さえていないとエラーの読み方も直し方も分かりません。
print("1 行目")
print("2 行目")
print("3 行目")表示は 1 行目 2 行目 3 行目 の順です。書いた順にしか動かないので、3 行目 を先に出したければコードの位置そのものを入れ替えます。
プログラムは書いた順にしか動きません。逆に言えば、書いた順を追えば必ず動きを説明できます。「なぜか動かない」と感じたときは、上から 1 行ずつ指でなぞってみてください。
定義してから呼ぶ
順番の規則は、関数にも効きます。def で関数を作る行より 前 でその関数を呼ぶと、まだ存在しないものを呼んだことになり NameError が出ます。
def title():
return "=== おこづかい帳 ==="
print(title())この並びは正しく動きます。def の行が先に実行されて title という名前が用意され、そのあとで print(title()) が走るからです。逆に print(title()) を先頭に書くと落ちます。
def の行が実行されるのは「関数を作る」ところまでで、中身の return はまだ動きません。中身が動くのは title() と呼び出したその瞬間です。
return より下は動かない
関数の中で return に到達すると、そこで関数は 終わります。下に何行書いてあっても実行されません。
def title():
return "=== おこづかい帳 ==="
print("ここは絶対に表示されない")print の行は永遠に出番がありません。エラーにはならず、ただ黙って無視されます。「書いたのに動かない」の原因がこれ、ということが本当によくあります。
returnは関数の出口です。出口を通ったあとの部屋は使われません。1 つの関数にreturnを複数書くこともできますが、実際に通るのは最初に到達した 1 つだけです。
順番どおりに組み立てる
今回は 3 行のレシートを 1 本の文字列で返します。行の区切りには 改行文字 \n を使います。バックスラッシュと n の 2 文字で、1 つの改行を表します。
def receipt_lines(name, price_text):
return "=== おこづかい帳 ===" + "\n" + name + " " + price_text + "円" + "\n" + "--- ここまで ---"receipt_lines("りんご", "120") を呼ぶと、下記の 3 行になります。
=== おこづかい帳 ===
りんご 120円
--- ここまで ---連結は左から順に進むので、書いた順がそのまま表示の順になります。見出しを先に書けば見出しが上に、--- ここまで --- を最後に書けばそれが下に来ます。
末尾に \n は付けません。最後の行のうしろに改行を足すと、見た目には分からない余分な空行が入り、テストが落ちます。
順番を入れ替えるとどうなるか
試しに、見出しと品名の行を逆に書いてみます。
def receipt_lines(name, price_text):
return name + " " + price_text + "円" + "\n" + "=== おこづかい帳 ===" + "\n" + "--- ここまで ---"エラーは出ません。ただ、品名が一番上に来た別のレシートができるだけです。Python は「意図」を読んでくれるわけではなく、書かれた順にひたすら従います。正しく動かすとは、正しい順番で書くことにほかなりません。
エラーが出ないからといって正しいとは限りません。順番の間違いは静かに間違った結果を返します。テストケースを用意しておくと、この手の静かな間違いを機械が見つけてくれます。
よくある間違い
- 末尾に余分な
\nを付ける —+ "\n"で締めくくると、目に見えない差でテストが失敗します。改行は行と行の 間 にだけ入れます。 \nを全角で書く —¥nや全角のnでは改行になりません。半角のバックスラッシュと半角のnを使います。日本語キーボードでは¥キーで入力できます。- 関数を定義する前に呼ぶ —
defより上で呼び出すとNameErrorになります。定義が先、呼び出しがあと、という順番を守ります。
やってみよう
関数 receipt_lines を実装してください。引数は品名 name と金額の文字列 price_text の 2 つです。下記の 3 行を \n でつないだ 1 本の文字列を return します。
1 行目は === おこづかい帳 ===、2 行目は 品名 金額円、3 行目は --- ここまで --- です。ハイフンは半角 3 つで、内側は半角スペース 1 つずつ空けます。末尾に改行は付けません。
要件
- 関数名は receipt_lines で、引数は name と price_text の2つ
- 1行目は "= おこづかい帳 ="、3行目は "--- ここまで ---" にする
- 2行目は品名と金額を半角スペースでつなぎ末尾に「円」を付ける
- 行の区切りは \n を使い、末尾には改行を付けない
入出力例
receipt_lines("りんご", "120") → "=== おこづかい帳 ===
りんご 120円
--- ここまで ---"
receipt_lines("牛乳", "198") → "=== おこづかい帳 ===
牛乳 198円
--- ここまで ---"
receipt_lines("ノート", "0") → "=== おこづかい帳 ===
ノート 0円
--- ここまで ---"
receipt_lines("", "50") → "=== おこづかい帳 ===
50円
--- ここまで ---"
receipt_lines("チョコレートアイス", "298") → "=== おこづかい帳 ===
チョコレートアイス 298円
--- ここまで ---"