Concatenating strings with variables with Ruby - ruby

I am writing a test script that opens a file with a list of URLs without the "www" and "com".
I am trying to read each line and put the line into the URL. I then check to see if it redirects or even exists.
My problem is when I read the line from the file and assign it to a variable. I then do a compare with what's in the URL after loading and what I initially put in there, but it seems to be adding a return after my variable.
Basically it is always saying redirect because it puts "http://www.line\n.com/".
How can I get rid of the "\n"?
counter = 1
file = File.new("Data/activeSites.txt", "r")
while (line = file.gets)
puts "#{counter}: #{line}"
counter = counter + 1
browser.goto("http://www." + line + ".com/")
if browser.url == "http://www." + line + ".com/"
puts "Did not redirect"
else
puts ("Redirected to " + browser.url)
#puts ("http://www." + line + ".com/")
puts "http://www.#{line}.com/"
end
Basically it is always saying redirect because it puts http://www.line and then return .com/
How can I get rid of the return?

Short answer: strip
"text\n ".strip # => "text"
Long answer:
Your code isn't very ruby-like and could be refactored.
# Using File#each_line, the line will not include the newline character
# Adding with_index will add the current line index as a parameter to the block
File.open("Data/activeSites.txt").each_line.with_index do |line, counter|
puts "#{counter + 1}: #{line}"
# You're using this 3 times already, let's make it a variable
url = "http://#{line}.com"
browser.goto(url)
if browser.url == url
puts "Did not redirect"
else
puts ("Redirected to " + browser.url)
puts url
end
end

That's because your lines are terminated by a newline. You need to strip it off:
while (line = file.gets)
line.strip!
puts "#{counter}: #{line}"
# ...
Note that there are better ways of iterating over the lines in a file:
File.foreach("Data/activeSites.txt") do |line|
# ...
end

This is your code after reindenting it to the "Ruby way":
counter = 1
file = File.new("Data/activeSites.txt", "r")
while (line = file.gets)
puts "#{counter}: #{line}"
counter = counter + 1
browser.goto("http://www." + line + ".com/")
if browser.url == "http://www." + line + ".com/"
puts "Did not redirect"
else
puts ("Redirected to " + browser.url)
#puts ("http://www." + line + ".com/")
puts "http://www.#{line}.com/"
end
It's not correct because it's missing a closing end for the while. But, it's also not dealing with file IO correctly.
This is how I'd write it:
File.foreach("Data/activeSites.txt") do |line|
puts "#{ $. }: #{ line }"
browser.goto("http://www.#{ line }.com/")
if browser.url == "http://www.#{ line }.com/"
puts "Did not redirect"
else
puts "Redirected to #{ browser.url }"
puts "http://www.#{ line }.com/"
end
end
File.foreach is a method inherited from IO. If you read the file correctly you don't need to strip or chomp, because Ruby will handle it correctly when IO.foreach reads the line.
Every time IO reads a line it increments the $. global, which is short-hand for $INPUT_LINE_NUMBER. There's no need to keep a counter. Using:
require 'english'
will enable the verbose names. See the English docs for more information.

Related

Ruby filtering specific lines from a text file

I'm a newbie! I have a text file that contains lines and lines of text. I want to try to create a code that only allows the lines that have the phrase "larry.bird" show while the others are deleted. This is my current code...
File.open("HM.txt").each do |line|
   puts line
   if line.include? "larry.bird"
      puts "larye.bird " + line
   end
end
File.readlines('HM.txt') do |li|
  puts li if (li['larry.bird'])
end
If you can help me out, that would be awesome!
You're pretty close. You're opening and reading the file correctly; you're just accidentally printing every line before performing the check. The puts line on the second line of your code is ensuring that this occurs.
File.open("HM.txt") do |file|
file.each_line do |line|
if line.include? "larry.bird"
puts "larry.bird " + line
end
end
end
We can also shorten one-line if statements in Ruby, using suffix notation that often makes code more concise.
File.open("HM.txt") do |file|
file.each_line do |line|
puts "larry.bird " + line if line.include? "larry.bird"
end
end
This is equivalent to the first example.

How to read a file after it's been written to in Ruby

When I run the following code taken from the Learn Ruby the Hard Way Course Exercise 16,
filename = ARGV.first
target = open(filename, 'w+')
puts "Now I'm going to ask you for three lines."
print "line 1: "
line1 = $stdin.gets.chomp
print "line 2: "
line2 = $stdin.gets.chomp
print "line 3: "
line3 = $stdin.gets.chomp
puts "I'm going to write these to the file."
target.write(line1 + "\n" + line2 + "\n" + line3)
puts "And now I'm going to print the file to prove I have altered it."
puts target.read
puts "And finally, we close it."
target.close
the line puts target.read does not print the three input lines, even though the text file does change.
I have tried changing the mode used by the open method and adding a new open method before calling the read method. Creating a separate program with the same script to read and print text file works as expected.
How can I read a file I have just written to? Why does it not work when I write and read within the same program?
why does it not work when I write and read within the same program
The answer is that when you write to a file, your IO stream is set to the end of where you have written. When you read, it continues from this point. In this case, after writing, you have reached the end of the file and there is nothing else to 'read'. You can use IO#rewind to reroll to the beginning and print out what was just written to through the IO Stream.
filename = 'Test.txt'
target = open(filename, 'w+')
text = '12345'
target.write(text) # target points to EOF
# Note that if you print target.write(), it will tell you the 'index' of where the IO stream is pointing. In this case 5 characters into the file.
puts "And now I'm going to rewind the file"
puts target.rewind # go back to the beginning of the file.
# => 0
puts "And now I'm going to print the file to prove I have rewound it."
puts target.read # read the file, target now points to EOF.
# => '12345'
target.close
File.open("my/file/path", "r") do |f|
f.each_line do |line|
puts line
end
end
File is closed automatically at end of block
It is also possible to explicitly close file after as above (pass a block to open closes it for you):
f = File.open("my/file/path", "r")
f.each_line do |line|
puts line
end
f.close
Credit to: https://stackoverflow.com/a/5545284/8328756

