12/19 レコード・オブジェクト・クラス(2)
前回の課題について
- 12人が提出
- 講義時間内に提出できた人は7名.
- 「インスタンス変数とアクセッサー」の問題は,自動採点の結果が誤っ
ていたので手動採点で修正しておいた.
- 「サブクラスと継承」の問題は,「2つの年月日の差」の定義が曖昧で,
Dt.new(2008,1,1).between(Dt.new(2008,1,3))
の結果を2とした人も,-2とした人もいたがどちらも正解とした.
- レコード・オブジェクト・クラス(1) 演習のページのdayDifferenceがyear2>year1
の時にnilを返すというバグを講義時間中に修正したが間に合わずに古い定義で提出した人もいたが,それに関しては減点していない.
- leap_year, dayDifference, daysFromNewYearの定義をメソッドbetweenの
定義の中に入れて
class ...
def between(d)
def leap_year(year)
...
end
def dayDifference(year1,year2)
...
end
def daysFromNewYear(year,month,day)
...
end
....
end
end
のように書いている人が複数人いた.Ruby言語ではメソッド内にメソッドの
定義を書くことも可能ではあるがあまりうれしいことはない(schemeやpythonのように外側の変数を参照することができない)し,実行効率上もメソッドを実行するたびに
メソッド定義を繰り返すことになるので避けた方が良い.上のleap_year, dayDifference は特定のオブジェクトに関連するものではないので,クラスに属さないメソッドで定義して,
def leap_year(year)
...
end
def dayDifference(year1,year2)
...
end
def daysFromNewYear(year,month,day)
...
end
class ...
def between(d)
....
end
end
とした方が良い(問題設定から「以下のメソッドを使って」も「???」の部分しか
埋めてはいけないと読めたかもしれないが).なお,特定のオブジェクトには関連しないが,特定のクラスには関連するメソッドとして「クラスメソッド」というものもあるがこの講義では扱わない.
- 用意したメソッドを利用しないもっとも短かった解答は以下のもの.
class Dt
def gepoch()
y = @year + 4800
m = @month
if m < 3
y -= 1
m += 12
end
365*y+y/4-y/100+y/400+(153*m-457)/5+@day-32045
end
def between(d)
(gepoch() - d.gepoch()).abs
end
end
大の月,小の月の関係が(153*m-457)/5という式に押し込められることを
知っておくと今後役に立つことがあるかもしれない.
今日の資料
スライド中のプログラム
class ComplexNumber
attr_accessor :realPart,:imaginaryPart
def initialize(r,i)
@realPart = r
@imaginaryPart = i
end
end
def add(x,z)
ComplexNumber.new(x.realPart + z.realPart , x.imaginaryPart + z.imaginaryPart)
end
def sub(x,z)
ComplexNumber.new(x.realPart - z.realPart , x.imaginaryPart - z.imaginaryPart)
end
def multiply(x,z)
ComplexNumber.new(x.realPart * z.realPart - x.imaginaryPart * z.imaginaryPart , x.realPart * z.imaginaryPart + x.imaginaryPart * z.realPart)
end
def rad2(x)
x.realPart * x.realPart + x.imaginaryPart * x.imaginaryPart
end
def inv(x)
r = rad2(x).to_f
ComplexNumber.new(x.realPart/r,-x.imaginaryPart/r)
end
def division(x,z)
multiply(x,inv(z))
end
x1 = ComplexNumber.new(1,2)
x2 = ComplexNumber.new(3,-4)
x3 = multiply(x1,x2)
division(x3,x1)
division(x3,x2)
multiply(inv(x3),x1)
operas = []
operas[0] = Opera.new("Traviata", "Verdi", 1853, "Italian", 3)
operas[1] = Opera.new("Carmen", "Bizet", 1875, "French", 4)
operas[2] = Opera.new("Otello", "Verdi", 1887, "Italian", 4)
operas[3] = Opera.new("Tannhauser", "Wagner", 1845, "German", 3)
operas[4] = Opera.new("Figaro", "Mozart", 1786, "Italian", 4)
operas[5] = Opera.new("Fidelio", "Beethoven", 1805, "German", 2)
composerInv = {}
for i in 0..operas.size-1
c = operas[i].composer
if composerInv[c] == nil
composerInv[c] = [i]
else
l = composerInv[c]
l[l.size] = i
end
end
while true
line = gets.chomp
for i in 0..operas.size-1
if operas[i].composer == line
p operas[i]
end
end
end
while true
line = gets.chomp
l = composerInv[line]
if l != nil
for j in 0..(l.size-1)
i = l[j]
p operas[i]
end
end
end
今日の課題
- CFIVEに入って,
コース選択で,「情報科学(水4)」を選択して下さい.
「課題」のところで,「12月19日分」が選べるようになるので,1/9(水)(今回はいつもと締切が違います)の23:55までに解いて提出する.
- 期限内なら何度でも再提出が可能である.1/9の夜23:55までに提出したものは8割以上を満点(8割以上は同じ),それ以降講義期間内(試験前)に提出したものは,10割を満点として採点する.もっとも点数の高いものを評価に用いる.
次回(1/9)の自習について
- 次回(1/9)は田中が出張のため自習とします.
- 講義時間中は小演習室2にTAが勤務するので質問がある人はTAにしてください.
- 新たな課題は出ません.今回の課題の1回目(締切は1/9 23:55),過去の課題の2回目などができていない人は取り組んでください.