Python | レベル別練習問題:コメント

Python
スポンサーリンク

では 初心者 → 中級 → 上級 の 3 レベル、各5問(合計15問)を用意します。各問題に「出題」「解答例」「ポイント解説」を付けてあるので、そのまま学習・演習に使えます。まずは最初のレベルからどうぞ。


Q1 — 単純な関数にコメントを付ける

出題: 次の関数に「何をするか」と「注意点」を一言コメントで付けてください。

def greet(name):
    return f"Hello, {name}!"
Python

解答例

# 名前を受け取り 'Hello, <name>!' を返す(name は文字列を想定)
def greet(name):
    return f"Hello, {name}!"
Python

ポイント: 何をするか+引数の前提(型や制約)を短く書くと良い。


Q2 — 行末コメントの使い方

出題: 次のコードの右端に短い行末コメントを付けて、factorial が何のための値か書いてください。

n = 5
fact = 1
for i in range(1, n+1):
    fact *= i
Python

解答例

n = 5
fact = 1  # n の階乗を格納する変数(後で出力する)
for i in range(1, n+1):
    fact *= i
Python

ポイント: 行末コメントは「短く一文」で使う。処理の理由を補足すると親切。


Q3 — ガード節にコメントを加える

出題: 空リストに対するガード節にコメントを付けてください。

def average(nums):
    if not nums:
        return 0
    return sum(nums) / len(nums)
Python

解答例

def average(nums):
    # nums が空の場合はゼロ除算を避けるため 0 を返す
    if not nums:
        return 0
    return sum(nums) / len(nums)
Python

ポイント: ガード節は理由(ゼロ除算回避)を明記するのが有用。


Q4 — 不要なコメントを見つける

出題: 次のコードのコメントは良い?悪い?理由を書け。

i = 0  # iを0で初期化する
Python

解答例

  • 悪い。コメントはコードの動作そのものを書いているだけで、なぜ 0 にするのか、何をカウントするのかが書かれていないため情報が少ない。
    ポイント: コメントは「どう」より「なぜ」を補足する。

Q5 — TODO タグを使う

出題: 次の関数に「将来の改良点」を TODO コメントで追加してください。

def process(data):
    # 実装(とりあえず)
    return data
Python

解答例

def process(data):
    # TODO: 大量データ対応のためストリーミング処理に変更する
    return data
Python

ポイント: TODO は IDE 検索で見つけやすく、チーム開発で便利。


中級(目的:docstring・詳細な説明・誤解を招かないコメント)


Q6 — 関数に docstring を書く

出題: 次の関数に docstring(引数・戻り値・例)を追加してください。

def multiply(a, b):
    return a * b
Python

解答例

def multiply(a, b):
    """2つの数 a, b を掛け合わせて返す。

    引数:
        a (int|float): 乗算の左オペランド
        b (int|float): 乗算の右オペランド

    戻り値:
        int|float: a * b

    例:
        >>> multiply(2, 3)
        6
    """
    return a * b
Python

ポイント: docstring は help() で見れる公式ドキュメント。簡単な使用例があると親切。


Q7 — なぜそのアルゴリズムか説明する

出題: 次の実装について「なぜこの方法を選んだか」をコメントで付けてください(素朴な実装を採用している場合)。

def find_max(nums):
    max_v = nums[0]
    for n in nums:
        if n > max_v:
            max_v = n
    return max_v
Python

解答例

# シンプルで分かりやすい O(n) の線形探索を使う(入力が小さければ十分、外部ライブラリ不要)
def find_max(nums):
    max_v = nums[0]
    for n in nums:
        if n > max_v:
            max_v = n
    return max_v
Python

ポイント: アルゴリズム選択理由(可読性・性能・依存の有無)を書くとメンテ性が上がる。


Q8 — コメントで前提条件を明示する

出題: 次の関数の前提(引数の範囲)をコメントで明記してください。

def sqrt(n):
    return n ** 0.5
Python

解答例

# 前提: n は非負の数(負の値を渡すと複素数を返す/エラーになる可能性あり)
def sqrt(n):
    return n ** 0.5
Python

ポイント: 引数の想定(型・有効範囲)を書くと誤用を防げる。


Q9 — バグになりやすい箇所に注意書きを入れる

出題: 次のコードでバグを起こしやすい箇所に注意コメントを付けてください。

def join_paths(a, b):
    return a + "/" + b
Python

解答例

def join_paths(a, b):
    # 注意: a が末尾に '/' を含む場合や、OS によるパス区切りの違いに注意(os.path.join を検討)
    return a + "/" + b
Python

ポイント: 既知の脆弱性や想定外の入力について注意喚起しておく。


