How Do You Put 'gets' Input Into An Array? - ruby

Ruby noob here learning the ropes. I'm currently going through this tutorial and am working on this exercise:
Let's write a program which asks us to
type in as many words as we want (one
word per line, continuing until we
just press Enter on an empty line),
and which then repeats the words back
to us in alphabetical order.
I'm ignoring the alphabetical order part, for now.
Here is my code:
puts 'Hi, do you need something sorted?'
yn = gets.chomp
while yn != 'no'
puts 'What else?'
array = [gets]
yn = gets.chomp
end
puts 'Here\'s what you told me: ' +array.to_s
I've tweaked this for a few hours. To prevent my laptop from breaking due to an act of frustration I'm taking a break. Can anybody with more experience, and possibly more patience, point out my errors?

Keep in mind that every time you gets is a method that asks the user for input. On your lines:
array = [gets]
yn = gets.chomp
You are actually asking for input twice. Instead, store the user input somewhere (such as the array, see below) and get the stored value rather than asking the user twice.
Further, array = [gets] replaces the existing array with an array containing one element (the user input). You are never building up user input into the array. Instead, initialize the array before the while loop and use << in the loop:
array = Array.new
...
while yn != "no"
...
array << gets.chomp
yn = array.last
...
end

If you're having difficulty with something, the first thing you should do is try something simpler.
Rather than doing gets and looping, just try doing a simple gets.
puts 'Hi, do you need something sorted?'
yn = gets.chomp
Then I'd see if yn was what I expected.
The next thing I'd do is, rather than doing a loop many times, just try it once
puts 'Hi, do you need something sorted?'
yn = gets.chomp
if yn != 'no'
puts 'What else?'
array = [gets]
yn = gets.chomp
STDERR.puts "array is #{array.inspect}"
STDERR.puts "yn is #{yn.inspect}"
end
Then you'd hopefully realize that array and yn are both getting input, which wouldn't make sense.
For more hints on how to debug Ruby code, see How do I debug Ruby scripts?

I was having the same problem. Here is where I ended up (I think it meets all the specifications from the question):
puts 'Type in as many words as you\'d like. When you\'re finished, press enter on an empty line'
array = []
input = ' '
while input != ''
input = gets.chomp
array.push input
end
puts
puts array.sort

while yn != "no"
array << yn
print "What else? "
yn = gets.chomp
end
The "<<" appends yn to your array. (The only reason I used print is because it puts the cursor right next to the question mark instead of on the next line. No other reason)

#encoding:utf-8
x = Array.new
puts "enter something:".capitalize
y = ''
while y !=#nill
y = gets.chomp
x.push y
end
x.delete ('')
x.compact
puts "You entered: " + x.sort.to_s
puts "Objects in array: " + x.size.to_s
#made by ~Pick#chu!!!

Another way to read ‘Arrays’ from the console could be:
1: print “enter the values: ”
2: a = gets.chomp # input: “tom mark rosiel suresh albert”
3: array = a.split(‘ ‘) # .split() method return an array
4: p array # ["tom, "mark, "rosiel", "suresh", "albert"]
now, lets say you want an array of integers, all you have to do is:
# input “1 2 3 4 5″
3: array = a.split(‘ ‘).map{ |value| value.to_i }
4: p array # [1, 2, 3, 4, 5]
the clue here is to use a standard separator in order to use the .split() function.

here is how I've done this program:
array = [ ]
input = gets.chomp
while
input != ''
array.push input
input = gets.chomp
end
puts array
puts
puts array.sort

Related

Making a sorted array of user's input

