情報科学概論
2001.6.5



  1. 本日の作業内容

    1. メール受信について
    2. ループについて
    3. 他の言語について
      1. Rubyによるスクリプト
      2. C
      3. Perl
    4. ローマ字−ひらがな変換
    5. 本日の実習
    6. 宿題


  2. メール受信について

    前回のコンピュータセミナーの授業で、メールの受信が未だに出来ていないケースが結構あることが判明した。メールの受信が出来ないと言うことは、質問が出来ないばかりでなく、今後の課題の提出にも大きな問題が残るので、一刻も早くメールの送受信の環境を構築しなければならない。問題がある場合には本日の授業時間内に必ず申し出て対策を考えること。


  3. ループ

    ここまで学習してきた内容から、人間が自分で作業を行うのではなく、コンピュータを使ってプログラミングにより行う方が適している操作にはどのようなものがあるかを考えていくと、結局膨大な量の情報を扱う場合や、同じ作業を繰り返す場合が簡単に思いつくことである。たとえば、何度も例にでてくるが、1から10までの整数の和を求める場合には、筆算でも電卓でも簡単にできる。プログラミングにしても、

    print 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10, "\n"

    として、別段特殊な方法を使わないでも簡単に行える。それが、1から1000までに拡張されるとどうなるであろうか。先週のガウスの方法のように、1000×1001/2の公式を使えば相変わらず簡単にはできるが、プログラミングで先ほどのようにすべての数の和を書くことは現実的ではない。上の例のように公式がわかっていれば簡単であるが、では、1から50までの数の4乗の和を求める場合はどうだろう?

    公式に入れて簡単に出す、というわけにはいかないので、このような場合にこそプログラミングにより楽して計算するのが良さそうである。では、どうやるか、というと、数を4乗して足す、ということを50回繰り返すことになる。このような、同じ処理を何度も繰り返す際に使用するのが、プログラミングにおけるループであり、forwhileがそのために使用される。方法は、

    quad = 0
    for i in 1..50
      quad += i**4
    end
    puts quad

    により、実現できる。同様に、

    quad = 0; i = 0
    while i <= 50
      quad += i**4
      i += 1
    end
    puts quad

    とすればwhileループで実現できる。上のforの例は、1から50までの整数iについて、iを4乗してquadに加えていく、という処理であり、下の例はiが50になるまで、iの4乗を足しあわせるのと、iを一増やすという操作の繰り返しである。目的によって、forwhileを使い分ければよい。たとえば、データファイルを読み込む場合などには読み込むデータが何行あるのかわからない場合が多いのでwhileを使って繰り返し読み込むのが普通であり、あらかじめ決められた回数繰り返しを行うのであれば、forの方が記述が簡潔で楽である。

    このように、何度も同じ処理を繰り返すループという操作に慣れない限りは、これからの授業や課題に対してずっと苦しい思いをすることが予想されるので、上のような単純な例でもよいので、自分で適当なループを作成し、実行してみよう。エラーが表示されてもエラーの中身をよく見ればだんだんと問題点が整理されてくるので、いつか必ず理解できるようになる。

  4. 他の言語について

    さて、これまでRubyにおけるプログラミングの基礎を学習してきた。Rubyは日本発の優れた言語であり現在ユーザが急激に増加中であるが、実際に使用されている比率からいくとC言語や代表的なスクリプト言語のPerlにはまだまだ及ばない。松江で開発されているので親近感があるという特殊事情はあるにしても、授業で学習するのがRubyで大丈夫かという不安がある人がいるかもしれない。そこで、今回はちょっと寄り道して、他の言語との比較を行ってみることにする。

    1. Rubyによるスクリプト

      例に使うスクリプトは現在までの知識で理解できるものとするために、C言語の作者であるKernighanとRitchieが書いた古典である「The C PROGRAMMING LANGUAGE」の最初にでてくる例題を参考にする。これは、アメリカで通常用いられている温度単位の華氏(Fahrenheit)により表示された温度を摂氏(Celsius)に変換するプログラムである。Rubyで書くとたとえば以下のようになる。

      lower = 0
      upper = 300
      step = 20
      
      fahr = lower
      while fahr <= upper
        celsius = 5 * (fahr - 32) / 9
        printf("%d\t%d\n", fahr, celsius)
        fahr += step
      end

      構造をわかりやすくするためにいろいろと変数を定義したり用意したりしているが、基本的な動作はわかると思う。華氏について0度から300度まで20度おきに華氏と摂氏の対応表を出力するものである。

    2. C

      さて、上記の例題は実はCによるものをRubyに書き直しているので、正確にはこちらが元である。Cでは以下のようになる。

      main()
      {
          int fahr, celsius, lower, upper, step ;
          
          lower = 0;
          upper = 300;
          step = 20;
      
          fahr = lower;
          while (fahr <= upper) {
              celsius = 5 * (fahr - 32) / 9;
              printf("%d\t%d\n", fahr, celsius);
              fahr += step;
          }
      }

      Cでは変数を扱う際に整数か浮動小数かをあらかじめ宣言しておく必要がある。また、文の終わりには;(セミコロン)が必要である。特徴は、Rubyでは隠れているmainという関数を必ず書いておかなければいけないことで、mainの内容全体が{}で囲まれている。また、whileの実行部分も{}で囲まれている。

      さて、上記のプログラムを実行する方法であるが、Cはコンパイル作業を伴う言語なので少し面倒である。以下のようにするととりあえず動作の確認ができる。まずは、上のプログラムをエディタで作成し、temp.cという名前で保存する。このとき、拡張子は必ず小文字のcにする。その後で以下のようにターミナルで操作しよう。

      $ gcc temp.c

      ソースに問題がなければそのままコンパイル作業は終了し、そのディレクトリにa.outというファイルが作成されている。次に、

      $ ./a.out

      とすると、実際のプログラムが動作する。

    3. Perl

      webのCGI処理など、テキストを扱うスクリプト言語としてもっとも広く使われているのが、Perlである。同様にPerlで記述すると、以下のようになる。

      $lower = 0;
      $upper = 300;
      $step = 20;
      
      $fahr = $lower;
      while ($fahr <= $upper){
        $celsius = 5 * ($fahr - 32) / 9;
        printf("%d\t%d\n", $fahr, $celsius);
        $fahr += $step;
      }
      

      変数の前に$を付ける必要があるのと、文の終わりにCと同様;を付ける。Perlもコンパイル不要のスクリプト言語なので、そのまま実行可能である。スクリプトをtemp.plとして保存したら

      $ perl temp.pl

      として実行してみよう。

      単純な例の比較であるのでわかりにくいかもしれないが、結局、RubyはCのような数値の型の宣言が不要であり、また、CやPerlと異なり文の終わりにくる;も不要であるが、それ以外の要素はかなり似ている、ということがわかると思う。すなわち、変数や定数、ループなどの処理、演算などはどの言語で学習しても基本的な仕組みは共通しているので問題はない。その上で、Rubyは面倒な宣言や;付けが不要であり、コンパイルも不要なので、もっとも楽に記述できる言語である。初心者がとりあえず「プログラミングとは何か」を学習するのに非常に適していることがわかっていただけただろうか。後期からC言語を学習する予定になっているが、この授業で配列やループをしっかり理解しておくと、後々楽になるはずである。

  5. ローマ字−ひらがな変換

    教科書p.45

    先週まで配列に関する課題を行い、配列の使い方を学習してきた。ここで、用いるのは配列と似ている変数の対応関係であるハッシュの方である。配列は順番により要素の中身が決まる数学関数のようなものであったが、ハッシュでは対応を決めるのは順番ではなく自分で定義した関連づけである。今扱うのは、ひらがなとローマ字を対応させるための定義であり、50音に従って順番に対応付けをやってしまおうというのがp.45の例である。上で説明したようにコンピュータは繰り返し処理が得意なので、ローマ字で50音を表現するときの子音と母音を分けてその組み合わせにより任意のひらがなを組み立てる方式を入力文字だけ繰り返すループで実行する。例を実行するときの注意は、教室のエディタの標準文字コードはEUCなので、$KCODE = "euc"に変えることである。

    • 二重配列Hiraganaの作成

      Hiragana = "あいうえお

      ".collect{ |line| line.chop.scan(/./) }

      の動作はp.44の中央部にあるように、まずは「あ」から「ぽ」までのひらがなを各行ごとに配列の要素にするので、["あいうえお", "かきくけこ", ‥]のような配列にし、次にline.chop.scan(/./)の操作を行う。chopは最後の一文字を削除するメソッドであり、ここでの最後の一文字は目には見えない改行文字である。次に、scan(/./)で一文字ずつ配列の要素にくみ上げられる。 . は任意の一文字を意味するので、文字一個ごとに配列の要素へと移されることを意味している。"あいうえお"を一文字ごとに配列に変更すると["あ", ‥, "お"]となるので、結局は二重配列を作ることになる。

    • each_with_indexの二重の入れ子

      Siin.each_with_index do |s, i|
        Boin.each_with_index do |b, j|
          puts s + b+ " " + Hiragana[i][j]
        end
      end
      

      の部分は、Siinの方ならば各要素をsが意味し、iについては0から順に増えていくので、結局は子音の配列を便宜上二重配列にして、ひらがなと対応させるために面倒な作業を行っている。結果、ローマ字を順にaiueokakikukeko...と表示するのに対して、それに対応するひらがなをHiragana[i][j]により出力し、対応表が完成する。流れとしては以下の図のようになる。

    • リダイレクト

      リダイレクトという言葉がでてくる。これは、ターミナルから入力したコマンドの出力を通常の画面(これを標準出力という)からファイルへと迂回させる意味である。リダイレクトを行うと、結果は画面には表示されず、ファイルの中身として保存される。また、>>の方は、すでにあるファイルの末尾に追加して保存するというリダイレクトである。

    • roma2hira.rbの動作

      roma2hira.tblなどの準備が整っていれば、p.47にあるroma2hira.rbの流れは以下のようになる。(なお、__FILE__という特殊な定数があるが、FILEの前後にあるのはそれぞれアンダースコア(下線)が二つずつである。)

      1. 空の配列RomajiおよびハッシュRoma2Hiraの定義

        要素の数が決まっていない配列やハッシュの定義は冒頭にあるように、要素を書かずにカッコだけで定義しておけばよい。スクリプト中で要素が確定するたびに追加されて入っていく。

      2. roma2hira.tblの読み込み

        あらかじめ作成されていたroma2hira.tblを一行ずつ読み込む。各行は「a あ」のように構成されているので、splitにより、ローマ字部分がromaに、ひらがな部分がhiraに格納され、push(p.36)によりromaがRomajiに追加され、それに対応するものとしてhiraが相当するようなハッシュRoma2Hiraが作成される。eachにより読み込む行が無くなるまでこの作業が続き、全ての組を含むハッシュが作成される。

      3. 正規表現の準備

        配列Romajiの要素を|を区切りとして一列に並べ、Roma_regという名前にする。

      4. 変換メソッドの定義

        スクリプトが始まってから、キー入力を行って入ってきたローマ字文字列をlineとし、それをひらがなに変換するメソッドの定義が行われる。ここではlineとして入ってきた文字列がrで表され、rから連想されるひらがなをハッシュRoma2Hiraから選び出し、gsubにより置き換える。この時点でローマ字からひらがなに変わる。

      5. キー入力の読みとり

        キー入力をARGFとして、データがある限り一行ずつ読み込んでひらがな変換メソッドを実行する。変換元のローマ字が入ってこなくて改行文字だけの行が現れるとbreak(中断)する。

      以上の流れで変換スクリプトが動作することになる。

  6. 本日の実習

    作業1
    3.に挙げたループの実習を本日の例を利用して自分で試してみること。

    作業2
    教科書のローマ字ひらがな変換スクリプトも試してみること。

    作業3
    4.に紹介したCやPerlの例題も試してみること。

  7. 宿題

    授業の終わり頃に次回までに提出する課題を発表するのでアナウンスに注意すること。また、発表されたら課題を表示するためには、一度このページを再読み込みする必要があるのでNetscapeのボタンをクリックする。そうしないと、課題のページは表示されない。


目次ページに戻る