我正在编写一个程序,它获取一组数据,然后对其进行平均。该数据集是拉瓜迪亚机场每个月的平均温度,对应于温度。
下面是一个数据点示例:
2009-07,23.6
这是年月,温度。
我有 163 个数据点。所有数据点都位于一个.txt文件中,每个数据点都在新行上。
我将数据制作成一个数组并拆分它。出于某种原因,我的程序每次尝试运行它时都说我的平均值为 0
这是我的代码:
data = File.open("avg_temp.txt", "r+")
contents = data.read
contents = contents.split("rn")
contents.collect! do |x|
x.split(',')
end
sum = 0
data.each do |x|
sum = sum + x[1].to_f
end
avg = sum / contents.length
puts avg
结束后将avg = sum/contents.length
分配给循环之外。 循环中定义的变量的作用域仅限于该循环。你也在循环data
,应该content
contents.each do |x|
puts x[1] # to check if the right value is being evaluated
sum = sum + x[1].to_f
end
avg = sum/contents.length
您的avg
不是顶级局部变量。因此,您无法从顶层访问它。 avg
的作用域仅限于块。您可以执行以下操作:-
avg = 0
data.each do |x|
sum = sum + temp[1].to_f
avg = sum / contents.length
end
puts avg
sum = 0
data.each do |x|
sum = sum + temp[1].to_f
avg = sum / contents.length
end
puts avg
avg
变量不再在范围内,因为它在每个块之外。要打印平均值,只需将其移动到块内即可,如下所示
sum = 0
data.each do |x|
sum = sum + temp[1].to_f
avg = sum / contents.length
puts avg
end
或者将 avg 变量移出循环(在循环退出后执行一次操作)
sum = 0
data.each do |x|
sum = sum + temp[1].to_f
end
avg = sum / contents.length
puts avg
更多信息请访问 http://rubyflare.com/2009/09/30/variables-scope-and-iterators/
我会写得更简单:
lines = 0
sum = 0
File.foreach("avg_temp.txt") do |data|
sum += data.split(',').last.to_f
lines = $.
end
puts 'Average: %f over %d datapoints' % [sum / lines.to_i, lines]
# >> Average: 23.375000 over 4 datapoints
哪些输出:
Average: 23.375000 over 4 datapoints
以"avg_temp.txt"开头,如下所示:
2009-07,23.6
2009-08,23.7
2009-09,23.6
2009-10,22.6
解释一下:
-
$.
是当前行号。每次通过循环时,它都会将最后一个读取的行号重新分配给lines
这样我们就知道要除以多少。 -
foreach
逐行读取,因此无需拆分文件。这也解释了为什么我使用$.
来跟踪元素的数量。这也意味着这可以毫无问题地读取包含数百万或数十亿个值的文件,read
会屈服。