(3)10/12の授業内容

  1. いろいろな繰り返し表現について
  2. 情報検索の授業では、繰り返しを行う際、主にwhileを用いてきました。ただし繰り返し処理にはwhile以外にもいくつかの方法があります。様々な方法を理解して自在に扱えるようにしましょう。

    一定回数繰り返す(times)

    timesは整数に備わっているメソッドで、単純に一定回数繰り返す場合に用います。以下のどちらの方法で記述しても構いません(times.rb)。

    #!/usr/koeki/bin/ruby
    
    4.times {
      print "Hello\n"
    }
    #!/usr/koeki/bin/ruby
    
    4.times do
      print "Hello\n"
    end
    irsv{学籍番号}%chmod +x times.rb
    ./times.rb
    Hello
    Hello
    Hello
    Hello

    整数を数えながら繰り返す

    1から10までの合計を出すことを考えてみましょう。これまではwhileを使って表現をしてきました。まずは前回のプログラムを再掲してみます(goukei.rb)。

    #!/usr/koeki/bin/ruby
    
    goukei = 0
    i = 1
    
    while i <= 10
      goukei += i
      i += 1
    end
    
    printf ("goukeiの値は%dです\n",goukei)

    このプログラムはiの初期値を1として、繰り返しを行うごとにiの値を1ずつ増加しながらgoukeiに加えていくというものです。そしてiが10を超えたら終了になりますので、結果的に1から10までの合計を出したことになります。

    これはuptoメソッド、downtoメソッドを使って表現することも可能です。以下はuptoメソッドを用いて上記のプログラムを書き直したものです。goukei-upto.rbの名前をつけて保存し、実行してみましょう。

    #!/usr/koeki/bin/ruby
    
    goukei = 0
    1.upto(10) do |i| #from.upto(to)。1から10までiを1ずつ増加させる。
      goukei += i
    end
    
    printf ("goukeiの値は%dです\n",goukei)

    同様にdowntoメソッドを用いて書き直すと下記のようになります。goukei-downto.rbの名前をつけて保存し、実行してみましょう。

    #!/usr/koeki/bin/ruby
    
    goukei = 0
    10.downto(1) do |i| #from.downto(to)。10から1までiを1ずつ減少させる。
      goukei += i
    end
    
    printf ("goukeiの値は%dです\n",goukei)

    もうひとつ、連続した整数を繰り返すには、for整数範囲を用いた以下の繰り返し表現も可能です

    for 変数 in 整数範囲
     繰り返して行う処理
    end

    これで1から10までの合計を記述すると以下のようになります。goukei-for.rbの名前をつけて実行してみましょう

    #!/usr/koeki/bin/ruby
    
    goukei = 0
    for i in 1..10 #iに1から10まで順次代入する
     goukei += i
    end
    
    printf ("goukeiの値は%dです\n",goukei)

    飛び飛びに繰り返す

    uptoやdowntoは1ずつ増加、減少させながら繰り返し処理を行うためのメソッドでした。では、10+20+30+、、、+100のように10ずつ増加する場合や、2+4+6+、、、+10のように2ずつ増加する場合はどうすればよいでしょうか。これについてもまずはwhileでの表現方法を見てみましょう

    #!/usr/koeki/bin/ruby
    
    goukei = 0
    i = 10
    
    while i <= 100
      goukei += i
      i += 10
    end
    
    printf ("goukeiの値は%dです\n",goukei)

    このようにiの初期値を10として、繰り返しを行う中で10ずつ増加させていけばうまくかけます。なお、一定間隔で値を変える方法として、stepメソッドもあります。stepメソッドの基本構造は下記の通りです。

    開始値.step(終了値, 増加値) do |変数|#開始値から終了値まで変数を増加値ずつ増加させる
     繰り返して行う処理
    end

    この中で増加値は省略することができます。省略された場合は増加値は1とみなされます。実際に10から100まで100ずつ増加させて加算してみましょう。goukei-step.rbの名前をつけて保存し実行してみましょう

    #!/usr/koeki/bin/ruby
    
    goukei = 0
    10.step(100, 10) do |i|
      goukei += i
    end
    
    printf ("goukeiの値は%dです\n",goukei)

    増加値には負の値を入れることもできます。上記の足し算は100から初めて10ずつ減らしながら10までを全て足すと置き換えても同じ結果が出るはずです。goukei-step.rbを書き換えて、同じ結果になることを確認しましょう

    変化の割合がばらばらな場合=配列の要素に対する繰り返し

    では、1から10までのような連続した値でなく、10、20、30、、、のような変化の割合が一定でもない場合はどうしたらよいでしょうか? 例えば、2+8+9+12+20+25の場合を考えましょう。この場合、[2,8,9,12,20,25]という配列を想定し、配列内の要素を全て足すことを考えればよいということになります。配列内の要素の足し算もwhileで記述することができました。

    #!/usr/koeki/bin/ruby
    a = [2,8,9,12,20,25]
    
    goukei = 0
    i = 0
    
    while i < a.length #.lengthは配列内の要素の数を返すメソッド
      goukei += a[i]
      i += 1
    end
    
    printf ("goukeiの値は%dです\n",goukei)

    配列内の要素の加算はforを使って表現することもできます。下記は、配列の中の要素を順次変数に代入していくことをあらわしています。

    for 変数 in 配列
     上記の変数を使った処理
    end

    これを使って先ほどのwhileのプログラムを書き直してみましょう

    #!/usr/koeki/bin/ruby
    a = [2,8,9,12,20,25]
    
    goukei = 0
    
    for i in a #配列内の要素を順次iに代入する
     goukei += i
    end
    
    printf ("goukeiの値は%dです\n",goukei)

  3. コマンドラインとの情報のやりとり
  4. ktermにおいてrubyプログラムを実行する際

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

    とか

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

    と入力しました。

    プログラムを実行する際に

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

    のようにプログラム自身に引数を与えると、プログラムを実行するときに利用することができます。与えた引数は自動的にARGVという配列変数に代入されます。

    上記の例では
    ARGV[0] = "100"
    ARGV[1] = "200"
    ARGV[2] = "300"
    となっています。いずれも文字列であることに注意が必要です

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

    例えば、1から10までuptoメソッドを使って合計を求めるgoukei-upto.rbを、1から指定した数までの合計を求めるプログラム(goukei-ARGV.rb)に書きかえることを考えましょう。例えば30までの合計を求める場合、実行する際に

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

    と入力することになります。これを実行できるようにプログラムを改良すると下記の通りとなります(goukei-ARGV.rbという名前をつけて保存し、実行してみよう)。なお、goukei-upto.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
    
    goukei = 0
    goal = ARGV[0].to_i
    
    1.upto(goal) do |i|
      goukei += i
    end
    
    printf ("1から%dまでの合計は%dです\n",goal, goukei)

    新しく出てきた部分について説明します

    if ARGV[0] == nil:nilはデータがないという意味。配列変数ARGVの0番目の値がない場合、つまりプログラムを起動する場合に引数を与えなかった場合は以下の処理を行いなさいという意味です

    STDERR.printの2行:nilの場合に画面に表示するメッセージです。rubyプログラムは結果を画面に出力する変わりにファイルに出力することもできます。しかしこの2つのメッセージはいわばエラーメッセージですから、ファイルに出力されては困ります。単に出力するメソッドはprintですが、STDERR.printとすることにより、出力先がファイルに指定されていても、必ず画面に表示することが可能になります

    exit(1):exitは直ちにプログラムの実行を終了しシステムに終了コードを返すための方法です。エラーが発生した場合などはプログラムを続けても意味がないのでexitを使用して終了させます。なお、プログラムの実行が終わった際、プログラム全体がうまくいったかどうかをシステムに対して教えることができ、これを終了ステータスと呼んでいます。終了ステータスは整数で表し、プログラムがうまくいったとき→0、うまくいかなかったとき→0以外とする決まりになっています。exit(1)としているのは、「予定した仕事ができずに終了してしまった」ことをシステムに伝えています。

    goal = ARGV[0].to_i:goalという変数にプログラム起動時に入力された引数を代入しています。引数は文字列として扱われるため、.to_iをつけて整数に変換しています

    1.upto(goal) do |i|:終了値を具体的な値ではなくgoal変数に変更しています。goal変数に代入されているのはプログラム起動時に指定した値です

    printf ("1から%dまでの合計は%dです\n",goal, goukei):%dを2つに増やしています。これに伴い""の後の変数を2つにしています。

