# 5 Object toss

## 5.1 Introduction

Let’s keep improving our function `toss()`, but now changing its output in order to return an object of class `"toss"`.

## 5.2 Motivation for object `"toss"`

So far we have a constructor function `coin()` (from chapter 3) and a `toss()` (from chapter 4) which actually corresponds to the `toss` method for objects of class `"coin"`:

``````# constructor function
coin <- function(sides = c("heads", "tails"), prob = c(0.5, 0.5)) {
if (length(sides) != 2) {
stop("\n'sides' must be of length 2")
}
check_prob(prob)
res <- list(sides = sides, prob = prob)
class(res) <- "coin"
return(res)
}``````
``````# toss method for "coin" objects
toss.coin <- function(x, times = 1) {
sample(x\$sides, size = times, replace = TRUE, prob = x\$prob)
}``````

Let’s use `toss()` to flip a coin 10 times:

``````set.seed(321)

toss10 <- toss(acoin, times = 10)
toss10

Having obtained several tosses, we can calculate things like:

1. the total number of tosses
2. the total number of `heads`
3. the total number of `tails`
``````# number of tosses
length(toss10)
#> [1] 10

#> [1] 3

# total number of tails
sum(toss10 == 'tails')
#> [1] 7``````

In general, when tossing a coin, we are not only interested in keeping track of such tosses; we would also like to know (or keep track of) the number of tosses, the number of heads, and the number of tails. Consequently, it would be nice to have another class of object for this purpose.

How do you know that you need this new object class?

Well, this is precisely an example that illustrates the process of programming in general, and OOP in particular. This kind of decisions require some (or sometimes “a lot” of) thinking, and brainstorming time. To be honest, while I was writing this book and playing with `"coin"` objects and their tosses, I decided that it would be convenient to have an object of class `"toss"` containing the following information:

• all the outcomes from the series of tosses
• the total number of tosses
• the total number of heads
• the total number of tails

The most flexible type of data structure in R to store other data structures is a `list`. Having a vector of tosses, we can use a list to keep all the desired information:

``````flips <- toss(coin1, times = 6)

a <- list(
tosses = flips,
total = length(flips),
tails = sum(flips == coin1\$sides[2])
)

a
#> \$tosses
#>
#> \$total
#> [1] 6
#>
#> [1] 3
#>
#> \$tails
#> [1] 3``````

The idea is to be able to invoke `toss()`, and then obtain an object like the list `a` in the above code. But do it in such a way that the output is an object of class `"toss"`.

### 5.2.1 Auxiliary Constructor

For convenience purposes, we can write an auxiliary constructor function, which I will call `make_toss()`. This function will take an input vector (i.e. a character vector with `"heads"` and `"tails"` elements), and it will return an object of class `"toss"`:

``````# auxiliary constructor function
make_toss <- function(coin, flips) {
res <- list(
coin = coin,
tosses = flips,
total = length(flips),
tails = sum(flips == coin\$sides[2]))
class(res) <- "toss"
res
}``````

This auxiliary function is not intended to be called by the user. Instead, it’s an internal function for auxiliary purposes.

## 5.3 Main Function `toss()`

Now that we have the auxiliary function `make_toss()`, we can integrate it inside the specific method `toss.coin()`. In this way, the function `toss.coin()` becomes the master function: the one designed to be called by the user:

``````# redefining toss.coin()
toss.coin <- function(x, times = 1) {
flips <- sample(x\$sides, size = times, replace = TRUE, prob = x\$prob)
make_toss(x, flips)
}``````

This is how `toss()` works:

``````set.seed(2233)
fair <- coin()
toss(fair, times = 5)
#> \$coin
#> object "coin"
#>
#>    side prob
#> 2 tails  0.5
#>
#> \$tosses
#>
#> \$total
#> [1] 5
#>
#> [1] 2
#>
#> \$tails
#> [1] 3
#>
#> attr(,"class")
#> [1] "toss"``````

You may ask: “Why do we need a function `make_toss()`, and another function `toss()`?”. Can’t we just write a single function `suppertoss()` that does everything at once?:

``````# can't we just put everything in one function?
supertoss <- function(x, times = 1) {
flips <- toss(x, times = times)
res <- list(
coin = x,
tosses = flips,
total = length(flips),
tails = sum(flips == x\$sides[2]))
class(res) <- "toss"
res
}``````

