Python / LESSON 08 / PY08

Python:関数定義(引数・戻り値・スコープ)

1学習の目的

2基礎解説

やりたいこと書き方意味
関数を作るdef greet(name):def 名前(引数): の次の行から中身
結果を返すreturn 値呼び出し元へ値を渡して終了
省略できる引数def tax(price, rate=0.1):渡さなければ既定値が使われる
複数の値を返すreturn total, besttotal, best = f() で受け取る
✅ 覚えるべき重要ポイント
  1. print と return は別物。print は画面に出すだけ、return は値を呼び出し元に渡す。計算結果を後で使うなら return。
  2. return を書かない関数の戻り値は Noneresult = f(5) が None になる事故の原因はほぼこれ。
  3. 既定値つき引数は後ろに置くdef f(a, rate=0.1) は可、def f(rate=0.1, a) はエラー。
  4. 関数の中で作った変数は外から見えない(ローカルスコープ)。外へ渡したいときは必ず return する。
  5. return はその場で関数を抜ける。先にエラー条件を return しておけば else が不要になる(早期リターン)。

現場使用例:税込計算 with_tax(price)、入力チェック validate(name)、データ整形 format_row(row)。同じ集計を複数の画面で使い回すときは必ず関数にする。

def greet(name):
    return f"こんにちは、{name}さん"

print(greet("田中"))   # こんにちは、田中さん

# 既定値つき引数
def with_tax(price, rate=0.1):
    return int(price * (1 + rate))

print(with_tax(1000))         # 1100
print(with_tax(1000, 0.08))   # 1080

# 複数の値を返す
def stats(nums):
    return sum(nums), max(nums)

total, best = stats([3, 9, 5])
print(total, best)   # 17 9

3基本ドリル(10問)

PY08-D01 名前を受け取って「こんにちは、田中さん」という文字列を返す関数 greet を定義し、"田中" で呼び出した結果を出力せよ。 コーディング★☆☆無料
期待される結果

出力 == こんにちは、田中さん

ヒント

def greet(name): の中で return する。呼び出しは print(greet("田中"))。

模範解答
def greet(name):
    return f"こんにちは、{name}さん"

print(greet("田中"))
解説

関数の最小形。定義(def)しただけでは何も起きず、呼び出して初めて動く点を押さえる。

PY08-D02 return を1行も書かない関数を呼び出したとき、戻り値は何になるか。
A. 0 B. 空文字 C. None D. エラーになる
選択★☆☆無料
期待される結果

解答 == C

ヒント

「何も返さない」をPythonはどう表すか。

模範解答
C
解説

戻り値なし=None。この None が後の計算に混ざって TypeError を起こすのが典型的なバグの連鎖。

PY08-D03 2つの数を受け取って合計を返す関数 add を定義し、add(3, 7) の結果を出力せよ。 コーディング★☆☆無料
期待される結果

出力 == 10

ヒント

引数はカンマ区切りで2つ書ける。

模範解答
def add(a, b):
    return a + b

print(add(3, 7))
解説

引数は必要なだけ増やせる。呼び出し時は定義した順番どおりに値を渡す。

PY08-D04 長方形の面積を返す関数を完成させよ。 穴埋め★☆☆無料
コード
def area(w, h):
    ____ w * h

print(area(3, 4))
期待される結果

出力 == 12

ヒント

計算結果を呼び出し元へ渡すキーワード。

模範解答
return w * h
解説

ここを print にすると画面には12が出るが、関数の戻り値は None になる。使い回すなら return。

PY08-D05 def f(x): print(x * 2) と定義し、result = f(5) としたとき result の中身はどれか。
A. 10 B. None C. 5 D. エラーになる
選択★☆☆無料
期待される結果

解答 == B

ヒント

画面に出ることと、値が返ることは同じか?

模範解答
B
解説

画面には10が表示されるが、returnが無いので result は None。print と return の違いが最もはっきり出る問題。

PY08-D06 価格と税率を受け取り、税込価格(整数に切り捨て)を返す関数 with_tax を定義せよ。税率は省略時 0.1 とする。with_tax(1000) と with_tax(1000, 0.08) の結果を2行で出力すること。 コーディング★★☆無料
期待される結果

出力 == 1100 / 1080(2行)

ヒント

def with_tax(price, rate=0.1): と書けば省略可能になる。切り捨ては int()。

模範解答
def with_tax(price, rate=0.1):
    return int(price * (1 + rate))

print(with_tax(1000))
print(with_tax(1000, 0.08))
解説

既定値つき引数は「ほとんどの場合は同じ値、たまに変えたい」場面に最適。軽減税率の8%だけ明示的に渡している。

PY08-D07 単位を省略すると「円」になる関数を完成させよ。 穴埋め★★☆無料
コード
def show(value, unit____"円"):
    return f"{value}{unit}"

print(show(500))
期待される結果

