Ruby, `puts` doesn't print anything [duplicate] - ruby

This question already has answers here:
Why does Ruby's 'gets' includes the closing newline?
(5 answers)
Closed 2 years ago.
I'm new to writing in Ruby and I have this assignment for my Programming Languages class where I have to implement Mergesort into Ruby such that the user can enter an array of their own choice of numbers and end with a -1. I thought I had everything written in correctly, there are no bugs being reported, but the program doesn't print anything out.
Here's the important part of the code:
puts "Please enter as many numbers as you would like followed by -1"
Many_Numbers = Array.new
x_1 = '-1'
while gets != x_1
Many_Numbers.push gets
end
sorted = merge_sort(Many_Numbers)
puts "SORTED CORRECTLY: #{sorted == Many_Numbers.sort}\n\n#{Many_Numbers}\n\n#{sorted}"
Like I said, nothing is printed out, not even what is provided in the puts methods, so I have nothing to present for an error. What am I doing wrong, here?
EDIT:
I edited the code after I had an idea to improve this part of the code but I still got nothing.
This is what I changed
puts "Please enter as many numbers as you would like followed by -1"
Many_Numbers = Array.new
input = gets
while input != -1
case response
when input != -1
Many_Numbers.push(input)
when input == -1
end
end

You have a couple of problems with your input code.
gets returns all the user input, which includes the newline. So, your loop condition is comparing "-1" to "-1\n" and hence will never end. Calling .chomp on the input will fix that.
You are calling gets twice for each valid number -- once in the loop condition and once when you actually push a value into your array. This causes the loss of one of every two entries. Using a loop do construct with a break condition can fix that problem.
END_OF_LIST = '-1'
puts "Please enter as many numbers as you would like followed by -1"
Many_Numbers = Array.new
loop do
val = gets.chomp
break if val == END_LIST
Many_Numbers.push val
end
The good news is your merge sort method appears to be working once you sort out your input woes.

Related

Simple program but so very stuck- Loops in Ruby

I have to write a program which asks the user to enter a number.
The program keeps on asking the user for a number until the user types 'Stop'
at which point the sum of the numbers that the user has entered should be printed.
I've tried many,many things and none of my ideas work.
This is what I have - but I can that it isn't correct. What am I doing wrong?
I've only used while loops and arrays
total_user_input = []
# As long as the user inputs a number, the program will keep putting Give me a number
# and then adding that number to the total_user_input array.
puts "Give me a number: "
while user_input = gets.chomp.to_i
#add the input to the array total_user_input
total_user_input.push(user_input.to_i)
puts "Give me a number: "
# If the user however types stop, then the loop is broken and we jump down to the
# sum bit - where all of the numbers in the total_user_input array are added together
# and printed. End of program!
if user_input == "stop"
break
end
sum = 0
total_user_input.each { |num|
sum += num
}
puts sum
end
The output isn't as it should be.
As others have identified the problems with your code let me suggest how you might reorganize it. Ruby provides many ways to execute loops but you many find it desirable to primarily relay on the method Kernel#loop and the keyword break. (As you will learn in time, loop is particularly convenient when used with enumerators.)
def sum_numbers
tot = 0
loop do
print 'Gimme a number: '
s = gets.chomp
break if s == 'Stop'
tot += s.to_i
end
tot
end
The keyword break can optionally take an argument (though why that is not mentioned in the doc I cannot say), in which case it (if a literal) or its value (if a variable or method) is returned by loop. Here one would generally see
break tot if s == 'Stop'
without the final line, tot. As the loop returns tot and that is the last calculation performed by the method, the method will return the final value of tot.
You could have instead written
return tot if user_input == 'Stop'
but I think most coders believe best practice dictates that one should not return from a method from within a loop (or from within nested loops) unless there is a good reason for doing so.
Some small points:
I used print rather than puts to that the user's entry will be shown on the same line as the prompt.
I used s (for "string") rather than user_input because it reduces the chance of spelling mistakes (e.g., user_imput), speeds reading, and (possibly a foible of mine), looks neater. True, s is not descriptive, but one only has to remember its meaning for three consecutive lines of code. Others may disagree.
You could write, break if s.downcase == 'stop' if you want, say, 'stop' or 'STOP' to have the same effect as 'Stop'.
'23O3'.to_i #=> 23 (that's an an oh, not a zero), so in real life you'd want to confirm that either 'Stop' or the string representation of a number had been typed.
This is how I would do this preferring to use loop do end syntax with a break when it should. Also added a bit more text so user knows what's happening.
total_user_input = []
puts 'Give me a number or "stop" to end: '
loop do
user_input = gets.chomp
total_user_input << user_input.to_i
puts "Give me a number: "
break if user_input.downcase == "stop"
end
puts "Total entered: #{total_user_input.inject(&:+)}" unless total_user_input.empty?
puts 'goodbye!'
Note these few things:
get.chomp.to_i will convert every input to integer. ("stop" or any non integer string will be 0)
Arrangement of the flow is quite messy.
total_user_input = []
puts "Give me a number: "
while user_input = gets.chomp.strip
total_user_input.push(user_input.to_i)
sum = 0
total_user_input.each { |num|
sum += num
}
puts sum
if user_input == "stop"
break
end
end
Hope you understand this.

