11/10 関数から「計算」へ(1)


前回までの補足


前回の感想,質問より

Q.
xcodeを使うと、elseの場合分けのとき改行時にtabが入力されてターミナルでうまく起動できませんでした。tabをすべてスペースにしたらなおりました。
A.
irb(isrb)にコピー&ペーストするときに,字下げのためのtabが入っているとうまくいかないようですね.ファイルを保存してから,
load("./ファイル名")
で読み込む場合は大丈夫のようです.
Q.
ひきすうをひきすうとよむとしってかんどうしました.
A.
「湯桶読み」ですよね.私が最初にプログラミング言語を本で自習した時は「いんすう」と読むと思っていました.
Q.
ターミナルに直接書くとミスったときに書き直しにくいので、いったん他のところに書いてコピペすることが重要だと感じた。
A.
はい.エディタを使ってファイルに残しておくと後からの再利用も簡単です.
Q.
個人的に はifの条件の <= を < にかえた方がきれいな円になるような気がしました。
A.
<=とすると上下左右に1ピクセル飛び出た感じで格好良くないのは確かですね.教科書の図とはちょっと違うようです.
Q.
最初の方の操作に手間取ってしまい、ついて行けなくなって大変だった。 TAの方がなかなかきてくれなかったから困った。 最後の問題も難しかったので、次回に説明していただけると助かります。
A.
はい.後で解答例を示します.
Q.
medianのプログラムは、結構すっきりまとめることができたと思います。 しかし穴がないか心配なのですが、厳密に調べるにはどうしたらよいでしょうか?
A.
この問題に限っていうと, A < B < C, A = B < C, A < B = C, A = B = C の4つのパターンについて,引数の 順列組み合わせ 3! 通りを与えて正しい結果になることを確認すればおそらく大丈 夫だとは思いますが, 「厳密に調べる」のは一般には難しいですね.
Q.
関数を定義する際の局所関数に、大文字を使用することはできないのでしょうか。
A.
「局所関数」ではなく「局所変数」ですね.Ruby言語では変数名に大文字で始まる名前を使うことはできません.局所変数以外でもこれは変わらないのですが,通常の変数のつもりで大文字で始まる名前を使うと「定数(この講義では教えず,代わりに定数関数を使います)」として使われます.「定数」だと,何度も値を変えると警告(warning)が出ますが,一見変数と区別がつかないので,使えたつもりになってしまったのでしょう.
irb(main):008:0> S=1
=> 1
irb(main):009:0> S
=> 1
irb(main):010:0> S=2
(irb):10: warning: already initialized constant S
=> 2
irb(main):011:0> S
=> 2

Q.
medianは、配列やmax,minを用いることで簡略可能でしょうか? 何度かチャレンジしてみましたがうまくいかなかったので、気になります。
A. おすすめはできませんが,たとえば以下のように書くことはできます. 
def median(x,y,z)
  x+y+z-min(x,min(y,z))-max(x,max(y,z))
end
def median(x,y,z)
  x+y+z-[x,y,z].min()-[x,y,z].max()
end
def median(x,y,z)
  [x,y,z].sort()[1]
end

Q.
&&を&、==を=と表記してしまうことが多々ありました。 二重に表記することにどんな意味があるのですか?
A.
単独の「&」や「=」を別の意味(後者は代入文)に使うため区別のために必要です.

前回の課題について

Q:
2 次方程式ax2 + bx + c = 0 の解の個数を求めるsolutions(a,b,c). 判別式の値だけでなく、1 次方程式になっている場合にも対応せよ。
解答例
「解の個数」を求めることに注意する.とりあえず,a=0, b=0はないと仮定する.a=0の時は解は1つ.それ以外の時は,判別式の値が負で解は0個, 0で解は1個(重解),正で2個となる.
def solutions(a,b,c)
  if a == 0
    1
  else
    d = b * b - 4 * a * c
    if d < 0
      0
    else
      if d == 0
        1
      else
        2
      end
    end
  end
end
irb(main):046:0> solutions(0,1,3)
=> 1
irb(main):047:0> solutions(1,2,1)
=> 1
irb(main):048:0> solutions(1,2,2)
=> 0
irb(main):049:0> solutions(1,2,0)
=> 2
Q:
3 つの異なる値x, y, z が与えられたときの中央値を求めるmedian(x,y,z). 中央値とは大きさ順に並べたときに真ん中に来る値のことである。
解答例
6通りに分岐するプログラム
def median(x,y,z)
  if x <= y
    if y <= z
      y
    else
      if x <= z
        z
      else
        x
      end
    end
  else
    if x <= z
      x
    else
      if y <= z
        z
      else
        y
      end
    end
  end
end
irb(main):097:0* median(3,1,2)
=> 2
irb(main):098:0> median(1,2,3)
=> 2
irb(main):099:0> median(1,3,2)
=> 2
irb(main):100:0> median(3,2,1)
=> 2
irb(main):101:0> median(2,1,3)
=> 2
irb(main):102:0> median(2,3,1)
def median(x,y,z)
  if (x<=y && y<=z) || (z<=y && y<=x)
    y
  else
    if ( z<=x && x<=y ) || ( y <=x && x <= z )
      x
    else
      z
    end
  end
end

投票システム

vote.rbをダウンロードして,ホームディレクトリに保存してください.ドックからターミナルを起動して,
ruby vote.rb 選択肢番号
のように使います.

今日の練習,投票

関連リンク


教科書の補足


今日の課題