step05 コマンドライン引数
これまでのサンプルプログラムでは、処理手順だけでなく、処理の対象となるデータ(たとえば素数かどうかを調べる整数)も、プログラム中に直接書き込まれていた。別のデータを与えたければ、プログラムを書きかえるしかなかった※1。これは、プログラムの外からデータを渡す方法をまだ習っていないからである。
1 これをハードコーディングといい、マジックナンバーなどとあわせて、よくないプログラム書法の典型とされる。
このstepでは、コマンドプロンプトのコマンドラインからプログラムにデータを渡す方法を学ぶ。数や単語といった単純なデータにとても有効だ。一方、より長い、複雑なデータを受け渡すには、step06で扱う入力リダイレクトやファイルからの入力の方が適している。
いずれにせよ、プログラムの外から処理対象のデータが渡せれば、プログラム中にはデータ処理のアルゴリズムだけを書けばよく、これまでのトイプログラムから実用プログラムへと進化する。
いままでのコマンドラインは、たとえば図5-1のようだった。

python処理系にプログラムprime.pyを渡して実行させているだけで、prime.py自体には引数※2を渡していない。調査対象の整数はprime.py中にハードコーディングされている。もし図5-2のように、コマンドラインで引数を渡せれば、アルゴリズムと処理対象データが完全に分離され、汎用の素数チェックプログラムになる。
2 「引数」というのは不思議な言葉で、プログラマは毎日のように口にするのに、一般社会で聞くことはまずない。そもそも、一体なにを「引く」というのか。講師はいつも、「何かに引き渡す数」説明することにしている。

引数渡しのテスト
まず、コマンドラインからの引数を、プログラム中でどのように受け取るのか、テストするプログラムを書いてみよう。リスト5-1に示す。
argtest.pyを実行させるコマンドラインに、いくつかの引数を追加して、何が表示されるか見てみよう。
コマンドライン引数は、python処理系によって、sys.argvというシステム定義のリストに格納される。だから、引数を扱うプログラムは、sysモジュールをimportしなくてはならない。引数の個数は、リストの長さを返す関数len()で得られる。他の言語(PerlやC系)との違いは、最初の要素であるsys.argv[0]がプログラム自身のファイル名であることだ。これはプログラムが出力するメッセージなどで使い方(usage)を表示する場合などには便利だ。他の言語では、プログラムは自分自身の名前を知らないことが多いからだ。
三角形の面積を求める
コマンドラインからデータを渡せるようになったので、少し実用的なツールを書いてみよう。
3角形の面積を求めるには、もちろん底辺と、底辺に垂直に計った高さが分かればよいのだが、実際の測量現場では、直角を図ったり、垂線を立てる作業が困難なことも多い。そこで一般的には、3辺の長さを測り、図5-3に示すヘロン※3の公式で面積を求める。
3 ヘロンは紀元1世紀にアレクサンドリアに住んでいたギリシャ人学者。エラトステネスといい、ヘロンといい、あのピタゴラスといい、まことに「古代ギリシャの数学力は(哲学力も)世界一イイイィィィ!!」なのだった。

コマンドライン引数として3辺の長さa, b, cを渡し、ヘロンの公式で求めた3角形の面積を返すのが、リスト5-2に示したプログラムである。コマンドライン引数は文字列として渡されるので、int()やfloat()などの関数で、あらかじめ数値化しておく必要がある。pythonは型付けが弱いとはいっても、PERLほどルーズではないということか。
このプログラムを使うには、図5-4のようにpython heron.pyの後に3辺の長さを引数として加える。土地の測量にも使える、ある程度の実用性を持ったツールではないか(自画自賛)。

エラー処理
コマンドライン引数は便利だが、これを利用するプログラム側は、正しい引数が渡されたかチェックしなければならない。世の中にはいろんな人がいるので、いつも3角形の面積が計算できる、正しい値を指定してくれるとは限らないからだ。これはエラー処理の一種である。heron.pyでつぎの2項目をチェックし、正しくなければエラーメッセージを出力して終了(エラー終了)するように改良してみよう。
- 引数が3つある。
- 実現不可能な3角形になっていない(平方根の中が負ではない)。

エラー処理の方法は2つに大別される。
- エラー処理専用の構文try:~except:を使う。これは本格的なエラー処理だが、どこかの文で例外が発生することを前提としている。例外は独自に発生させられるが、このサンプルプログラム程度ではそれも面倒である。
- 条件式を自分でチェックし、成立しないときはsys.exit()関数でプログラムの実行を異常終了する。
エラー処理のコードは、通常の処理(正常系)に対し、異常系と呼ばれる。これもプログラム版「根性無しの出口」に違いない。
コマンドライン引数の式を評価する
すでに説明したように、pythonは、テキストとして書かれたプログラムを1行ずつ読んで実行するスクリプト(インタープリタ)言語である。従って、たとえばユーザが与えた文字列でも、言語処理系が式として評価し、答を出せる。Cやjavaのようなコンパイラ言語では、相当面倒な処理がだ。
このためには関数eval()を使う。これは文字列で表現されたあらゆる式を評価できる。たとえば、コマンドラインから数式を入力して答えを出す、関数電卓のようなプログラムでも簡単に実現できる。リスト5-4に示す。
このプログラムを使う場合の注意点として、コマンドラインで入力する式に空白文字が含まれていてはならない(演算子の前後などに注意)。空白以降の部分が別の引数と見なされ、プログラムからは無視されるからだ。