(3) 10/23の授業内容:コマンドラインとの情報のやり取り

コマンドラインとの情報のやりとり

ktermにおいてrubyプログラムを実行する際、

irsv{学籍番号}%./prog.rb

とか

irsv{学籍番号}%ruby prog.rb

と入力した。

特殊な方法として、

irsv{学籍番号}%ruby prog.rb data.txt

のようにプログラム名の後ろにファイル名を指定すると、そのファイルを読み込ませ、プログラムの中で取り扱うことができた。前期の正規表現の授業で取り上げたが覚えているだろうか。

ktermからプログラムを実行する際に、プログラム名の後ろに値を指定することで、その値をプログラム内で使用することができる。前期はファイル名のみを指定したが、以下のように数値を指定することもできる。

irsv{学籍番号}%ruby prog.rb 100 200 300

ktermからプログラムを実行する際に上記のように与えた値のことを引数(ひきすう)という。Rubyでは、与えた引数は自動的にARGVという配列変数に代入される。

上記の例では100、200、300という引数が与えられており、配列変数のARGVのインデックス0、1、2にそれぞれ
ARGV[0] = "100"
ARGV[1] = "200"
ARGV[2] = "300"
のように代入される。いずれも文字列であることに注意する必要がある。なお100 200 300の間はスペースのみでありカンマ等はないことに注意せよ

これを利用すると、プログラムを起動する際に与えた値に基づいて動作を決定させることができる。

ktermからプログラムを実行する際に引数を指定すると、ARGVという配列変数に代入される

  • 引数が1つの場合はARGV[0]に代入される
  • 引数が2つの場合は1つ目の値がARGV[0]、2つ目の値がARGV[1]に代入される
  • 引数が3つの場合は1つ目の値がARGV[0]、2つ目の値がARGV[1]、3つ目の値がARGV[2]に代入される
  • 引数が増えるごとにARGVのインデックスを1ずつ増やしながら順番に代入される
  • 引数に与えた値はARGVにすべて文字列として代入される
  • 引数として複数の値を与える場合は、引数の間はスペースとする

1からユーザが指定した任意の値までの足し算を行うプログラムを書いてみよう。これまでは、プログラム実行後に「好きな数字を入力してください」と表示し、キーボードから入力された値をgetsメソッドで取得するという以下のようなプログラムを書いてきた(sum-gets.rb)。

#!/usr/koeki/bin/ruby
sum = 0
print "好きな数字を入力してください"
goal = gets.chomp!.to_i

1.upto(goal) do |i|
  sum += i
end

printf ("1から%dまでの合計は%dです\n",goal, sum)

これをARGVを使用して書き換えることを考えてみよう。仮に30までの合計を求める場合、ktermでプログラムを実行する際に以下のように引数を与える必要がある(プログラム名はsum-ARGV.rbとする)

irsv{学籍番号}%ruby sum-ARGV.rb 30

プログラムは以下の通りとなる。ktermにおけるプログラム実行時に与えた引数である30はARGV[0]に代入される。文字列として取り扱われるため、goal = ARGV[0].to_iとし、整数に変換してからgoalに代入している。

#!/usr/koeki/bin/ruby

sum = 0
goal = ARGV[0].to_i

1.upto(goal) do |i|
  sum += i
end

printf ("1から%dまでの合計は%dです\n",goal, sum)

出席課題

sum-ARGV.rbを実行してみよう。実行するときに引数を与えなかった場合にはどのような結果になるだろうか。実行結果を確認した上で、なぜそのような結果になるのかを考えてみよう。

制限時間は10分。出席点は2点。提出要領は下記の通り。

  • 提出先:naoya@e.koeki-u.ac.jp
  • メールのSubject:ruby03
  • 本文の構成:1行目で学籍番号、氏名を記載する。2行目以降にプログラムの実行結果を貼り付け、なぜそのようになったのかについて理由を述べること。

Tips:emacsでの日本語入力のオンオフはCtrl-oです

Tips:Mewによるメールの送り方はMewコマンドを参照

プログラムの強制終了

sum-ARGV.rbでは、プログラム実行時に引数を与えることが、プログラムを正常に実行する上での前提条件となっている。引数を与えなければ正しく実行することができない。しかし、実行しても何も起こらないプログラムでは、ユーザーは何がおかしいのかを理解することができない。おそらく自分の実行の方法が間違っているのではなく、プログラム自体に誤りがあるのではないかと考えるはずである。この問題を解決するために、プログラムを改良してみよう。

#!/usr/koeki/bin/ruby
if ARGV[0] == nil
  STDERR.print "1からプログラム起動時に指定した値までの合計を出します\n"
  STDERR.print "50までの総和を出したい場合 ruby goukei-ARGV.rb 50と入力します\n"
  exit(1)
end

sum = 0
goal = ARGV[0].to_i

1.upto(goal) do |i|
  sum += i
end

printf ("1から%dまでの合計は%dです\n",goal, sum)

