if-elsif-else-end
お題はうるう年
入力がうるう年(leap year)かどうかを表示するプログラムをかけ.
1. うるう年は4で割り切れる数の年.ただし,
2. 100で割り切れる年はうるう年でなく,
3. 400で割り切れる年はうるう年.
4. 2004, 1999, 1900, 2000で試せ.
5. それぞれtrue, false, false, true
簡単な解説:if-elsif-else-end
if 式 [then]
式 ...
[elsif 式 [then]
式 ... ]
...
[else
式 ... ]
end
[]は省略可能箇所
詳しい解法:2004年はleap year
4で割り切れるので閏年
p year = ARGV[0].to_i
if year % 4 == 0
p true
end
受け取った引数を.to_iで整数に変換し4で割り切れるときtrueを返す.
> ruby check_leap_2004.rb 2004
2004
true
類題:1999はfalse
1999年は4で割り切れないので閏年ではない.
p year = ARGV[0].to_i
if year % 4 == 0
p true
else
p false
end
結果
> ruby check_leap_0.rb 1999
1999
false
array, each
お題:テストの自動化
テストの内容が増えたときいちいち引数でチェックするのが面倒なので自動化
簡単な解説: array, each
各要素に対してブロックを評価します。
ブロックが与えられなかった場合は、自身と each から生成した
Enumerator オブジェクトを返します。
[1, 2, 3].each do |i|
puts i
end
#=> 1
2
3
この記法では,出力が#=>以下に記される.
配列Arrayは[]で定義.do-loop内で使う値は'|i|'のように縦棒で挟まれた変数名に入る.
array,eachを用いたテスト自動化
[2004, 1999].each do |year|
p year
if year%4 == 0
p true
else
p false
end
end
結果
> ruby check_leap_2004_1999.rb
2004
true
1999
false
詳しい解法1:1900はtrue? いえいえfalse
1900は4で割り切れるが,100で割り切れるので閏年ではない.1900でfalseが返るよう変更.
まずはテストの修正
[1900, 2004, 1999].each do |year|
次に100で割り切れる場合の処理
if year % 100 == 0
p false
end
とりあえず付け加えてみる
[1900, 2004, 1999].each do |year|
p year
if year % 100 == 0
p false
end
if year % 4 == 0
p true
else
p false
end
end
結果
> ruby check_leap_1900_2004_1999.rb
1900
false
true
2004
true
1999
false
1900が100で割り切れるかどうか判断したあとそのまま4で割り切れるか判断されて結果falseのあとtrueが出力される.なので条件を満たしたら次の要素に移るnextを追加
[1900, 2004, 1999].each do |year|
p year
if year % 100 == 0
p false
next
end
if year % 4 == 0
p true
else
p false
end
end
結果
> ruby check_leap_1900_2004_1999.rb
1900
false
2004
true
1999
false
これでOK
詳しい解法2:refactoring 条件式の単純化
先ほどの条件式は二つに完全に分けているがもっと単純にできる.
[1900,2004,1999].each do |year|
p year
if year % 100 ==0
p false
else
if year % 4 == 0
p true
else
p false
end
end
end
elsifで更に単純に
[1900,2004,1999].each do |year|
p year
if year % 100 ==0
p false
elsif year % 4 == 0
p true
else
p false
end
end
類題:そして2000はtrue!
2000は400で割り切れるので閏年
[2000, 1900, 2004, 1999].each do |year|
p year
if year % 400 == 0
p true
elsif year % 100 == 0
p false
elsif year % 4 == 0
p true
else
p false
end
end
結果
> ruby check_leap_2000_1900_2004_1999.rb
2000
true
1900
false
2004
true
1999
false
類題:refactoring_methodに
今書いたものをメソッドに
def leap?(year)
if year % 400 == 0
p true
elsif year % 100 == 0
p false
elsif year % 4 == 0
p true
else
p false
end
end
[2000, 1900, 2004, 1999].each do |year|
p year
leap?(year)
end
case
簡単な解説
case [式]
[when 式 [, 式] ...[, `*' 式] [then]
式..]..
[when `*' 式 [then]
式..]..
[else
式..]
end
解法
def leap?(year)
case
when year % 400 == 0 ; p true
when year % 100 == 0 ; p false
when year % 4 == 0 ; p true
else ; p false
end
end
[2000, 1900, 2004, 1999].each do |year|
p year
leap?(year)
end
結果
> ruby check_leap_2000_1900_2004_1999.rb
2000
true
1900
false
2004
true
1999
false
問題にもよるけどcaseのほうが見やすそう.
- source ~/grad_members_20f/members/yoshida/c3_if_case_leap_year.org