最近开始使用Ruby(之前没有编程背景)。
任务: 编写一个程序,要求开始年份和结束年份,然后将所有闰年放在它们之间(包括它们,如果它们也是闰年)。闰年是可被4整除的年份(如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 :(得分:2)
让我们逐行浏览代码。我将解释发生了什么,并说明如何改进。
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
最后一行要求只要while
为start_year <= end_year
,Ruby就会继续true
循环。当此表达式变为false
时(当start_year == end_year + 1
时),她退出循环。请注意此行和下面行中的简化。
if start_year % 400 == 0
puts start_year
如果年份可被400
整除,则为闰年。
elsif start_year % 100 == 0
如果年份可以被100
整除,但不能被400
整除,那么它不是闰年,所以我们什么都不做,转到if / elsif / end子句的末尾和下一个执行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
返回循环顶部并重复。
<强>更好强>
这里有一种类似Ruby的编写方式,将代码转换为方法,使用单个布尔表达式并打印方法的返回值(闰年数组)。
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]
答案 1 :(得分: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
答案 2 :(得分:0)
你问的是输出来自哪里? puts
打印到控制台。
来自Kernel#puts
的文档:
相当于
$stdout.puts(obj, ...)
来自IO#puts
的文档:
将给定对象写入ios,与IO#print一样。在没有以换行符结束的任何内容之后写入记录分隔符(通常是换行符)。如果使用数组参数调用,则将每个元素写入新行。如果不带参数调用,则输出单个记录分隔符。
$stdout.puts("this", "is", "a", "test")
产生
this is a test
答案 3 :(得分:0)
我还将使用迭代器:
puts "Please select 2 years to calculate the leap ones in between. What's your 1st one?"
start_year = gets.chomp.to_i
puts "...and your second one?"
end_year = gets.chomp.to_i
range = start_year..end_year
range.select do |year|
puts year if year % 4 == 0 or year % 400 == 0
end
上面的while循环也可以重写如下:
puts 'Input a starting year:'
start_year = gets.chomp.to_i
puts 'Input an ending year:'
end_year = gets.chomp.to_i
puts ''
while start_year <= end_year
if start_year % 400 == 0 or start_year % 4 == 0
puts start_year
end
start_year += 1
end