配列と別れる50の方法《00》JPL の事例から

記事一覧if 篇for 篇配列 篇

Python.use(better) # OOP への道 《Python3.1, Jython2.5.0, IronPython2.6.x》
JPL の事例から

《著》真樹育未・後藤いるか・小粒ちゃん《監修》小泉ひよ子とタマゴ倶楽部
第0版♪1988/10/12 ● 第1版♪1993/05/23 ● 第2版♪2003/05/25

■ 概要

配列はいくつかの問題を抱え「コードを汚染」する一因になり「バグの温床」になりがちです。

伝統的なC言語風の for 文や悪名高い switch 文、配列の呪縛から解かれ、オブジェクト指向プログラミング〔OOP〕の醍醐味を堪能するための準備を行います。

何が問題か

Java 言語の解説書 JPL には、伝統的な配列を利用した事例を紹介しています。しかし、配列はいくつかの問題を抱え、「コードを汚染」する一因になり「バグの温床」になりがちです。そこで、その問題点を明らかにするとともに、それを解消する術を紹介します。

事例:JPL, pp.19-20

JPL の読者の多くは、以下の事例によって、配列を知ることでしょう。

public double average(int[] values) {
    if (values == null)
        throw new IllegalArgumentException();
    else
        if (values.length == 0)
            throw new IllegalArgumentException();
        else {
            double sum = 0.0;
            for (int i = 0; i < values.length; i++)
                sum += values[i]     # (=.=) ... is a bit worrying
            return sum / values.length;
        }
}

関数 average は、整数配列 values の平均値を求めます。

事例:Python3.1

まず「テストケース」を紹介します。

from random import randint

def ex():
    values = None
    try:
        print(average(values), values)
    except ValueError:
        print("ValueError")

    values = []
    try:
        print(average(values), values)
    except ValueError:
        print("ValueError")

    values = [randint(0, 100) for e in range(10)]
    print(average(values), values)

整数配列 values が None の場合や、空リスト [] の場合には、例外 ValueError を補足します。そして最後に、10個の乱数を列挙した、整数配列 values の平均値を出力します。これを実行すると、次のような出力が得られます。

>>> ex()
ValueError
ValueError
53.6 [82, 97, 39, 15, 42, 49, 16, 83, 66, 47]

配列の隘路

■ while 文(伝統的な for 文の代用表現)

Python には、伝統的なC言語風の for 文がありません。そこで、while 文による代用表現で説明します。

def average(values):
    if values == None:
        raise ValueError()
    elif len(values) == 0:
        raise ValueError()
    else:
        sum = 0.0
        i = 0
        while i < len(values):
            sum += values[i]     # (=.=) ... is a bit worrying
            i += 1
        return sum / len(values)

バグの温床となるのは、配列の境界です。そのため、変数 i の初期値や条件式に間違いがないか気を配ります。そこで気を抜くと、

>>> ex()
Traceback (most recent call last):
  File "exArray.py", line 57, in 
    print("-"*20,"step 0"); ex1()
  File "exArray.py", line 39, in ex1
    print(average(values), values)
  File "exArray.py", line 53, in average
    sum += values[i]
IndexError: list index out of range

といった不具合に悩まされます。

Tips

》作業中です《

Last updated♪2009/07/09