library(tidyverse)
library(stringr)
# Creating a function called mySum with 2 required arguments
mySum<-function(number1, number2){
  return(number1+number2)
}
# Defaulting to order of arguments in function
mySum(5,3)
## [1] 8
# Manually specifying arguments
mySum(number1 = 5, number2 = 3)
## [1] 8
# Create the mySum() function, and use it to calculate the sum of 13 and 1989.
mySum(13,1989)
## [1] 2002
#What happens when we calculate the sum of NA and 1989?
mySum(NA, 1989)
## [1] NA
# Creating a function called fun1
fun1 <- function(x, y) {
  return(x + y)
}

# Creating a function called fun_2
fun_2 <- function(x, y) {
  return(x - y)
}
# Good naming of functions

# Creating a function called computeSum
computeSum <- function(number1, number2) {
  return(number1 + number2)
}

# Creating a function called computeDiff
computeDiff <- function(number1, number2) {
  return(number1 - number2)
}
# Creating a function called mySum with 2 required arguments, 1 optional argument
myNewSum <- function(number1, number2, remove.na = TRUE) {
  if(remove.na) {
    #if remove.na s True replace NA values with 0
    calcSum <- ifelse(is.na(number1), 0, number1) + 
         ifelse(is.na(number2), 0, number2)
  } else {
    #otherwise add the two numbers
    calcSum <- number1 + number2
  }
  return(calcSum)
}

ifelse(condition, valueifconditionTrue, valueif conditionFalse)

#Read the source code for each of the following three functions, determine the purpose of each function, and propose better function names.

#Checks if a string begins with a given prefix
Check_prefix <- function(string, prefix) {
  str_sub(string, 1, nchar(prefix)) == prefix
}

Check_prefix(string = "anti-hero", prefix = "anti")
## [1] TRUE
Check_prefix(string = "heo-anti", prefix = "anti")
## [1] FALSE
#Create a function to drop the last value
drop_last_value <- function(x) {
  if (length(x) <= 1){ 
    #return NULL if no value
    return(NULL)
}
else {
  #Drop last value
  x[-length(x)]
}

}

drop_last_value(1:5)
## [1] 1 2 3 4
drop_last_value(c("gvsu","GV","LAKERS"))
## [1] "gvsu" "GV"
#Create function to calculate harmonic mean
harmonic_mean <- function(x) {
  1 / (mean(1 / x))
}


#Crete function to calculate geometric mean
geometric_mean<-function(values){
  n<-length(x)
   return(prod(x)^(1/n))
}
geometric_mean(1:5)
## Error in geometric_mean(1:5): object 'x' not found
mean(1:5)
## [1] 3

Conditional execution, warnings and errors

mean(c("GVSU", 5))
## Warning in mean.default(c("GVSU", 5)): argument is not numeric or logical:
## returning NA
## [1] NA
# Function to calculate square root
calcSqrt <- function(val) {
if (val >= 0) {
  return(val^0.5)
} else {
  stop("val is negative but must be >= 0!")
  return(NaN)
}
}

calcSqrt(4)
## [1] 2
calcSqrt(-9)
## Error in calcSqrt(-9): val is negative but must be >= 0!

chain if else statements

foodType <- function(food) {
  
  food<-str_to_lower(food)
  
if (food %in% c("apple", "orange", "banana")) {
  return("fruit")
} else if(food %in% c("broccoli", "asparagus")) {
  return("vegetable")
} else {
  return("other")
}}

foodType("Reese's Puffs")
## [1] "other"
foodType("apple")
## [1] "fruit"
foodType("BANANA")
## [1] "fruit"
#Create a function called is_whole_number(), which checks if a given value is a whole number (e.g.,0, 1, 2, …) or not.
is_whole_number<-function(number){
  if (floor(number)==number & number>=0){
    return(TRUE)
    
  } else{
    return(FALSE)
    
  }
  
}

