Magic 8 Ball Function

R
Learning to write a function in R
Author

Nik

Published

01 January 2018

In my PREDICT 454 class, one of the R challenges that our professor wanted us to undertake involved creating a simple function that acted’ like the Magic 8 Ball. So let’s get to it!

Requirements

  1. The function must output one of the following texts:
  • I dont see that happening.
  • You must be dreaming.
  • Chances are good.
  • If you work hard and stay focused, then this might happen.
  • When the sun shines, it shines on your face.
  • Definitely going to happen!
  • Take some time to think about it.
  • This is not a good idea!
  • This is a great idea!
  • Cannot be determined at this time. Try Again!
  1. Add an option feature in which the user can include the seed number.

  2. The function should be called magic.8ball() and if a seed is to be used, then the function should be run as magic.8ball().

Approach

Let’s start with defining our messages into a vector:

# store the messages into a vector
messages <- c("I don't see that happening.",
              'You must be dreaming.',
              'Chances are good.',
              'If you work hard and stay focused, then this might happen.',
              'When the sun shines, it shines on your face.',
              'Definitely going to happen!',
              'Take some time to think about it.',
              'This is not a good idea!',
              'This is a great idea!',
              'Cannot be determined at this time.  Try Again!')

Keep in mind that in R, you can call a specific ‘spot’ within a vector. For instance, if we wanted the third1 message (“Chances are good.”), we simply have to say messages[3]:

messages[3]
[1] "Chances are good."

Now let’s write a function. In R, you have to ‘store’ the function in a variable name. That variable name becomes the name of the function.

If we want arguments (i.e., values that can be supplied by the user for the function to be used), we simply add a name for the value within the function() argument. Here, we’ll use the input value name (i.e., argument) of ‘seed_value’.

I’ve commmented the code to help explain what it’s doing.

magic.8ball <- function(seed_value) {
  # check to see if the argument is missing
  # if argument is missing, the output will change every time the function is run
  if(missing(seed_value)) {
    x <- sample(1:10,1)
  } else {
    # if seed is provided, then the results are reproducible
    set.seed(seed_value)
    x <- sample(1:10,1)
  }
  
  # store the message that has been 'selected'
  out <- messages[x]
  
  # return the message to the console
  return(out)
}

Now let’s call the function in 2 ways: without a seed and with a seed.

Without a seed:

magic.8ball()
[1] "This is not a good idea!"

With a seed:

magic.8ball(seed_value = 123)
[1] "Chances are good."

If no seed_value is provided, then a random message will be generated.

Some Takeaways

I highly recommend having some defensive coding practices when using functions. For instance, the missing() function (built-in to base R) is helpful when the user does not specify a specific argument. We could even take this a step further and check to make sure that the user enters an integer value (for example).

Functions are powerful in almost any language. They help to reduce “copying/pasting” code multiple times, help the code look cleaner, and far easier to work with when you have to make changes.

TL;DR

Here’s the final code:

magic.8ball <- function(seed_value) {
  # check to see if the argument is missing
  # if argument is missing, the output will change every time the function is run
  if(missing(seed_value)) {
    x <- sample(1:10,1)
  } else {
    # if seed is provided, then the results are reproducible
    set.seed(seed_value)
    x <- sample(1:10,1)
  }
  
  # store the message that has been 'selected'
  out <- messages[x]
  
  # return the message to the console
  return(out)
}

Acknowledgements

Footnotes

  1. Unlike Python, R is not 0 indexed. This means that initial spots or values start at position 1 not 0.↩︎

Reuse