# INBO CODING CLUB 25 August 2020 Welcome! ## Share your code snippet If you want to share your code snippet, copy paste your snippet within a section of three backticks (```): As an **example**: ``` library(tidyverse) ``` (*you can copy paste this example and add your code further down*) ## Participants Name | Challenges --- | --- Damiano Oldoni | Emma Cartuyvels|** Els Lommelen |* Hans Van Calster |** Els De Bie |** (oops forgot) Salvador Fernández | *** An Vanden Broeck | ** Raïsa Carmen |** Anja Leyman| ** Leen Govaere | *** Thierry Onkelinx | *** Luc De Bruyn | ** No yellow sticky notes online. Put your name + " | " and add a "*" each time you solve a challenge. ## Live coding snippet ``` library(MASS) # provides `cats` data gamma_est <- function(data) { # this fits a gamma distribution to a collection of numbers m <- mean(data) v <- var(data) s <- v/m a <- m/s return(list(a = a,s = s)) } calc_var <- function(estimates){ var_of_ests <- apply(estimates, 2, var) return(((n - 1)^2/n)*var_of_ests) } gamma_jackknife <- function(data) { ## jackknife the estimation n <- length(data) jack_estimates = gamma_est(data[-1]) for (omitted_point in 2:n) { jack_estimates = rbind(jack_estimates, gamma_est(data[-omitted_point])) } jack_var = calc_var(jack_estimates) return(sqrt(jack_var)) } # jackknife gamma dist. estimates of cat heart weights gamma_jackknife(cats$Hwt) ``` Credits: Chris Paciorek, Department of Statistics, UC Berkley ## Challenge 1 Emma: I used debug(EvenOdd) ``` evenOdd <- function(n) { char_n <- as.character(n) char_n_split <- strsplit(char_n, "")[[1]] counter_even <- 0 counter_odd <- 0 for (i in char_n_split) { digit <- as.integer(i) if (digit %% 2 == 0) { counter_even <- counter_even + 1 } else { counter_odd <- counter_odd + 1 } } return(list(n_even = counter_even, n_odd = counter_odd)) } ``` Thierry: debug(evenOdd) and F10 (next statement) ``` # vectorised version evenOdd_vector <- function(n) { char_n <- as.character(n) splitted <- strsplit(char_n, "") splitted <- lapply(splitted, as.integer) counts <- sapply( splitted, function(x) { odd <- sum(x %% 2) c(n_even = length(x) - odd, n_odd = odd) } ) t(counts) } evenOdd_vector(c(398473234, 459)) ``` solution withouth strsplit ``` evenOdd <- function(n) { char_n <- as.character(n) counter_even <- 0 counter_odd <- 0 for (i in seq_len(nchar(char_n))) { digit <- as.integer(substring(char_n, i, i)) if (digit %% 2 == 0) { counter_even <- counter_even + 1 } else { counter_odd <- counter_odd + 1 } } return(c(n_even = counter_even, n_odd = counter_odd)) } ``` Example with a conditional breakpoint. Enter the debugger only when `i > 3` ``` evenOdd <- function(n) { char_n <- as.character(n) counter_even <- 0 counter_odd <- 0 for (i in seq_len(nchar(char_n))) { browser(expr = i > 3) # conditional breakpoint digit <- as.integer(substring(char_n, i, i)) if (digit %% 2 == 0) { counter_even <- counter_even + 1 } else { counter_odd <- counter_odd + 1 } } return(c(n_even = counter_even, n_odd = counter_odd)) } ``` Anja: I used source and red points ? I didn't get an error, so debug seemed strange Luc -> debug(evenOdd) Hans -> debug(evenOdd) Need to split char_n into character digits; I used strsplit() to do it + simple example to try out strsplit(): ``` a <- "1234" strsplit(a, split = "") strsplit(a, split = "")[[1]] evenOdd <- function(n) { n <- as.integer(n) char_n <- strsplit(as.character(n), split = "")[[1]] counter_even <- 0 counter_odd <- 0 for (i in char_n) { digit <- as.integer(i) if (digit %% 2 == 0) { counter_even <- counter_even + 1 } else { counter_odd <- counter_odd + 1 } } return(list(n_even = counter_even, n_odd = counter_odd)) } ``` Salvador -> debug(evenOdd). Found the error inside the loop: the length of char_n is 1, so it returns only if the whole number is odd or even. ## Challenge 2 Thierry: debug(steps), F10 (next statement) and shift+F4 (step into) The step() works simpler when evenOdd() returns a vector instead of a list. Note that `x %% 2` equal 1 when `x` is odd. Hence `sum(`x %% 2`)` is the number of odd items in `x`. ``` evenOdd <- function(n) { char_n <- as.character(n) char_n <- strsplit(char_n, "")[[1]] n_odd <- sum(as.integer(char_n) %% 2) return(c(n_even = length(char_n) - n_odd, n_odd = n_odd)) } step <- function(n) { as.integer(paste0(c(evenOdd(n), nchar(n)), collapse = "")) } steps <- function(n) { n_steps <- 0 while (n != 123) { n <- step(n) n_steps <- n_steps + 1 } return(n_steps) } ``` Emma: debug(step) and read error steps ``` evenOdd <- function(n) { char_n <- as.character(n) char_n_split <- strsplit(char_n, "")[[1]] counter_even <- 0 counter_odd <- 0 for (i in char_n_split) { digit <- as.integer(i) if (digit %% 2 == 0) { counter_even <- counter_even + 1 } else { counter_odd <- counter_odd + 1 } } return(c(counter_even, counter_odd)) } step <- function(n) { n_odd_even_total <- c(evenOdd(n), nchar(n)) step1 <- as.character(n_odd_even_total) step2 <- paste(step1, sep = '', collapse = '') step3 <- as.numeric(step2) return(step3) } steps <- function(n) { n_steps = 0 while (n != 123) { n <- step(n) n_steps <- n_steps + 1 } return(n_steps) } # steps as a recursive function steps2 <- function(n) { if (n == 123) { return(1) } steps2(step(n)) + 1 } ``` Hans: debug(steps) and see that the function is not initialized and n is not correctly returned in the while loop ``` steps <- function(n) { n_steps <- 0 while (n != 123) { n <- step(n) n_steps <- n_steps + 1 n <- paste0(n$n_even, n$n_odd, n$n_total) n <- as.integer(n) } return(n_steps) } ``` Salvador: debug(step) ## Challenge 3 Thierry: Use the `assertthat` package to validate the input. `.Machine$integer.max` is the largest integer value the machine can store. ``` evenOdd <- function(n) { if (!require(assertthat)) { stop("Please install the assertthat package.") } assert_that( is.number(n), # must be a single number (real or integer) noNA(n), # may not contain missing values 0 <= n, # must be positive n <= .Machine$integer.max ) if (!is.integer(n)) { assert_that(abs(n - as.integer(n)) < 1e-8, msg = "Not an integer") n <- as.integer(n) } char_n <- as.character(n) char_n <- strsplit(char_n, "")[[1]] n_odd <- sum(as.integer(char_n) %% 2) return(c(n_even = length(char_n) - n_odd, n_odd = n_odd)) } evenOdd(39847323439847323413244564) evenOdd(c(1, 1234)) evenOdd(list(1, 1234)) evenOdd(NA) evenOdd(NA_integer_) evenOdd(-1) evenOdd(1.5) evenOdd(1.00000000000000000000001) ``` options(scipen=999) THANK YOU !! Very interesting session!! Whoop whoop!