配列と別れる50の方法《00》JPL の事例から
Python.use(better) # OOP への道 《Python3.1, Jython2.5.0, IronPython2.6.x》
JPL の事例から
■ 概要
配列はいくつかの問題を抱え「コードを汚染」する一因になり「バグの温床」になりがちです。
伝統的なC言語風の for 文や悪名高い switch 文、配列の呪縛から解かれ、オブジェクト指向プログラミング〔OOP〕の醍醐味を堪能するための準備を行います。
■ 関連記事
- Java プログラマーのための Python 導入ガイド
- 例題で学ぶ Jython/Swing デザインパターン《Jython2.5》改訂版
- ゲームに学ぶ Jython/Swing フレームワーク《Jython2.5》改訂版
- IronPython で学ぶ WPF プログラミングの世界《IronPython2.6》改訂版
何が問題か
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, inprint("-"*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
》作業中です《