New to ruby - how can I take this further?

S

Stuart Cullum

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
 
J

Jesús Gabriel y Galán

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. =A0- basically a critique would be most
welcome.

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

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

number1 =3D rand(100)
number2 =3D rand(100)

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

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

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

# We know the operators are methods of the numbers
# so I'd rather send the method than eval a string
answer =3D 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 =3D gets.chomp.to_i

#no need to eval here, just compare the ints
if user_answer =3D=3D 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.
 
F

Fabian Streitel

[Note: parts of this message were removed to make it a legal post.]

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! :)

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


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

Jesús Gabriel y Galán

just some more suggestions:

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

number1 =3D rand(100)
number2 =3D rand(100)

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


I personally prefer %w:

operator_array =3D %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.
you missed one! :)

Yep, good catch :)

Cheers,

Jesus.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,996
Messages
2,570,238
Members
46,826
Latest member
robinsontor

Latest Threads

Top