The short answer is: yes, you can. And probably this is what most beginners tend to do. The reason why I decided to break things down into simpler and smaller functions is because I went already through a couple of implementations, and realized that it was better to have the auxiliary function `make_toss()`. Also, it is good practice to write short functions that preferably do one thing.

Here’s a brief recap of the main functions we have so far:

• `coin()` is a constructor function to create objects of class `"coin"`.
• `toss()` is a generic `"toss"` method.
• `make_toss()` is an auxiliary function that takes a `"coin"` and a vector of flips, and which produces an object `"toss"`.
• `toss.coin()` is the specific `"toss"` method to be used on `"coin"` objects.
• notice that `make_toss()` is called by `toss.coin()`.

## 5.4 Upgrading `toss()`

Let’s consider our `quarter` coin, and apply `toss()` on it:

``````quarter1 <- coin(c("washington", "fort"))
class(quarter1) <- c("quarter", "coin")
quarter1
#> object "coin"
#>
#>         side prob
#> 1 washington  0.5
#> 2       fort  0.5

toss(quarter1, times = 4)
#> \$coin
#> object "coin"
#>
#>         side prob
#> 1 washington  0.5
#> 2       fort  0.5
#>
#> \$tosses
#> [1] "washington" "washington" "fort"       "washington"
#>
#> \$total
#> [1] 4
#>
#> [1] 3
#>
#> \$tails
#> [1] 1
#>
#> attr(,"class")
#> [1] "toss"``````

`toss()` is working as expected, and you can try it with different values for `times`. The only issue is that a distracted user could pass an unexpected value for the argument `times`:

``````toss(quarter1, times = -4)
#> Error in sample.int(length(x), size, replace, prob): invalid 'size' argument``````

R produces an error when `times = -4`, but it’s an error that may not be very helpful for the user. The error message clearly says that `'size'` is an invalid argument, but `toss()` just has one argument: `times`.

To be more user friendly, among other reasons, it would be better to check whether `times` has a valid value. One way to do that is to include a conditional statement like the following one:

``````toss.coin <- function(x, times = 1) {
if (times <= 0) {
stop("\nargument 'times' must be a positive integer")
}
flips <- sample(x\$sides, size = times, replace = TRUE, prob = x\$prob)
make_toss(x, flips)
}

# this works ok
toss(quarter1, 5)
#> \$coin
#> object "coin"
#>
#>         side prob
#> 1 washington  0.5
#> 2       fort  0.5
#>
#> \$tosses
#> [1] "fort"       "fort"       "washington" "washington" "fort"
#>
#> \$total
#> [1] 5
#>
#> [1] 2
#>
#> \$tails
#> [1] 3
#>
#> attr(,"class")
#> [1] "toss"

# this doesn't work, but the error message is clear
toss(quarter1, -4)
#> Error in toss.coin(quarter1, -4):
#> argument 'times' must be a positive integer``````

Once again, it is good practice to write short functions that preferably do one thing. In this case, we could define a checking function `check_times()` to make sure that `times` has a valid value:

``````# auxiliary function to check 'times' input
check_times <- function(times) {
if (times <= 0 | !is.numeric(times)) {
stop("\nargument 'times' must be a positive integer")
} else {
TRUE
}
}``````

Once `check_times()` has been defined, we can include it inside `toss()`:

``````toss.coin <- function(x, times = 1) {
check_times(times)
flips <- sample(x\$sides, size = times, replace = TRUE, prob = x\$prob)
make_toss(x, flips)
}

toss(quarter1, 5)
#> \$coin
#> object "coin"
#>
#>         side prob
#> 1 washington  0.5
#> 2       fort  0.5
#>
#> \$tosses
#> [1] "washington" "washington" "fort"       "fort"       "fort"
#>
#> \$total
#> [1] 5
#>
#> [1] 2
#>
#> \$tails
#> [1] 3
#>
#> attr(,"class")
#> [1] "toss"``````

### 5.4.1 In Summary

The more you understand a problem (i.e. phenomenon, process), the better you will be prepared to design objects, and program their corresponding methods, auxiliary functions, classes, etc.

In my experience, you will very likely need to iterate several times with the creation of objects and functions for your code. At one iteration you will realize that you need to break down a given function into two ore more simpler functions. Sometimes you will see an opportunity to create a secondary function to check ceratin inputs. Likewise, you will identify situations when derived methods are needed to make your code more flexible and user friendly. Of course, like anything in this life, learning when all these components are needed takes a lot of time and practice.

#### Make a donation

If you find this resource useful, please consider making a one-time donation in any amount. Your support really matters.