Q10 — テストを意識したコメント

出題: 次の関数の動作条件と、それをテストするための簡単な例をコメントに書いてください。

def clamp(x, low, high):
    if x < low:
        return low
    if x > high:
        return high
    return x
Python

解答例

def clamp(x, low, high):
    """x を [low, high] の範囲に収める。

    例:
        clamp(5, 1, 10) -> 5
        clamp(-1, 0, 5) -> 0
        clamp(7, 0, 6) -> 6
    """
    if x < low:
        return low
    if x > high:
        return high
    return x
Python

ポイント: docstring 内の短い例は単体テストを書くときの参考になる。


上級(目的:コードレビュー向けコメント、誤解を招くコメントの修正、リファクタ案)


Q11 — 誤解を招くコメントを修正する

出題: 次のコードにあるコメントを改善してください(コメントが実態と違う)。

# この関数は O(n^2) だが実用上問題ない
def sum_list(nums):
    return sum(nums)
Python

解答例

# sum() を使って O(n) で合計を計算する(以前の O(n^2) 実装を改善済み)
def sum_list(nums):
    return sum(nums)
Python

ポイント: コメントとコードが一致していることが最重要。古いコメントは必ず直す。


Q12 — リファクタの提案コメントを書く

出題: 次の複雑な関数に「将来のリファクタ提案」コメントを追加してください。

def process_items(items):
    result = []
    for it in items:
        # 多くの処理がここにある(長い)
        result.append(it)
    return result
Python

解答例

def process_items(items):
    # TODO: 処理が長いので、各処理を小さな関数に分割してテストを容易にする
    result = []
    for it in items:
        # 多くの処理がここにある(長い)
        result.append(it)
    return result
Python

ポイント: リファクタ方針(分割・テスト容易化)を書くとレビューでの合意形成が速い。


Q13 — ドキュメント化が必要な公開 API のコメント

出題: ライブラリの公開関数に必要な情報を docstring に書いてください(例: 例外・返り値・副作用)。

def load_config(path):
    # 実装
    ...
Python

解答例

def load_config(path):
    """指定パスから設定ファイルを読み込み辞書として返す。

    引数:
        path (str): 設定ファイルのパス(JSON 形式を想定)

    戻り値:
        dict: 設定内容

    例外:
        FileNotFoundError: ファイルが存在しない場合
        json.JSONDecodeError: JSON のパースに失敗した場合

    副作用:
        なし(読み取り専用)
    """
    ...
Python

ポイント: 公開 API はユーザーに必要な情報(例外・副作用・形式)を明記する。


Q14 — 多言語コメント(チームに外国人がいる場合)

出題: チームに英語利用者がいる想定で、先の clamp 関数に英日両方の docstring を示してください。
解答例

def clamp(x, low, high):
    """Clamp x into [low, high].

    日本語: x を [low, high] の範囲に収める。
    例: clamp(5,1,10) -> 5
    """
    if x < low:
        return low
    if x > high:
        return high
    return x
Python

ポイント: 英語ドキュメントを優先しつつ、必要なら日本語で補足する。二重化は情報の整合に注意。


Q15 — コメントに基づくコードレビュー課題

出題: 次の関数のコメントとコードを比較して、問題点を指摘し改善案をコメントで追加してください。

# この関数はリストを正順に並べ替えて返す(破壊的ではない)
def sort_descending(lst):
    lst.sort(reverse=True)
    return lst
Python

解答例(改善コメント)

# 問題点:
# - コメントは「正順に並べ替える」とあるが、実際は降順(descending)である → コメントが間違っている。
# - 現在の実装は破壊的(引数 lst を変更する)。破壊的ではないというコメントと矛盾。
#
# 改善案:
# - コメントを正しく「降順にソートする」と修正
# - 破壊的でない実装にするなら lst.copy() を使って新しいリストを返す
def sort_descending(lst):
    # 降順にソートした新しいリストを返す(元のリストは変更しない)
    new_lst = lst.copy()
    new_lst.sort(reverse=True)
    return new_lst
Python

ポイント: コメントと実装の整合性を検証する習慣を付ける。レビューコメントは具体的な修正案を含めると良い。


練習の進め方(おすすめ)

  1. 各問題をまず自分で解いてみる(3〜10分)。
  2. 解答例と比較して、どこが違うかをノートする。
  3. 自分のプロジェクトのコードを 5 行以上取り出し、何を・なぜ の観点でコメントを書いてみる。
  4. チームや友人にコードレビューしてもらい、コメントが伝わるか確認する。

Python
スポンサーリンク
シェアする
@lifehackerをフォローする
スポンサーリンク
タイトルとURLをコピーしました