このプログラムでは上部の5行(黄色の部分)を追加している。これは1つのif文である。ifの横の条件としてARGV[0] == nilを指定している。nilとはデータがないという意味であり、ARGV[0]にデータがないということは、プログラムを実行する際に引数を与えていないということを意味する。この場合にendの前にある3行を実行する。

STDERR.printの2行:メッセージをディスプレイに出力する。このメッセージを出すことでユーザはプログラムの実行方法が間違っていたことがわかる。このプログラムに関して言えば、STDERR.printではなくprintでもよい。STDERR.printは出力先としてファイルとディスプレイのいずれも指定することができる場合に、ディスプレイを指定する際の記法である(詳細は前期のopenメソッドの回を確認しよう)。STDERR.printとすることでディスプレイに表示することを明示的に示していると考えておけばよい。

exit(1):exitはプログラムの強制終了をあらわす。このプログラムでは引数を入力せずにプログラムを実行した場合、プログラムを継続する意味がない。そこでexitを使用して強制的にプログラムを終了している。プログラムを終了させる場合、プログラムの実行がうまくいったかどうかをシステムに対して示すことができる。これを終了ステータスというが、プログラムがうまくいった場合は0を用い(exit(0))、うまくいかなかった場合は0以外とする(exit(1))決まりになっている。

レポート課題

以下のうちいずれかを選んで解答する。ARGVを用いて記述すること。ARGVを用いなかった場合は配点を1点マイナスとする(例えば、10点満点の問題は9点満点で採点)。

問題1(8点満点):プログラム実行時に2つの引数を与え、その値に基づいて何らかの処理を行うプログラムARGV.rbを作成せよ。自力で作ったことがわかるよう、ほかの人と重複しないような独自性の高いプログラムを作成してみよう。

問題2(10点満点):シーザー暗号とはもとの文字を○文字ずらして変換することで無意味文字つづりに変換するものである。例えば3文字ずらすというルールを設けた場合、KOEKIはNRHNLとなる。プログラムを実行する際に、もとの文字列と、何文字ずらすか、変換モードを引数として与えることで、暗号化及び復号ができるプログラムcode.rbを作成せよ。ここで暗号化とはもとの文字列を無意味文字つづりに変換することを指し、復号は無意味文字つづりからもとの文字列に変換することを指す。変換モードとして1を与えた場合は暗号化、2を与えた場合は復号ができるようにせよ。

このプログラムを作成するに当たっては文字コードについての理解が必要である。文字はすべて2進数で表現することができる。以下は半角英数字の文字コードであるASCIIコード表である。ここで大文字のAは0x41(16進数)、小文字のaは0x61(16進数)となる。0x41を0x44に変更すればAがDに変わり3文字ずらしたことになる。復号する場合は44から3を引いて41にすればよい。日本語を取り扱うのは難しいため、以下の条件で作成すればよい。

  • 半角のアルファベットのうち大文字のみを対象とする
  • Zまでいった場合はAに戻るものとする
  • プログラム中での文字コードの取扱いについては前期の第10回目の授業を参照すること

ASCIIコード

  • 提出先:naoya@e.koeki-u.ac.jp
  • 提出期限:10/29(日)23:59
  • メールのSubject:自分の学籍番号-kadai02
  • 本文の構成:1行目で学籍番号、氏名を記載する。2行目以降は下記の構成とする
  1. 作成したプログラム
  2. プログラムの実行結果
  3. プログラムの説明
  4. 感想

  • 採点基準(問題1):期限内提出点(2点)、メールの体裁(1点)、プログラム(2点)、独自性(1点)、プログラムの説明(2点)
  • 採点基準(問題2):期限内提出点(2点)、メールの体裁(1点)、プログラム(4点)、プログラムの説明(3点)
  • プログラムの説明(問題1):何をするプログラムなのか概要を示した上で、ARGVに代入された値をどのように活用しているのかについて説明せよ。1行1行説明する必要はない。
  • 独自性(問題1):今回は自分で自由に作成するプログラムであるため、プログラムや説明が他の人と偶然に一致する可能性は低いと考えられる。ほかの人と同じプログラムの場合は0点(変数名だけ違う場合も0点)、ほかに同じプログラムを書いた人がいない場合は1点とする。
  • プログラムの説明(問題2):ARGVに代入された値をどのように活用しているのかに関する説明に加え、○文字ずらして結果を表示する箇所についての説明を行うこと。
  • 説明に関して、文章の意味がわかりづらい場合や、Webページを単にコピー&ペーストしたものは減点することがある。一度読み直してから提出すること。
  • 驚異的に良くできているレポートについては満点を超える得点をつけることがある。
  • よくできていたレポートは、他の人の参考になるよう、本人が特定できないような形で掲載する。掲載してほしくない場合はメールでの課題提出時にその旨記載すること。

Tips:emacsでの日本語入力のオンオフはCtrl-oです

Tips:ktermでのプログラムの実行結果をメールに貼り付けるには、コピーしたい箇所をマウスで選択し、emacs(Mew)上でマウスの真ん中ボタンをクリックする

Tips:Mewによるメールの送り方はMewコマンドを参照