为什么在尝试查找股票的平均交易量时,以下方法会返回无穷大:
class Statistics
def self.averageVolume(stocks)
values = Array.new
stocks.each do |stock|
values.push(stock.volume)
end
values.reduce(:+).to_f / values.size
end
end
class Stock
attr_reader :date, :open, :high, :low, :close, :adjusted_close, :volume
def initialize(date, open, high, low, close, adjusted_close, volume)
@date = date
@open = open
@high = high
@low = low
@close = close
@adjusted_close = adjusted_close
@volume = volume
end
def close
@close
end
def volume
@volume
end
end
CSV.foreach(fileName) do |stock|
entry = Stock.new(stock[0], stock[1], stock[2], stock[3], stock[4], stock[5], stock[6])
stocks.push(entry)
end
以下是调用该方法的方法:
Statistics.averageVolume(stocks)
使用包含251行的文件输出到控制台:
stock.rb:32: warning: Float 23624900242507002003... out of range
Infinity
警告在以下行中调用:values.reduce(:+).to_f / values.size
答案 0 :(得分:1)
在编写平均函数时,您需要密切关注除零的可能性。
这是一个固定的,更像Ruby的实现:
def self.average_volume(stocks)
# No data in means no data out, can't calculate.
return if (stocks.empty?)
# Pick out the `volume` value from each stock, then combine
# those with + using 0.0 as a default. This forces all of
# the subsequent values to be floating-point.
stocks.map(&:volume).reduce(0.0, &:+) / values.size
end
在Ruby中,强烈建议将变量和方法名称保存在x_y
表单中,如average_volume
。首都具有重要意义,并表示类,模块和常量名称等常量。
您可以使用模拟股票测试此方法:
require 'ostruct'
stocks = 10.times.map do |n|
OpenStruct.new(volume: n)
end
average_volume(stocks)
# => 4.5
average_volume([ ])
# => nil
如果你仍然无限,那可能是因为volume
那里的某个地方有一个破碎的价值,这让事情搞得一团糟。您可以尝试过滤掉这些:
stocks.map(&:value).reject(&:nan?)...
在哪里测试与nan?
可能是您需要删除垃圾数据的。