diff --git a/01_debugging_comfy.R b/01_debugging_comfy.R deleted file mode 100644 index 2cba950..0000000 --- a/01_debugging_comfy.R +++ /dev/null @@ -1,30 +0,0 @@ -# Determine the bug when you run `get_climates()` -# Hint: Use `traceback()` to find where it occurs, add breakpoints / `browser()` calls -# Hint: look at the types of the data and make sure they are what the functions expect. - -library(tidyverse) - -# Separate, flatten, and trim values in the vector -clean <- function(vec) { - values <- strsplit(vec, ",") - flat_values <- unlist(values) - trimmed_values <- str_trim(flat_values) - trimmed_values -} - -# Clean vector and get the unique values -uniquify <- function(vec) { - clean_values <- clean(vec) - unique_values <- unique(clean_values) - unique_values -} - -# Read data and get unique climate values -get_climates <- function() { - planets <- read.csv2(here::here("activities/planets.csv")) - unique_climate <- uniquify(planets$climate) - unique_climate -} - -# This example originally used in Amanda Gadrow's excellent debugging talk at rstudio::conf 2018, -# https://github.com/ajmcoqui/debuggingRStudio/blob/b70a3575a3ff5e7867b05fb5e84568abba426c4b/error_example.R diff --git a/01_debugging_jim.R b/01_debugging_jim.R deleted file mode 100644 index c72f0b3..0000000 --- a/01_debugging_jim.R +++ /dev/null @@ -1,30 +0,0 @@ -# Determine the bug when you run `get_climates()` -# Hint: Use `traceback()` to find where it occurs, add breakpoints / `browser()` calls -# Hint: look at types of input - -library(tidyverse) - -# Separate, flatten, and trim values in the vector -clean <- function(vec) { - values <- strsplit(vec, ",") - flat_values <- unlist(values) - trimmed_values <- str_trim(flat_values) - trimmed_values -} - -# Clean vector and get the unique values -uniquify <- function(vec) { - clean_values <- clean(vec) - unique_values <- unique(clean_values) - unique_values -} - -# Read data and get unique climate values -get_climates <- function() { - planets <- readr::read_csv2(here::here("activities/planets.csv")) - unique_climate <- uniquify(planets$climate) - unique_climate -} - -# This example originally used in Amanda Gadrow's excellent debugging talk at rstudio::conf 2018, -# https://github.com/ajmcoqui/debuggingRStudio/blob/b70a3575a3ff5e7867b05fb5e84568abba426c4b/error_example.R diff --git a/01_debugging_spartan.R b/01_debugging_spartan.R deleted file mode 100644 index 502adaa..0000000 --- a/01_debugging_spartan.R +++ /dev/null @@ -1,30 +0,0 @@ -# Determine the bug when you run `get_climates()` -# Hint: Use `traceback()` to find where it occurs, add breakpoints / `browser()` calls -# Hint: look at types of input - -library(tidyverse) - -# Separate, flatten, and trim values in the vector -clean <- function(vec) { - values <- strsplit(vec, ",") - flat_values <- unlist(values) - trimmed_values <- str_trim(flat_values) - trimmed_values -} - -# Clean vector and get the unique values -uniquify <- function(vec) { - clean_values <- clean(vec) - unique_values <- unique(clean_values) - unique_values -} - -# Read data and get unique climate values -get_climates <- function() { - planets <- read.csv2(here::here("activities/planets.csv")) - unique_climate <- uniquify(planets$climate) - unique_climate -} - -# This example originally used in Amanda Gadrow's excellent debugging talk at rstudio::conf 2018, -# https://github.com/ajmcoqui/debuggingRStudio/blob/b70a3575a3ff5e7867b05fb5e84568abba426c4b/error_example.R diff --git a/01_exercise/01_debugging_comfy.R b/01_exercise/01_debugging_comfy.R new file mode 100644 index 0000000..de870fa --- /dev/null +++ b/01_exercise/01_debugging_comfy.R @@ -0,0 +1,58 @@ +# Origin ----------------------------------------------------------------------- +# This example was originally used inJenny Bryan's rstudio::conf(2020) keynote +# Object of type 'closure' is not subsettable, +# https://github.com/jennybc/debugging + + +# open 01_sourceme to inspect & review code --------------------------------------- +# try file.edit() + + +# source functions ------------------------------------------------------------- +# source in 01_exercise/01_sourceme.R + +# view fruit data -------------------------------------------------------------- + +# successful execution --------------------------------------------------------- +# confirm function works for berry +fruit_avg(fruit, "berry") + +# error on execution ----------------------------------------------------------- +# observe error +fruit_avg(fruit, "peach") + +# identify location of error --------------------------------------------------- +# try traceback() + +# copy and paste traceback results as a comment here to compare with next exercise + + +# modify options for a richer traceback via rlang ------------------------------ + +# copy and paste traceback results as a comment here to compare with next exercise + + +# interactive debugging -------------------------------------------------------- +# enter interactive debugger by inserting browser() into the fruit_avg() function +# trigger interactive debugger by executing function + +# use these commands at the Browse[]> prompt to navigate the debugger + +# | command | operation | +# |---------|-------------------------| +# | `n` | next statement | +# | `c` | continue | +# | `s` | step into function call | +# | `f` | finish loop / function | +# | `where` | show previous calls | +# | `Q` | quit debugger | + +# while in the debugger, explore the objects in your environment +# with ls.str() + +# Can you determine exactly why the bug is occurring? +# If you have time, try to fix it! + + + + diff --git a/01_exercise/01_debugging_solution.R b/01_exercise/01_debugging_solution.R new file mode 100644 index 0000000..0621b07 --- /dev/null +++ b/01_exercise/01_debugging_solution.R @@ -0,0 +1,70 @@ +# Origin ----------------------------------------------------------------------- +# This example was originally used inJenny Bryan's rstudio::conf(2020) keynote +# Object of type 'closure' is not subsettable, +# https://github.com/jennybc/debugging + + +# open sourceme to inspect & review code --------------------------------------- +file.edit("01_exercise/01_sourceme.R") + + +# source functions ------------------------------------------------------------- +# open 01_exercise/01_sourceme.R and click on Source button +# OR +source("01_exercise/01_sourceme.R") + + +# view fruit data -------------------------------------------------------------- +fruit + + +# successful execution --------------------------------------------------------- +# confirm function works for berry +fruit_avg(fruit, "berry") + +# error on execution ----------------------------------------------------------- +# observe error +fruit_avg(fruit, "peach") + +# identify location of error --------------------------------------------------- +traceback() + +# copy and paste traceback results as a comment here to compare with next exercise + + +# modify options for a richer traceback ---------------------------------------- +options(error = rlang::entrace) +fruit_avg(fruit, "peach") +rlang::last_error() +rlang::last_trace() + +# copy and paste traceback results as a comment here to compare with next exercise + + +# interactive debugging -------------------------------------------------------- +# enter interactive debugger by inserting `browser()` statement in +# the fruit_avg() function in 01_sourceme.R +# Restart R, re-source file +source("01_exercise/01_sourceme.R") + +# trigger interactive debugger +fruit_avg(fruit, "peach") + +# use these commands at the Browse[]> prompt to navigate the debugger + +# | command | operation | +# |---------|-------------------------| +# | `n` | next statement | +# | `c` | continue | +# | `s` | step into function call | +# | `f` | finish loop / function | +# | `where` | show previous calls | +# | `Q` | quit debugger | + +# while in the debugger, explore the objects in your environment +# with ls.str() + +# Can you determine exactly why the bug is occurring? +# If you have time, try to fix it! + + diff --git a/01_exercise/01_debugging_spartan.R b/01_exercise/01_debugging_spartan.R new file mode 100644 index 0000000..a519810 --- /dev/null +++ b/01_exercise/01_debugging_spartan.R @@ -0,0 +1,43 @@ +# Origin ----------------------------------------------------------------------- +# This example was originally used inJenny Bryan's rstudio::conf(2020) keynote +# Object of type 'closure' is not subsettable, +# https://github.com/jennybc/debugging + + +# open 01_sourceme to inspect & review code --------------------------------------- + + +# source functions ------------------------------------------------------------- + + +# view fruit data -------------------------------------------------------------- + + +# successful execution --------------------------------------------------------- +# confirm function works for berry +fruit_avg(fruit, "berry") + +# error on execution ----------------------------------------------------------- +# observe error +fruit_avg(fruit, "peach") + + + +# identify location of error --------------------------------------------------- + +# copy and paste traceback results as a comment here to compare with next exercise + + + +# modify options for a richer traceback ---------------------------------------- + + +# copy and paste traceback results as a comment here to compare with next exercise + + +# interactive debugging -------------------------------------------------------- +# enter interactive debugger + +# Can you determine exactly why the bug is occurring? +# If you have time, try to fix it! + diff --git a/01_exercise/01_sourceme.R b/01_exercise/01_sourceme.R new file mode 100644 index 0000000..1951b16 --- /dev/null +++ b/01_exercise/01_sourceme.R @@ -0,0 +1,14 @@ +fruit <- data.frame( + row.names = c("calories", "weight", "yumminess"), + blackberry = c(4L, 9L, 6L), + blueberry = c(1L, 2L, 8L), + peach = c(59L, 150L, 10L), + plum = c(30L, 78L, 5L) +) + +fruit_avg <- function(dat, pattern) { + cols <- grep(pattern, names(dat)) + mini_dat <- dat[ , cols] + message("Found ", ncol(mini_dat), " fruits!") + rowMeans(mini_dat) +} \ No newline at end of file diff --git a/02_debugging_comfy.R b/02_debugging_comfy.R deleted file mode 100644 index f5c8118..0000000 --- a/02_debugging_comfy.R +++ /dev/null @@ -1,17 +0,0 @@ -# dplyr::na_if(x, y) replaces NA values in `x` with `y` -# it works when x is a data.frame _without_ Date objects, but fails when there is a Date in the df -# Can you use our debugging tools to figure out where and why it is failing? -library(dplyr) - -test <- tibble(a = lubridate::today() + runif(5) * 30, b = c(1:4, ""), c = c(runif(4), ""), d = c(sample(letters, 4, replace = TRUE), "")) -test - -test %>% na_if("") - -# The traceback is easier to understand without the pipe involved - -# Also useful to look at the implementation of `na_if()` -# Can you reproduce the error without using `na_if()`? - -# What happens if you remove the date column from the tibble? -# How could you apply na_if only to non-date columns? diff --git a/02_debugging_jim.R b/02_debugging_jim.R deleted file mode 100644 index cbc00f4..0000000 --- a/02_debugging_jim.R +++ /dev/null @@ -1,26 +0,0 @@ -# dplyr::na_if(x, y) replaces NA values in `x` with `y` -# it works when x is a data.frame _without_ Date objects, but fails when there is a Date in the df -# Can you use our debugging tools to figure out where and why it is failing? -library(dplyr) - -test <- tibble(a = lubridate::today() + runif(5) * 30, b = c(1:4, ""), c = c(runif(4), ""), d = c(sample(letters, 4, replace = TRUE), "")) -test - -test %>% na_if("") - -traceback() - -# The traceback is easier to understand without the pipe involved -na_if(test, "") - -# Also useful to look at the implementation of `na_if()` -# We get the same error from -test[test == ""] <- NA -traceback() - -# And also from -as.Date("") - -# So it seems we need to only use na_if on _character_ columns -test %>% - mutate_if(is.character, ~ na_if(.x, "")) diff --git a/02_debugging_spartan.R b/02_debugging_spartan.R deleted file mode 100644 index bfa6306..0000000 --- a/02_debugging_spartan.R +++ /dev/null @@ -1,9 +0,0 @@ -# dplyr::na_if(x, y) replaces NA values in `x` with `y` -# it works when x is a data.frame _without_ Date objects, but fails when there is a Date in the df -# Can you use our debugging tools to figure out where and why it is failing? -library(dplyr) - -test <- tibble(a = lubridate::today() + runif(5) * 30, b = c(1:4, ""), c = c(runif(4), ""), d = c(sample(letters, 4, replace = TRUE), "")) -test - -test %>% na_if("") diff --git a/02_exercise/02_debugging_comfy.R b/02_exercise/02_debugging_comfy.R new file mode 100644 index 0000000..6b0096f --- /dev/null +++ b/02_exercise/02_debugging_comfy.R @@ -0,0 +1,68 @@ +# Origin ----------------------------------------------------------------------- +# This example was originally used inJenny Bryan's rstudio::conf(2020) keynote +# Object of type 'closure' is not subsettable, +# https://github.com/jennybc/debugging + +# Restart R! + +# open 02_sourceme to inspect & review code --------------------------------------- +# the content is essentially the same as 01_exercise, but the code has been re-structured +# try file.edit() + + +# source functions ------------------------------------------------------------- +# source in 02_exercise/02_sourceme.R + +# view fruit data -------------------------------------------------------------- + + +# successful execution --------------------------------------------------------- +# confirm function works for berry +fruit_avg(fruit, "berry") + +# error on execution ----------------------------------------------------------- +# observe error +fruit_avg(fruit, "peach") + +# identify location of error via traceback ------------------------------------- +# try traceback() + +# copy and paste traceback results as a comment here to compare with other exercises + + +# modify options for a richer traceback via rlang ------------------------------ + + +# copy and paste traceback results as a comment here to compare with other exercises + +# How do the tracebacks look different compared to 01_exercise? + +# interactive debugging via IDE ------------------------------------------------ +# Restart R +# enter interactive debugger by inserting a breakpoint in +# the fruit_avg() function in 02_sourceme.R +# re-source file +# trigger interactive debugger by executing the function + +# navigate the debugger using the buttons at the top of the console +# be sure to try the "step into" option! + +# while in the debugger, explore the objects in your environment +# with ls.str() + + +# interactive debugging via IDE, again ----------------------------------------- +# Remove breakpoint from 02_sourceme.R +# Restart R +# Modify IDE settings to Debug -> On Error -> ?? +# re-source in the file + +# trigger console error inspector by executing the function + +# explore the "Show Traceback" and "Rerun with Debug" options +# Where does the debugger drop you in? + +# Can you determine exactly why the bug is occurring? +# If you have time, try to fix it! + + diff --git a/02_exercise/02_debugging_solution.R b/02_exercise/02_debugging_solution.R new file mode 100644 index 0000000..4959d66 --- /dev/null +++ b/02_exercise/02_debugging_solution.R @@ -0,0 +1,80 @@ +# Origin ----------------------------------------------------------------------- +# This example was originally used inJenny Bryan's rstudio::conf(2020) keynote +# Object of type 'closure' is not subsettable, +# https://github.com/jennybc/debugging + +# Restart R! + +# open sourceme to inspect & review code --------------------------------------- +# the content is essentially the same as 01_exercise, but the code has been re-structured +file.edit("02_exercise/02_sourceme.R") + + +# source functions ------------------------------------------------------------- +# open 01_exercise/01_sourceme.R and click on Source button +# OR +source("02_exercise/02_sourceme.R") + + +# view fruit data -------------------------------------------------------------- +fruit + + +# successful execution --------------------------------------------------------- +# confirm function works for berry +fruit_avg(fruit, "berry") + +# error on execution ----------------------------------------------------------- +# observe error +fruit_avg(fruit, "peach") + +# identify location of error --------------------------------------------------- +traceback() + +# copy and paste traceback results as a comment here to compare with other exercises + + +# modify options for a richer traceback ---------------------------------------- +options(error = rlang::entrace) +fruit_avg(fruit, "peach") +rlang::last_error() +rlang::last_trace() + +# copy and paste traceback results as a comment here to compare with other exercises + +# How do the tracebacks look different compared to 01_exercise? + +# interactive debugging via IDE ------------------------------------------------ +# Restart R +# enter interactive debugger by inserting a breakpoint in +# the fruit_avg() function in 02_sourceme.R +# re-source file via +debugSource("02_exercise/02_sourceme.R") + +# trigger interactive debugger +fruit_avg(fruit, "peach") + +# navigate the debugger using the buttons at the top of the console +# be sure to try the "step into" option! + +# while in the debugger, explore the objects in your environment +# with ls.str() + + +# interactive debugging via IDE, again ----------------------------------------- +# Remove breakpoint from 02_sourceme.R +# Restart R +# Modify IDE settings to Debug -> On Error -> check Error Inspector +# re-source in the file +source("02_exercise/02_sourceme.R") + +# trigger console error inspector +fruit_avg(fruit, "peach") + +# explore the "Show Traceback" and "Rerun with Debug" options +# Where does the debugger drop you in? + +# Can you determine exactly why the bug is occurring? +# If you have time, try to fix it! + + diff --git a/02_exercise/02_debugging_spartan.R b/02_exercise/02_debugging_spartan.R new file mode 100644 index 0000000..84a66e0 --- /dev/null +++ b/02_exercise/02_debugging_spartan.R @@ -0,0 +1,56 @@ +# Origin ----------------------------------------------------------------------- +# This example was originally used inJenny Bryan's rstudio::conf(2020) keynote +# Object of type 'closure' is not subsettable, +# https://github.com/jennybc/debugging + +# Restart R! + +# open 02_sourceme to inspect & review code --------------------------------------- +# the content is essentially the same as 01_exercise, but the code has been re-structured + + + +# source functions ------------------------------------------------------------- +# source in 02_exercise/02_sourceme.R + +# view fruit data -------------------------------------------------------------- + + +# successful execution --------------------------------------------------------- +# confirm function works for berry +fruit_avg(fruit, "berry") + +# error on execution ----------------------------------------------------------- +# observe error +fruit_avg(fruit, "peach") + +# identify location of error --------------------------------------------------- + +# copy and paste traceback results as a comment here to compare with other exercises + + +# modify options for a richer traceback ---------------------------------------- + +# copy and paste traceback results as a comment here to compare with other exercises + +# How do the tracebacks look different compared to 01_exercise? + +# interactive debugging via IDE ------------------------------------------------ +# Restart R +# enter interactive debugger by inserting a breakpoint in +# the fruit_avg() function in 02_sourceme.R + + + + +# interactive debugging via IDE, again ----------------------------------------- +# Remove breakpoint from 02_sourceme.R +# Restart R +# Modify IDE settings to Debug -> On Error -> ?? + +# explore the "Show Traceback" and "Rerun with Debug" options +# Where does the debugger drop you in? + + +# Can you determine exactly why the bug is occurring? +# If you have time, try to fix it! diff --git a/02_exercise/02_sourceme.R b/02_exercise/02_sourceme.R new file mode 100644 index 0000000..6466ede --- /dev/null +++ b/02_exercise/02_sourceme.R @@ -0,0 +1,33 @@ +fruit <- data.frame( + row.names = c("calories", "weight", "yumminess"), + blackberry = c(4L, 9L, 6L), + blueberry = c(1L, 2L, 8L), + peach = c(59L, 150L, 10L), + plum = c(30L, 78L, 5L) +) + +find_cols <- function(dat, pattern){ + grep(pattern, names(dat)) +} + +reduce_dat <- function(dat, cols){ + dat[ , cols] +} + +message_fruit <- function(mini_dat){ + message("Found ", ncol(mini_dat), " fruits!") +} + +compute_avg <- function(mini_dat){ + rowMeans(mini_dat) +} + + +fruit_avg <- function(dat, pattern) { + cols <- find_cols(dat, pattern) + mini_dat <- reduce_dat(dat, cols) + message_fruit(mini_dat) + compute_avg(mini_dat) +} + + diff --git a/03_debugging_comfy.R b/03_debugging_comfy.R deleted file mode 100644 index 5fbfcd7..0000000 --- a/03_debugging_comfy.R +++ /dev/null @@ -1,10 +0,0 @@ -# Given this function, use `trace()` to add a `browser()` statement before the -# stop -# Hint: Use as.list(body(fun)) and [[c(1, 2, 3)]] to descend into the expression -# tree. -fun <- function() { - for (i in 1:10000) { - if (i == 9876) - stop("Ohno!") - } -} diff --git a/03_debugging_jim.R b/03_debugging_jim.R deleted file mode 100644 index d4f26a4..0000000 --- a/03_debugging_jim.R +++ /dev/null @@ -1,24 +0,0 @@ -# Given this function, use `trace()` to add a `browser()` statement before the -# stop -# Hint: Use as.list(body(fun)) and [[c(1, 2, 3)]] to descend into the expression -# tree. -fun <- function() { - for (i in 1:10000) { - if (i == 9876) - stop("Ohno!") - } -} - -x <- as.list(body(fun)) -x - -as.list(x[[2]]) - -as.list(x[[c(2, 4)]]) - -as.list(x[[c(2, 4, 2)]]) - -as.list(x[[c(2, 4, 2, 3)]]) - -trace(fun, browser, at = list(c(2, 4, 2, 3))) -fun() diff --git a/03_debugging_spartan.R b/03_debugging_spartan.R deleted file mode 100644 index 19213a0..0000000 --- a/03_debugging_spartan.R +++ /dev/null @@ -1,8 +0,0 @@ -# Given this function, use `trace()` to add a `browser()` statement before the -# stop -fun <- function() { - for (i in 1:10000) { - if (i == 9876) - stop("Ohno!") - } -} diff --git a/03_exercise/03_debugging_comfy.R b/03_exercise/03_debugging_comfy.R new file mode 100644 index 0000000..8ebd4dc --- /dev/null +++ b/03_exercise/03_debugging_comfy.R @@ -0,0 +1,86 @@ +# Origin ----------------------------------------------------------------------- +# This example was originally used inJenny Bryan's rstudio::conf(2020) keynote +# Object of type 'closure' is not subsettable, +# https://github.com/jennybc/debugging + +# Restart R! + +# install the wtfdbg package --------------------------------------------------- +# the content is essentially the same as 02_exercise, but now the code is no +# longer yours! +# install.packages("devtools") +devtools::install_github("rstats-wtf/wtfdbg") + + +# attach package --------------------------------------------------------------- + + +# view fruit data -------------------------------------------------------------- + +# successful execution --------------------------------------------------------- +# confirm function works for berry +fruit_avg(fruit, "berry") + +# error on execution ----------------------------------------------------------- +# observe error +fruit_avg(fruit, "peach") + +# identify location of error via traceback ------------------------------------- + + +# copy and paste traceback results as a comment here to compare with other exercises + + +# modify options for a richer traceback via rlang ------------------------------ + +# copy and paste traceback results as a comment here to compare with other exercises + + +# How do the tracebacks look different compared to 02_exercise? + + +# interactive debugging via debugonce() ---------------------------------------- +# set interactive debugger + +# trigger interactive debugger + + +# navigate the debugger using the buttons at the top of the console +# be sure to try the "step into" option! + +# while in the debugger, explore the objects in your environment +# with ls.str() + + +# interactive debugging via recover error option-------------------------------- +# options(? = ?) + +# trigger recover + +# explore the frames + +# reset options + + + +# interactive debugging via trace() -------------------------------------------- + +# investigate the function body with as.list() + body() + +# identify a function step to enter debugger + + +# insert browser statement at specified step + +# trigger trace + +# try ls.str() to get your bearings +# and s, s, s, to keep stepping through functions + +# cancel tracing + + +# Can you determine exactly why the bug is occurring? +# If you have time, try to fix it! + + diff --git a/03_exercise/03_debugging_solution.R b/03_exercise/03_debugging_solution.R new file mode 100644 index 0000000..0d9e0c6 --- /dev/null +++ b/03_exercise/03_debugging_solution.R @@ -0,0 +1,100 @@ +# Origin ----------------------------------------------------------------------- +# This example was originally used inJenny Bryan's rstudio::conf(2020) keynote +# Object of type 'closure' is not subsettable, +# https://github.com/jennybc/debugging + +# Restart R! + +# install the wtfdbg package --------------------------------------------------- +# the content is essentially the same as 02_exercise, but now the code is no +# longer yours! +# install.packages("devtools") +devtools::install_github("rstats-wtf/wtfdbg") + + +# attach package --------------------------------------------------------------- +library(wtfdbg) + +# view fruit data -------------------------------------------------------------- +fruit + +# successful execution --------------------------------------------------------- +# confirm function works for berry +fruit_avg(fruit, "berry") + +# error on execution ----------------------------------------------------------- +# observe error +fruit_avg(fruit, "peach") + +# identify location of error --------------------------------------------------- +traceback() + +# copy and paste traceback results as a comment here to compare with other exercises + + +# modify options for a richer traceback ---------------------------------------- +options(error = rlang::entrace) +fruit_avg(fruit, "peach") +rlang::last_error() +rlang::last_trace() + +# copy and paste traceback results as a comment here to compare with other exercises + +# How do the tracebacks look different compared to 02_exercise? + + +# interactive debugging via debugonce------------------------------------------- +# set interactive debugger +debugonce(fruit_avg) +# trigger interactive debugger +fruit_avg(fruit, "peach") + +# navigate the debugger using the buttons at the top of the console +# be sure to try the "step into" option! + +# while in the debugger, explore the objects in your environment +# with ls.str() + + +# interactive debugging via recover error option-------------------------------- +options(error = recover) + +# trigger recover +fruit_avg(fruit, "peach") +# explore the frames + +# reset options +options(error = NULL) + + + +# interactive debugging via trace ---------------------------------------------- + +# investigate the function body +x <- as.list(body(fruit_avg)) +View(x) + +# identify a function step to enter debugger +as.list(x[[5]][[1]]) +# equivalent notation +as.list(x[[c(5, 1)]]) + + +# insert browser statement at specified step +trace(fruit_avg, browser, at = list(c(5, 1))) + +# trigger trace +fruit_avg(fruit, "peach") + +# try ls.str() to get your bearings +# and s, s, s, to keep stepping through functions + +# cancel tracing +untrace(fruit_avg) + + +# Can you determine exactly why the bug is occurring? +# If you have time, try to fix it! + + + diff --git a/03_exercise/03_debugging_spartan.R b/03_exercise/03_debugging_spartan.R new file mode 100644 index 0000000..63d84a0 --- /dev/null +++ b/03_exercise/03_debugging_spartan.R @@ -0,0 +1,55 @@ +# Origin ----------------------------------------------------------------------- +# This example was originally used inJenny Bryan's rstudio::conf(2020) keynote +# Object of type 'closure' is not subsettable, +# https://github.com/jennybc/debugging + +# Restart R! + +# install the wtfdbg package --------------------------------------------------- +# the content is essentially the same as 02_exercise, but now the code is no +# longer yours! +# install.packages("devtools") +devtools::install_github("rstats-wtf/wtfdbg") + + +# attach package --------------------------------------------------------------- + + +# view fruit data -------------------------------------------------------------- + +# successful execution --------------------------------------------------------- +# confirm function works for berry +fruit_avg(fruit, "berry") + +# error on execution ----------------------------------------------------------- +# observe error +fruit_avg(fruit, "peach") + +# identify location of error --------------------------------------------------- + + +# copy and paste traceback results as a comment here to compare with other exercises + + +# modify options for a richer traceback ---------------------------------------- + +# copy and paste traceback results as a comment here to compare with other exercises + + +# How do the tracebacks look different compared to 02_exercise? + + +# interactive debugging via debugonce() ---------------------------------------- + + + +# interactive debugging via recover error option-------------------------------- + + + +# interactive debugging via trace() ---------------------------------------------- + + + +# Can you determine exactly why the bug is occurring? +# If you have time, try to fix it! diff --git a/README.md b/README.md new file mode 100644 index 0000000..6ffd534 --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +# Get started + +```r +usethis::use_course("rstats-wtf/wtf-debugging") +``` + +# Exercises + +* `01_exercise` practice debugging your own code + +* `02_exercise` practice debugging your own code with RStudio IDE features + +* `03_exercise` practice debugging others' code + +Choose your own adventure! + +* `0X_debugging_spartan.R` (directions to explore without suggested code) + +* `0X_debugging_comfy.R` (directions to explore with suggested code) + +* `0X_debugging_solution.R` (directions to explore with code solutions) + + +# Restart R + +Remember to restart R as indicated. In the RStudio IDE: + +* Session -> Restart R, or + +* Ctrl + Shift + F10 (Windows), + +* Cmd + Shift + 0 / Cmd + Shift + F10 (Mac) \ No newline at end of file diff --git a/planets.csv b/planets.csv deleted file mode 100644 index ef1a435..0000000 --- a/planets.csv +++ /dev/null @@ -1,11 +0,0 @@ -"name";"rotation_period";"orbital_period";"diameter";"climate";"gravity";"terrain";"surface_water";"population";"edited" -"Alderaan";"24";"364";"12500";"temperate";"1 standard";"grasslands, mountains";"40";"2000000000";"2014-12-20T20:58:18.420000Z" -"Yavin IV";"24";"4818";"10200";"temperate, tropical";"1 standard";"jungle, rainforests";"8";"1000";"2014-12-21T20:58:18.421000Z" -"Hoth";"23";"549";"7200";"frozen";"1.1 standard";"tundra, ice caves, mountain ranges";"100";"unknown";"2014-12-22T20:58:18.423000Z" -"Dagobah";"23";"341";"8900";"murky";"N/A";"swamp, jungles";"8";"unknown";"2014-12-23T20:58:18.425000Z" -"Bespin";"12";"5110";"118000";"temperate";"1.5 (surface), 1 standard (Cloud City)";"gas giant";"0";"6000000";"2014-12-24T20:58:18.427000Z" -"Endor";"18";"402";"4900";"temperate";"0.85 standard";"forests, mountains, lakes";"8";"30000000";"2014-12-25T20:58:18.429000Z" -"Naboo";"26";"312";"12120";"temperate";"1 standard";"grassy hills, swamps, forests, mountains";"12";"4500000000";"2014-12-26T20:58:18.430000Z" -"Coruscant";"24";"368";"12240";"temperate";"1 standard";"cityscape, mountains";"unknown";"1000000000000";"2014-12-27T20:58:18.432000Z" -"Kamino";"27";"463";"19720";"temperate";"1 standard";"ocean";"100";"1000000000";"2014-12-28T20:58:18.434000Z" -"Geonosis";"30";"256";"11370";"temperate, arid";"0.9 standard";"rock, desert, mountain, barren";"5";"100000000000";"2014-12-29T20:58:18.437000Z" diff --git a/shhh-secret-fixed-fruit_avg.R b/shhh-secret-fixed-fruit_avg.R new file mode 100644 index 0000000..d1bbc87 --- /dev/null +++ b/shhh-secret-fixed-fruit_avg.R @@ -0,0 +1,18 @@ +# source of error: +# +# when only one fruit is found, +# mini_dat <- dat[ , cols] +# returns a vector instead of a data frame +# +# e.g., fruit[, 1:2] vs fruit[, 1] +# +# this can be fixed with the drop argument +# fruit[, 1, drop = FALSE] + +# here is this fixed fruit_avg() +fruit_avg <- function(dat, pattern) { + cols <- grep(pattern, names(dat)) + mini_dat <- dat[ , cols, drop = FALSE] + message("Found ", ncol(mini_dat), " fruits!") + rowMeans(mini_dat) +}