New to ruby - how can I take this further?

Hi all

I'm new to programming, and new to Ruby.

I've written a little program listed below, a very simple math test, to
get into the swing of things.

My question; could someone point out what I could do to make this more
elegant, and any mistakes etc. - basically a critique would be most
welcome.

I think this would give me some real help in understanding what I need
to learn next.

Many thanks for your time

s.

puts "Please enter your name:"
firstname = gets.chomp

number1 = rand(100)
number2 = rand(100)

operatorarray = ["+", "-"]
randop = rand(2)
getoperator = operatorarray[randop]

question = number1.to_s + getoperator + number2.to_s

answer = eval "#{number1} #{getoperator} #{number2}"

puts "Welcome to MathTest!"

puts "#{firstname}" + ", here is your first question:"

puts question
usranswer = gets.chomp

if
  eval "#{usranswer} == #{answer}"
  puts "Correct!"
else
  puts "Incorrect. The answer is " + "#{answer}"
end

···

--
Posted via http://www.ruby-forum.com/.

This is how I'd do it straight away from your code:

puts "Please enter your name:"
first_name = gets.chomp

number1 = rand(100)
number2 = rand(100)

# I'd use symbols for the operators
# also note the snake_case convention
operator_array = [:+, :-]

#removed some unnecessary variables
operator = operator_array[rand(2)]

# Cleaner (IMHO) with string interpolation,
# no need for .to_s
question = "#{number1} #{operator} #{number2}"

# We know the operators are methods of the numbers
# so I'd rather send the method than eval a string
answer = number1.send(operator, number2)

puts "Welcome to MathTest!"
# String interpolation rather than concatenation
puts "#{first_name}, here is your first question:"

puts question
# get the answer as an integer
user_answer = gets.chomp.to_i

#no need to eval here, just compare the ints
if user_answer == answer
puts "Correct!"
else
puts "Incorrect. The answer is " + "#{answer}"
end

The next step could be to put the questions in a loop, so you don't
need to type your name every time, and to count correct/incorrect
answers and show a summary. Further, you could extend this to save to
a file a count of correct/incorrect answers by name, and load this
data at start and update it with the new session of answers.

Good luck !

Jesus.

···

On Thu, Aug 13, 2009 at 10:56 PM, Stuart Cullum<stuart.cullum@gmail.com> wrote:

Hi all

I'm new to programming, and new to Ruby.

I've written a little program listed below, a very simple math test, to
get into the swing of things.

My question; could someone point out what I could do to make this more
elegant, and any mistakes etc. - basically a critique would be most
welcome.

Good luck !

Jesus.

Jesus

Thanks very much for your time. I will go and attempt a new version!

Best regards

s.

···

--
Posted via http://www.ruby-forum.com/\.

just some more suggestions:

puts "Please enter your name:"

first_name = gets.chomp

number1 = rand(100)
number2 = rand(100)

# I'd use symbols for the operators
# also note the snake_case convention
operator_array = [:+, :-]

I personally prefer %w:

operator_array = %w{+ -}

Especially when you get more entries, %w helps you save time and maintain
readability.
Basically, what it does is, it splits the string in between the {} at every
whitespace and
returns an Array containing the Strings inbetween the whitespace.

#removed some unnecessary variables

operator = operator_array[rand(2)]

# Cleaner (IMHO) with string interpolation,
# no need for .to_s
question = "#{number1} #{operator} #{number2}"

# We know the operators are methods of the numbers
# so I'd rather send the method than eval a string
answer = number1.send(operator, number2)

Also, you should steer clear of eval, since it is quite a security risk.
Users could give you any Ruby code, even stuff that deletes files etc.
I've found that most of the time you can get rid of it.

puts "Welcome to MathTest!"

# String interpolation rather than concatenation
puts "#{first_name}, here is your first question:"

puts question
# get the answer as an integer
user_answer = gets.chomp.to_i

#no need to eval here, just compare the ints
if user_answer == answer
puts "Correct!"
else
puts "Incorrect. The answer is " + "#{answer}"

you missed one! :slight_smile:

puts "Incorrect. The answer is #{answer}"

end

Keep it up! Hope you have lots of fun with Ruby!
Greetz!

just some more suggestions:

puts "Please enter your name:"

first_name = gets.chomp

number1 = rand(100)
number2 = rand(100)

# I'd use symbols for the operators
# also note the snake_case convention
operator_array = [:+, :-]

I personally prefer %w:

operator_array = %w{+ -}

Especially when you get more entries, %w helps you save time and maintain
readability.

I use %w a lot, when I want Strings. In this case though, my
preference is to use symbols,
because they represent better what they are used for in this program.

puts "Incorrect. The answer is " + "#{answer}"

you missed one! :slight_smile:

Yep, good catch :slight_smile:

Cheers,

Jesus.

···

On Fri, Aug 14, 2009 at 6:25 PM, Fabian Streitel<karottenreibe@googlemail.com> wrote: