Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I am trying to write a Ruby loop for the song "99 Bottles of Beer On The Wall" for an exercise from the book "Learn To Programs". What am I doing wrong? I have the following:
def bottles_of_beer
i = 99
while i < 99 and i > 0
puts "#{a} bottles of beer on the wall. #{a} bottle of beer."
i = i - 1
puts "Take one down, pass it around. #{i} bottle of beer on the wall."
end
end
You are referencing undefined variable a in your first string.
I have simplified your code by quite a bit:
i = 99
while i < 99 and (anything else)
(anything)
end
Try and see if you can figure it out now.
TL;DR
You have many problems with your code, not least of which i starts out equal to 99, so the rest of the code block is never evaluated. Even if you fix that, a will always be nil because you never assign anything to it.
Fix Your Conditional
There are many ways to do this, but you probably want to use the >= or <= methods for your comparisons.
Be More Idiomatic
Using Integer#downto and a block would be much more idiomatic. For example:
12.downto(1) { |count| p "#{count} bottles of beer on the wall..." }
p "You drank the whole case!"
Perhaps...
99.downto(1) do |i|
puts "#{i} bottle#{i==1 ? '' : 's'} of beer on the wall, #{i} bottle#{i==1 ? '' : 's'} of beer!"
puts "Take one down, pass it around, #{i-1} bottle#{i-1==1 ? '' : 's'} of beer on the wall!"
end
To give you a definitive answer, there are three reasons why your code produces no output
You set i to 99 and then loop while i < 99 and i > 0, so the loop is never executed. Since you are always decrementing i, there is no need for anything more than while i > 0
You interpolate the variable a into the string you are printing. Since you haven't declared it your program will refuse to run, saying undefined local variable or method 'a'
You never actually call your method.
Fixing these three problems gives this (non-idiomatic, but working) program
def bottles_of_beer
i = 99
while i > 0
puts "#{i} bottles of beer on the wall. #{i} bottle of beer."
i = i - 1
puts "Take one down, pass it around. #{i} bottle of beer on the wall."
end
end
bottles_of_beer
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
Code not returning the correct answer.
I've tired assigning a value to the animal choices. I've put it in the def and outside of it.
puts "Choose your favorite: cats or dogs"
choose = gets
cats = 1
dogs = 2
def favorite_animal (number)
remainder_when_divided_by_2 = number % 2
if remainder_when_divided_by_2 == 0
return "Ken does too."
end
if remainder_when_divided_by_2 == 1
return "Dogs are better!"
end
end
If the user enters Cats the answer "Ken does too!" should show. If the user enters Dogs the answer "Dogs are better!" should show. All I've gotten is 1 or 2 as an answer.
Try this.
loop do
puts "Choose your favorite: cats or dogs"
case gets.chomp
when "cats"
break "Ken does too."
when "dogs"
break "Dogs are better!"
else
puts "That answer is invalid. Try again"
end
end
Here is an example of a session using this code, with my answers being "pigs" and "dogs".
Choose your favorite: cats or dogs
pigs
That answer is invalid. Try again
Choose your favorite: cats or dogs
dogs
#=> "Dogs are better!"
See Kernel#loop. Many Rubyists use loop with the keyword break for most loops, rather than while or until. (for loops are never used).
For what you are doing you don't need a method, but if you want one add the line
def favorite_animal
at the beginning and the line
end
at the end. Then
favorite_animal
#=> "Dogs are better!"
provided I were to give the same answers as I did earlier.
There's a couple things going on:
You have to call the method favorite_animal somewhere; you've only defined it
Your cats/dogs isn't "mapped" to anything, so you need some logic to convert your input into a number, before you call the favorite_animal method
You still have to do something with the value you return inside your method (puts or something else to get it to show)
Here's a minimum example that works that might be useful for you to see the 3 issues above
def favorite_animal (number)
remainder_when_divided_by_2 = number % 2
if remainder_when_divided_by_2 == 0
return "Ken does too."
end
if remainder_when_divided_by_2 == 1
return "Dogs are better!"
end
end
puts "Choose your favorite: cats or dogs"
choose = gets.chomp
answer = if choose == 'cats'
1
else
2
end
puts favorite_animal(answer)
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I'm trying to define a method that countdowns 10 to 0 and at the end returns HAPPY NEW YEARS! however i don't want i"am doing wrong?
def countdown(number)
while number > 0
puts "#{number} SECONDS(S)!"
number -= 1
end
"HAPPY NEW YEAR!"
end
A quick Google search revealed that you are apparently trying to solve https://learn.co/lessons/countdown-to-midnight (you really should have included that link)
Your code is not passing the spec, because it contains an additional S:
puts "#{number} SECONDS(S)!"
# ^
It has to be:
puts "#{number} SECOND(S)!"
def countdown(number)
while number > 0
puts "#{number} SECONDS(S)!"
number -= 1
end
puts "HAPPY NEW YEAR!"
end
I added a puts on the last line of your code. You method is counting down to 0 seconds, but the last line only return the string "HAPPY NEW YEAR!", and does not print it to the screen. Or if you need to return the string and print it on the screen, you can do p "HAPPY NEW YEAR!"
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I have two methods turn_count(board) and current_player(board). The turn_count(board) method, which returns the number of "X"s and "O"s in an array is working appropriately. But the current_player(board) method, which is supposed to puts "X" if turn_count(board) is even and "O" if turn_count(board) is odd keeps giving me an error. The error is:
/Users/john/Desktop/test file.rb:13:in current_player': undefined method%' for nil:NilClass (NoMethodError)
from /Users/john/Desktop/test file.rb:18:in `'
Clearly it's saying there's an issue with the modulo operator being used, but i'm not sure why and have been wracking my brain trying to figure it out.
Any help is greatly appreciated!
def turn_count(board)
count = 0
board.each do |x| if x == "X" || x == "O"
count = count + 1
end
end
puts count
end
def current_player(board)
if turn_count(board) % == 0
puts "X"
else
puts "O"
end
end
The problem is you are using % on a NilClass. Your turn_count() method returns nil. Check what happens if you replace puts count with count.
I'm new to ruby and new to stack. I am trying to use the .each method on an array of numbers to see which numbers are divisible by 4, and 400. It is based on an exercises from Chris Pine's "Learn to Program" Ruby tutorial. In it you are supposed to find the leap years, then print them, from a range of years that the user inputs. I accomplished this using an if/else statement...but it seems to me this should be able to be done using the each method, or maybe the map method? Less code.
For example:
puts "Enter two years (to - from) to find out which years are leap years!"
puts "Enter the first year.."
year1 = gets.chomp.to_i
puts "Now enter the second year"
year2 = gets.chomp.to_i
range = (year1..year2).to_a
puts "These are the leap years between those years:"
range.each do |year|
leaps = (year % 4 == 0 || year % 400 == 0)
end
puts leaps
this code may not be correct, but i have toyed with different ways of doing it (puts inside .each, defining variable outside, etc...) but nothing seems to work. Like I said, I accomplished it with an if/else...I just feel there may be a better way, and it's driving me nuts. Do i not understand the .each correctly? am i using the wrong method? can it be done at all using each/map/or collect???? Thanks in advance!
You need to puts inside the each block too. Also, you can just divide by 4 and check if the remainder is 0. No need of 400
range.each do |year|
puts year if year % 4 == 0;
end
The puts year will be executed only if the if condition is satisfied.
I am building a command line ruby blackjack game using methods. I have gotten to the point where the player can hit or stick (after having being dealt 2 cards). Right now I can't seem to make the jump to thinking logically about how to limit my player to only four hits. make
This tells me that my problem is looping - that is I am approaching the loop part of the program the wrong way.
Here is my code so far:
def blackjack
promt
end
def promt
puts "Welcome! Would you like to play a game of blackjack? Enter Yes or No"
play = gets.chomp.downcase
if play == "yes"
game_plan
elsif play =="no"
puts "That's too bad. Come back when you feel like playing"
else
puts "Sorry but I don't understand your respones. Please type and enter yes to play Or no to to quit"
blackjack
end
end
def game_plan
wants_to_play = true
hand = []
total = first_move(hand)
wants_to_play = hit_me(hand)
if wants_to_play == true
hit_me(hand)
end
end
def first_move(hand)
deal(hand)
deal(hand)
total(hand)
end
def deal(hand)
card = rand(12)
puts "You have been dealt a card with a value of #{card}"
hand << card
end
def total(hand)
total = 0
hand.each do |count|
total += count
end
puts "The sum of the cards you have been dealt is #{total}"
total
end
def hit_me(hand)
puts "Would you like to hit or stick?"
yay_or_nah = gets.chomp.downcase
if yay_or_nah == "stick" && total(hand) < 21
puts "Sorry! The sum of the cards you have been dealt is less than 21. You lost this round!"
else
deal(hand)
total(hand)
playing = true
end
end
blackjack
What I want to do is limit my player to 2 hits (after the initial first hit, which deals 2 cards). I know this is a totally annoying newbie question but I really would appreciate any feedback that would help me think of the solution in the proper manner.
PS: while I understand how loops work I am STRUGGLING with knowing how and when to implement them … so any feedback would be very much appreciated. Thank you!
Are you looking for something like that?
MAX_HITS = 2
hits = 0
loop do
break if hits > MAX_HITS
puts "Would you like to hit or stick?"
…
else
hits += 1
…
end
end