is_whole_number(0)
## [1] TRUE
is_whole_number(2)
## [1] TRUE
is_whole_number(-1)
## [1] FALSE
#The ^ operator raises a number to a specified power in R. Create a function that raises a number to a specified power, and returns a warning and an NaN value if the number is negative and the power is not a whole number.
raise_power<-function(number, power){
  if(number<0 &!(is_whole_number(power))){
    warning("🚩🚩🚩🚩Hey!! that number is negative and power is not a whole number")
    return(NaN)
    
  } 
  
  return(number^power)
  
}


#Use your function to calculate 4^(2), (-9)^(2), 3^(1/3), and (-3)^(1/3).
raise_power(4,-2)
## [1] 0.0625
raise_power(-2,9)
## [1] -512
raise_power(3,1/3)
## [1] 1.44225
raise_power(-3,1/3)
## [1] NaN

The ifelse()function

# Creating a function called mySum with 2 required arguments, 1 optional argument
myNewSum <- function(number1, number2, remove.na = TRUE) {
  if(remove.na) {
    calcSum <- ifelse(is.na(number1), 0, number1) + 
         ifelse(is.na(number2), 0, number2)
  } else {
    calcSum <- number1 + number2
  }
  return(calcSum)
}

#Create the myNewSum() function, and use it to calculate the sum of 13 and 1989
myNewSum(13,1989)
## [1] 2002
#What happens when we calculate the sum of NA and 1989 using myNewSum()?
myNewSum(NA, 1989)
## [1] 1989
myNewSum(NA, 1989)
## [1] 1989

Logical operators

# The 'or' operator
(3 < 5) || (-1 > 0)
## [1] TRUE
# The 'and' operator
(3 < 5) && (-1 > 0)
## [1] FALSE
# Checking Equality
# The 'equals' operator
3 == 5
## [1] FALSE
(4/2) == 2
## [1] TRUE
3 != 5
## [1] TRUE
# Vectorized examples
1:4
## [1] 1 2 3 4
1:4 == 3
## [1] FALSE FALSE  TRUE FALSE
(1:4 < 4) & (1:4 > 1)
## [1] FALSE  TRUE  TRUE FALSE
(1:4 < 4) | (1:4 > 1)
## [1] TRUE TRUE TRUE TRUE
#Create a function that takes a numeric vector as input, and returns a single boolean value indicating whether or not the vector has any negative values.
any_negative <- function(numbers){
  return(any(numbers<0))
  
}

any_negative(-5)
## [1] TRUE
any_negative(c(-5,0,1,2))
## [1] TRUE
any_negative(c(0,1,2))
## [1] FALSE
#Does the code (1:4 < 4) & (1:4 > 1) produce the same result as (1:4 < 4) && (1:4 > 1)? Which code achieves what appears to be its intended purpose?

(1:4 < 4) & (1:4 > 1)
## [1] FALSE  TRUE  TRUE FALSE
(1:4 < 4) && (1:4 > 1)
## [1] FALSE

The first one does what the code is intended to do.

Modulus

#For positive numbers, the Modulus is the remainder of the division of two numbers. For example, 10 divided by 3 is 1, so 10 modulus 3 is 1. The modulus operator in R is implemented using %% as below:

# 10 mod 3
10 %% 3
## [1] 1
# 10 mod 2
10 %% 2
## [1] 0
# 10 mod 5
10 %% 5
## [1] 0
# 12 mod 5
12 %% 5
## [1] 2
# Write a function to check if a number is even or odd that returns a vector containing the values “even”, “odd”, or “not an integer” depending on its input.
evenOrOdd<- function(number){
  if (number%%2==0 & floor(number) ){
    return("even")
  }else if(number%%2!=0 & floor(number)){
    return("odd")
  }else{
    return("not an integer")
  }
}

evenOrOdd(2) 
## [1] "even"
evenOrOdd(0.6)
## [1] "not an integer"
evenOrOdd(-1)
## [1] "odd"