DEV Community

kjfossman
kjfossman

Posted on

Flatiron Project 1 - Ruby Utilizing the Sample Method

For my Flatiron phase 1 CLI Application project I created an interactive trivia game. I used an API that had old JEOPARDY! clues, and I took that data to configure the clues in a nice format for the user. I made it for two players to compete against each other in a trivia battle. There are two formats to play: one is where the user chooses a category and all questions for the game are from that single category; the other way to play is to play with randomized clues that display the category and the value of the clue. You can choose to play with 2-20 random clues.

The sample method stood out to me as the most useful method I came across during my project. You have the iterators and enumerators which are super useful and are more powerful than the sample method, but up until building my project I was unaware of the functionality of sample.

Getting started from a blank file was the hardest part of the project for me. Once I started to get the ball rolling it was a slow deliberate process. I had to take time to really think through each method and class I was working with and how to relate them to each other. There was one part that really slowed me down.

My Goal: To pull out 12 random clue objects from a bank of 89 to create a randomized game and assign to an instance variable.
Note: I did not want any duplicate values in the 12 clues.

My Process:
It ended up being a laborious part of my project. I first had to figure how to do something twelve times which was easy enough.

           12.times do
               What to put here???
           end
Enter fullscreen mode Exit fullscreen mode

This is where the sample method enters. Inside that times block I would put the sample method. Sample pulls a random element from an array that you pass through to it. In this case I was pulling from the array of 89 clues and getting the id number from the clue. I also had to consider where to store this value so I stored it in an array that I initialized at the beginning of my method.

       def random_clues
            id = []
              12.times do
                id << Clue.all.sample.id
               end
       end
Enter fullscreen mode Exit fullscreen mode

I was pretty happy with this for a start. This would give me the id numbers of 12 clue objects. I could iterate through the Clue.all array to find the objects that those id numbers matched and store that in an instance variable.

     def random_clues
            id = []
                12.times do
                    id << Clue.all.sample.id
                end
           @board = Clue.all.select do |x|
           id.include?(x.id)
           end
         end
Enter fullscreen mode Exit fullscreen mode

In this case I would use the select enumerator so that it stores each value that returns true in the block.
My Thought Process:
Now I have what I need, an instance variable with twelve random clues that I can continue to work with in my CLI class....WAIT there could be duplicate clues! I need to check for that.

This is what I came up with to account for duplicate clue objects.

 def random_clues
       id = []
           12.times do
               id << Clue.all.sample.id
           end
       if id.uniq == id
           @board = Clue.all.select do |x|
           id.include?(x.id)
           end
       else
           random_clues
       end
Enter fullscreen mode Exit fullscreen mode

Now I am checking to make sure that id.uniq == id, and if that is true it can continue to run the Clue.all.select enumerator and everything is good. If that is not true then it needs to start the method all over again.

My Thought Process:
This should work, but looks wordy. I am ok with that and will think about refactoring later.

I tested my code and it worked, then I tested it again and it didn’t work. I kept doing this for about 30 minutes using binding.pry to see if I could find anything. I did find where the mistake was happening which was in this method random_clues but I could not figure out why it would work sometimes and why it wouldn’t. The conclusion that I came up with through research and talking with other programmers is that I had a recursion issue. When I would call random_clues again this would sometimes cause an error.

Whatever the reason was it was not going to be acceptable to have a program that worked half of the time. That is when I stumbled upon the sample method for a second time. It was already in my code and I hadn’t thought much of it since the beginning of this process. With a little more research I found that you can pass sample an integer argument. It will pull the argument amount of unique elements from the array.

My Thought Process:
Wow I made this way harder than it needed to be. Maybe I should have researched this a bit more before defining this method with all these extra steps.

My method went from all this code

 def random_clues
       id = []
           12.times do
               id << Clue.all.sample.id
           end
       if id.uniq == id
           @board = Clue.all.select do |x|
           id.include?(x.id)
           end
       else
           random_clues
       end
end
Enter fullscreen mode Exit fullscreen mode

To this:

def random_clues(int)
       @board = Clue.all.sample(int)
   end
Enter fullscreen mode Exit fullscreen mode

Not only was this super helpful for my goals, it also created some flexibility to my project. Now instead of being limited to a fixed number of random clues for that type of a game I can give the user the option to choose how many clues they want to play with.

Takeaway:

array = [1,2,3,4,5,6,7,8]
array.sample => [4] #returns random element from the array array.sample(3) => [3,7,1] #will return 3 random elements (No Duplicate Elements) from the array in random order

Top comments (0)