Python講座 / 条件分岐と反復で成績を集計する

成績の集計では、入力検証、分類、合計・平均の計算を組み合わせます。不正な点数は統計から除きつつ件数を報告し、データの欠落を黙って見えなくしないことが大切です。

入力と計算規則を決める

この例は、すでに整数のリストがあることを前提にします。0~100を有効、60以上を合格とし、負数と100を超える値は不正件数へ加えます。CSVやユーザー入力の文字列を整数へ変える作業は、その前の別段階です。

ケース 規則
60 合格
0 有効な点数
-1または101 不正件数を増やす
有効な点数がない 平均を計算しない

条件式と境界値の自動検証は、比較演算子と論理演算子で条件を組み合わせるとunittestで正常値・境界値・失敗をテストするで扱う規則とつながります。

成績集計の全体例を実行する

scores.pyへ次のコードを保存し、仮想環境でpython scores.pyを実行します。

scores = [80, 60, 0, 100, -1, 101]
valid = []
invalid = 0
passed = 0
for score in scores:
    if not 0 <= score <= 100:
        invalid += 1
        continue
    valid.append(score)
    if score >= 60:
        passed += 1
print("valid:", len(valid), "invalid:", invalid)
if valid:
    print(f"average: {sum(valid) / len(valid):.1f}")
    print("passed:", passed)
else:
    print("no valid scores")

予想される結果です。元の入力は6件で、有効4件と不正2件の合計も6件です。

valid: 4 invalid: 2
average: 60.0
passed: 3

カウンターと平均の分母を追う

invalidは除外した入力、passedは有効な入力の中で合格した点数を数えます。continueにより不正値はvalidへ入らず、平均の分母にも入りません。0は条件で偽と扱われても有効な点数です。if scoreと書いてしまうと、0を誤って除外します。

有効な点数を集めてから、一度だけ空かどうかを調べて平均を求めます。これなら有効データがないケースでゼロ除算を避け、各反復の途中で何度も平均を計算する必要もありません。

境界と前提を変えて確認する

空リストではno valid scoresになります。[59, 60, 61]では二つが合格し、[-1, 101]では平均が表示されません。観察後は元の入力へ戻して、有効件数と不正件数の和を元の件数と照合します。

整数以外も受け付ける仕様に広げるなら、floatを認めるか、intのサブクラスであるboolを拒むかなども決めます。ここで確認しているのは整数入力という前提の範囲です。データ型の契約を変えたのに、範囲比較だけですべての検証が済むとは考えないでください。

境界値の表はそのままテスト入力にできます。空のリストは平均を計算する前に方針に従って拒否するか別処理にします。0、合格境界の直前59、境界60が意図した分岐に入ることを確認すると、比較演算子の誤りを見つけやすくなります。

関連する公式リファレンス