Search code examples
rubycsvio

Input Output from CSV in Ruby. console output different from file output


I am learning the csv application in ruby.

I have a function which takes a string and looks up words against it based on starting alphabet

Now i am trying to read a file which has lots of strings and the program should read it and give the output in a seperate csv file.

My function is working and so is csv in. because i can see the output in the console and it is correct.. It just does not write to output csv .. and i am not able to figure out why..

code as under

require 'csv'

# Define a hash containing adjectives for each letter
adjectives_by_letter = {
  'a' => ['awesome', 'amazing’],
  'b' => ['beautiful', 'brave'],
  'c' => ['calm', 'clever'],
}

# Method to match each letter to a set of adjectives
def match_to_adjectives(letters, adjectives)
  matched_adjectives = {}

  letters.each do |letter|
    print "#{letter.upcase}: "
    available_adjectives = adjectives[letter.downcase] - matched_adjectives.values
    if available_adjectives.empty?
      puts "No available adjectives found for '#{letter}'"
    else
      adjective = available_adjectives.sample
      matched_adjectives[letter] = adjective
      puts adjective.upcase
    end
    puts "\n"
  end
end


# Define the input and output file paths
input_file = 'names.csv'
output_file = 'output.csv'

# Open the input file for reading
CSV.open(input_file, 'r') do |csv_in|
  # Open the output file for writing
  CSV.open(output_file, 'w') do |csv_out|
    # Iterate over each row in the input CSV
    csv_in.each do |row|
      # Extract the name from the row
      name = row[0]
      letters = name.chars
      results = match_to_adjectives(letters, adjectives_by_letter)
      
      # Write the name and its length to the output CSV
      csv_out << [ results ]
    end
  end
end

input names

heineken stella

output to console

A: ACTIVE



[Finished in 634ms]

output to output.csv

"[""h"", ""e"", ""i"", ""n"", ""e"", ""k"", ""e"", ""n""]"
"[""s"", ""t"", ""e"", ""l"", ""l"", ""a""]"


Whats the mistake i have made in csv_out?


Solution

  • the function prints the output to the console but does not return anything that can be used by the outer code to write to the CSV file. So when you call the match_to_adjectives it is not returning anything it just prints it to the console

    # Method to match each letter to a set of adjectives and return them
    def match_to_adjectives(letters, adjectives)
      matched_adjectives = []
      letters.each do |letter|
        available_adjectives = adjectives[letter.downcase] || []
        if available_adjectives.empty?
          # Optionally, handle the case when no adjectives are found for a letter
          matched_adjectives << "No adjective for '#{letter}'"
        else
          adjective = available_adjectives.sample
          matched_adjectives << adjective
        end
      end
      matched_adjectives
    end
    
    # Define the input and output file paths
    input_file = 'names.csv'
    output_file = 'output.csv'
    
    # Open the input file for reading
    CSV.open(input_file, 'r') do |csv_in|
      # Open the output file for writing
      CSV.open(output_file, 'w') do |csv_out|
        # Iterate over each row in the input CSV
        csv_in.each do |row|
          # Extract the name from the row
          name = row[0]
          letters = name.chars
          results = match_to_adjectives(letters, adjectives_by_letter)
          
          csv_out << [name, results.join(', ')] # Adjust the join delimiter as needed
        end
      end
    end