2016-11-11 56 views
-2

最近開始使用Ruby(沒有以前的編程背景)。閏年。用Ruby編程。有人可以解釋嗎?

任務: 編寫一個程序,要求開始年份和結束年份,然後將所有閏年放在它們之間(並且包括它們,如果它們也是閏年)。閏年是可以被四分之一的年份(如1984年和2004年)。然而,多年來通過100整除不是閏年(如1800和1900年),除非它們被400整除(如1600和2000年,這實際上是閏年)

代碼:

puts 'Input a starting year:' 
start_year = gets.chomp 
puts 'Input an ending year:' 
end_year = gets.chomp 
puts '' 

while start_year.to_i <= end_year.to_i 

    if start_year.to_f%400 == 0 
     puts start_year 
    elsif start_year.to_f%100 == 0 
    elsif start_year.to_f%4 == 0 
     puts start_year 
    end 
    start_year = start_year.to_i + 1 
end 

燦有人解釋我這個代碼一步一步(字面)?以及控制檯如何打印出這些日期?我們在哪裏要求程序在此代碼中打印?

+0

Ruby有一個相當不錯的[documentation](http://ruby-doc.org/core)。你有沒有試圖自己查看方法? – Stefan

+0

堆疊在@Stefan所說的內容上。我會查找循環方法和Ruby運算符來弄清楚這個代碼是如何工作的。 – Antonio

回答

1

讓我們通過代碼行由行。我會解釋發生了什麼,並說明如何改進。

puts 'Input a starting year:' 
start_year = gets.chomp 

這將是使start_year整數更方便,所以我們不必保持一個字符串和一個整數之間的轉換。因此,我們應該在第二行改爲

start_year = gets.to_i 

如果您檢查文檔爲String#to_i,你會看到,這是一樣的

start_year = gets.chomp.to_i 

接下來,

puts 'Input an ending year:' 
end_year = gets.to_i 
puts '' 

while start_year <= end_year 

最後一行要求Ruby繼續while循環,只要start_year <= end_yeartrue。當這個表達式變成false(當start_year == end_year + 1)時,她退出循環。注意這一行和下面的行簡化。

if start_year % 400 == 0 
    puts start_year 

如果年份可以被400整除,那麼這是一個閏年。

elsif start_year % 100 == 0 

如果年份是100整除,而不是由400,它是不是閏年,所以我們什麼也不做,轉到如果/ ELSIF /結束子句的結束和下一個執行start_year += 1

elsif start_year % 4 == 0 
    puts start_year 
end 

如果年份是4整除,而不是由100,是爲閏年。如果start_year % 4 != 0這不是一個閏年,所以我們不打印它。

start_year += 1 

其中Ruby擴展爲start_year = start_year + 1

end 

返回到循環的頂部並重復。

更好

這裏的編寫,代碼轉換的方法,使用單個布爾表達式和打印方法(閏年的陣列)的返回值的更紅寶石狀方式。

def leap_years(start_year, end_year) 
    (start_year..end_year).select { |yr| 
    yr % 400 == 0 || (yr % 100 != 0 && yr % 4 == 0) } 
end 

puts 'Input a starting year:' 
start_year = gets.to_i 
puts 'Input an ending year:' 
end_year = gets.to_i 

p leap_years(start_year, end_year) 
    #=> [1904, 1908, 1912, 1916, 1920] 

first_year..last_year是一個範圍(類Range的一個實例)。 Range包括模塊Enumerable,它爲它提供了實例方法Enumerable#select

最佳

下將獲得兩個給定年間的閏年更簡單的方法,通過利用類方法Date::leap?的。

require 'date' 

def leaps_between(first_year, last_year) 
    (first_year..last_year).select { |y| Date.leap?(y) } 
end 

leaps_between(2000, 2016) 
    #=> [2000, 2004, 2008, 2012, 2016] 

leaps_between(1900, 1916) 
    #=> [1904, 1908, 1912, 1916] 
+0

'(first_year..last_year).select {| y | Date.leap?(y)}' – steenslag

+0

謝謝@nsenslag。我不知道[Date :: leap?](http://ruby-doc.org/stdlib-2.3.0/libdoc/date/rdoc/Date.html#method-c-leap-3F)(或[日期#飛躍?](http://ruby-doc.org/stdlib-2.3.0/libdoc/date/rdoc/Date.html#method-i-leap-3F))。讀者,我以前有'(first_year..last_year).select {| y | Date.new(y,2,-1).day == 29}'。 –

0
# Print the sentence "Input a starting year:" 
puts 'Input a starting year:' 
# Create a variable start_year and set its content to the user's input stripping it from the new line character 
start_year = gets.chomp 
# Read above 
puts 'Input an ending year:' 
end_year = gets.chomp 
puts '' 

# Do something while start_year is smaller or equal to end_year 
while start_year.to_i <= end_year.to_i 
    # If start_year divided by 400 doesn't have any remainder 
    if start_year.to_f%400 == 0 
     # Print that year in the console 
     puts start_year 
    # Else if ... 
    elsif start_year.to_f%100 == 0 
    elsif start_year.to_f%4 == 0 
     puts start_year 
    end 
    # Increase start_year by 1 
    start_year = start_year.to_i + 1 
end 
0

你問過輸出是從哪裏來的? puts打印到控制檯。

Kernel#puts文檔:

相當於

$stdout.puts(obj, ...) 

而且從IO#puts文檔:

將給定對象的ios與IO#打印。在沒有以換行符結束的任何之後寫入記錄分隔符(通常是換行符)。如果使用數組參數調用,則將每個元素寫入新行。如果不帶參數調用,則輸出單個記錄分隔符。

$stdout.puts("this", "is", "a", "test") 

生產:

this 
is 
a 
test