2017-10-17 134 views
0

爲什麼試圖尋找一個股票的平均體積時,下面的方法返回無窮大:無限返回

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

+1

請提供[mcve],讓我們確切知道警告正在發生什麼行。 –

+0

警告發生在以下行''values.reduce(:+).to_f/values.size'''上。 – forgetaboutme

+1

在第7行的'end'後面加一個斷點,看看'values'的外觀。 – henrebotha

回答

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?可能是你需要剔除垃圾數據是什麼。

+1

謝謝你提供一個明確的例子。我可以設法找到錯誤;每當創建一個新股票時,交易量都將被存儲爲一個字符串。對字符串使用[to_f](https://apidock.com/ruby/String/to_f),因此將其轉換爲浮點數解決了此問題。 – forgetaboutme