Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
Whats the difference between this 2? why one works and the other does not?
array.each{ |item| puts "The item is #{item}" puts item + 1 }
array.each do |item|
puts "The item is #{item}"
puts item + 1
end
When you have two statements in a single line, you need to put a ; between the two. Thus: puts "The item is #{item}"; puts item + 1.
You're trying to cram two expressions where only one is expected. You can separate the two expressions using a semicolon:
array.each { |item| puts "The item is #{item}"; puts item + 1 }
Why not just supply both "The item is #{item}" and item + 1 to puts?
array.each { |item| puts "The item is #{item}", item + 1 }
array.each{ |item| puts "The item is #{item}" puts item + 1 }
This is simply a syntax error, as mentioned by your interpreter:
syntax error, unexpected tIDENTIFIER, expecting '}'
Your second example is syntactically correct and so does not raise an error.
array.each do |item|
puts "The item is #{item}"
puts item + 1
end
You are missing a space after the each method call, before the first { which is perhaps at best a bad habit.
Also, you can have your first example as:
array.each {|item| puts "The item is #{item}"
puts item + 1 }
And it would become syntactically correct, because of the new line. Nothing says that the curly brace form of a block given to each has to be written on one line, though it is one common convention.
For style, though, (and this is not Code Review, I know), I would probably try to keep the code consistent.
array.each do |item|
puts "The item is #{item}\n#{item.next}"
end
Or perhaps with the curly braces:
array.each do { |item| puts "The item is #{item}\n#{item.next}" }
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 is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I am a total beginner to Ruby. I am trying to print if an object is an array or an integer, but I am getting a syntax error I cannot figure how to solve it.
D:\Ruby>ruby -c Learning-Ruby\loops_stuff.rb
Learning-Ruby/loops_stuff.rb:9: syntax error, unexpected keyword_else, expecting keyword_end
Learning-Ruby/loops_stuff.rb:11: syntax error, unexpected end-of-input, expecting keyword_end
This is my code
obj = ["a", 1, 3.6]
if object.is_a(obj)
puts "Is array: "
obj.each do |index|
puts index
elseif object.is_i(obj)
puts "Is integer: {#obj}"
else
puts "Is neither array or integer"
end
the keyword is elsif (without the e in the middle)
obj = ["a", 1, 3.6]
if obj.is_a?(Array)
puts "Is array: "
obj.each do |index|
puts index
end
elsif obj.is_a?(Integer)
puts "Is integer: #{obj}"
else
puts "Is neither array or integer"
end
also stumbled over this in my first ruby sessions
For addition, you can use case..when statement (looks more elegant as for me):
case obj
when Integer
#some actions
when Array
#some actions
else
#some actions
end
According to the strings you print, this might be what you want to code.
obj = ["a", 1, 3.6]
if obj.is_a?(Array)
puts "Is array: "
obj.each do |index|
puts index
end
elsif obj.is_a?(Integer)
puts "Is integer: {#obj}"
else
puts "Is neither array or integer"
end
The output is:
Is array:
a
1
3.6
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
This code is almost right, but I need to sort the inputs in alphabetical order before alternating between upcase and downcase.
football_team = []
5.times do |i|
puts "Please enter a UK football team:"
team = gets.chomp
if i.even?
football_team << team.upcase
else
football_team << team.downcase
end
end
puts football_team
I cannot use each_with_index.
I need to sort the inputs in alphabetical order before alternating between upcase and downcase.
I can identify 3 parts:
collect input
sort alphabetical
upcase and downcase
Obviously, this can't be done in a single loop.
That being said, here's one way to separate your code:
Part 1:
teams = []
5.times do |i|
puts "Please enter a UK football team:"
teams << gets.chomp
end
Part 2:
teams.sort!
Part 3:
5.times do |i|
if i.even?
teams[i].upcase!
else
teams[i].downcase!
end
end
puts teams
Adapting your answer, try this:
football_team = []
5.times do |i|
puts "Please enter a UK football team:"
team = gets.chomp.downcase
football_team << team
end
final_index = football_team.size - 1
football_team.sort!
(0..final_index).each do |i|
if i.even?
football_team[i] = football_team[i].upcase
else
football_team[i] = football_team[i].downcase
end
end
p football_team
This question already has answers here:
Array that alphabetizes and alternates between all caps
(5 answers)
Closed 7 years ago.
Without changing any of the other code- What can I put into my if else statement to make array 0, 2, 4 show up as all capital letters? I can't figure out how to assign this within the if and else statement.
test = []
puts "Please type 5 different words when you're ready-"
5.times do
test << gets.chomp
end
test.sort.each do |user|
if #what could I put in this statement for all capital letters on [0,2,4]?
user.upcase
else #.downcase isn't needed, if its simpler to remove it that is fine
user.downcase
end
end
I think what you need to do is change the each loop to each_with_index. The each_with_index loop should get what you need.
test.sort.each_with_index do |user, index|
if ([0,2,4]include? index)
user.upcase
else
user.downcase
end
end
If the array is going to expand, you could use the #even? method on the index as the check in the if statement like so.
test.sort.each_with_index do |user, index|
if (index.even?)
user.upcase
else
user.downcase
end
end
If you can't change the type of loop then you could use the #index method on the array, to tell you where the user is in the test array like so
test.sort.each do |user|
if ([0,2,4].include? (test.sort.index(user)))
user.upcase
else
user.downcase
end
end
Why without changing any of the other code? Just do this, no one will care:
puts "Please type 5 different words when you're ready-"
5.times.map { |i| i.even? ? gets.chomp.downcase : gets.chomp.upcase }
The times loop autoindexes for this reason, and the ternary operator (?:) is built for this case.
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 8 years ago.
Improve this question
Hi I`m learning from LRtHW and I got stuck....
I have program like this:
require 'open-uri'
WORD_URL = "http://learncodethehardway.org/words.txt"
WORDS = []
PHRASES = {
"class ### < ###\nend" => "Make a class named ### that is-a ###.",
"class ###\n\tdef initialize(###)\n\tend\nend" => "class ### has-a initialize that takes ### parameters.",
"class ###\n\tdef ***(###)\n\tend\nend" =>"class ### has-a function named *** that takes ### parameters.",
"*** = ###.new()" => "Set *** to an instance of class ###.",
"***.***(###)" => "From *** get the *** function, and call it with parameters ###.",
"***.*** = '***'" => "From *** get the *** attribute and set it to '***'."
}
PHRASE_FIRST = ARGV[0] == "english"
open(WORD_URL) do |f|
f.each_line {|word| WORDS.push(word.chomp)}
end
def craft_names(rand_words, snippet, pattern, caps=false)
names = snippet.scan(pattern).map do
word = rand_words.pop()
caps ? word.capitalize : word
end
return names * 2
end
def craft_params(rand_words,snippet,pattern)
names = (0...snippet.scan(pattern).length).map do
param_count = rand(3) + 1
params = (0...param_count).map {|x| rand_words.pop()}
params.join(', ')
end
return names * 2
end
def convert(snippet, phrase)
rand_words = WORDS.sort_by {rand}
class_names = craft_names(rand_words, snippet, /###/, caps=true)
other_names = craft_names(rand_words, snippet,/\*\*\*/)
param_names = craft_params(rand_words, snippet, /###/)
results = []
for sentence in [snippet, phrase]
#fake class name, also copies sentence
result = sentence.gsub(/###/) {|x| class_names.pop}
#fake other names
result.gsub!(/\*\*\*/) {|x| other_names.pop}
#fake parameter list
result.gsub!(/###/) {|x| param_names.pop}
results.push(result)
end
return results
end
# keep going until they hit CTRL-D
loop do
snippets = PHRASES.keys().sort_by { rand }
for snippet in snippets
phrase = PHRASES[snippet]
question, answer = convert(snippet, phrase)
if PHRASE_FIRST
question, answer = answer, question
end
print question, "\n\n> "
odp = gets.chomp
if odp == "exit"
exit(0)
end
#exit(0) unless STDIN.gets
puts "\nANSWER: %s\n\n" % answer
end
end
I understand most of this code, but I have a problem with:
for sentence in [snippet, phrase]
I know that it is a "for" loop and it creates a "sentence" variable, but how does the loop know that it need to look in a key and value of hash "PHRASES"
And my second "wall" is:
question, answer = convert(snippet, phrase)
It looks like it creates and assigns "question" and "answer variables to the "convert" method with "snippet" and "phrase" parameters... again how does it assigns "question" to a key and answer to a value.
I know that this is probably very simple but as for now it blocks my mind :(
For your first question about the for-loop:
Look at where the for-loop is defined. It's inside the convert() method, right? And the convert() method is passed two arguments: one snippet and one phrase. So the loop isn't "looking" for values in the PHRASES hash, you are the one supplying it. You're using the method's arguments.
For your second question about assignment:
In Ruby we can do something called "destructuring assignment". What this means is that we can assign an array to multiple variables, and each variable will hold one value in the array. That's what's happening in your program. The convert() method returns a two-item array, and you're giving a name (question and answer) to each item in the array.
Here's another example of a destructuring assignment:
a, b, c = [1, 2, 3]
a # => returns 1
b # => returns 2
c # returns 3
Try this out in IRB and see if you get the hang of it. Let me know if I can help clarify anything, or if I misunderstood your question. You should never feel bad about asking "simple" questions!