24

I have a ruby script that will create two files by taking and merging values from another file.

#Resources
require 'rubygems'
require 'csv'

col_date = []
col_constant1 = []
col_constant2 = []
col_appYear = []
col_statsDesc = []
col_keyStats =[]
col_weeklyTotal=[]


weekly_total = []

fname = "finalStats.csv" #variable for capture file
        finalStatsFile = File.open(fname, "w") #write to capture file
fname2 = "weeklyStats.csv"
        weeklyStatsFile = File.open(fname2, "w")    
CSV.foreach('compareData.csv', converters: :numeric) do |row|
    weekly_total << row[0] - row[1]

    weekly_total.each do |data| 
    data << weekly_total.shift 
     weeklyStatsFile.puts data
end 
end

#retrieve stats from original document 
 CSV.foreach("autoCapture.csv") {|row| col_date << row[0]}
 CSV.foreach("autoCapture.csv") {|row| col_constant1 << row[1]}
 CSV.foreach("autoCapture.csv") {|row| col_appYear << row[2]}
 CSV.foreach("autoCapture.csv") {|row| col_statsDesc << row[3]}
 CSV.foreach("autoCapture.csv") {|row| col_constant2 << row[4]}
 CSV.foreach("autoCapture.csv") {|row| col_keyStats << row[5]}
 CSV.foreach("weeklyStats.csv") {|row| col_weeklyTotal << row[0]}



  col_date.zip(col_constant1, col_appYear, col_statsDesc, col_constant2, col_keyStats, col_weeklyTotal).each do |col_date, col_constant1, col_appYear, col_statsDesc, col_constant2, 
  col_keyStats, col_weeklyTotal|

  finalStatsFile.puts col_date+", "+col_constant1+", "+ col_appYear+", "+col_statsDesc+", "+col_constant2+", "+col_keyStats+", "+col_weeklyTotal

 end

In one file I wish to subtract the values in row[1] from the values in row[0] to create a new 'weekly_total' value. I then output this array of values in a file called weeklyStats.csv. This will output a column of values fine.

However, I want to join these values with another set from another file (autoCapture.csv) and when I try to zip them as arrays so that they read across in corresponding rows I get the error:

weeklyStats_csv.rb:42:in `+': no implicit conversion of nil into String (TypeError)
    from weeklyStats_csv.rb:42:in `block in <main>'
    from weeklyStats_csv.rb:40:in `each'
    from weeklyStats_csv.rb:40:in `<main>'

I gather this means that the array zip will not catch an exception if the one of the values is nil and therefore cannot convert to string. The problem is, I have tried converting weekly_total to string and array as I thought that it may be the problem (a mismatch of types) but I just dont where to go from here. Can anyone help?

Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160
Angela Jonon
  • 253
  • 1
  • 2
  • 8

1 Answers1

33

One of (or more) values in string

finalStatsFile.puts col_date+", "+col_constant1+", "+ col_appYear+", "+col_statsDesc+", "+col_constant2+", "+col_keyStats+", "+col_weeklyTotal

became nil. To fix the output you should explicitly cast them to strings:

finalStatsFile.puts col_date.to_s + ", " + 
                    col_constant1.to_s + ", " + 
                    col_appYear.to_s + ", " + 
                    col_statsDesc.to_s + ", " +
                    col_constant2.to_s + ", " +
                    col_keyStats.to_s + ", " + 
                    col_weeklyTotal.to_s 

BTW, the whole clause might be rewritten in more rubyish manner:

finalStatsFile.puts [ col_date,
                      col_constant1,
                      col_appYear,
                      col_statsDesc,
                      col_constant2,
                      col_keyStats,
                      col_weeklyTotal ].map(&:to_s).join(', ')
Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160
  • I think you are right about the nil value but unfortunately the .to_s stopped the error occuring but the column still did not write to the file. I have a feeling the problem can be fixed with + nil.to_s explicit conversion but I tried this in the .puts and it still did not work. I also changed he weekly total .each do to CSV.foreach('compareData.csv', converters: :numeric) do |row| weekly_total << row[0] - row[1] end weekly_total.each do |i| weeklyStatsFile.puts i end to no avail :( – Angela Jonon Jan 07 '15 at 13:15
  • 2
    Hey thanks, I have fixed this now. The .to_s worked in the end, it was just that I was putting the variable weekly_total into a separate file first and trying to read the value back. I did this because I didnt know about the converting to string initially and I thought that would fix it. Anyway once I ditched the other file, your answer worked. Cheers! – Angela Jonon Jan 08 '15 at 10:32
  • 2
    You could also use `.compact` on the array to remove any nils: `[ ... ].compact.join(', ')` – Joshua Pinter Dec 24 '17 at 21:21