---
title: "Week 1 Lecture 2"
output: html_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

### Functions Review

Let's look at a very simple function:
```{r}
f <- function(x){
  x ** 2 + 1
}
```

Here's the process by which the value of this function is computed:


We want to compute `f(5)` 

We substitute `x <- 5`

The value the function computes is $5^2 + 1 = 26$.

`f(5)` is evaluated to 26.

This is the same process that you'd know from algebra when computing $g(x)$ for $g(x) = x^2 + 1$.

#### Local variables and "scratch work"

Here is a slightly more complicated function

```{r}
h <- function(x){
  y <- 2 * x
  y ** 2 - x
}
```

Here, we defined a local variable `y` to help us with the computation. The process we use is

We want to compute `h(2)` 

We substitute `x <- 2`

We evaluate and substitue `y <- 2 * 2` (i.e., 4)

The value the function computes is $4^2 - 2 = 14$

The value of `h(2)` was evaluated to 14.


Note that we cannot access `y` outside of the function `h`. That makes sense: `y` is defined in terms of the parameter `x`, which might change.


### Computing values vs printing them to the screen

Consider the following two functions:

```{r}
emo.state <- function(score){
  if(score >= 98){
    "Hooray"
  }else if(score >= 95){
    "OK"
  }else{
    "Alas"
  }
}
```

```{r}
emo.state.2 <- function(score){
  if(score >= 98){
    cat("Hooray")
  }else if(score >= 95){
    cat("OK")
  }else{
    cat("Alas")
  }
}
```

The function `emo.state` *computes* a value, just like our functions `f` and `h` above. For example, `emo.state(99)` evaluates to `"Hooray!"`. You can see this in the following example:

```{r}
a <- emo.state(99)
cat(a)
```

We first evaluated `emo.state(99)` and put it in `a`. Then we gave an instruction to R to print the value of `a` to the screen.

On the other hand, consider this piece of code:

```{r}
a <- emo.state.2(99)
```

This already had the effect of printing an output to the screen. That's because when R sees `cat("Hooray")`, it outputs `Hooray` to the screen. But the value that the function computes, which is `cat("Hooray")` is not `"Hooray"`. In fact, it is

```{r}
a
```

You will *very rarely* need to use `cat` inside functions. Outside of Precept 1, you just should not use it at all in this course.

#### `secret.number` example

This is an example of a function where we do a lot of "scratch work". The last line in the body of the function is the value that the function computes.

```{r}
guess.secret.number <- function(secret.num){
  res1 <- secret.num + 8
  res2 <- res1 * 2
  res3 <- res2 / 4
  res3 - secret.num / 2
}
```

Note that `guess.secret.number` always computes 4, regardless of what `secret.number` you plug in. That is how the algebra works out!


## Comments

Comments are meant to help humans understand R code. Anything that follow the pound sign `#` is ignored by R. You can use comments to explain your code (to your partner, preceptor, or your future self), or to temporarily disable parts of your code.

```{r}
cat("hi") # This part will be ignored by R

# You can write comments here too
cat("Things are happenning again")
```

## Syntax

"Syntax" is the set of rules according to which R statements must be constructed. For example, as we saw in the previous lecture, to construct an if-statement, you must write things as

    if(<CONDITION1>){
      <STATEMENT1>
      <STATEMENT2>
      ...
    }else if(<CONDITION2>){
      <STATEMENT3>
      <STATEMENT4>
      ...
    }else if(<CONDITION3>){
      <STATEMENT5>
      <STATEMENT6>
      ...
    }...else{
     <STATEMENT7>
     ...
    }


The curly braces and brackets are mandatory. Violating syntax rules would usually result in R producing an error.

(Syntax is distinct from semantics -- the rules that determine the *meaning* of R statements. This is analoguous to terms used for human languages.)


## Vectors

Here is an example of a vector

```{r}
offer <- c(241, 590, 533, 425, 261)
```

A vector is a sequence of values of the same type (you can also have vectors of characters). Here is how you can access elements of a vector:

```{r}
offer[1]
offer[4]
```


You can find the length (i.e., the number of elements of a vector) like so:

```{r}
length(offer)
```

Aside: technically, everything in R is a vector. It's just that some vectors have length 1.

```{r}
a <- 42
a[1]
```

You can even do the following, if you insist:
```{r}
42[1]
```

Here are some things we can do with vectors:

```{r}
sort(offer) # Compute a sorted version of the vector, in increasing order
```

```{r}
unique(c(1, 2, 1, 4, 5, 2)) # Get a vector with every element of the input appearing once
```

```{r}
max(offer)
min(offer)
```

Here is how we can compute the `max` without using the `max` function:

```{r}
sort(offer)[length(offer)]
```

(Explain this!)


We can also perform operations on all the elements of a vector.

```{r}
offer > 533
```

```{r}
offer == 533
```

## Indexing vectors with logical vectors

A powerful way of extracting elements from a vector is by indexing the vector using logical vectors. Here is how we can get the third and fourth elements of the vector:

```{r}
offer[c(F, T, T, F, F)]
```

Of course, we could compute the logical vector above using

```{r}
offer > 500
```

Combining those, we can go

```{r}
offer[offer > 500]
```

Note what we did: we extracted the elements that are larger than 500.


## Operating on logical values

Suppose we wanted something fancier: extracting all elements between 400 and 550. In other words, suppose we want the elements that are both larger than 400 and smaller than 550. To achieve this, we would want to combine the conditions "larger than 400" and "smaller than 550".

We can do this using logical operators

    AND:    a & b. TRUE only if a is TRUE and b is TRUE. FALSE otherwise
    OR:     a | b. TRUE if at least one of a or b is TRUE, FALSE otherwise
    NOT:    !a. TRUE if a is FALSE, FALSE if a is TRUE

Some examples:
 

```{r}
pie <- TRUE
icecream <- FALSE
pie | icecream
```

```{r}
pie <- FALSE
icecream <- FALSE
pie | icecream
```


```{r}
pie <- TRUE
icecream <- FALSE
pie & icecream
```

```{r}
pie <- TRUE
icecream <- TRUE
pie | icecream
```

Note: this is not quite how it works in English. If I say I will have pie or icecream, and then have both, that means what I said wasn't true. But for R, the expression `pie | icecream` is TRUE. Technically, `|` is called "inclusive OR" (as opposed to the "exclusive OR" we usually mean in English.)


```{r}
pie <- FALSE
icecream <- TRUE
pie | icecream
```

```{r}
pie <- FALSE
icecream <- FALSE
pie | icecream
```

```{r}
pie <- TRUE
!pie
```

### Inclusive OR and exclusive OR

So how *do* you make an expression in R that corresponds to "I will have ice cream or pie"? That is, we want to write an expression that will be `TRUE` whenever `pie` or `icecream` are true, but not both.

Here are several ways of accomplishing this. They all do the same thing

    (pie | ice.cream) & !(pie & ice.cream)
    (pie == T & ice.cream == F) | (pie == F & ice.cream == T)
    (pie & !ice.cream) | (!pie & ice.cream)
    pie != ice.cream