unique rand number in a ruby loop

I am reading the book "Learn to program", and I have come across an exercise that I am having trouble with.
year = (rand(1900...1990))
while true do
puts "What would you like to say to grandma?"
ask = gets.chomp
if
ask == ask.downcase
puts "SPEAK UP SONNY"
elsif
ask == ask.upcase
puts "NO, NOT SINCE #{year}!"
end
break if ask == "BYE"
end
everything is functioning properly, but if the rand number "year" comes up more than once, it repeats the same number. Is there a way to have it become a unique random number each time it comes up during the same loop?
thank you in advance
Move year assignment into the loop to have it assigned before each chomp.
The value of year does not change within the loop because it is defined outside the loop. It would change if the definition were moved inside the loop, but you still may have years repeated. To fix both of these problems, change
year = rand(1900...1990)
to
years = (1900...1990).to_a.shuffle
(outside the loop) and change
puts "NO, NOT SINCE #{year}!"
to
puts "NO, NOT SINCE #{years.shift}!"
(or years.pop). If this is repeated more than 91 times an exception will be raised.

I am unable to break a loop that repeatedly asks for user input. Anyone know how to solve this?

I am trying to create a loop that will ask the user for an integer and will then print "hi" an integer number of times and then ask for input again. I then want the loop to break if the user inputs "bye".
my code so far:
def hi_hi_goodbye
loop do
number = gets
(number.to_i).times do
print "hi"
end
break if
gets == "bye"
end
end
My code so far will not loop. It receives the integer and prints "hi" a given amount of times. However, I am unable to break the loop.
Try
break if gets.chomp == "bye"
This is so because your input would be something like bye\n, so your condition always false, because gets takes even the enter.

Learn to Program (Chris Pine) Answer explanation

Chapter 7, first exercise at the end of the chapter (e-book) --> https://pine.fm/LearnToProgram/chap_07.html
I was able to get the code, but only once I set a variable and set it equal to something. I don't really understand why and would appreciate any explanation as to why you have to do this.
Here's my code:
puts "Tell me some of your favorite words-- one at a time, please!"
fave_words = []
word = '0'
while word != ''
word = gets.chomp
fave_words.push word
end
puts "Here are a few of your favorite words..."
puts fave_words.join(' ')
puts "Now in alphabetical order..."
puts fave_words.sort
Thanks in advance!
The condition for the loop to work (and to get into it for the first time mainly) is the word having a value different than an empty string. So it doesn't matter if you make it word = '0' or word ='any other string'. As long as you set it to something different than '' the loop clause will evaluate to true and the loop will start. As long as you provide a non empty input to it it will keep in the loop because the clause will remain evaluating to true.
Actually you don't even need to declare a variable outside of the loop. You could just do something like:
while true
word = gets.chomp
break if word.empty?
fave_words.push word
end
So the loop starts immediately because eval(true) is truth. The loop will keep going until your input is an empty string, condition in which we break the loop.
word is always the input from the user and as long as it's a non-empty string the while loop functions. In order to get the ball rolling word is defined outside of the loop and set to a non-empty string, thus the loop executes.
When the user inputs nothing by pressing enter alone, the while loop condition fails and the loops ceases.

Ruby unjumble words and match to dictionary [duplicate]

This question already has an answer here:
ruby to unjumble words [closed]
(1 answer)
Closed 8 years ago.
I am trying to write ruby code that unscrambles the word entered and then match those word to a dictionary. The goal is to find match those words to dictionary and find a word in the dictionary and print it. This is how my code looks like.
print "Enter scrambled word here:"
Jumble = gets.chomp
a = Jumble.split("")
perms = a.permutation.to_a.collect do |perm|
perm.join
end
return perms
fin = File.open("dict.txt", "r")
while line = fin.gets
word = line.chomp
if word = word.downcase
perms = word
print perms
end
end
fin.close
My code seems to work fine until "return perms". it gives me error saying unexpected return (LocalJumpError). i do not know if my code after that point is correct or not because i cannot get past that point. I somehow need to get those perms and match them with the dictionary. The first word that is found in the dictionary needs to be printed. How do i go about that.
This is what the dictionary looks like:
words_un
Aarhus
Aaron
Ababa
aback
abaft
abandon
abandoned
abandoning
abandonment
abandons
abase
...
Zulus
Zurich
I appreciate the feedback.
return perms
Values (objects) get returned from methods, or functions. Technically you are not in a method, so Ruby has no idea what you are talking about.
Extra: technically you are inside the Object class, and you cannot return things from a class.

Resources