In Ruby, why aren't variables not interchangeable within code blocks?

I have a file called "file1.txt":
Ruby
programming
is fun
In files.rb, which I'm calling from IRB, I have:
File.open('file1.txt', 'r') do |file|
while line = file.gets
puts "** " + line.chomp + " **" #--> why can't I use file.gets.chomp?
end
end
Why isn't line and file.gets interchangeable on line 3? If I switch line with file.gets, the function does not work, and I am a little bit perplexed considering that
line = file.gets
and
file.gets = line
should be interchangeable, but in this case, it is not as it gives me an error. The function works with line.chomp.
I tried getting rid of the while code block, and simply writing
puts file.gets
and it seems to output a line of code from file1.txt, but does not work inside the while statement on line 3.
I'm not really into Ruby, but I think that is because if you use while line = file.gets, the file.gets return a line and read (and copy to buffer) the next one. In the final iteration, where the while is in the last line, the while line = file.gets will return the last line. But in the while, you call again file.gets, so as there are no more lines in file, it returns an error.
This is untested, but your code can be reduced to:
File.foreach('file1.txt') do |line|
puts "** " + line + " **"
end

Ruby - How to skip 2 lines after reading a blank line from file

I have this loop:
File.open(path_to_file, "r") do |infile|
infile.each_line do |line|
#do things with line
end
end
And what I want to do:
If the current line is blank "/^[\s]*$\n/" skip the next 2 lines and continue reading from there.
For such situation, I would do something like this:
file = File.open(path_to_file, "r")
while !file.eof?
line = file.gets
if line.match(/^[\s]*$\n/)
2.times{ file.gets if !file.eof? }
else
# do something with line
end
end
Let's first create a test file.
str =
" \nNow is \nthe time \n \nfor all \ngood \npeople \n\nto \nsupport\na nasty\n \nperson\n"
puts str
#
# Now is
# the time
#
# for all
# good
# people
#
# to
# support
# a nasty
#
# person
#=> nil
FName = "almost_over"
IO.write(FName, str)
#=> 75
Let's confirm the file was written correctly.
IO.read(FName) == str
#=> true
We can skip the unwanted lines as follows.
count = 0
IO.foreach(FName) do |line|
if count > 0
count -=1
elsif line.strip.empty?
count = 2
else
puts "My code using the line '#{line.strip}' goes here"
end
end
# My code using the line 'people' goes here
# My code using the line 'a nasty' goes here
#=> nil
As File is a subclass of IO (File < IO #=> true), you will often see expressions using IO methods with File as the receiver (e.g., File.read(FName)).

How to do a newline in output

How do I make \n actually work in my output? At the moment it just writes it all in 1 long block. Thanks for any help
Dir.chdir 'C:/Users/name/Music'
music = Dir['C:/Users/name/Music/*.{mp3, MP3}']
puts 'what would you like to call the playlist?'
#new = ''
playlist_name = gets.chomp + '.m3u'
music.each do |z|
#new += z + '\n'
end
File.open playlist_name, 'w' do |f|
f.write #new
end
Use "\n" instead of '\n'
I would like to share my experience with \n
I came to notice that "\n" works as-
puts "\n\n" // to provide 2 new lines
but not
p "\n\n"
also
puts '\n\n'
Doesn't works.
Hope will work for you!!
You can do this all in the File.open block:
Dir.chdir 'C:/Users/name/Music'
music = Dir['C:/Users/name/Music/*.{mp3, MP3}']
puts 'what would you like to call the playlist?'
playlist_name = gets.chomp + '.m3u'
File.open playlist_name, 'w' do |f|
music.each do |z|
f.puts z
end
end
Actually you don't even need the block:
Dir.chdir 'C:/Users/name/Music'
music = Dir['C:/Users/name/Music/*.{mp3, MP3}']
puts 'what would you like to call the playlist?'
playlist_name = gets.chomp + '.m3u'
File.open(playlist_name, 'w').puts(music)
For me it didn't work with adding "\n" to the end of an existing argument to puts, so as a workaround I called print on the next line with "\n" as an argument, although I suppose I could have just called puts again.
This did not produce the desired result:
puts "Coach says: #{coach_answer(user_input)}\n"
But this did:
puts "Coach says: #{coach_answer(user_input)}"
print "\n"

Resources