CodeKata Four - Data Munging
http://codekata.pragprog.com/2007/01/kata_four_data_.html
Mungが訳せない・・・。
Martin Fowlerが KataTwoについて
「ひとつの関数についての練習だけで,実践的でない」
と注文をつけてくれた。その通りだと思う。
そこで,今日はもうちょっと複雑にしてみた。
実際のデータを扱う問題を3つ用意した。
【Part One: Weather Data】
2002年6月,NewJersey州Morristownの気象データが,weather.datに記録されている。
temperature spread(注)が一番小さい日のday number(カラム1)を探し出してほしい。
注 1188116772*1 一日の最高気温(カラム2)と最低気温(カラム3)の差
weather.dat
http://choko-chai.haru.gs/kshun/Hatena/weather.htm
【Part Two: Soccer League Table】
2001年第2シーズン,英国 Premier Leagueの結果がfootball.dat に記録されている。
Fカラムはチームの得点のシーズン合計,Aカラムは失点の合計だ。
得点合計と,失点合計の差が最も小さいチームの,チーム名を出力するコードを
書いてみてくれ。
football.dat
http://choko-chai.haru.gs/kshun/Hatena/football.htm
【Part Three: DRY Fusion】
上の2つのコードから,できる限り共通部分を切り出して,
より短くなった2つのコードと,共通コードという形にまとめてほしい。
【振り返り】
・最初にコードを書くときの設計方針が,後で共通部を切り出す作業に
どれくらい影響を与えただろうか?
・2つ目のコードを書くときに,1つ目のコードを書いたことの影響があったろうか?
・共通化を図ることはいつでも良いことだろうか?
共通化することで,可読性は下がらなかったか?保守性はどうかな?
【Ans.共通化前】
#wether.rb def calMinSpread file = File.open('wether.dat') file.gets file.gets minArray = calSpread(file.gets) while line = file.gets array = calSpread(line) minArray = array if minArray[1] > array[1] end return minArray[0] end def calSpread(line) dummy, day, mxT, miT = line.split(/\s+/) return day.to_i, mxT.to_i - miT.to_i end #football.rb def calBestTeam file = File.open('football.dat') file.gets minPoint = calPointDefference(file.gets) while line = file.gets if(!(line=~/---/)) array = calPointDefference(line) minPoint = array if minPoint[1] > array[1] puts "#{minPoint[0]}/#{minPoint[1]}" end end return minPoint[0] end def calPointDefference(line) array = line.split(/\s+/) puts "#{array[7]}-#{array[9]}" return array[2], (array[7].to_i - array[9].to_i).abs end
【Ans.共通化後】
#wether.rb def calMinSpread_common file = fileread('wether.dat',2) minArray = calDiff(file.gets, 1,2,3) while line = file.gets array = calDiff(line, 1,2,3) minArray = array if minArray[1] > array[1] end return minArray[0].to_i end #football.rb def calBestTeam_common file = fileread('football.dat',2) minArray = calDiff(file.gets, 2,7,9) while line = file.gets if(!(line=~/---/)) array = calDiff(line, 2,7,9) minArray = array if minArray[1] > array[1] end end return minArray[0] end #共通コード def fileread(name,skip) file = File.open(name) skip.times do file.gets end return file end def calDiff(line, name_i, max_i, min_i) array = line.split(/\s+/) return array[name_i], (array[max_i].to_i - array[min_i].to_i).abs end