I'm learning Ruby with 'Learn to Program' by Chris Pine. On chapter 10 I should write a program where the user types as many words as he like and when he's done, he can just press Enter on an empty line and exit.
I came up with this:
puts "Type whatever you want!"
index = 0
word = ''
array = []
while word != nil
word << gets.chomp
array[index] = word
index = index + 1
end
puts ''
puts array.sort
But that doesn't work. What did I miss? Is there another way I could define word without having to repeat it?
The word will not have nil value. It will be an empty string. So you need to check for that:
while word != ""
# or even better
while !word.empty?
Also, you are adding everything to your word. You probably want to assign to it instead:
word = gets.chomp
Per author's comment:
begin
# your code here
end while !word.empty?
# OR more readable
begin
# your code here
end until word.empty?
It seems like there's a simpler solution, if I'm reading the question correctly.
You could do something like this:
user_input = gets.chomp.split(" ").sort
ex)
input: bananas clementine zebra tree house plane mine
output: ["bananas", "clementine", "house", "mine", "plane", "tree", "zebra"]
Here's a simple loop that you could do just for kicks:
arr = []
arr << $_.strip until gets =~ /^\s*$/
puts arr.sort
$_ is a special variable that evaluates to the last input read from STDIN. So basically this reads "Call gets and check if the input is just spaces. If it is then break out of the loop, otherwise append the last input with whitespace removed value onto the array and continue looping."
Or even more fun, a one liner:
puts [].tap {|arr| arr << $_.strip until gets =~ /^\s*$/}.sort
Basically same thing as above except using tap to initialize the variable.
To answer your questions:
Is there another way I could define word without having to repeat it?
Use side effects of assignment. In ruby when you assign a variable the return value of that assignment is the assigned variable, as in:
irb(main):001:0> (variable = 2) == 2
=> true
The idea would be to put the assignment in the your conditional. If I were to write something like this in a comprehensible loop, as opposed to those above, I'd write something like this:
arr = []
while !(word = gets.strip).empty?
arr << word
end
puts arr.sort
Using loop might simplify the code:
a = []
loop do
input = gets.chomp
if input.empty?
break
else
a << input
end
end
a.sort!
puts a

How to determine whether input is empty or enter is pressed

I have a task to puts an infinite number of word, each in one line to array, and when enter is pressed on an empty line, puts these words in reverse order. How can I define when enter is pressed or empty line is input?
Code is here:
word = []
puts "Enter word"
add = 0
until add == ????
word.push gets.chomp
add = word.last
end
puts word.reverse
Here's a possible solution, with comments. I didn't see any useful role being played by your add variable, so I ignored it. I also believe in prompting the user regularly so they know the program is still engaged with them, so I moved the user-prompt inside the loop.
word = [] # Start with an empty array
# Use loop when the terminating condition isn't known at the beginning
# or end of the repetition, but rather it's determined in the middle
loop do
print 'Enter word: ' # I like to prompt the user each time.
response = gets.chomp # Read the response and clean it up.
break if response.empty? # No response? Time to bail out of the loop!
word << response # Still in the loop? Append the response to the array.
end
puts word.reverse # Now that we're out of the loop, reverse and print
You may or may not prefer to use strip rather than chomp. Strip would halt if the user input a line of whitespace.
Here, this is a modified version of your code and it works as requested.
word = []
puts "Enter word"
add = 0
while add != -1
ans = gets.chomp
word.push ans
if ans == ""
puts word.reverse
exit
end
add += 1
end
puts word.reverse
This is another version, using (as you did originally) the until loop.
word = []
puts "Enter word"
add = 0
until add == Float::INFINITY
ans = gets.chomp
word.push ans
if ans == ""
puts word.reverse
exit
end
add += 1
end
puts word.reverse

Trouble summing an array in vanilla Ruby

I'm having trouble summing an array. Here's my existing code:
pageArray = Array.new
puts "How many pages long is the book you're reading?"
pageArray << gets.chomp
puts "Are you reading any other books right now?"
yn = gets.chomp
while yn != "no" do
puts "How many pages long is your next book?"
pageArray << gets.chomp
puts "Are you reading any other books right now?"
yn = gets.chomp
end
pageSum = pageArray.reduce(:+)
puts pageSum
When I go through and enter the values 100 and 50, the final return is "10050," rather than "150." Am I missing something obvious?
The code could be written more clearly, and more Ruby-like. Here's some untested code that is more idiomatic:
page_array = []
puts "How many pages long is the book you're reading?"
page_array << gets.chomp
loop do
puts 'Are you reading any other books right now?'
yn = gets.chomp.downcase
break if yn == 'no'
puts 'How many pages long is your next book?'
page_array << gets.chomp.to_i
end
page_sum = page_array.reduce(:+)
puts page_sum
Notice:
variables in Ruby are in snake_case, notInCamelCase.
loop do will loop forever. Simply break when you've received the break value.
you should fold the case of the value used as a break to catch variations in 'y' and 'Y'.
take the time to format your code so it's easily read, even for quick tests. It's amazing how often code we think is just a test actually gets put into production, so do it right the first time.
You are entering strings and concatenating them.
Use gets.chomp.to_i
You need to change the string you get from gets to an int.
pageArray << gets.chomp.to_i