課題

以下のうちどれか1つを選んで解答してください。ただし、いずれの場合も

ものとします。


問題1:1からはじめて任意の自然数までの奇数の積を求めるプログラムoddmul.rbを作成せよ(8点満点で採点)

問題2:指定した任意の自然数からはじめて、100までのその自然数の倍数を全て足した値を求めるaddsum.rbを作成せよ(9点満点で採点)

いずれも最後のprintfの行で積や和の値だけを表示した場合の採点基準です。1×3×5×、、、×X=XXXXXや、2+4+6+、、、Y=YYYYYのように式の形式で結果を出力することができた場合は、それぞれ満点を1点プラスして採点します(これはかなり難しいので無理に挑戦しなくても良いです)

作成したプログラムや実行結果をメールでnaoya@e.koeki-u.ac.jp宛に送る.

課題の提出期限は10月18日(火)23:59までです


メール送信時の注意

採点基準:期限内提出(2点)、プログラム(2点〜4点:何点満点で採点するかにより異なる)、説明(3点)、指示通りにメールを送っているか(1点)

説明の採点は、使用した繰り返し表現、ARGVについて説明がなされているか、満点が+1点になる結果出力方法を用いた場合は、うまく表示させるためにどのような工夫をしたかを詳しく書いているかどうかを中心に見る

途中までしかできない場合でも提出をすれば部分点を与えますので、未提出だけは避けましょう

Tips

emacsについて

Mewについて