Is this the correct use of rand?

In the example below why was it necessary to put (max+1)? Couldn’t that
result in the generation of a random number up to and including 50?

This code calls a code blocklimittimes, each time passing in a random
number betweenminandmax:

def pick_random_numbers(min, max, limit)
limit.times { yield min+rand(max+1) }
end

This code is a wrapper method for pick_random_numbers. It calls a code
block 6 times, each time with a random number from 1 to 49:

def lottery_style_numbers(&block)
pick_random_numbers(1, 49, 6, &block)
end

lottery_style_numbers { |n| puts “Lucky number: #{n}” }

2012/6/28 Emeka P. [email protected]:

This code calls a code blocklimittimes, each time passing in a random
number betweenminandmax:

def pick_random_numbers(min, max, limit)
limit.times { yield min+rand(max+1) }
end

rand(max+1) may generates a number between 0 and max.
So, pick_random_numbers produces numbers between min and min+max.

% ruby -e ’
def pick_random_numbers(min, max, limit)
limit.times { yield min+rand(max+1) }
end
pick_random_numbers(10,10,5) {|n| p n }

11
19
20
20
13
% ruby -e ’
def pick_random_numbers(min, max, limit)
limit.times { yield min+rand(max+1) }
end
ary = []
pick_random_numbers(10,10,500) {|n| ary << n }
p ary.minmax

[10, 20]

I recommend rand(min…max) if you use Ruby 1.9.3.

Hi,

If you call rand(n) with n being an Integer, the method will return a
pseudorandom Integer r with 0 <= r < n. So the result will never be n.
If you want to include n, you have to call rand(n + 1).

But I believe in your case it should be rand(max - min + 1), because
otherwise the actual maximum of the result is max + min and not max.

In newer versions of Ruby you can also pass a range to the rand method,
which makes the whole thing more intutitive:

rand(0…n)

On Thu, Jun 28, 2012 at 9:44 AM, Emeka P. [email protected]
wrote:

In the example below why was it necessary to put (max+1)? Couldn’t that
result in the generation of a random number up to and including 50?

This code calls a code blocklimittimes, each time passing in a random
number betweenminandmax:

def pick_random_numbers(min, max, limit)
limit.times { yield min+rand(max+1) }
end

I am surprised nobody mentioned that code is flawed because it does
not adherer to the mentioned contract: the code will yield random
numbers outside the range given by min and max. Demonstration:

irb(main):005:0> pick_random_numbers(10, 11, 20){|r| p r}
15
20
17
10
10
12
17
15
21
12
11
21
12
13
11
17
19
17
10
18
=> 20

You need

def pick_random_numbers(min, max, limit)
limit.times { yield min + rand(max + 1 - min) }
end

Or use the range version as has been mentioned.

Kind regards

robert

Thanks for the help everyone! Going to use the range version as I’m
using Ruby 1.9.3, but it’s great to understand exactly how rand works.

One more somewhat off topic question…

Just finished a Ruby class and currently reviewing, and trying to
improve my comfort with and knowledge of the language. Thinking about
starting a Ruby on Rails class in the next week or so, but not sure if I
should wait until I have a better grasp of Ruby or just forge ahead. Any
thoughts or suggestions?

Also, planning on going through all the Ruby Monk, learn Ruby the Hard
Way, and Ruby Koans. Any other suggested resources, or suggestions for
the order in which to go through the resources I listed. FYI, I also
have a copy of Chris P.'s book.

Thanks,

Emeka

Robert K. wrote in post #1066503:

On Thu, Jun 28, 2012 at 11:05 AM, Robert K.
[email protected] wrote:

I am surprised nobody mentioned that code is flawed because it does
not adherer to the mentioned contract: the code will yield random
numbers outside the range given by min and max.

Sorry Tanaka A., you mentioned it - and I overlooked it. :slight_smile:

Kind regards

robert

On Thu, Jun 28, 2012 at 11:05 AM, Robert K.
[email protected] wrote:

I am surprised nobody mentioned that code is flawed because it does
not adherer to the mentioned contract: the code will yield random
numbers outside the range given by min and max.

Sorry Tanaka A., you mentioned it - and I overlooked it. :slight_smile:

Kind regards

robert

Thanks for the reply. Also was looking to do some quick review to make
sure that I actually do grasp the basics. Any suggestions?

Thanks

Bartosz Dziewoński wrote in post #1066550:

2012/6/28 Emeka P. [email protected]:

Also, planning on going through all the Ruby Monk, learn Ruby the Hard
Way, and Ruby Koans. Any other suggested resources, or suggestions for
the order in which to go through the resources I listed. FYI, I also
have a copy of Chris P.'s book.

“Learn Ruby the Hard Way” probably won’t help much if you’ve already
grasped the basics. This one is for real beginners.

– Matma R.

On Thu, Jun 28, 2012 at 9:06 AM, Emeka P. [email protected]
wrote:

Also, planning on going through all the Ruby Monk, learn Ruby the Hard
Way, and Ruby Koans. Any other suggested resources, or suggestions for
the order in which to go through the resources I listed. FYI, I also
have a copy of Chris P.'s book.

Here are some bricks I’ve added to the wall of learning:

http://testfirst.org - a series of test-driven ruby labs

GitHub - alexch/ruby_notes - a series of slides roughly
synchronized with the labs

You can do the test-first labs on your own machine, or if you like you
can play with the super-secret new “live” labs at
http://testfirst.org/live (still pre-alpha and not pretty).

Also codeschool.com has some great stuff.

2012/6/28 Emeka P. [email protected]:

Also, planning on going through all the Ruby Monk, learn Ruby the Hard
Way, and Ruby Koans. Any other suggested resources, or suggestions for
the order in which to go through the resources I listed. FYI, I also
have a copy of Chris P.'s book.

“Learn Ruby the Hard Way” probably won’t help much if you’ve already
grasped the basics. This one is for real beginners.

– Matma R.