出力 == 500円

ヒント

既定値は = でつなぐ。スペースは入れないのが慣例。

模範解答
def show(value, unit="円"):
解説

引数の既定値は = の前後にスペースを入れないのがPythonの書式ルール(PEP8)。細かいが現場では揃える。

PY08-D08 関数の中で total = 100 と代入した。関数の外で print(total) するとどうなるか。
A. 100が出る B. NameErrorになる C. Noneが出る D. 0が出る
選択★★☆無料
期待される結果

解答 == B

ヒント

関数の中で作った変数はどこまで生きているか。

模範解答
B
解説

関数内の変数は関数を抜けると消える(ローカルスコープ)。外へ持ち出したければ return するのが唯一の正攻法。

PY08-D09 リストを受け取り、合計と最大値の2つを返す関数 stats を定義し、[3, 9, 5] で呼び出して「合計17 最大9」の形式で出力せよ。 コーディング★★☆無料
期待される結果

出力 == 合計17 最大9

ヒント

return sum(nums), max(nums) と書ける。受け取りは total, best = stats(...)。

模範解答
def stats(nums):
    return sum(nums), max(nums)

total, best = stats([3, 9, 5])
print(f"合計{total} 最大{best}")
解説

カンマで並べるとタプルとしてまとめて返る。PY06で学んだアンパックがそのまま使える。

PY08-D10 点数を受け取り、60以上なら「合格」、未満なら「不合格」を返す関数 judge を定義し、judge(72) と judge(45) の結果を2行で出力せよ。 コーディング★★☆無料
期待される結果

出力 == 合格 / 不合格(2行)

ヒント

関数の中で if / else を使い、それぞれ return する。

模範解答
def judge(score):
    if score >= 60:
        return "合格"
    else:
        return "不合格"

print(judge(72))
print(judge(45))
解説

PY04の条件分岐を関数に閉じ込めた形。判定ロジックを1箇所にまとめておけば、基準が変わってもここだけ直せばよい。

4実践シナリオ(5問)

PY08-S01 【送料計算の部品化】購入額を受け取り、5,000円以上なら0、未満なら600を返す関数 shipping_fee を定義せよ。そのうえで [4800, 5000, 12000] の3件を「4,800円 → 送料600円」の形式で出力せよ。 コーディング★★☆無料
期待される結果

3行。4,800円 → 送料600円 ほか

ヒント

関数を定義してから for で回す。f-stringの中で shipping_fee(p) を直接呼べる。

模範解答
def shipping_fee(price):
    if price >= 5000:
        return 0
    else:
        return 600

for p in [4800, 5000, 12000]:
    print(f"{p:,}円 → 送料{shipping_fee(p)}円")
解説

PY04で書いた送料判定を関数にした形。ループの中で関数を呼ぶと、判定ロジックとループが分離されて読みやすくなる。

PY08-S02 【BMI判定の関数化】身長(m)と体重(kg)を受け取り、BMI(小数1桁に丸めた値)と判定の2つを返す関数 bmi_check を定義せよ。判定は25以上「肥満」、18.5未満「痩せ」、その他「標準」。(1.72, 78) で呼び出し「BMI:26.4 → 肥満」の形式で出力すること。 コーディング★★☆無料
期待される結果

出力 == BMI:26.4 → 肥満

ヒント

丸めは round(bmi, 1)。return で2つ返し、value, judge = bmi_check(...) で受け取る。

模範解答
def bmi_check(height, weight):
    bmi = weight / height ** 2

    if bmi >= 25:
        judge = "肥満"
    elif bmi < 18.5:
        judge = "痩せ"
    else:
        judge = "標準"

    return round(bmi, 1), judge

value, judge = bmi_check(1.72, 78)
print(f"BMI:{value} → {judge}")
解説

計算と判定を1つの関数に閉じ込め、結果だけを返す設計。呼び出す側はBMIの計算式を知らなくてよくなる。これが「部品化」の効果。

PY08-S03 【入力チェックの関数化】名前とパスワードを受け取り、名前が空なら「名前を入力してください」、パスワードが8文字未満なら「パスワードは8文字以上にしてください」、どちらも問題なければ「OK」を返す関数 validate を定義せよ。("", "abc123")、("田中", "abc123")、("田中", "abcd1234") の3通りを順に出力すること。 コーディング★★☆無料
期待される結果

出力3行が完全一致

ヒント

エラー条件を先に書いて即 return すると、else を書かずに済む。

模範解答
def validate(name, password):
    if not name:
        return "名前を入力してください"

    if len(password) < 8:
        return "パスワードは8文字以上にしてください"

    return "OK"

print(validate("", "abc123"))
print(validate("田中", "abc123"))
print(validate("田中", "abcd1234"))
解説

早期リターンという書き方。return はその場で関数を抜けるので、else や入れ子のifが消えて一気に読みやすくなる。実務のバリデーションはほぼこの形。

