zappdapper
zappdapper

Reputation: 59

Need some guidance with a small calculator I am working on Ruby

def averager
puts "Put in three numbers. One per line"
num_1 = $stdin.gets.chomp.to_i
num_2 = $stdin.gets.chomp.to_i
num_3 = $stdin.gets.chomp.to_i

half_total =  num_1 + num_2 + num_3
total = half_total / 3
end

Ok so that is a little averager I am working on. It works fine except for one thing. I would like the user to decide how many numbers he wants to type in. That way I wouldn't be limited to just three numbers to average . Thanks

Upvotes: 0

Views: 111

Answers (4)

pcrglennon
pcrglennon

Reputation: 457

You could try using a while loop. Here's a pretty good guide on loops in Ruby.

Then at each stage in the loop, ask the user for a number, or to enter something else to quit (for example, quit if they input a string). Something like this:

puts "Enter a number: "
total = 0
count = 0
number = gets.chomp.to_i       # you don't need $stdin here
while number != 0              # calling to_i on a String will return 0
  total += number
  count += 1
  puts "Enter another number, or 'quit' to end: "
  number = gets.chomp.to_i
end

average = total / count

This isn't the most graceful way to do it, but probably easier to understand.

Upvotes: 0

Todd A. Jacobs
Todd A. Jacobs

Reputation: 84343

Loop Indefinitely Until Break Condition

The easiest way to take an unknown number of arguments is to use Kernel#loop. This will repeat endlessly, until you trigger an exit from the loop with the break keyword or raise StopIteration.

The following just collects as many arguments as you want in the numbers Array until you type q or quit followed by RETURN. It then calculates the average based on the count of items in numbers and prints the result to standard output.

def avg *args
  args.flatten!
  args.reduce(:+) / args.size
end

numbers = []
loop do
  printf 'Enter number ("q" to quit): '
  input = gets.downcase.chomp
  case input
  when ''
    next
  when /q(uit)?/
    puts avg(numbers)
    break
  else
    numbers << Float(input)
  end
end

If you want full readline support or to turn off character echoes to the screen, you can look at a gem like highline for additional features.

Sample Output

Enter number ("q" to quit): 5
Enter number ("q" to quit): 10
Enter number ("q" to quit): 15
Enter number ("q" to quit): 20
Enter number ("q" to quit): q
12.5

Upvotes: 0

Agush
Agush

Reputation: 5116

Here it is explained line by line in the comments marked with #

def averager
  puts "How many numbers?" #ask the user how many numbers
  numbers = gets.chomp.to_i #get how many numbers
  count = 1 #start the count variable for the while loop
  half_total = 0 #half_total starts on zero
  while(count <= numbers) do #while count is less than or equal to amount of numbers
    puts "Enter #{count}° number" #puts "Enter 1°,2° or whatever number"
    number = gets.chomp.to_i #get the actual number from the user
    half_total = half_total + number #add it to your half total
    count = count + 1 #add one to count so we go to the 2°,3° or wtv number
  end #end the loop

  total = half_total/numbers.to_f #divide half_total by the amount of numbers 
             #.to_f is used to force float division so decimals don't get cut

  puts "The average is: #{total}" #prints the result
  total #returns the result in case you don't want to print it

end #end of the function or method

This is made with a simple while loop, like the other answer says check out a tutorial on loops if you are still confused by how they work http://www.tutorialspoint.com/ruby/ruby_loops.htm

Upvotes: 1

Anthony
Anthony

Reputation: 15957

you could do something like:

def average(input_str)
  arr = input_str.split
  arr.inject { |sum, x| sum.to_i + x.to_i } / arr.size
end

puts "Please enter numbers you would like to average(separated by a space)"
input = gets.chomp
avg = average(input)
puts "The average is #{avg}"

The user will give me a string of numbers like this:

Please enter numbers you would like to average(separated by a space)
1 2 3

We call a function that takes the string 1 2 3 and puts that into an array with the split call:

[1] pry(main)> input_str = "1 2 3"
=> "1 2 3"
[2] pry(main)> input_str.split
=> ["1", "2", "3"]

We then can sum up that array using the inject method:

arr.inject { |sum, x| sum.to_i + x.to_i }

Finally we just divide that amongst the size of the total array.

Upvotes: 0

Related Questions