Program to take input from command line into an array and find the biggest among them

I am new to Ruby and just can't figure out how you take input for an array from a user and display it.If anyone could clear that I can add my logic to find the biggest number.
#!/usr/bin/ruby
puts "Enter the size of the array"
n = gets.chomp.to_i
puts "enter the array elements"
variable1=Array.new(n)
for i in (0..n)
variable1[i]=gets.chomp.to_i
end
for i in (0..n)
puts variable1
end
How about capturing the array in one line?
#!/usr/bin/ruby
puts "Enter a list of numbers"
list = gets # Input something like "1 2 3 4" or "3, 5, 6, 1"
max = list.split.map(&:to_i).max
puts "The largest number is: #{max}"
You are doing it ok. But try this little change
#!/usr/bin/ruby
puts "Enter the size of the array"
n = (gets.chomp.to_i - 1)
puts "enter the array elements"
variable1=Array.new(n)
for i in (0..n)
variable1[i]=gets.chomp.to_i
end
puts variable1
or for undefined number of values here is one way
#!/usr/bin/ruby
puts "enter the array elements (type 'done' to get out)"
input = gets.chomp
arr = []
while input != 'done'
arr << input.to_i
input = gets.chomp
end
puts arr
I believe that this is a little bit more elegant solution.
puts "Please enter numbers separated by spaces:"
s = gets
a = s.split(" ")
#Displays array
puts a
#Displays max element
puts a.max
First you collect the series of numbers from the user, then you use a split method on the string, which converts it to the array. If you want to use some other separator, like "," than you can write s.split(","). After that you can use your logic to find the biggest number or you could just use max method.
Some feedback:
chomp.to_i is a bit redundant, since the latter will also remove newlines.
for x in y is not commonly seen in idiomatic Ruby code. It basically behaves like each with slightly different scoping rules and probably should have been removed from the language a while ago.
Ruby arrays are dynamic, so no need to preinitialize them. Something like (1..n).map { gets.to_i } would also produce the array you need.
Displaying it can then be done like this: array.each { |n| puts n }
Alternatively you can use the strip approach outlined before, take the numbers as command line arguments in ARGV or pipe into your program using ARGF.

Misbehaving Case Statement

I'm messing around in Ruby some more. I have a file containing a class with two methods and the following code:
if __FILE__ == $0
seq = NumericSequence.new
puts "\n1. Fibonacci Sequence"
puts "\n2. Pascal\'s Triangle"
puts "\nEnter your selection: "
choice = gets
puts "\nExcellent choice."
choice = case
when 1
puts "\n\nHow many fibonacci numbers would you like? "
limit = gets.to_i
seq.fibo(limit) { |x| puts "Fibonacci number: #{x}\n" }
when 2
puts "\n\nHow many rows of Pascal's Triangle would you like?"
n = gets.to_i
(0..n).each {|num| seq.pascal_triangle_row(num) \
{|row| puts "#{row} "}; puts "\n"}
end
end
How come if I run the code and supply option 2, it still runs the first case?
Your case syntax is wrong. Should be like this:
case choice
when '1'
some code
when '2'
some other code
end
Take a look here.
You also need to compare your variable against strings, as gets reads and returns user input as a string.
Your bug is this: choice = case should be case choice.
You're providing a case statement with no "default" object, so the first clause, when 1, always returns true.
Effectively, you've written: choice = if 1 then ... elsif 2 then ... end
And, as Mladen mentioned, compare strings to strings or convert to int: choice = gets.to_i

Resources