I've been trying to complete an exercise on HackerRank but am having trouble with the initial stage of "Read input from STDIN. Print output to STDOUT". I've tried a couple of methods, among which this seems to work the best:
myArray = ARGF.read
newarr = myArray.split(" ").map! do |n|
n.to_i
end
This returns an array, but when I run closestNumbers(newarr), I get "
~ no response on stdout ~". My code works in IRB. Any ideas on where I might be going wrong?
IRB shows you the result of the last computation. For Hackerrank you need to put it in STDOUT explicitly. In a word - use puts for return values.
UPD: Just for reference. There is STDOUT.write method as well.
Related
For some reason, I can't find any tutorial mentioning how to do this...
So, how do I read the first n lines from a file?
I've come up with:
while File.open('file.txt') and count <= 3 do |f|
...
count += 1
end
end
but it is not working and it also doesn't look very nice to me.
Just out of curiosity, I've tried things like:
File.open('file.txt').10.times do |f|
but that didn't really work either.
So, is there a simple way to read just the first n lines without having to load the whole file?
Thank you very much!
Here is a one-line solution:
lines = File.foreach('file.txt').first(10)
I was worried that it might not close the file in a prompt manner (it might only close the file after the garbage collector deletes the Enumerator returned by File.foreach). However, I used strace and I found out that if you call File.foreach without a block, it returns an enumerator, and each time you call the first method on that enumerator it will open up the file, read as much as it needs, and then close the file. That's nice, because it means you can use the line of code above and Ruby will not keep the file open any longer than it needs to.
There are many ways you can approach this problem in Ruby. Here's one way:
File.open('Gemfile') do |f|
lines = 10.times.map { f.readline }
end
File.foreach('file.txt').with_index do |line, i|
break if i >= 10
puts line
end
File inherits from IO and IO mixes in Enumerable methods which include #first
Passing an integer to first(n) will return the first n items in the enumerable collection. For a File object, each item is a line in the file.
File.open('filename.txt', 'r').first(10)
This returns an array of the lines including the \n line breaks.
You may want to #join them to create a single whole string.
File.open('filename.txt', 'r').first(10).join
You could try the following:
`head -n 10 file`.split
It's not really "pure ruby" but that's rarely a requirement these days.
So I am trying to make the transition from PHP to ruby(finally). I am attempting to complete the rubymonk challenges but I am stuck on the third challenge.
The challenge itself is easy and I've already found a solution, but I cant figure out what type of data I'm looking at or how to process it properly.
The challenge simply wants you create a method that takes a array containing some strings, and return a count of each string in that same position. so ["I","suck","at","ruby"] == ["1","4","2","4"].
That part is Ez-pz, but I cant for the life of me figure out how to process the input properly.
It gives you a shell of method and tells you to complete it
def lenght_finder(input_array)
#I added the print input_array
print input_array #=> ["I","am","genius"]["things","are","","awesome"]
end
Is this a multidimensional array?
I've tried to replicate this in IRB with
input_array = ["I","am","genius"]["things","are","","awesome"]
but it returns and error
input_array = [["I","am","genius"],["things","are","","awesome"]]
works, but that is clearly not that same.
Because of this I am struggling to traverse the array to process that data properly.
I can't get anything like input_array.flatten to work, or input_array[0] which returns "Ithings".
This is confusing me. Am I looking at a single array? a multidimensional array? Clearly it cant be a string. Why does it skip "am" when accessing input_array[0]?
Ha, like Justin Ko suggested in his comment above, what you're seeing is the stdout of running the function twice.
Since you used print, there's no newline. Use puts instead.
This should help you see it more clearly:
def length_finder(input_array)
puts '*** '+input_array.inspect
return 0
end
In the process of understanding ruby, I was trying to overide '+' with a default argument value. Something like this.
class C
def something(a = 5)
puts "Received: #{a}"
end
def +(b = 10)
puts "Received: #{b}"
end
end
Now
x = C.new
x.something #=> Received: 5
x.something(88) #=> Received: 88
x.+ #=> IRB shows ? whereas I was expecting an output 'Received: 10'
Is this because of operator precedence?
Problem with IRB (look like it doesn't handle such cases). If you create separate .rb file and run it you will get expected output:
Received: 5
Received: 88
Received: 10
IRB is parsing the + and expecting a second parameter for the binary operation. If you provide parenthesis it works correctly:
x.+() #=> Received: 10
IRb uses a different parser than Ruby does. So, in some weird corner cases, IRb may parse code differently than Ruby. If you want to see whether something is valid Ruby or not, you should ask Ruby not IRb.
The reason for this is mainly that Ruby always parses the entire file at once, so it always knows when an expression ends. IRb on the other hand, has to "guess" every time when you press ENTER whether you simply want to continue the expression on a new line or whether you wanted to evaluate the expression as-is. As a result, IRb cannot just use the Ruby parser, it needs to have its own. And Ruby's grammar is so complex that writing your own parser is really really hard. That's why such bugs and corner cases pop up from time to time even in a piece of software as old and as widely used as IRb.
I'm trying out the return function for the first time. The following lines of code show no output. I'm trying to figure out what's wrong with my code. I'd appreciate your input.
def favourite_drink name
if name == "tea"
return "I love tea too!"
end
if name == "lemonade"
return "Stuff's refreshing, isn't it?"
end
if name == "coffee"
return "Dude, don't have too much of that stuff!"
end
"So what exactly is it that you like? (scratches head)"
end
favourite_drink "tea"
There's no output because you don't output the result of your function.
puts favourite_drink("tea")
outputs:
"I love tea too!"
You've probably experimented with Ruby in irb, which is a REPL -- a read-eval-print loop. In irb, if you entered your code, you'd see:
=> "I love tea too!"
because irb automatically shows you the value of whatever you type. When actually running your program, you need to specifically ask to output whatever you want printed.
I'm no Ruby wizz by far, but I think you are missing a piece of code that will actually do the output for you. You have some strings, but they remain just that: string. To actually send them to the screen you need a command like puts or print.
see: http://en.wikibooks.org/wiki/Ruby_Programming/Strings
puts 'Hello world'
To target your method, in order to display out the string "I love tea too!" to the output screen(your terminal) you need to give accurate instructions to your method. i.e, you need to instruct your method 'favourite_drink' to take the argument "tea" and paly with it according to the structure described inside the method 'favourite_drink'
puts favourite_drink "tea"
the above will solve your issue.
So I found this question on here, but I'm having an issue with the output and how to handle it with an if statement. This is what I have, but it's always saying that it's true even if the word monitor does not exist in the file
if File.readlines("testfile.txt").grep(/monitor/)
do something
end
Should it be something like == "nil"? I'm quite new to ruby and not sure of what the outputs would be.
I would use:
if File.readlines("testfile.txt").grep(/monitor/).any?
or
if File.readlines("testfile.txt").any?{ |l| l['monitor'] }
Using readlines has scalability issues though as it reads the entire file into an array. Instead, using foreach will accomplish the same thing without the scalability problem:
if File.foreach("testfile.txt").grep(/monitor/).any?
or
if File.foreach("testfile.txt").any?{ |l| l['monitor'] }
See "Why is "slurping" a file not a good practice?" for more information about the scalability issues.
Enumerable#grep does not return a boolean; it returns an array (how would you have access to the matches without passing a block otherwise?).
If no matches are found it returns an empty array, and [] evaluates to true. You'll need to check the size of the array in the if statement, i.e.:
if File.readlines("testfile.txt").grep(/monitor/).size > 0
# do something
end
The documentation should be your first resource for questions like this.
Grep will give you an array of all found 'monitor's. But you don't want an array, you want a boolean: is there any 'monitor' string in this file?
This one reads as little of the file as needed:
if File.open('test.txt').lines.any?{|line| line.include?('monitor')}
p 'do something'
end
readlines reads the whole file, lines returns an enumerator which does it line by line.
update
#lines are deprecated, Use #each_line instead
if File.open('test.txt').each_line.any?{|line| line.include?('monitor')}
p 'do something'
end
if anyone is looking for a solution to display last line of a file where that string occurs just do
File.readlines('dir/testfile.txt').select{|l| l.match /monitor/}.last
example
file:
monitor 1
monitor 2
something else
you'll get
monitor 2
I generally skip ruby for the command-line utilities as they tend to be faster.
`grep "monitor" "testfile.txt" > /dev/null`
$?.success #=> true if zero exit status, false otherwise.