PY08-S04 【割引価格の関数化】価格・会員かどうか・クーポンの有無を受け取り、支払額を返す関数 final_price を定義せよ。会員なら10%引き(整数に切り捨て)、クーポンがあればさらに500円引き、結果がマイナスなら0とする。会員フラグとクーポンは省略時 False
final_price(12000, True, False) / final_price(12000) / final_price(400, False, True) の3通りを「12,000円 → 10,800円」の形式で出力せよ。
コーディング★★★無料
期待される結果

出力3行が完全一致

ヒント

def final_price(price, is_member=False, coupon=False): と定義する。中身はPY04の割引計算と同じ。

模範解答
def final_price(price, is_member=False, coupon=False):
    if is_member:
        price = int(price * 0.9)

    if coupon:
        price -= 500

    if price < 0:
        price = 0

    return price


print(f"12,000円 → {final_price(12000, True, False):,}円")
print(f"12,000円 → {final_price(12000):,}円")
print(f"400円 → {final_price(400, False, True):,}円")
解説

既定値を False にしておくと「普通の客なら引数1つで呼べる」関数になる。よくある呼び方を短く書けるようにするのが良い関数設計。

PY08-S05 【集計関数の使い回し】点数リストを受け取り、平均・最高点・合格者数(60点以上)の3つを返す関数 summarize を定義せよ。class_a = [82, 45, 91, 68]、class_b = [70, 55, 88] の2クラスに同じ関数を使い、「A組 → 平均71.5点 / 最高91点 / 合格3人」の形式で2行出力すること。 コーディング★★★無料
期待される結果

出力2行が完全一致

ヒント

return average, max(scores), passed で3つ返す。2クラスは [("A組", class_a), ("B組", class_b)] のタプルのリストで回すとループ1本で書ける。

模範解答
def summarize(scores):
    average = sum(scores) / len(scores)

    passed = 0
    for s in scores:
        if s >= 60:
            passed += 1

    return average, max(scores), passed


class_a = [82, 45, 91, 68]
class_b = [70, 55, 88]

for name, scores in [("A組", class_a), ("B組", class_b)]:
    average, best, passed = summarize(scores)
    print(f"{name} → 平均{average:.1f}点 / 最高{best}点 / 合格{passed}人")
解説

同じ関数を違うデータに何度でも使えるのが関数化の最大の利点。クラスが10個に増えてもコードは1行も増えない。PY06のタプルのリストも組み合わせている。

5仕上げ課題

PY08-FINAL 【請求書作成スクリプト】3つの関数を定義し、組み合わせて請求書を出力せよ。
items = [("ノートPC", 128000, 1), ("マウス", 3200, 2), ("USBメモリ", 1500, 3)]
is_member = True


定義する関数:
subtotal(price, qty) — 小計(単価×数量)を返す
apply_discount(amount, is_member) — 会員なら10%引き(整数に切り捨て)、会員でなければそのまま返す
with_tax(amount, rate=0.1) — 税込額(整数に切り捨て)を返す。税率は省略可

処理:明細を1行ずつ出力しながら小計を積み上げ、最後に「小計 → 会員割引後 → 消費税込」の順に出力する。

出力仕様(8行):
=== 請求書 ===
ノートPC:128,000円 × 1 = 128,000円
マウス:3,200円 × 2 = 6,400円
USBメモリ:1,500円 × 3 = 4,500円
---
小計:138,900円
会員割引後:125,010円
消費税込:137,511円
期待される結果

出力8行が完全一致

ヒント

関数を3つ先に定義してから処理を書く。ループの中で subtotal() を呼んで total に足し込み、ループが終わってから apply_discount() → with_tax() の順に通す。タプルは for name, price, qty in items: で3つに分解できる。

模範解答
items = [("ノートPC", 128000, 1), ("マウス", 3200, 2), ("USBメモリ", 1500, 3)]
is_member = True


def subtotal(price, qty):
    return price * qty


def apply_discount(amount, is_member):
    if is_member:
        return int(amount * 0.9)
    return amount


def with_tax(amount, rate=0.1):
    return int(amount * (1 + rate))


print("=== 請求書 ===")

total = 0
for name, price, qty in items:
    line = subtotal(price, qty)
    total += line
    print(f"{name}:{price:,}円 × {qty} = {line:,}円")

discounted = apply_discount(total, is_member)
taxed = with_tax(discounted)

print("---")
print(f"小計:{total:,}円")
print(f"会員割引後:{discounted:,}円")
print(f"消費税込:{taxed:,}円")
解説

小さな関数を並べて、処理の流れで組み立てる——これが実務のプログラムの標準的な形。税率が変わっても with_tax の中だけ、割引率が変わっても apply_discount の中だけを直せばよい。変更が1箇所で済む構造を作れることが、関数を学ぶ本当の目的。