In Progress
Unit 1, Lesson 21
In Progress

Random Samples

Video transcript & code

Sometimes we need to pick a random selection of items. Ruby provides some easy to use tools for this. Some of these tools may be familiar from other programming languages, but Ruby puts some twists on them that may be new to you.

Let's start with the basics. To simply get a random number, we use the rand method, which is globally available thanks to the Kernel module.

rand                            # => 0.05823762482076911
rand                            # => 0.24481532875262757
rand                            # => 0.3715421503879194

What sort of random numbers are these? When we don't supply any argument at all, Ruby gives us a floating point number between zero and one. So for instance if we wanted to make a quarter of users lucky winners, we send rand and see if the output is less than 0.25.

if rand < 0.25
  puts "you're a lucky winner!"
end

Very often it's more convenient to work with integers than with floating point numbers. In that case, we can give rand an integer argument. For instance, we might want to simulate a 6-sided die. In that case, we could give it the argument 6.

rand(6)                         # => 3
rand(6)                         # => 3
rand(6)                         # => 5

When given an integer, rand will return a random number between zero and one less than the integer. So when given six, the output will always be between zero and five.

But maybe we want to simulate a 6-sided die more literally, and not have to compensate for the zero-base. In that case, we can pass a range to rand, telling it exactly what range of numbers to pick from.

rand(1..6)                      # => 2

In this case, rand will pick a number between one and six, inclusive.

A lot of times in programs, the reason we want a random number is to help us pick a random element in some collection. For instance, in a recent episode I needed to randomly generate status updates for a feline social media site.

I started with a list of words, but I needed a way to pick random sentences out.

words = %W[meow rowwwwr mew meep purrp ewoo meooooow purrrr ack thpppt
           rrrrrrr MEOW mrowr HURRRRK mroooooo ssssst spsss fsst]

If we were working in other programming languages, we'd probably start out something like this: we'd use the random number generator to generate a random array index.

words = %W[meow rowwwwr mew meep purrp ewoo meooooow purrrr ack thpppt
           rrrrrrr MEOW mrowr HURRRRK mroooooo ssssst spsss fsst]
words[rand(words.size)]         # => "mew"

But Ruby knows this is a common use case, so it provides a shortcut: we can send an array the #sample message, and it will pick a random element for us.

words = %W[meow rowwwwr mew meep purrp ewoo meooooow purrrr ack thpppt
           rrrrrrr MEOW mrowr HURRRRK mroooooo ssssst spsss fsst]
words.sample                    # => "mrowr"

Even better, #sample takes an argument, specifying how many elements to pick. So if we want random "sentences" of four words, we can do that:

words = %W[meow rowwwwr mew meep purrp ewoo meooooow purrrr ack thpppt
           rrrrrrr MEOW mrowr HURRRRK mroooooo ssssst spsss fsst]
words.sample(4)                 # => ["mroooooo", "fsst", "mew", "rrrrrrr"]

If we put everything we've learned so far together, we can use #rand to randomize the number of words we pick from the word list.

words = %W[meow rowwwwr mew meep purrp ewoo meooooow purrrr ack thpppt
           rrrrrrr MEOW mrowr HURRRRK mroooooo ssssst spsss fsst]
words.sample(rand(1..5))
# => ["mew", "mroooooo", "meow", "rowwwwr"]

Every time we run this code, we get a random sampling of between one and five words. All we need to do now is stitch them together with #join.

words = %W[meow rowwwwr mew meep purrp ewoo meooooow purrrr ack thpppt
           rrrrrrr MEOW mrowr HURRRRK mroooooo ssssst spsss fsst]
words.sample(rand(1..5)).join(" ")
# => "thpppt purrp meep ewoo rrrrrrr"

There's a lot more to be said about randomness. We should talk about random seeds and security at some point. But what you've seen here today should be enough to get you started easily generating things like randomized test data sets, or probabilities for games. Happy hacking!

Responses