Pickles
Pickles

Reputation: 11

Ruby File Handing, reading then storing as Array

I'm unable to understand how get this piece of code working, the program is able to read the file but ends up print the same line multiple times.

Output:

Track title is: c/music/1

Track file location is: c/music/1

Track title is: c/music/2 

Track file location is: c/music/2

Track title is: c/music/3

Track file location is: c/music/3

Expected output:

Track title is: Taco

Track file location is: c/music/1

Track title is: Burrito 

Track file location is: c/music/2

Track title is: Nacho

Track file location is: c/music/3

Code:

class Track
    attr_accessor :title, :file_location
end

def read_tracks music_file

    count = music_file.gets().to_i
  tracks = Array.new
  $i = 0

  while $i < count do
  track = read_track(music_file)
  tracks << track
  $i += 1
  end
    tracks
end


def read_track aFile

  track_title = aFile.gets
  track_file_location = aFile.gets
  track = Track.new
  track.title = track_title
  track.file_location = track_file_location

end



def print_tracks tracks
  $i = 0
  while $i < tracks.length do
    print_track(tracks)
    $i += 1
  end

end


def print_track tracks
  puts('Track title is: ' + tracks[$i].to_s)
    puts('Track file location is: ' + tracks[$i].to_s)
end


def main
  aFile = File.new("input.txt", "r") 
  if aFile  
    tracks = read_tracks(aFile)
    aFile.close
  else
    puts "Unable to open file to read!"
  end

  print_tracks(tracks)
end

main

Sample of input file:

5

Taco

c/music/1

Burrito

c/music/2

Nacho

c/music/3

Upvotes: 1

Views: 522

Answers (2)

Ivan Olshansky
Ivan Olshansky

Reputation: 959

Problem is in the methods print_tracks and print_track.
These methods should look like this:

def print_tracks tracks
  $i = 0
  while $i < tracks.length do
    print_track(tracks[$i])
    $i += 1
  end    
end


def print_track track
  puts('Track title is: ' + track.title.to_s)
    puts('Track file location is: ' + track.file_location.to_s)
end

But if you want to make your code better, try something like this:

def print_tracks(tracks)
  tracks.each do |track|
    puts "Track title is: #{track.title}"
    puts "Track file location is: #{track.file_location}"
    puts
  end
end

In this case whole code will be:

class Track
  attr_accessor :title, :file_location
end

def read_tracks music_file
  count = music_file.gets().to_i
  tracks = Array.new
  i = 0

  while i < count do
    track = read_track(music_file)
    tracks << track
    i += 1
  end

  tracks
end

def read_track aFile
  track = Track.new
  track.title = aFile.gets
  track.file_location = aFile.gets
  track
end

def print_tracks(tracks)
  tracks.each do |track|
    puts "Track title is: #{track.title}"
    puts "Track file location is: #{track.file_location}"
    puts
  end
end

def main
  aFile = File.new("input.txt", "r").
  if aFile..
    tracks = read_tracks(aFile)
    aFile.close
  else
    puts "Unable to open file to read!"
  end

  print_tracks(tracks)
end

main

I've tested this code using sample file input.txt:

3
Taco
c/music/1
Burrito
c/music/2
Nacho
c/music/3

I've got output:

Track title is: Taco
Track file location is: c/music/1

Track title is: Burrito
Track file location is: c/music/2

Track title is: Nacho
Track file location is: c/music/3

This is exactly what you expected!

Upvotes: 0

iGian
iGian

Reputation: 11183

Try this, coping lines to array, then manipulating it:

lines = File.readlines('tracks.txt') # reads lines into array
lines.reject! { |e| e == "\n" } # removes empti lines
total_tracks = lines.shift.chomp.to_i # extract the first line from the array
lines.each_slice(2) { |e| puts e } # lines now contains only the pair track/directory
# adapt at your will

For each_slice(2) see Enumerable#each_slice, it groups the elements of array in groups.

Upvotes: 1

Related Questions