Reputation: 59
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
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
Reputation: 84343
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.
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
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
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