diff --git a/.Rbuildignore b/.Rbuildignore index 1f5de73..93e63ee 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -29,3 +29,4 @@ vignettes/.httr-oauth$ ^vignettes/toc_close.css$ ^package_bundles/leanbuild_0.1.2.tar.gz* ^package_bundles/leanbuild_0.1.2.tgz* +inst/extdata/tmp/default* diff --git a/.gitignore b/.gitignore index 7f2dadd..08d9016 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,5 @@ tests/testthat/googlesheets_token.rds run_test.R /doc/ /Meta/ +.secrets +inst/extdata/tmp/default* \ No newline at end of file diff --git a/DESCRIPTION b/DESCRIPTION index 03ceed8..2d43b82 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,49 +1,50 @@ +Type: Package Package: ottrpal -Version: 1.1.1 Title: Companion Tools for Open-Source Tools for Training Resources (OTTR) -Description: Tools for converting Open-Source Tools for Training Resources (OTTR) - courses into Leanpub or Coursera courses. 'ottrpal' is for use with the OTTR Template repository to create courses. -Authors@R: c(person(given = "Candace",family = "Savonen", - email = "cansav09@gmail.com", - role = c("aut", "cre"), - comment = c(ORCID = "0000-0001-6331-7070")), - person(given = "John",family = "Muschelli", - email = "muschellij2@gmail.com", - role = c("aut"), - comment = c(ORCID = "0000-0001-6469-1750")), - person(given = "Carrie", family = "Wright", - email = "cwrigh60@jhu.edu", - role = c("ctb")) +Version: 1.1.1 +Authors@R: c( + person("Candace", "Savonen", , "cansav09@gmail.com", role = c("aut", "cre"), + comment = c(ORCID = "0000-0001-6331-7070")), + person("John", "Muschelli", , "muschellij2@gmail.com", role = "aut", + comment = c(ORCID = "0000-0001-6469-1750")), + person("Carrie", "Wright", , "cwrigh60@jhu.edu", role = "ctb") ) -Depends: R (>= 3.5.0) +Description: Tools for converting Open-Source Tools for Training Resources + (OTTR) courses into Leanpub or Coursera courses. 'ottrpal' is for use + with the OTTR Template repository to create courses. License: GPL-3 -Imports: dplyr, - httr, - fs, - rmarkdown (>= 2.10), - xml2, - rvest, - readr, - R.utils, +URL: https://github.com/jhudsl/ottrpal +BugReports: https://github.com/jhudsl/ottrpal/issues +Depends: + R (>= 3.5.0) +Imports: bookdown, - glue, curl, - rprojroot, + dplyr, + fs, + glue, + httr, + jsonlite, + knitr (>= 1.33), magrittr, - yaml, + openssl, + purrr, + R.utils, + readr, + rmarkdown (>= 2.10), + rprojroot, + rvest, stringr, - knitr (>= 1.33), - purrr + xml2, + yaml Suggests: remotes, testthat, tibble, utils +VignetteBuilder: + knitr +ByteCompile: true Encoding: UTF-8 LazyData: true -ByteCompile: true -Type: Package -VignetteBuilder: knitr -URL: https://github.com/jhudsl/ottrpal -BugReports: https://github.com/jhudsl/ottrpal/issues RoxygenNote: 7.2.3 diff --git a/NAMESPACE b/NAMESPACE index ba30c0c..68aaac3 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,6 +1,8 @@ # Generated by roxygen2: do not edit by hand export("%>%") +export(auth_from_secret) +export(authorize) export(bad_quiz_path) export(bookdown_destination) export(bookdown_file) @@ -19,15 +21,17 @@ export(convert_coursera_quizzes) export(convert_footnotes) export(convert_quiz) export(convert_utube_link) -export(download_gs_file) export(example_repo_cleanup) export(example_repo_setup) export(extract_meta) +export(extract_object_id) export(extract_quiz) export(get_bookdown_spec) export(get_chapters) +export(get_gs_pptx) export(get_image_from_slide) export(get_image_link_from_slide) +export(get_object_id_notes) export(get_slide_id) export(get_slide_page) export(good_quiz_path) @@ -40,6 +44,9 @@ export(make_embed_markdown) export(parse_q_tag) export(parse_quiz) export(parse_quiz_df) +export(pptx_notes) +export(pptx_slide_note_df) +export(pptx_slide_text_df) export(remove_yaml_header) export(render_without_toc) export(replace_html) @@ -47,7 +54,24 @@ export(replace_single_html) export(set_knitr_image_path) export(set_up_leanpub) export(simple_references) +export(unzip_pptx) +export(xml_notes) importFrom(fs,dir_copy) +importFrom(httr,GET) +importFrom(httr,accept_json) +importFrom(httr,config) +importFrom(httr,content) +importFrom(httr,oauth2.0_token) +importFrom(httr,oauth_app) +importFrom(httr,oauth_endpoints) +importFrom(jsonlite,fromJSON) importFrom(magrittr,"%>%") +importFrom(openssl,aes_cbc_decrypt) importFrom(readr,write_tsv) importFrom(utils,download.file) +importFrom(utils,installed.packages) +importFrom(utils,menu) +importFrom(utils,unzip) +importFrom(xml2,read_xml) +importFrom(xml2,xml_find_all) +importFrom(xml2,xml_text) diff --git a/R/aaa_utils.R b/R/aaa_utils.R index 67dab29..bbd5195 100644 --- a/R/aaa_utils.R +++ b/R/aaa_utils.R @@ -1,4 +1,3 @@ - utils::globalVariables(c( "num", "quiz_dir", "type_url", "file_name", "trimmed", "quiz", "quiz_path", "type", "q_num", "verbose", "chapt_title", "data_path", "image_dir" diff --git a/R/auth.R b/R/auth.R new file mode 100644 index 0000000..2b871ef --- /dev/null +++ b/R/auth.R @@ -0,0 +1,125 @@ +.tokenEnv <- new.env(parent = emptyenv()) +.tokenEnv$Token <- NULL + +# Set token to environment +set_token <- function(value) { + .tokenEnv$Token <- value + return(value) +} + +# Get token from environment +get_token <- function() { + .tokenEnv$Token +} + +### Declare all the scopes +scopes_list <- c( + "https://www.googleapis.com/auth/drive", + "https://www.googleapis.com/auth/drive.file", + "https://www.googleapis.com/auth/drive.readonly", + "https://www.googleapis.com/auth/presentations", + "https://www.googleapis.com/auth/presentations.readonly" +) + + +#' Authorize R package to access the Google Slides API +#' @description This is a function to authorize the R package to access the Google Slides API interactively. +#' @param token An output from \code{\link{oauth2.0_token}} to set as the authentication token. +#' @param cache Should the token be cached as an .httr-oauth file? +#' @param ... Additional arguments to send to \code{\link{oauth2.0_token}} +#' @return OAuth token saved to the environment so the package can use the users' Google data +#' @importFrom utils menu installed.packages +#' @importFrom httr oauth_app oauth_endpoints oauth2.0_token +#' @export +#' @examples \dontrun{ +#' +#' authorize() +#' } +authorize <- function(token = NULL, cache = FALSE, ...) { + if (!cache) { + cache_it <- menu(c("Yes store credentials as .httr-oauth file", "No do not store credentials, I will re-run this authorize() in my next R session")) + if (cache_it == 1) { + message("You chose to cache your credentials, if you change your mind, just delete the .httr-oauth. Be careful not to push this file to GitHub or share it anywhere.") + } + } else { + cache_it <- 1 + } + if (is.null(token)) { + token <- httr::oauth2.0_token( + endpoint = app_set_up()$endpoint, + app = app_set_up()$app, + cache = cache_it == 1, + scope = scopes_list, + ... + ) + } + set_token(token) + return(invisible(token)) +} + +#' Use secrets to authorize R package to access Google Slides API +#' @description This is a function to authorize the R package to access the Google Slides API. If no +#' client.id and client.secret is provided, the package would provide predefined values. +#' @param access_token Access token can be obtained from running authorize() interactively: token <-authorize(); token$credentials$access_token +#' @param refresh_token Refresh token can be obtained from running authorize() interactively: token <-authorize(); token$credentials$refresh_token +#' @return OAuth token saved to the environment so the package can use the users' Google data +#' @importFrom utils menu installed.packages +#' @importFrom httr oauth_app oauth_endpoints oauth2.0_token +#' @importFrom openssl aes_cbc_decrypt +#' @export +#' @examples \dontrun{ +#' +#' token <- authorize() +#' +#' auth_from_secret( +#' token$credentials$access_token, +#' token$credentials$refresh_token +#' ) +#' } +#' +auth_from_secret <- function(access_token = NULL, refresh_token = NULL) { + + # If no tokens are specified, we'll grab the default ones. + if (is.null(access_token) | is.null(refresh_token)) { + decrypted <- openssl::aes_cbc_decrypt( + readRDS(encrypt_creds_user_path()), + key = readRDS(key_encrypt_creds_path()) + ) + access_token <- unserialize(decrypted)[[1]]$access_token + refresh_token <- unserialize(decrypted)[[1]]$refresh_token + } + + credentials <- list( + access_token = access_token, + expires_in = 3599L, + refresh_token = refresh_token, + scope = scopes_list, + token_type = "Bearer" + ) + + token <- httr::oauth2.0_token( + endpoint = app_set_up()$endpoint, + app = app_set_up()$app, + scope = scopes_list, + credentials = credentials + ) + + set_token(token) + return(invisible(token)) +} + +# This sets up the app creds no matter which way authorization is called +app_set_up <- function() { + decrypted <- openssl::aes_cbc_decrypt( + readRDS(encrypt_creds_path()), + key = readRDS(key_encrypt_creds_path()) + ) + app <- httr::oauth_app( + appname = "ottrpal", + key = unserialize(decrypted)$client_id, + secret = unserialize(decrypted)$client_secret + ) + endpoint <- httr::oauth_endpoints("google") + + return(list(app = app, endpoint = endpoint)) +} diff --git a/R/bookdown_to_leanpub.R b/R/bookdown_to_leanpub.R index 6f35176..fbe9522 100644 --- a/R/bookdown_to_leanpub.R +++ b/R/bookdown_to_leanpub.R @@ -1,4 +1,3 @@ - #' Convert Bookdown to Leanpub #' #' @param path path to the bookdown book, must have a `_bookdown.yml` file @@ -162,10 +161,11 @@ bookdown_to_leanpub <- function(path = ".", #' @examples \dontrun{ #' #' ottrpal::bookdown_to_embed_leanpub( -#' base_url = "https://jhudatascience.org/OTTR_Template/", -#' make_book_txt = TRUE, -#' quiz_dir = NULL) -#'} +#' base_url = "https://jhudatascience.org/OTTR_Template/", +#' make_book_txt = TRUE, +#' quiz_dir = NULL +#' ) +#' } bookdown_to_embed_leanpub <- function(path = ".", chapt_img_key = NULL, bookdown_index = file.path(base_url, "index.html"), @@ -209,12 +209,11 @@ bookdown_to_embed_leanpub <- function(path = ".", bookdown_index = paste0(base_url, "index.html"), base_url = base_url ) %>% - dplyr::mutate(chapt_title = gsub("\\:|\\?|\\&|\\!|\\'", "", chapt_title)) + dplyr::mutate(chapt_title = gsub("\\:|\\?|\\&|\\!|\\'", "", chapt_title)) } # If there's no img_path supplied, then use a default image for each. if (!("img_path" %in% colnames(chapt_df))) { - # If no default image is supplied if (is.null(default_img)) { default_img <- "https://docs.google.com/presentation/d/1jEUxUY1qXDZ3DUtvTU6NCc6ASG5nx4Gwczv5aAglYX4/edit#slide=id.p" @@ -293,7 +292,6 @@ bookdown_to_book_txt <- function(path = ".", output_dir = "manuscript", quiz_dir = "quizzes", verbose = TRUE) { - # If md_files are not specified, then try to get them if (is.null(md_files)) { # Establish path @@ -435,7 +433,6 @@ make_embed_markdown <- function(url, #' get_chapters <- function(bookdown_index = file.path("docs", "index.html"), base_url = NULL) { - # Read in html index_html <- suppressWarnings(try(xml2::read_html(paste(bookdown_index, collapse = "\n")))) diff --git a/R/coursera.R b/R/coursera.R index 46b7669..df478e8 100644 --- a/R/coursera.R +++ b/R/coursera.R @@ -172,7 +172,6 @@ convert_quiz <- function(quiz_path, convert_coursera_quizzes <- function(input_quiz_dir = "quizzes", output_quiz_dir = "coursera_quizzes", verbose = TRUE) { - # Create directory if it is not yet created if (!dir.exists(output_quiz_dir)) { dir.create(output_quiz_dir, recursive = TRUE) @@ -221,10 +220,9 @@ render_without_toc <- function(output_dir = file.path("docs", "no_toc"), input_quiz_dir = "quizzes", output_quiz_dir = "coursera_quizzes", verbose = TRUE) { - # Find root directory by finding `_bookdown.yml` file root_dir <- bookdown_path() - + # Output files: output_dir <- file.path(root_dir, output_dir) @@ -297,12 +295,12 @@ render_without_toc <- function(output_dir = file.path("docs", "no_toc"), # Copy over css file(s) that's specified org_css_file <- output_yaml_lines$`bookdown::gitbook`$css - - # Check if there are multiple .css - if(length(org_css_file) > 1){ + + # Check if there are multiple .css + if (length(org_css_file) > 1) { # Read all .css css_files_read <- sapply(org_css_file, readLines) - + # Make a "mega .css" and write if (verbose) { message("Combining .css files") @@ -312,11 +310,11 @@ render_without_toc <- function(output_dir = file.path("docs", "no_toc"), writeLines(css_lines_cat, css_file) } else { css_file <- file.path(output_dir, org_css_file) - + # Write it as "style.css" fs::file_copy(org_css_file, - css_file, - overwrite = TRUE + css_file, + overwrite = TRUE ) } diff --git a/R/data.R b/R/data.R new file mode 100644 index 0000000..40c1c60 --- /dev/null +++ b/R/data.R @@ -0,0 +1,29 @@ + +#' Get file path to an key encryption RDS +key_encrypt_creds_path <- function() { + list.files( + pattern = "encrypt_pass.rds", + recursive = TRUE, + system.file("extdata", package = "ottrpal"), + full.names = TRUE + ) +} +#' Get file path to an encrypted credentials RDS +encrypt_creds_path <- function() { + list.files( + pattern = "encrypt.rds", + recursive = TRUE, + system.file("extdata", package = "ottrpal"), + full.names = TRUE + ) +} + +#' Get file path to an default credentials RDS +encrypt_creds_user_path <- function() { + list.files( + pattern = "encrypted_default_user_creds.rds", + recursive = TRUE, + system.file("extdata", package = "ottrpal"), + full.names = TRUE + ) +} diff --git a/R/example_data.R b/R/example_data.R index 4670e2c..1af693f 100644 --- a/R/example_data.R +++ b/R/example_data.R @@ -46,7 +46,7 @@ bad_quiz_path <- function() { #' #' # Run this to get the files we need #' example_files <- ottrpal::example_repo_setup() -#'} +#' } example_repo_setup <- function(dest_dir = tempdir()) { bookdown_path <- list.files( pattern = "_bookdown.yml$", diff --git a/R/footnotes.R b/R/footnotes.R index c54082a..d2701f4 100644 --- a/R/footnotes.R +++ b/R/footnotes.R @@ -7,14 +7,12 @@ #' @rdname footnotes #' convert_footnotes <- function(content) { - #### Find footnotes # For a vector of content read in, look for Bookdown-formatted footnotes and format them as Leanpub wants them start_footnote_indices <- grep("\\^\\[", content) # Don't bother if there are no footnotes if (length(start_footnote_indices) > 0) { - # Find the line which the footnote ends at end_footnote_indices <- sapply(start_footnote_indices, find_end_of_footnote, @@ -60,7 +58,6 @@ convert_footnotes <- function(content) { # Given an index of the start of a footnote, find the end of it. find_end_of_footnote <- function(start_footnote_index, content) { - # See if the end of the footnote is in the same line end_bracket <- grepl("\\]$", content[start_footnote_index]) diff --git a/R/gs_png.R b/R/gs_png.R index 4145533..9366c03 100644 --- a/R/gs_png.R +++ b/R/gs_png.R @@ -97,57 +97,7 @@ gs_png_download <- function(url, output_dir = ".", overwrite = TRUE) { include_slide <- function(url, output_dir = knitr::opts_chunk$get("fig.path"), overwrite = TRUE, ...) { + get_gs_pptx(url) outfile <- gs_png_download(url, output_dir, overwrite = overwrite) knitr::include_graphics(outfile, ...) } - -#' Download Google Slides File -#' -#' @param id Identifier of Google slides presentation, passed to -#' \code{\link{get_slide_id}} -#' @param out_type output type of file to download. Usually -#' `pdf` or `pptx` -#' -#' @note This downloads presentations if they are public and also try to make -#' sure it does not fail on large files -#' @return Downloaded file (in temporary directory) -#' @export -download_gs_file <- function(id, out_type = "pptx") { - id <- as.character(id) - id <- get_slide_id(id) - url <- type_url(id = id, page_id = NULL, type = out_type) - - tfile <- tempfile(fileext = paste0(".", out_type)) - result <- httr::GET(url, httr::write_disk(tfile)) - warn_them <- FALSE - fr_header <- result$headers$`x-frame-options` - if (!is.null(fr_header)) { - if (all(fr_header == "DENY")) { - warn_them <- TRUE - } - } - if (httr::status_code(result) >= 300) { - warn_them <- TRUE - } - # don't write something if not really a pptx - ctype <- result$headers$`content-type` - if (httr::status_code(result) >= 400 && - !is.null(ctype) && grepl("html", ctype)) { - file.remove(tfile) - } - if (grepl("ServiceLogin", result$url)) { - warn_them <- TRUE - } - # if (result$times["redirect"] > 0) { - # warn_them = TRUE - # } - if (warn_them) { - warning( - paste0( - "This presentation may not be available, ", - "did you turn link sharing on?" - ) - ) - } - tfile -} diff --git a/R/leanpub_checks.R b/R/leanpub_checks.R index 5959504..6f32e1a 100644 --- a/R/leanpub_checks.R +++ b/R/leanpub_checks.R @@ -1,4 +1,3 @@ - #' Check Leanpub Course or Book #' #' @param path path to the Leanpub book/course diff --git a/R/notes_to_fig_alt.R b/R/notes_to_fig_alt.R new file mode 100644 index 0000000..7640f8a --- /dev/null +++ b/R/notes_to_fig_alt.R @@ -0,0 +1,359 @@ +#' Download Google Slides pptx file +#' +#' @param id Identifier of Google slides presentation, passed to +#' \code{\link{get_slide_id}} +#' +#' @note This downloads presentations if they are public and also try to make +#' sure it does not fail on large files +#' @return Downloaded file (in temporary directory) +#' @export +get_gs_pptx <- function(id) { + id <- as.character(id) + pres_id <- get_slide_id(id) + url <- export_url(id = pres_id) + + pptx_file <- file.path(paste0(pres_id, ".pptx")) + + # Only download it if it isn't yet present + if (!file.exists(pptx_file)) { + result <- httr::GET(url, httr::write_disk(pptx_file)) + warn_them <- FALSE + fr_header <- result$headers$`x-frame-options` + if (!is.null(fr_header)) { + if (all(fr_header == "DENY")) { + warn_them <- TRUE + } + } + if (httr::status_code(result) >= 300) { + warn_them <- TRUE + } + # don't write something if not really a pptx + ctype <- result$headers$`content-type` + if (httr::status_code(result) >= 400 && + !is.null(ctype) && grepl("html", ctype)) { + file.remove(pptx_file) + } + if (grepl("ServiceLogin", result$url)) { + warn_them <- TRUE + } + if (warn_them) { + warning( + paste0( + "This presentation may not be available, ", + "did you turn link sharing on?" + ) + ) + } + } + pptx_file +} + + +export_url <- function(id, page_id = NULL, type = "pptx") { + url = paste0( + "https://docs.google.com/presentation/d/", + id, "/export/", type, "?id=", id) + if (!is.null(page_id)) { + url = paste0(url, "&pageid=", page_id) + } + url +} + +#' Get Notes from a PowerPoint (usually from Google Slides) +#' +#' @param file Character. Path for `PPTX` file +#' @param ... additional arguments to pass to \code{\link{xml_notes}}, +#' particularly \code{xpath} +#' +#' @return Either a character vector or `NULL` +#' @export +#' +#' @importFrom utils unzip +#' @examples +#' \dontrun{ +#' pptx_notes(ex_file) +#' pptx_slide_note_df(ex_file) +#' pptx_slide_text_df(ex_file) +#' } +pptx_notes <- function(file, ...) { + df <- pptx_slide_note_df(file, ...) + if (is.null(df)) { + return(NULL) + } + # factorize file names + fac <- basename(df$file) + fac <- factor(fac, levels = unique(fac)) + # split df by file names + # (notesSlide1.xml, notesSlide2.xml, ...) + ss <- split(df, fac) + # concatenate all notes in each slide + res <- sapply(ss, function(x) { + paste(x$text, collapse = " ") + }) + if (any(trimws(res) %in% "")) { + warning("Slides with no notes exists") + } + # if notes don't exist, put semicolon + res[res == ""] <- ";" + + res +} + +#' @export +#' @rdname pptx_notes +pptx_slide_text_df <- function(file, ...) { + L <- unzip_pptx(file) + slides <- L$slides + + if (length(slides) > 0) { + # in case empty notes + res <- lapply(slides, function(x) { + xx <- xml_notes(x, collapse_text = FALSE, ...) + if (length(xx) == 0) { + return(NULL) + } + snum <- sub("[.]xml", "", sub("slide", "", basename(x))) + snum <- as.numeric(snum) + data.frame( + file = x, + slide = snum, + text = xx, + index = 1:length(xx), + stringsAsFactors = FALSE + ) + }) + res <- do.call(rbind, res) + return(res) + } else { + return(NULL) + } +} + +#' @export +#' @rdname pptx_notes +pptx_slide_note_df <- function(file, ...) { + L <- unzip_pptx(file) + notes <- L$notes + slides <- L$slides + note_dir <- L$note_dir + + if (length(notes) > 0) { + # in case empty notes + assoc_notes <- sub("slide", "", basename(slides)) + assoc_notes <- paste0("notesSlide", assoc_notes) + assoc_notes <- file.path(note_dir, assoc_notes) + no_fe <- !file.exists(assoc_notes) + # if assoc_notes don't exist + if (any(no_fe)) { + file.create(assoc_notes[no_fe]) + notes <- assoc_notes + } + res <- lapply(notes, function(x) { + if (file.size(x) == 0) { + xx <- "" + } else { + xx <- xml_notes(x, collapse_text = FALSE, ...) + } + if (length(xx) == 0) { + xx <- "" + } + snum <- sub("[.]xml", "", sub("notesSlide", "", basename(x))) + snum <- as.numeric(snum) + data.frame( + file = x, + slide = snum, + text = xx, + index = 1:length(xx), + stringsAsFactors = FALSE + ) + }) + res <- do.call(rbind, res) + return(res) + } else { + return(NULL) + } +} + + +pptx_reorder_xml <- function(files) { + if (length(files) == 0) { + return(files) + } + nums <- basename(files) + # nums = gsub(pattern = paste0(pattern, "(\\d*)[.]xml"), + # replacement = "\\1", nums) + nums <- sub("[[:alpha:]]*(\\d.*)[.].*", "\\1", nums) + nums <- as.numeric(nums) + if (any(is.na(nums))) { + warning(paste0( + "Trying to parse set of files (example: ", files[1], + ") from PPTX, failed" + )) + return(files) + } + files[order(nums)] +} + +#' @export +#' @rdname pptx_notes +unzip_pptx <- function(file) { + # return a file path that can be used for temporary files + tdir <- tempfile() + # create tdir (temporary file path) + dir.create(tdir) + # extract file + unzip(file, exdir = tdir) + + # file path to xml files of slides + slide_dir <- file.path(tdir, "ppt", "slides") + slides <- list.files( + path = slide_dir, pattern = "[.]xml$", + full.names = TRUE + ) + # order xml files (slide1.xml, slide2.xml, ...) + slides <- pptx_reorder_xml(slides) + + # file path to xml files of notes + note_dir <- file.path(tdir, "ppt", "notesSlides") + notes <- list.files( + path = note_dir, pattern = "[.]xml$", + full.names = TRUE + ) + # order xml files (notesSlide1.xml, notesSlide2.xml, ...) + notes <- pptx_reorder_xml(notes) + + # create core.xml file path + tdir <- normalizePath(tdir) + props_dir <- file.path(tdir, "docProps") + props_file <- file.path(props_dir, "core.xml") + ari_core_file <- system.file("extdata", "docProps", + "core.xml", + package = "ariExtra" + ) + # copy core.xml from ariExtra to props_file + if (!dir.exists(props_file)) { + dir.create(props_dir, recursive = TRUE) + file.copy(ari_core_file, props_file, + overwrite = TRUE + ) + } + + L <- list( + slides = slides, + notes = notes, + slide_dir = slide_dir, + note_dir = note_dir, + props_dir = props_dir, + props_file = props_file, + root_dir = tdir + ) + return(L) +} + +#' Get Notes from XML +#' +#' @param file XML file from a PPTX +#' @param collapse_text should text be collapsed by spaces? +#' @param xpath \code{xpath} to pass to [xml2::xml_find_all()] +#' +#' @return A character vector +#' @export +#' +#' @importFrom xml2 read_xml xml_text xml_find_all +xml_notes <- function(file, collapse_text = TRUE, xpath = "//a:r//a:t") { + xdoc <- xml2::read_xml(file) + # probably need to a:p//a:t and collapse all text within a a:p + txt <- xml2::xml_find_all(x = xdoc, xpath = xpath) + txt <- xml2::xml_text(txt) + if (collapse_text) { + txt <- paste(txt, collapse = " ") + } + return(txt) +} + +#' Extract Object IDs using Google Slides API +#' +#' Performs a HTTP GET method to request the IDs of every slide in a Google +#' Slides presentation. The ID of the first slide is always 'p'. +#' +#' @param slide_url URL whose 'General access' is set to 'Anyone with the link' +#' @param token OAuth 2.0 Access Token. If you don't have a token, use +#' [authorize()] to obtain an access token from Google's OAuth 2.0 server. +#' @param access_token Access token can be obtained from running authorize() +#' interactively (token <-authorize(); token$credentials$access_token). This +#' allows it to be passed in using two secrets. +#' @param refresh_token Refresh token can be obtained from running authorize() +#' interactively (token <-authorize(); token$credentials$refresh_token). This +#' allows it to be passed in using two secrets. +#' @return Character vector of object ID(s) +#' @importFrom httr config +#' @importFrom httr GET +#' @importFrom httr accept_json +#' @importFrom httr content +#' @importFrom jsonlite fromJSON +#' @export +#' @examples +#' \dontrun{ +#' # First, obtain access token and store token for extract_object_id() to use +#' authorize(client_id = "MY_CLIENT_ID", client_secret = "MY_CLIENT_SECRET") +#' # Use stored token to talk to Google Slides API +#' extract_object_id(slide_url = "https://docs.google.com/presentation/d/1H5aF_ROKVxE-H +#' FHhoOy9vU2Y-y2M_PiV0q-JBL17Gss/edit?usp=sharing") +#' } +extract_object_id = function(slide_url, token = NULL, access_token = NULL, refresh_token = NULL) { + # Get Slide ID from URL + id <- get_slide_id(slide_url) + # Using Slide ID, create url that we'll send to GET + get_url <- gsub("{presentationId}", id, + "https://slides.googleapis.com/v1/presentations/{presentationId}", fixed=TRUE) + + # if token not provided, fetch token + if (is.null(token)) { + + token_try <- try(get_token(), silent = TRUE) + + # We will supply credentials if none can be grabbed by get_token() + if (is.null(token_try)) { + auth_from_secret(access_token = access_token, + refresh_token = refresh_token) + } + token <- get_token() + } # else user provides token + + # Perform GET HTTP request + config <- httr::config(token = token) + result <- httr::GET(get_url, config = config, httr::accept_json()) + # Read in result + result_content <- httr::content(result, "text") + result_list <- jsonlite::fromJSON(result_content) + + result_list$slides$objectId +} + +#' Retrieve Speaker Notes and their corresponding Object (Slide) IDs from a Google Slides presentation +#' +#' Google Slides API calls a presentation slide ID as an 'object ID'. +#' +#' @param slide_url URL whose 'General access' is set to 'Anyone with the link' +#' +#' @return Data frame of Object IDs and Speaker notes. +#' @export +#' +#' @examples +#' \dontrun{ +#' get_object_id_notes("https://docs.google.com/presentation/d/ +#' 1H5aF_ROKVxE-HFHhoOy9vU2Y-y2M_PiV0q-JBL17Gss/edit?usp=sharing") +#' } +get_object_id_notes <- function(slide_url) { + # page ids + object_ids <- extract_object_id(slide_url) + # download as pptx + pptx_file <- get_gs_pptx(slide_url) + # Extract speaker notes + speaker_notes <- pptx_notes(pptx_file) + # Get rid of filenames in name + names(speaker_notes) <- NULL + + data.frame(id = object_ids, notes = speaker_notes) +} + diff --git a/R/question_error_report.tsv b/R/question_error_report.tsv new file mode 100644 index 0000000..5136549 --- /dev/null +++ b/R/question_error_report.tsv @@ -0,0 +1,160 @@ +question_names quiz warning_msg related_index +Use this space to practice writing another, different example of a question that could be answered by data science. 01_forming_questions_01_data_science_process_quiz.md No incorrect answer options provided for Use this space to pr ... in quiz: 01_forming_questions_01_data_science_process_quiz.md 13 +Practice asking questions and write down a question you have about data science right now. Then send this question to someone who might be able to help. 01_forming_questions_02_types_of_questions_quiz.md No incorrect answer options provided for Practice asking ques ... in quiz: 01_forming_questions_02_types_of_questions_quiz.md 38 +Practice asking questions and write down another question you have about data science right now. Then send this question to someone who might be able to help. 01_forming_questions_03_how_to_learn_quiz.md No incorrect answer options provided for Practice asking ques ... in quiz: 01_forming_questions_03_how_to_learn_quiz.md 19 +Install [this lesson's swirl module](http://swirlstats.com/scn/DataTrail_01_Forming_Questions.html) with the following command in R: `swirl::install_course(""DataTrail_01_Forming_Questions"")` Use the `swirl()` function and navigate to the course: `DataTrail_01_Forming Questions`. Complete this swirl module on object assignment. Once complete, paste the code provided at the end of the swirl module here. 01_forming_questions_04_rstudio_cloud_tour_quiz.md Colon detected in question on lines: 71 in question starting with:Install [this lesson ... in quiz: 01_forming_questions_04_rstudio_cloud_tour_quiz.md 71 +Install [this lesson's swirl module](http://swirlstats.com/scn/DataTrail_01_Forming_Questions.html) with the following command in R: `swirl::install_course(""DataTrail_01_Forming_Questions"")` Use the `swirl()` function and navigate to the course: `DataTrail_01_Forming Questions`. Complete this swirl module on object assignment. Once complete, paste the code provided at the end of the swirl module here. 01_forming_questions_04_rstudio_cloud_tour_quiz.md No incorrect answer options provided for Install [this lesson ... in quiz: 01_forming_questions_04_rstudio_cloud_tour_quiz.md 70 +Suppose I enter the following code in R: `x <- 2`. What is the class of the `x` object? 02_getting_data_02_objects_quiz.md Colon detected in question on lines: 7 in question starting with:Suppose I enter the ... in quiz: 02_getting_data_02_objects_quiz.md 7 +Which function would you use to determine the class of the object 'x' generated from the code: `x <- 2` 02_getting_data_02_objects_quiz.md Colon detected in question on lines: 63 in question starting with:Which function would ... in quiz: 02_getting_data_02_objects_quiz.md 63 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_02_Getting_Data.html) with the following command in R: `swirl::install_course(""DataTrail_02_Getting_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_02_Getting_Data`. Then, navigate to the lesson `R Objects`. Complete this swirl module on object assignment. Once complete, paste the code provided at the end of the swirl module here. 02_getting_data_02_objects_quiz.md Colon detected in question on lines: 87 in question starting with:Install [this lesson ... in quiz: 02_getting_data_02_objects_quiz.md 87 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_02_Getting_Data.html) with the following command in R: `swirl::install_course(""DataTrail_02_Getting_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_02_Getting_Data`. Then, navigate to the lesson `R Objects`. Complete this swirl module on object assignment. Once complete, paste the code provided at the end of the swirl module here. 02_getting_data_02_objects_quiz.md No incorrect answer options provided for Install [this lesson ... in quiz: 02_getting_data_02_objects_quiz.md 86 +Which of the commands below will give the same result as `(iris$Sepal.Length == 5.0) | (iris$Sepal.Length == 5.1)`? 02_getting_data_03_logicals_quiz.md Colon detected in question on lines: 79 in question starting with:Which of the command ... in quiz: 02_getting_data_03_logicals_quiz.md 79 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_02_Getting_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_02_Getting_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_02_Getting_Data`. Then, navigate to the lesson `Working with Logicals`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 02_getting_data_03_logicals_quiz.md Colon detected in question on lines: 88 in question starting with:Install [this lesson ... in quiz: 02_getting_data_03_logicals_quiz.md 88 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_02_Getting_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_02_Getting_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_02_Getting_Data`. Then, navigate to the lesson `Working with Logicals`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 02_getting_data_03_logicals_quiz.md No incorrect answer options provided for Install [this lesson ... in quiz: 02_getting_data_03_logicals_quiz.md 87 +The following snapshot of the `iris` data frame shows the first six rows of the 5 column data frame. How can I extract the `Petal.Length` column as a simple vector (as opposed to a single column data frame)? 02_getting_data_04_dataframes_quiz.md Colon detected in question on lines: 8 in question starting with:The following snapsh ... in quiz: 02_getting_data_04_dataframes_quiz.md 8 +The following snapshot of the `iris` data frame shows the first six rows of the 5 column data frame. How can I extract the `Petal.Length` column as a simple vector (as opposed to a single column data frame)? 02_getting_data_04_dataframes_quiz.md Exclamation point detected in answer for: The following snapsh ... in quiz: 02_getting_data_04_dataframes_quiz.md 8 +The following snapshot of the `iris` data frame shows the first six rows of the 5 column data frame. How can I extract the `Sepal.Length` column as a simple vector (as opposed to a single column data frame)? 02_getting_data_04_dataframes_quiz.md Colon detected in question on lines: 31 in question starting with:The following snapsh ... in quiz: 02_getting_data_04_dataframes_quiz.md 31 +The following snapshot of the `iris` data frame shows the first six rows of the 5 column data frame. How can I extract the `Sepal.Length` column as a simple vector (as opposed to a single column data frame)? 02_getting_data_04_dataframes_quiz.md Exclamation point detected in answer for: The following snapsh ... in quiz: 02_getting_data_04_dataframes_quiz.md 31 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_02_Getting_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_02_Getting_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_02_Getting_Data`. Then, navigate to the lesson `Dataframes`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 02_getting_data_04_dataframes_quiz.md Colon detected in question on lines: 51 in question starting with:Install [this lesson ... in quiz: 02_getting_data_04_dataframes_quiz.md 51 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_02_Getting_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_02_Getting_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_02_Getting_Data`. Then, navigate to the lesson `Dataframes`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 02_getting_data_04_dataframes_quiz.md No incorrect answer options provided for Install [this lesson ... in quiz: 02_getting_data_04_dataframes_quiz.md 50 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_02_Getting_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_02_Getting_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_02_Getting_Data`. Then, navigate to the lesson `Basic Commands`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 02_getting_data_05_basic_commands_quiz.md Colon detected in question on lines: 107 in question starting with:Install [this lesson ... in quiz: 02_getting_data_05_basic_commands_quiz.md 107 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_02_Getting_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_02_Getting_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_02_Getting_Data`. Then, navigate to the lesson `Basic Commands`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 02_getting_data_05_basic_commands_quiz.md No incorrect answer options provided for Install [this lesson ... in quiz: 02_getting_data_05_basic_commands_quiz.md 106 +Which of the following R function and Terminal command pairs perform the same function? (Note: The R function is represented by `function()`, where the Terminal command does not have the parentheses `function`.) 02_getting_data_07_managing_files_quiz.md Colon detected in question on lines: 19 in question starting with:Which of the followi ... in quiz: 02_getting_data_07_managing_files_quiz.md 19 +Refer to the file system diagram below. The current working directory is `code`. Which of the following Terminal commands and/or R functions will move the `tidy_data1.R` file in the `raw_code` directory to the `final_code` directory? 02_getting_data_07_managing_files_quiz.md Colon detected in question on lines: 42 in question starting with:Refer to the file sy ... in quiz: 02_getting_data_07_managing_files_quiz.md 42 +Refer to the file system diagram below. The current working directory is `code`. Which of the following Terminal commands and/or R functions will move the `tidy_data1.R` file in the `raw_code` directory to the `final_code` directory? 02_getting_data_07_managing_files_quiz.md Exclamation point detected in answer for: Refer to the file sy ... in quiz: 02_getting_data_07_managing_files_quiz.md 42 +TRUE or FALSE: Files in your current working directory can only be listed from the Terminal (and not the R Console). 02_getting_data_07_managing_files_quiz.md Colon detected in question on lines: 56 in question starting with:TRUE or FALSE: Files ... in quiz: 02_getting_data_07_managing_files_quiz.md 56 +TRUE or FALSE: Files in your current working directory can only be listed from the R Console (and not the Terminal) 02_getting_data_07_managing_files_quiz.md Colon detected in question on lines: 61 in question starting with:TRUE or FALSE: Files ... in quiz: 02_getting_data_07_managing_files_quiz.md 61 +TRUE or FALSE: Files in your current working directory can be listed from both the Terminal and the R Console. 02_getting_data_07_managing_files_quiz.md Colon detected in question on lines: 66, 73 in question starting with:TRUE or FALSE: Files ... in quiz: 02_getting_data_07_managing_files_quiz.md NA +TRUE or FALSE: Files in your current working directory can be listed from both the Terminal and the R Console. 02_getting_data_07_managing_files_quiz.md Exclamation point detected in answer for: TRUE or FALSE: Files ... in quiz: 02_getting_data_07_managing_files_quiz.md 73 +Refer to the above diagram of a file system for this question. The current working directory is the `raw_code` directory. This directory contains 4 files: `tidy1.R`, `tidy2.R`, `trim1.R`, `trim2.R`. Which of the following commands will move only the `tidy1.R` and `tidy2.R` files out of this directory and into the `final_code` directory? 02_getting_data_07_managing_files_quiz.md Colon detected in question on lines: 168 in question starting with:Refer to the above d ... in quiz: 02_getting_data_07_managing_files_quiz.md 168 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_02_Getting_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_02_Getting_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_02_Getting_Data`. Then, navigate to the lesson `Managing Files`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 02_getting_data_07_managing_files_quiz.md Colon detected in question on lines: 184 in question starting with:Install [this lesson ... in quiz: 02_getting_data_07_managing_files_quiz.md 184 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_02_Getting_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_02_Getting_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_02_Getting_Data`. Then, navigate to the lesson `Managing Files`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 02_getting_data_07_managing_files_quiz.md No incorrect answer options provided for Install [this lesson ... in quiz: 02_getting_data_07_managing_files_quiz.md 183 +How would you install the package `forcats` (You can try this code on RStudio Cloud to verify!)? 02_getting_data_08_intro_to_packages_quiz.md Colon detected in question on lines: 13 in question starting with:How would you instal ... in quiz: 02_getting_data_08_intro_to_packages_quiz.md 13 +How would you install the package `forcats` (You can try this code on RStudio Cloud to verify!)? 02_getting_data_08_intro_to_packages_quiz.md Exclamation point detected in answer for: How would you instal ... in quiz: 02_getting_data_08_intro_to_packages_quiz.md 13 +`tuber` is a package on GitHub, written by the user 'soodoku'. How would you install the package `tuber` (You can try this code on RStudio Cloud to verify!)? 02_getting_data_08_intro_to_packages_quiz.md Colon detected in question on lines: 19, 20 in question starting with:`tuber` is a package ... in quiz: 02_getting_data_08_intro_to_packages_quiz.md NA +`tuber` is a package on GitHub, written by the user 'soodoku'. How would you install the package `tuber` (You can try this code on RStudio Cloud to verify!)? 02_getting_data_08_intro_to_packages_quiz.md Exclamation point detected in answer for: `tuber` is a package ... in quiz: 02_getting_data_08_intro_to_packages_quiz.md NA +Once `tuber` has been successfully installed, how would you make the functions in tuber available to you in RStudio? 02_getting_data_08_intro_to_packages_quiz.md Colon detected in question on lines: 33, 34, 41, 43 in question starting with:Once `tuber` has bee ... in quiz: 02_getting_data_08_intro_to_packages_quiz.md NA +Once `tuber` has been successfully installed, how would you make the functions in tuber available to you in RStudio? 02_getting_data_08_intro_to_packages_quiz.md Exclamation point detected in answer for: Once `tuber` has bee ... in quiz: 02_getting_data_08_intro_to_packages_quiz.md NA +Which of the following pieces of code would solve this error? 02_getting_data_08_intro_to_packages_quiz.md Colon detected in question on lines: 47, 49 in question starting with:Which of the followi ... in quiz: 02_getting_data_08_intro_to_packages_quiz.md NA +Which of the following pieces of code would solve this error? 02_getting_data_08_intro_to_packages_quiz.md Exclamation point detected in answer for: Which of the followi ... in quiz: 02_getting_data_08_intro_to_packages_quiz.md NA +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_02_Getting_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_02_Getting_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_02_Getting_Data`. Then, navigate to the lesson `R Packages`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 02_getting_data_08_intro_to_packages_quiz.md Colon detected in question on lines: 63 in question starting with:Install [this lesson ... in quiz: 02_getting_data_08_intro_to_packages_quiz.md 63 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_02_Getting_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_02_Getting_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_02_Getting_Data`. Then, navigate to the lesson `R Packages`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 02_getting_data_08_intro_to_packages_quiz.md No incorrect answer options provided for Install [this lesson ... in quiz: 02_getting_data_08_intro_to_packages_quiz.md 62 +Click on this link to open the [""R Markdown Cheatsheet""](https://posit.co/wp-content/uploads/2022/10/rmarkdown-1.pdf){target=""_blank""}, take a look at the ""Dynamic Documents"" section. Which type of file is NOT a possible output from an R Markdown document? 02_getting_data_09_Rmarkdowns_quiz.md Colon detected in question on lines: 57 in question starting with:Click on this link t ... in quiz: 02_getting_data_09_Rmarkdowns_quiz.md 57 +Click on this link to open the [""R Markdown Cheatsheet""](https://posit.co/wp-content/uploads/2022/10/rmarkdown-1.pdf){target=""_blank""}, take a look at the "".Rmd structure"" section. Which type of file is NOT a part of the typical Rmd structure? 02_getting_data_09_Rmarkdowns_quiz.md Colon detected in question on lines: 69 in question starting with:Click on this link t ... in quiz: 02_getting_data_09_Rmarkdowns_quiz.md 69 +Click on this link to open the [""R Markdown Cheatsheet""](https://posit.co/wp-content/uploads/2022/10/rmarkdown-1.pdf){target=""_blank""}, take a look at the ""Embed code with knitr syntax"" section. What option would you use to display code in the output document? 02_getting_data_09_Rmarkdowns_quiz.md Colon detected in question on lines: 79 in question starting with:Click on this link t ... in quiz: 02_getting_data_09_Rmarkdowns_quiz.md 79 +Click on this link to open the [""R Markdown Cheatsheet""](https://posit.co/wp-content/uploads/2022/10/rmarkdown-1.pdf){target=""_blank""}, take a look at the ""Embed code with knitr syntax"" section. What option would you use to run code in a code chunk? 02_getting_data_09_Rmarkdowns_quiz.md Colon detected in question on lines: 90 in question starting with:Click on this link t ... in quiz: 02_getting_data_09_Rmarkdowns_quiz.md 90 +TRUE or FALSE: Your computer knows that .r and .R files are the same type of file. 02_getting_data_10_datafiles_quiz.md Colon detected in question on lines: 35 in question starting with:TRUE or FALSE: Your ... in quiz: 02_getting_data_10_datafiles_quiz.md 35 +TRUE or FALSE: Your computer thinks that .r and .R files are two different types of file. 02_getting_data_10_datafiles_quiz.md Colon detected in question on lines: 40 in question starting with:TRUE or FALSE: Your ... in quiz: 02_getting_data_10_datafiles_quiz.md 40 +TRUE or FALSE: When reading in a file ""file.r"" into R, if you type ""file.R"", your code will know what file to read in. 02_getting_data_10_datafiles_quiz.md Colon detected in question on lines: 45 in question starting with:TRUE or FALSE: When ... in quiz: 02_getting_data_10_datafiles_quiz.md 45 +TRUE or FALSE: When reading in a file ""file.r"" into R, if you type ""file.R"", your code will *not* know what file to read in. 02_getting_data_10_datafiles_quiz.md Colon detected in question on lines: 50 in question starting with:TRUE or FALSE: When ... in quiz: 02_getting_data_10_datafiles_quiz.md 50 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_02_Getting_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_02_Getting_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_02_Getting_Data`. Then, navigate to the lesson `Data Files`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 02_getting_data_10_datafiles_quiz.md Colon detected in question on lines: 105 in question starting with:Install [this lesson ... in quiz: 02_getting_data_10_datafiles_quiz.md 105 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_02_Getting_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_02_Getting_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_02_Getting_Data`. Then, navigate to the lesson `Data Files`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 02_getting_data_10_datafiles_quiz.md No incorrect answer options provided for Install [this lesson ... in quiz: 02_getting_data_10_datafiles_quiz.md 104 +Please paste the link to the Google Sheet with your Leanpub data. (Reminder: This sheet should contain data collected from Leanpub. It should not contain any personal information.) 02_getting_data_13_google_sheets_quiz.md Colon detected in question on lines: 29 in question starting with:Please paste the lin ... in quiz: 02_getting_data_13_google_sheets_quiz.md 29 +Please paste the link to the Google Sheet with your Leanpub data. (Reminder: This sheet should contain data collected from Leanpub. It should not contain any personal information.) 02_getting_data_13_google_sheets_quiz.md No incorrect answer options provided for Please paste the lin ... in quiz: 02_getting_data_13_google_sheets_quiz.md 28 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_03_Cleaning_the_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_03_Cleaning_the_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_03_Cleaning_the_Data`. Then, navigate to the lesson `Reshaping Data`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 03_cleaning_data_02_reshapingdata_quiz.md Colon detected in question on lines: 36 in question starting with:Install [this lesson ... in quiz: 03_cleaning_data_02_reshapingdata_quiz.md 36 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_03_Cleaning_the_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_03_Cleaning_the_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_03_Cleaning_the_Data`. Then, navigate to the lesson `Reshaping Data`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 03_cleaning_data_02_reshapingdata_quiz.md No incorrect answer options provided for Install [this lesson ... in quiz: 03_cleaning_data_02_reshapingdata_quiz.md 35 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_03_Cleaning_the_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_03_Cleaning_the_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_03_Cleaning_the_Data`. Then, navigate to the lesson `Tidying Data`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 03_cleaning_data_03_tidyingdata_quiz.md Colon detected in question on lines: 126 in question starting with:Install [this lesson ... in quiz: 03_cleaning_data_03_tidyingdata_quiz.md 126 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_03_Cleaning_the_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_03_Cleaning_the_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_03_Cleaning_the_Data`. Then, navigate to the lesson `Tidying Data`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 03_cleaning_data_03_tidyingdata_quiz.md No incorrect answer options provided for Install [this lesson ... in quiz: 03_cleaning_data_03_tidyingdata_quiz.md 125 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_03_Cleaning_the_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_03_Cleaning_the_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_03_Cleaning_the_Data`. Then, navigate to the lesson `Joining Data`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 03_cleaning_data_04_joining_data_quiz.md Colon detected in question on lines: 21 in question starting with:Install [this lesson ... in quiz: 03_cleaning_data_04_joining_data_quiz.md 21 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_03_Cleaning_the_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_03_Cleaning_the_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_03_Cleaning_the_Data`. Then, navigate to the lesson `Joining Data`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 03_cleaning_data_04_joining_data_quiz.md No incorrect answer options provided for Install [this lesson ... in quiz: 03_cleaning_data_04_joining_data_quiz.md 20 +Using, str_view_all(), how would you only highlight strings that start with a vowel? 03_cleaning_data_05_working_with_strings_quiz.md No incorrect answer options provided for Using, str_view_all( ... in quiz: 03_cleaning_data_05_working_with_strings_quiz.md 98 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_03_Cleaning_the_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_03_Cleaning_the_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_03_Cleaning_the_Data`. Then, navigate to the lesson `Working with Strings`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 03_cleaning_data_05_working_with_strings_quiz.md Colon detected in question on lines: 105 in question starting with:Install [this lesson ... in quiz: 03_cleaning_data_05_working_with_strings_quiz.md 105 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_03_Cleaning_the_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_03_Cleaning_the_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_03_Cleaning_the_Data`. Then, navigate to the lesson `Working with Strings`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 03_cleaning_data_05_working_with_strings_quiz.md No incorrect answer options provided for Install [this lesson ... in quiz: 03_cleaning_data_05_working_with_strings_quiz.md 104 +Assuming you have a dataframe (`df`) with two columns: `car`, and `size`, what would the code `df %>% fct_reorder(car, size)` accomplish? 03_cleaning_data_06_working_with_factors_quiz.md Colon detected in question on lines: 25 in question starting with:Assuming you have a ... in quiz: 03_cleaning_data_06_working_with_factors_quiz.md 25 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_03_Cleaning_the_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_03_Cleaning_the_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_03_Cleaning_the_Data`. Then, navigate to the lesson `Working with Factors`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 03_cleaning_data_06_working_with_factors_quiz.md Colon detected in question on lines: 47 in question starting with:Install [this lesson ... in quiz: 03_cleaning_data_06_working_with_factors_quiz.md 47 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_03_Cleaning_the_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_03_Cleaning_the_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_03_Cleaning_the_Data`. Then, navigate to the lesson `Working with Factors`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 03_cleaning_data_06_working_with_factors_quiz.md No incorrect answer options provided for Install [this lesson ... in quiz: 03_cleaning_data_06_working_with_factors_quiz.md 46 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_03_Cleaning_the_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_03_Cleaning_the_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_03_Cleaning_the_Data`. Then, navigate to the lesson `Working with Dates`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 03_cleaning_data_07_working_with_dates_quiz.md Colon detected in question on lines: 88 in question starting with:Install [this lesson ... in quiz: 03_cleaning_data_07_working_with_dates_quiz.md 88 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_03_Cleaning_the_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_03_Cleaning_the_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_03_Cleaning_the_Data`. Then, navigate to the lesson `Working with Dates`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 03_cleaning_data_07_working_with_dates_quiz.md No incorrect answer options provided for Install [this lesson ... in quiz: 03_cleaning_data_07_working_with_dates_quiz.md 87 +If you were to run the following code, what color would the points be?: `ggplot(data = diamonds, aes(x = carat, y = price, color = ""blue"")) + geom_point()` 04_plot_the_data_02_ggplot2_quiz.md Colon detected in question on lines: 64 in question starting with:If you were to run t ... in quiz: 04_plot_the_data_02_ggplot2_quiz.md 64 +If you were to run the following code, what color would the points be?: `ggplot(data = diamonds, aes(x = carat, y = price), color = ""blue"") + geom_point()` 04_plot_the_data_02_ggplot2_quiz.md Colon detected in question on lines: 75 in question starting with:If you were to run t ... in quiz: 04_plot_the_data_02_ggplot2_quiz.md 75 +If you were to run the following code, what color would the points be?: `ggplot(data = diamonds, aes(x = carat, y = price)) + geom_point(color = ""blue"")` 04_plot_the_data_02_ggplot2_quiz.md Colon detected in question on lines: 86 in question starting with:If you were to run t ... in quiz: 04_plot_the_data_02_ggplot2_quiz.md 86 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_04_Plot_the_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_04_Plot_the_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_04_Plot_the_Data`. Then, navigate to the lesson `Intro to ggplot2`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 04_plot_the_data_02_ggplot2_quiz.md Colon detected in question on lines: 113 in question starting with:Install [this lesson ... in quiz: 04_plot_the_data_02_ggplot2_quiz.md 113 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_04_Plot_the_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_04_Plot_the_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_04_Plot_the_Data`. Then, navigate to the lesson `Intro to ggplot2`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 04_plot_the_data_02_ggplot2_quiz.md No incorrect answer options provided for Install [this lesson ... in quiz: 04_plot_the_data_02_ggplot2_quiz.md 112 +Explore the `ggthemes` package by clicking on [this link](https://mran.microsoft.com/snapshot/2016-12-03/web/packages/ggthemes/vignettes/ggthemes.html){target=""_blank""}), which theme is based on the scales and colors used at [www.fivethirtyeight.com](www.fivethirtyeight.com){target=""_blank""}. 04_plot_the_data_03_customization_quiz.md Colon detected in question on lines: 62 in question starting with:Explore the `ggtheme ... in quiz: 04_plot_the_data_03_customization_quiz.md 62 +Explore the `ggthemes` package by clicking on [this link](https://mran.microsoft.com/snapshot/2016-12-03/web/packages/ggthemes/vignettes/ggthemes.html){target=""_blank""}), which theme is based on the scales and colors used at Google Docs. 04_plot_the_data_03_customization_quiz.md Colon detected in question on lines: 75 in question starting with:Explore the `ggtheme ... in quiz: 04_plot_the_data_03_customization_quiz.md 75 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_04_Plot_the_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_04_Plot_the_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_04_Plot_the_Data`. Then, navigate to the lesson `Customization in ggplot2`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 04_plot_the_data_03_customization_quiz.md Colon detected in question on lines: 110 in question starting with:Install [this lesson ... in quiz: 04_plot_the_data_03_customization_quiz.md 110 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_04_Plot_the_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_04_Plot_the_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_04_Plot_the_Data`. Then, navigate to the lesson `Customization in ggplot2`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 04_plot_the_data_03_customization_quiz.md No incorrect answer options provided for Install [this lesson ... in quiz: 04_plot_the_data_03_customization_quiz.md 109 +To add a caption to a plot, what would you use? (Note: this isn't discussed in this lecture. It may require Googling for the answer.) 04_plot_the_data_05_exploratory_to_explanatory_quiz.md Colon detected in question on lines: 60 in question starting with:To add a caption to ... in quiz: 04_plot_the_data_05_exploratory_to_explanatory_quiz.md 60 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_04_Plot_the_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_04_Plot_the_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_04_Plot_the_Data`. Then, navigate to the lesson `Tables in R`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 04_plot_the_data_07_tables_in_R_quiz.md Colon detected in question on lines: 51 in question starting with:Install [this lesson ... in quiz: 04_plot_the_data_07_tables_in_R_quiz.md 51 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_04_Plot_the_Data.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_04_Plot_the_Data"")`. Use the `swirl()` function and navigate to the course: `DataTrail_04_Plot_the_Data`. Then, navigate to the lesson `Tables in R`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 04_plot_the_data_07_tables_in_R_quiz.md No incorrect answer options provided for Install [this lesson ... in quiz: 04_plot_the_data_07_tables_in_R_quiz.md 50 +How many plots would have `ggplot2` theme `theme_bw()` w/ this code: `((p1 + p2 + p3) + plot_layout(ncol = 1)) * theme_bw() + p4`? 04_plot_the_data_08_multiple_plots_quiz.md Colon detected in question on lines: 32 in question starting with:How many plots would ... in quiz: 04_plot_the_data_08_multiple_plots_quiz.md 32 +How many plots would have the default `ggplot2` theme `theme_gray()` w/ this code: `((p1 + p2 + p3) + plot_layout(ncol = 1)) * theme_bw() + p4`? 04_plot_the_data_08_multiple_plots_quiz.md Colon detected in question on lines: 41 in question starting with:How many plots would ... in quiz: 04_plot_the_data_08_multiple_plots_quiz.md 41 +What kind of data is the following: Data that is collected from the same sample of the population at multiple points in time. 05_get_stats_02_identifying_data_quiz.md Colon detected in question on lines: 15 in question starting with:What kind of data is ... in quiz: 05_get_stats_02_identifying_data_quiz.md 15 +Which of the following is a representative sample? 05_get_stats_02_identifying_data_quiz.md Colon detected in question on lines: 66, 67, 68, 69, 70, 71 in question starting with:Which of the followi ... in quiz: 05_get_stats_02_identifying_data_quiz.md NA +Which of the following is a representative sample? 05_get_stats_02_identifying_data_quiz.md Exclamation point detected in answer for: Which of the followi ... in quiz: 05_get_stats_02_identifying_data_quiz.md NA +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_05_Get_Stats.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_05_Get_Stats"")`. Use the `swirl()` function and navigate to the course: `DataTrail_05_Get_Stats`. Then, navigate to the lesson `Descriptive Analysis`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 05_get_stats_04_descriptive_quiz.md Colon detected in question on lines: 58 in question starting with:Install [this lesson ... in quiz: 05_get_stats_04_descriptive_quiz.md 58 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_05_Get_Stats.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_05_Get_Stats"")`. Use the `swirl()` function and navigate to the course: `DataTrail_05_Get_Stats`. Then, navigate to the lesson `Descriptive Analysis`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 05_get_stats_04_descriptive_quiz.md No incorrect answer options provided for Install [this lesson ... in quiz: 05_get_stats_04_descriptive_quiz.md 57 +In the [dataset](https://www.kaggle.com/heesoo37/120-years-of-olympic-history-athletes-and-results) used in this lesson, what is the number of missing values in the variable `Height`? 05_get_stats_05_exploratory_quiz.md Colon detected in question on lines: 36 in question starting with:In the [dataset](htt ... in quiz: 05_get_stats_05_exploratory_quiz.md 36 +In the [dataset](https://www.kaggle.com/heesoo37/120-years-of-olympic-history-athletes-and-results) used in this lesson, what is the weight of the heaviest athlete? 05_get_stats_05_exploratory_quiz.md Colon detected in question on lines: 45 in question starting with:In the [dataset](htt ... in quiz: 05_get_stats_05_exploratory_quiz.md 45 +In the [dataset](https://www.kaggle.com/heesoo37/120-years-of-olympic-history-athletes-and-results) used in this lesson, what is the height of the tallest athlete? 05_get_stats_05_exploratory_quiz.md Colon detected in question on lines: 55 in question starting with:In the [dataset](htt ... in quiz: 05_get_stats_05_exploratory_quiz.md 55 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_05_Get_Stats.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_05_Get_Stats"")`. Use the `swirl()` function and navigate to the course: `DataTrail_05_Get_Stats`. Then, navigate to the lesson `Exploratory Analysis`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 05_get_stats_05_exploratory_quiz.md Colon detected in question on lines: 84 in question starting with:Install [this lesson ... in quiz: 05_get_stats_05_exploratory_quiz.md 84 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_05_Get_Stats.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_05_Get_Stats"")`. Use the `swirl()` function and navigate to the course: `DataTrail_05_Get_Stats`. Then, navigate to the lesson `Exploratory Analysis`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 05_get_stats_05_exploratory_quiz.md No incorrect answer options provided for Install [this lesson ... in quiz: 05_get_stats_05_exploratory_quiz.md 83 +Given the model: `fit <- lm(Sepal.Length ~ Sepal.Width, data = iris)` (meaning, go run that code), how much would you expect sepal length to change given a one unit increase in sepal width? 05_get_stats_07_regression_quiz.md Colon detected in question on lines: 27 in question starting with:Given the model: `fi ... in quiz: 05_get_stats_07_regression_quiz.md 27 +If your beta coefficient for a model that looked at the relationship between height and weight (for example: `lm(height ~ weight)`) were 0.2, what would that mean? 05_get_stats_07_regression_quiz.md Colon detected in question on lines: 38 in question starting with:If your beta coeffic ... in quiz: 05_get_stats_07_regression_quiz.md 38 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_05_Get_Stats.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_05_Get_Stats"")`. Use the `swirl()` function and navigate to the course: `DataTrail_05_Get_Stats`. Then, navigate to the lesson `Linear Regression`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 05_get_stats_07_regression_quiz.md Colon detected in question on lines: 49 in question starting with:Install [this lesson ... in quiz: 05_get_stats_07_regression_quiz.md 49 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_05_Get_Stats.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_05_Get_Stats"")`. Use the `swirl()` function and navigate to the course: `DataTrail_05_Get_Stats`. Then, navigate to the lesson `Linear Regression`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 05_get_stats_07_regression_quiz.md No incorrect answer options provided for Install [this lesson ... in quiz: 05_get_stats_07_regression_quiz.md 48 +This code would run which of the following analyses: `lm(weight ~ height, data = df)` 05_get_stats_09_multiple_regression_quiz.md Colon detected in question on lines: 15 in question starting with:This code would run ... in quiz: 05_get_stats_09_multiple_regression_quiz.md 15 +This code would run which of the following analyses: `lm(weight ~ height + sex, data = df)` 05_get_stats_09_multiple_regression_quiz.md Colon detected in question on lines: 34 in question starting with:This code would run ... in quiz: 05_get_stats_09_multiple_regression_quiz.md 34 +Using information in [the `caret` book](http://topepo.github.io/caret/index.html), if you wanted to use a tree-based model for prediction, which `method` could you specify? 05_get_stats_10_prediction_ml_quiz.md Colon detected in question on lines: 27 in question starting with:Using information in ... in quiz: 05_get_stats_10_prediction_ml_quiz.md 27 +Take a look at the analysis done [here](https://rstudio-pubs-static.s3.amazonaws.com/261616_3097bfd3aa4341faafede5ed2ca7bb39.html). Of the models they tried, which was most accurate for predicting Species in the `iris` dataset? 05_get_stats_10_prediction_ml_quiz.md Colon detected in question on lines: 39 in question starting with:Take a look at the a ... in quiz: 05_get_stats_10_prediction_ml_quiz.md 39 +Which code below is the DRY-ier version? 06_report_results_01_reproducibility_quiz.md Colon detected in question on lines: 33, 40 in question starting with:Which code below is ... in quiz: 06_report_results_01_reproducibility_quiz.md NA +Which code below is the DRY-ier version? 06_report_results_01_reproducibility_quiz.md Colon detected in question on lines: 52, 55, 59 in question starting with:Which code below is ... in quiz: 06_report_results_01_reproducibility_quiz.md NA +Which code below is the DRY-ier version? 06_report_results_01_reproducibility_quiz.md Colon detected in question on lines: 69, 73 in question starting with:Which code below is ... in quiz: 06_report_results_01_reproducibility_quiz.md NA +Which chunk of code appears to better adhere to a style? 06_report_results_01_reproducibility_quiz.md Colon detected in question on lines: 109, 111, 113, 115 in question starting with:Which chunk of code ... in quiz: 06_report_results_01_reproducibility_quiz.md NA +Which chunk of code appears to better adhere to a style? 06_report_results_01_reproducibility_quiz.md Colon detected in question on lines: 123, 128 in question starting with:Which chunk of code ... in quiz: 06_report_results_01_reproducibility_quiz.md NA +Fill in the blanks: I'm done editing a file, I need to \_\_\_\_ those changes then \_\_\_\_ them, and \_\_\_\_ it to the \_\_\_\_? 06_report_results_02_version_control_quiz.md Colon detected in question on lines: 26 in question starting with:Fill in the blanks: ... in quiz: 06_report_results_02_version_control_quiz.md 26 +On each repository page, in the top right hand corner there are three options. They are: 06_report_results_03_github_quiz.md Colon detected in question on lines: 16 in question starting with:On each repository p ... in quiz: 06_report_results_03_github_quiz.md 16 +Fill in the blank: I will have a GitHub repository for each ________. 06_report_results_04_creating_repos_quiz.md Colon detected in question on lines: 15 in question starting with:Fill in the blank: I ... in quiz: 06_report_results_04_creating_repos_quiz.md 15 +To make a new repository, which can you **not** do? (Note: To figure out the answer to this question, you may have to play around on GitHub a bit.) 06_report_results_04_creating_repos_quiz.md Colon detected in question on lines: 27 in question starting with:To make a new reposi ... in quiz: 06_report_results_04_creating_repos_quiz.md 27 +Read through the [GitHub Guide](https://guides.github.com/activities/hello-world/). What is a **pull request**? 06_report_results_04_creating_repos_quiz.md Colon detected in question on lines: 37 in question starting with:Read through the [Gi ... in quiz: 06_report_results_04_creating_repos_quiz.md 37 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_06_Share_Results.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_06_Share_Results"")`. Use the `swirl()` function and navigate to the course: `DataTrail_06_Share_Results`. Then, navigate to the lesson `GitHub Creds`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 06_report_results_05_cloning_repos_quiz.md Colon detected in question on lines: 28 in question starting with:Install [this lesson ... in quiz: 06_report_results_05_cloning_repos_quiz.md 28 +Install [this lesson's swirl course](http://swirlstats.com/scn/DataTrail_06_Share_Results.html) (if you have not yet) with the following command in R: `swirl::install_course(""DataTrail_06_Share_Results"")`. Use the `swirl()` function and navigate to the course: `DataTrail_06_Share_Results`. Then, navigate to the lesson `GitHub Creds`. Complete this swirl module. Once complete, paste the code provided at the end of the swirl module here. 06_report_results_05_cloning_repos_quiz.md No incorrect answer options provided for Install [this lesson ... in quiz: 06_report_results_05_cloning_repos_quiz.md 27 +Search the web and assess whether the following statement is TRUE or FALSE: Any user regardless of whether they are contributors to a *public* repository or not can create an issue for the repository. 06_report_results_07_issues_quiz.md Colon detected in question on lines: 14 in question starting with:Search the web and a ... in quiz: 06_report_results_07_issues_quiz.md 14 +Search the web and assess whether the following statement is TRUE or FALSE: Any user regardless of whether they are contributors to a *private* repository or not can create an issue for the repository. 06_report_results_07_issues_quiz.md Colon detected in question on lines: 19 in question starting with:Search the web and a ... in quiz: 06_report_results_07_issues_quiz.md 19 +Search the web and assess whether the following statement is TRUE or FALSE: Any GitHub user can submit an issue to a *public* repository. 06_report_results_07_issues_quiz.md Colon detected in question on lines: 24 in question starting with:Search the web and a ... in quiz: 06_report_results_07_issues_quiz.md 24 +What git command will you want to run if you realize you want to change the message on your last commit (Hint: This has not been directly discussed in this lesson. You'll need to Google to determine the answer!)? 06_report_results_10_git_help_quiz.md Colon detected in question on lines: 27 in question starting with:What git command wil ... in quiz: 06_report_results_10_git_help_quiz.md 27 +Please paste the link to the Google Slide presentation you created below. (Reminder: This link should only contain information about the Leanpub book prices project you completed. It should not contain any personal information.) 06_report_results_13_slides_quiz.md Colon detected in question on lines: 19 in question starting with:Please paste the lin ... in quiz: 06_report_results_13_slides_quiz.md 19 +Please paste the link to the Google Slide presentation you created below. (Reminder: This link should only contain information about the Leanpub book prices project you completed. It should not contain any personal information.) 06_report_results_13_slides_quiz.md No incorrect answer options provided for Please paste the lin ... in quiz: 06_report_results_13_slides_quiz.md 18 +TRUE or FALSE: The best presentations are off the cuff and unpracticed. 06_report_results_14_presentations_quiz.md Colon detected in question on lines: 50 in question starting with:TRUE or FALSE: The b ... in quiz: 06_report_results_14_presentations_quiz.md 50 +TRUE or FALSE: The best presentations have been practiced beforehand. 06_report_results_14_presentations_quiz.md Colon detected in question on lines: 55 in question starting with:TRUE or FALSE: The b ... in quiz: 06_report_results_14_presentations_quiz.md 55 +TRUE or FALSE: you can connect your Chromebook directly to most projectors 06_report_results_15_projecting_quiz.md Colon detected in question on lines: 4 in question starting with:TRUE or FALSE: you c ... in quiz: 06_report_results_15_projecting_quiz.md 4 +On the general audience presentation slides (found [here](http://bit.ly/general_audience)){target=""_blank""}, on slide 134, which of these is one of the terms on this outline slide? 06_report_results_16_general_quiz.md Colon detected in question on lines: 5 in question starting with:On the general audie ... in quiz: 06_report_results_16_general_quiz.md 5 +On the technical audience presentation slides (found [here](http://bit.ly/technical_audience)){target=""_blank""}, on slide 146, what color was used for the comparison ""NC vs. PC""? 06_report_results_17_technical_quiz.md Colon detected in question on lines: 5 in question starting with:On the technical aud ... in quiz: 06_report_results_17_technical_quiz.md 5 +Go to Google Slides and develop a presentation that you would present to a technical audience about your Final Project from the last course in this course series. Be sure your slides tell a story, that the number of words on each slide is limited, and that the figures use good colors and text size for presentation. **Paste the viewable link to your slides below**. 06_report_results_17_technical_quiz.md No incorrect answer options provided for Go to Google Slides ... in quiz: 06_report_results_17_technical_quiz.md 40 +TRUE or FALSE: Examples should not be included in blog posts. 06_report_results_18_blogpost_quiz.md Colon detected in question on lines: 29 in question starting with:TRUE or FALSE: Examp ... in quiz: 06_report_results_18_blogpost_quiz.md 29 +TRUE or FALSE: It's a good idea to include examples in blot posts. 06_report_results_18_blogpost_quiz.md Colon detected in question on lines: 34 in question starting with:TRUE or FALSE: It's ... in quiz: 06_report_results_18_blogpost_quiz.md 34 +TRUE or FALSE: One goal of an announcement blog post is to announce a resource. 06_report_results_18_blogpost_quiz.md Colon detected in question on lines: 39 in question starting with:TRUE or FALSE: One g ... in quiz: 06_report_results_18_blogpost_quiz.md 39 +TRUE or FALSE: One goal of an announcement blog post is to announce a tool. 06_report_results_18_blogpost_quiz.md Colon detected in question on lines: 44 in question starting with:TRUE or FALSE: One g ... in quiz: 06_report_results_18_blogpost_quiz.md 44 +Consider the following scenario: You've carried out an analysis and presented the results to your collaborator. They are not happy with what you've found and argue that you've got to re-do your analysis until you find what they were expecting. **What should you do?** 06_report_results_20_one_on_one_quiz.md Colon detected in question on lines: 6 in question starting with:Consider the followi ... in quiz: 06_report_results_20_one_on_one_quiz.md 6 +Consider the following scenario: After your follow-up meeting, your collaborator sends an email to your bosses misinterpreting the results of your analysis. **What should you do?** 06_report_results_20_one_on_one_quiz.md Colon detected in question on lines: 17 in question starting with:Consider the followi ... in quiz: 06_report_results_20_one_on_one_quiz.md 17 +Consider the following scenario: In the initial meeting, you discussed data that you expected to have in a month. In two months, your collaborator returns and informs you that they lost funding and will no longer be getting that data. **What should you do?** 06_report_results_20_one_on_one_quiz.md Colon detected in question on lines: 40 in question starting with:Consider the followi ... in quiz: 06_report_results_20_one_on_one_quiz.md 40 +Fill in the blank: The typical resume is \_\_\_\_\_\_\_\_ page(s) long. If I feel I have too much information to fit in this length, I should \_\_\_\_\_\_\_\_\_\_\_\_. 07_build_a_resume_01_resume_quiz.md Colon detected in question on lines: 5 in question starting with:Fill in the blank: T ... in quiz: 07_build_a_resume_01_resume_quiz.md 5 +TRUE/FALSE: Full sentences should always be used on resumes. Bullet points are unprofessional and should be avoided 07_build_a_resume_01_resume_quiz.md Colon detected in question on lines: 51 in question starting with:TRUE/FALSE: Full sen ... in quiz: 07_build_a_resume_01_resume_quiz.md 51 +TRUE/FALSE: No text on your resume should be bold or underlined. 07_build_a_resume_01_resume_quiz.md Colon detected in question on lines: 56 in question starting with:TRUE/FALSE: No text ... in quiz: 07_build_a_resume_01_resume_quiz.md 56 +TRUE/FALSE: Everything on your resume should be absolutely true. 07_build_a_resume_01_resume_quiz.md Colon detected in question on lines: 61 in question starting with:TRUE/FALSE: Everythi ... in quiz: 07_build_a_resume_01_resume_quiz.md 61 +Which of the following is **not** a word or phrase to avoid using in a cover letter? (Note: Read the information in [this link](https://www.glassdoor.com/blog/cover-letter-words/) before answering this question.) 07_build_a_resume_02_coverletter_quiz.md Colon detected in question on lines: 5 in question starting with:Which of the followi ... in quiz: 07_build_a_resume_02_coverletter_quiz.md 5 +TRUE or FALSE: It's best to demonstrate that you're an outgoing and bubbly person in a cover letter, regardless of whether or not that's true. 07_build_a_resume_02_coverletter_quiz.md Colon detected in question on lines: 33 in question starting with:TRUE or FALSE: It's ... in quiz: 07_build_a_resume_02_coverletter_quiz.md 33 +TRUE or FALSE: My cover letter is the place in the application where I should use specific examples from my experience and tell a story or two to demonstrate why I'm a good fit for the position. 07_build_a_resume_02_coverletter_quiz.md Colon detected in question on lines: 38 in question starting with:TRUE or FALSE: My co ... in quiz: 07_build_a_resume_02_coverletter_quiz.md 38 +TRUE or FALSE: If the job description requires a college degree for the job and I do not have one, I should state that I do anyway in my cover letter. 07_build_a_resume_02_coverletter_quiz.md Colon detected in question on lines: 43 in question starting with:TRUE or FALSE: If th ... in quiz: 07_build_a_resume_02_coverletter_quiz.md 43 +?4 What would you run in the R Console to preview changes to your website in RStudio Cloud? 07_build_a_resume_03_website_quiz.md Colon detected in question on lines: 49, 50, 51, 52, 53, 54, 55, 56, 57 in question starting with:?4 What would you ru ... in quiz: 07_build_a_resume_03_website_quiz.md NA +?4 What would you run in the R Console to preview changes to your website in RStudio Cloud? 07_build_a_resume_03_website_quiz.md Exclamation point detected in answer for: ?4 What would you ru ... in quiz: 07_build_a_resume_03_website_quiz.md NA +?4 What function would you use to generate a new `blogdown` site in RStudio Cloud? 07_build_a_resume_03_website_quiz.md Colon detected in question on lines: 62, 63, 64, 65, 66, 67, 68, 69, 70 in question starting with:?4 What function wou ... in quiz: 07_build_a_resume_03_website_quiz.md NA +?4 What function would you use to generate a new `blogdown` site in RStudio Cloud? 07_build_a_resume_03_website_quiz.md Exclamation point detected in answer for: ?4 What function wou ... in quiz: 07_build_a_resume_03_website_quiz.md NA +?5 If you were to include a logo from [Font Awesome Standard](https://fontawesome.com/icons), what would you include in the `icon_pack` variable? 07_build_a_resume_03_website_quiz.md Colon detected in question on lines: 73 in question starting with:?5 If you were to in ... in quiz: 07_build_a_resume_03_website_quiz.md 73 +?5 If you were to include a logo from [Font Awesome Brand](https://fontawesome.com/icons), what would you include in the `icon_pack` variable? 07_build_a_resume_03_website_quiz.md Colon detected in question on lines: 86 in question starting with:?5 If you were to in ... in quiz: 07_build_a_resume_03_website_quiz.md 86 +?5 If you were to include a logo from [Academic Icons](https://jpswalsh.github.io/academicons/), what would you include in the `icon_pack` variable? 07_build_a_resume_03_website_quiz.md Colon detected in question on lines: 99 in question starting with:?5 If you were to in ... in quiz: 07_build_a_resume_03_website_quiz.md 99 +?7 Submit the URL for your new website here! 07_build_a_resume_03_website_quiz.md No incorrect answer options provided for ?7 Submit the URL fo ... in quiz: 07_build_a_resume_03_website_quiz.md 133 +?8 Submit the URL to your *resume* on your website here! 07_build_a_resume_03_website_quiz.md No incorrect answer options provided for ?8 Submit the URL to ... in quiz: 07_build_a_resume_03_website_quiz.md 138 +Throughout this lesson, you should have updated your website with a link to a blog post describing the analysis you did in the Final Project of this Course Set. **Paste the URL to the project on your website below**. 07_build_a_resume_04_projects_quiz.md No incorrect answer options provided for Throughout this less ... in quiz: 07_build_a_resume_04_projects_quiz.md 51 +You'll also need to have projects that you've completed on your own on your website. **Paste the URL to the a project you've completed and put on your website below.** This project must include the following: **getting data**, **cleaning data**, **exploratory data analysis**, **data analysis**, *and* **data visualization**. 07_build_a_resume_04_projects_quiz.md Colon detected in question on lines: 57 in question starting with:You'll also need to ... in quiz: 07_build_a_resume_04_projects_quiz.md 57 +You'll also need to have projects that you've completed on your own on your website. **Paste the URL to the a project you've completed and put on your website below.** This project must include the following: **getting data**, **cleaning data**, **exploratory data analysis**, **data analysis**, *and* **data visualization**. 07_build_a_resume_04_projects_quiz.md No incorrect answer options provided for You'll also need to ... in quiz: 07_build_a_resume_04_projects_quiz.md 56 +Read the documentation about contributing to `ggplot2` development [here](https://github.com/tidyverse/ggplot2/blob/master/CONTRIBUTING.md). What are the steps required to make a change to `ggplot2`? 07_build_a_resume_05_github_quiz.md Colon detected in question on lines: 5 in question starting with:Read the documentati ... in quiz: 07_build_a_resume_05_github_quiz.md 5 +Submit the URL to your now-complete GitHub profile. 07_build_a_resume_05_github_quiz.md No incorrect answer options provided for Submit the URL to yo ... in quiz: 07_build_a_resume_05_github_quiz.md 35 +Find a typo in a GitHub repo (This could be any GitHub repo!). Submit a PR (pull request) to edit that typo. **Paste the URL to that GitHub pull request below**. 07_build_a_resume_05_github_quiz.md No incorrect answer options provided for Find a typo in a Git ... in quiz: 07_build_a_resume_05_github_quiz.md 40 +TRUE or FALSE : Your LinkedIn profile should contain *less* information than your resume. 07_build_a_resume_06_linkedin_quiz.md Colon detected in question on lines: 25 in question starting with:TRUE or FALSE : Your ... in quiz: 07_build_a_resume_06_linkedin_quiz.md 25 +TRUE or FALSE : Your LinkedIn profile should contain *more* information than your resume. 07_build_a_resume_06_linkedin_quiz.md Colon detected in question on lines: 30 in question starting with:TRUE or FALSE : Your ... in quiz: 07_build_a_resume_06_linkedin_quiz.md 30 +Submit the URL to your now-complete LinkedIn profile. 07_build_a_resume_06_linkedin_quiz.md No incorrect answer options provided for Submit the URL to yo ... in quiz: 07_build_a_resume_06_linkedin_quiz.md 45 +TRUE or FALSE: For your professional Twitter account, it's best to keep your tweets generally focused on data science 07_build_a_resume_07_twitter_quiz.md Colon detected in question on lines: 29 in question starting with:TRUE or FALSE: For y ... in quiz: 07_build_a_resume_07_twitter_quiz.md 29 +TRUE or FALSE: For your professional Twitter account, it's best to tweet not only about data science but also trashy TV and other guilty pleasures as you're looking for a job. 07_build_a_resume_07_twitter_quiz.md Colon detected in question on lines: 34 in question starting with:TRUE or FALSE: For y ... in quiz: 07_build_a_resume_07_twitter_quiz.md 34 +Tweet or retweet something from your professional Twitter account related to data science. This could be a tweet about one of your projects (with a link to it on your website!) or a tweet about something cool someone else did. Paste the URL to this tweet below. 07_build_a_resume_07_twitter_quiz.md No incorrect answer options provided for Tweet or retweet som ... in quiz: 07_build_a_resume_07_twitter_quiz.md 50 +Read [Advice for Applying to Data Science Jobs](http://hookedondata.org/Advice-for-Applying-to-Data-Science-Jobs/){target=""_blank""}. At one point the author mentions a time she was interviewing someone. What does she say impressed her? 07_build_a_resume_11_interviews_quiz.md Colon detected in question on lines: 12 in question starting with:Read [Advice for App ... in quiz: 07_build_a_resume_11_interviews_quiz.md 12 diff --git a/R/quiz.R b/R/quiz.R index 9e5d596..11f659a 100644 --- a/R/quiz.R +++ b/R/quiz.R @@ -62,7 +62,6 @@ parse_quiz_df <- function(quiz_lines, remove_tags = FALSE) { # Rename "other" as also part of prompts for (index in 1:length(start_prompt_indices)) { if (start_prompt_indices[index] != end_prompt_indices[index]) { - # Mark things as a part of prompts quiz_df$type[(start_prompt_indices[index] + 1):(end_prompt_indices[index] - 1)] <- "extended_prompt" @@ -114,7 +113,6 @@ parse_quiz_df <- function(quiz_lines, remove_tags = FALSE) { #' # Extract metadata tags #' meta <- extract_meta(tags) extract_meta <- function(tags) { - # trim whitespace tags <- trimws(tags) @@ -144,7 +142,6 @@ extract_meta <- function(tags) { #' tag <- "{quiz, id: quiz_name_here, attempts: 10}" #' parse_q_tag(tag) parse_q_tag <- function(tag) { - # Trim whitespace tag <- trimws(tag) @@ -276,7 +273,6 @@ extract_quiz <- function(quiz_lines) { #' #' check_quiz_attributes <- function(quiz_specs, quiz_name = NULL, verbose = TRUE) { - # Assume good until otherwise metadata_msg <- "good" @@ -329,7 +325,6 @@ check_quiz_attributes <- function(quiz_specs, quiz_name = NULL, verbose = TRUE) check_quiz_question_attributes <- function(question_df, quiz_name = NULL, verbose = TRUE) { - # Assume good until shown otherwise attr_msg <- "good" @@ -392,7 +387,6 @@ check_quiz_question_attributes <- function(question_df, #' bad_quiz_checks <- check_all_questions(bad_quiz_specs) #' } check_all_questions <- function(quiz_specs, quiz_name = NA, verbose = TRUE, ignore_coursera = TRUE) { - # Remove header part and split into per question data frames question_dfs <- quiz_specs$data %>% dplyr::filter(question > 0) %>% @@ -450,7 +444,6 @@ check_all_questions <- function(quiz_specs, quiz_name = NA, verbose = TRUE, igno #' good_quiz_checks <- check_question(questions_df[[2]]) #' } check_question <- function(question_df, quiz_name = NA, verbose = TRUE, ignore_coursera = TRUE) { - # Things are considered innocent until proven guilty colon_msg <- tot_ans_msg <- cor_ans_msg <- inc_ans_msg <- exclam_msg <- "good" colon_index <- tot_ans_index <- cor_ans_index <- inc_ans_index <- exclam_index <- NA @@ -486,7 +479,7 @@ check_question <- function(question_df, quiz_name = NA, verbose = TRUE, ignore_c colon_msg <- paste0( "Colon detected in question on lines: ", paste0(colon_index, collapse = ", "), - " in question starting with:", quiz_identity + " in question starting with:", quiz_identity ) if (!ignore_coursera) { warning(colon_msg) @@ -537,7 +530,6 @@ check_question <- function(question_df, quiz_name = NA, verbose = TRUE, ignore_c #### If choose answer, make sure that there are more answers than specified in tag if ("tag" %in% question_df$type) { - # Retrieve lines with tags tags <- question_df$original[question_df$type == "tag"] @@ -597,7 +589,7 @@ check_question <- function(question_df, quiz_name = NA, verbose = TRUE, ignore_c inc_ans_msg, exclam_msg ) - related_index <- c( + related_index <- c( as.numeric(colon_index), as.numeric(tot_ans_index), as.numeric(cor_ans_index), @@ -614,7 +606,7 @@ check_question <- function(question_df, quiz_name = NA, verbose = TRUE, ignore_c as.numeric(tot_ans_index), as.numeric(cor_ans_index), as.numeric(inc_ans_index) - ) + ) } # Store all warning messages as a list; they will say "good" if nothing is detected as wrong question_result <- data.frame( @@ -688,7 +680,6 @@ check_quizzes <- function(quiz_dir = "quizzes", readr::write_tsv(question_report, file = "question_error_report.tsv" ) - } else { message("\n No question errors to report!") } @@ -736,7 +727,7 @@ check_quiz <- function(quiz_path, verbose = TRUE, ignore_coursera = TRUE) { # Check main quiz attributes meta_checks <- check_quiz_attributes(quiz_specs, quiz_name = quiz_name - ) + ) # Check each question question_checks <- check_all_questions( diff --git a/R/replace_html.R b/R/replace_html.R index 9bdc91e..26026bc 100644 --- a/R/replace_html.R +++ b/R/replace_html.R @@ -1,4 +1,3 @@ - #' Convert youtube link #' #' @param utube_link a link to a youtube video that may or may not be "www.youtube.com/embed" or "www.youtube.com/watch?v=" @@ -8,7 +7,6 @@ #' @export #' convert_utube_link <- function(utube_link) { - # If it has a youtube embed link, switch to the watch format link if (grepl("www.youtube.com/embed", utube_link)) { utube_link <- paste0( diff --git a/R/set_knitr_image_path.R b/R/set_knitr_image_path.R index ab0c180..b5a4769 100644 --- a/R/set_knitr_image_path.R +++ b/R/set_knitr_image_path.R @@ -1,9 +1,8 @@ - #' Set image path for `knitr` #' #' @param verbose print out what the figure path is #' -#' @return When used inside a knitted R Markdown document, will set the image path to a place compatible with 'ottrpal' output folders. +#' @return When used inside a knitted R Markdown document, will set the image path to a place compatible with 'ottrpal' output folders. #' @export set_knitr_image_path <- function(verbose = FALSE) { fp <- knitr::fig_path() diff --git a/R/set_up.R b/R/set_up.R index ee55cfc..7c10807 100644 --- a/R/set_up.R +++ b/R/set_up.R @@ -6,7 +6,6 @@ #' @export get_bookdown_spec <- function(path = ".") { - # Get the file path to _bookdown.yaml file_path <- bookdown_file(path = path) @@ -26,7 +25,6 @@ get_bookdown_spec <- function(path = ".") { #' @export bookdown_path <- function(path = ".") { - # See what unzip is being used operating_system <- Sys.info()[1] @@ -82,7 +80,6 @@ bookdown_rmd_files <- function(path = ".") { #' @export #' bookdown_destination <- function(path = ".") { - # Find _bookdown.yml root_dir <- bookdown_path(path = file.path(path)) @@ -111,7 +108,6 @@ bookdown_destination <- function(path = ".") { copy_resources <- function(path = ".", images_dir = "resources", output_dir = "manuscript") { - # Get file path to bookdown.yml path <- bookdown_path(path) diff --git a/R/zzz.R b/R/zzz.R new file mode 100644 index 0000000..bee70d8 --- /dev/null +++ b/R/zzz.R @@ -0,0 +1,3 @@ +.onAttach <- function(libname, pkgname) { + packageStartupMessage("Use the authorize() function to begin. This gives the package the proper credentials to run.") +} diff --git a/inst/extdata/tmp/encrypt.rds b/inst/extdata/tmp/encrypt.rds new file mode 100644 index 0000000..dc4bbdc Binary files /dev/null and b/inst/extdata/tmp/encrypt.rds differ diff --git a/inst/extdata/tmp/encrypt_pass.rds b/inst/extdata/tmp/encrypt_pass.rds new file mode 100644 index 0000000..f50ca13 Binary files /dev/null and b/inst/extdata/tmp/encrypt_pass.rds differ diff --git a/inst/extdata/tmp/encrypted_default_user_creds.rds b/inst/extdata/tmp/encrypted_default_user_creds.rds new file mode 100644 index 0000000..bb436e0 Binary files /dev/null and b/inst/extdata/tmp/encrypted_default_user_creds.rds differ diff --git a/man/auth_from_secret.Rd b/man/auth_from_secret.Rd new file mode 100644 index 0000000..e99bbc6 --- /dev/null +++ b/man/auth_from_secret.Rd @@ -0,0 +1,32 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/auth.R +\name{auth_from_secret} +\alias{auth_from_secret} +\title{Use secrets to authorize R package to access Google Slides API} +\usage{ +auth_from_secret(access_token = NULL, refresh_token = NULL) +} +\arguments{ +\item{access_token}{Access token can be obtained from running authorize() interactively: token <-authorize(); token$credentials$access_token} + +\item{refresh_token}{Refresh token can be obtained from running authorize() interactively: token <-authorize(); token$credentials$refresh_token} +} +\value{ +OAuth token saved to the environment so the package can use the users' Google data +} +\description{ +This is a function to authorize the R package to access the Google Slides API. If no +client.id and client.secret is provided, the package would provide predefined values. +} +\examples{ +\dontrun{ + +token <- authorize() + +auth_from_secret( + token$credentials$access_token, + token$credentials$refresh_token +) +} + +} diff --git a/man/authorize.Rd b/man/authorize.Rd new file mode 100644 index 0000000..f26d32f --- /dev/null +++ b/man/authorize.Rd @@ -0,0 +1,27 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/auth.R +\name{authorize} +\alias{authorize} +\title{Authorize R package to access the Google Slides API} +\usage{ +authorize(token = NULL, cache = FALSE, ...) +} +\arguments{ +\item{token}{An output from \code{\link{oauth2.0_token}} to set as the authentication token.} + +\item{cache}{Should the token be cached as an .httr-oauth file?} + +\item{...}{Additional arguments to send to \code{\link{oauth2.0_token}}} +} +\value{ +OAuth token saved to the environment so the package can use the users' Google data +} +\description{ +This is a function to authorize the R package to access the Google Slides API interactively. +} +\examples{ +\dontrun{ + +authorize() +} +} diff --git a/man/bookdown_to_embed_leanpub.Rd b/man/bookdown_to_embed_leanpub.Rd index 78a0b85..6450032 100644 --- a/man/bookdown_to_embed_leanpub.Rd +++ b/man/bookdown_to_embed_leanpub.Rd @@ -72,8 +72,9 @@ Convert Bookdown to Embed version of Leanpub \dontrun{ ottrpal::bookdown_to_embed_leanpub( - base_url = "https://jhudatascience.org/OTTR_Template/", - make_book_txt = TRUE, - quiz_dir = NULL) + base_url = "https://jhudatascience.org/OTTR_Template/", + make_book_txt = TRUE, + quiz_dir = NULL +) } } diff --git a/man/encrypt_creds_path.Rd b/man/encrypt_creds_path.Rd new file mode 100644 index 0000000..64ee34b --- /dev/null +++ b/man/encrypt_creds_path.Rd @@ -0,0 +1,11 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/data.R +\name{encrypt_creds_path} +\alias{encrypt_creds_path} +\title{Get file path to an encrypted credentials RDS} +\usage{ +encrypt_creds_path() +} +\description{ +Get file path to an encrypted credentials RDS +} diff --git a/man/encrypt_creds_user_path.Rd b/man/encrypt_creds_user_path.Rd new file mode 100644 index 0000000..116c94e --- /dev/null +++ b/man/encrypt_creds_user_path.Rd @@ -0,0 +1,11 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/data.R +\name{encrypt_creds_user_path} +\alias{encrypt_creds_user_path} +\title{Get file path to an default credentials RDS} +\usage{ +encrypt_creds_user_path() +} +\description{ +Get file path to an default credentials RDS +} diff --git a/man/extract_object_id.Rd b/man/extract_object_id.Rd new file mode 100644 index 0000000..18e8f43 --- /dev/null +++ b/man/extract_object_id.Rd @@ -0,0 +1,43 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/notes_to_fig_alt.R +\name{extract_object_id} +\alias{extract_object_id} +\title{Extract Object IDs using Google Slides API} +\usage{ +extract_object_id( + slide_url, + token = NULL, + access_token = NULL, + refresh_token = NULL +) +} +\arguments{ +\item{slide_url}{URL whose 'General access' is set to 'Anyone with the link'} + +\item{token}{OAuth 2.0 Access Token. If you don't have a token, use +[authorize()] to obtain an access token from Google's OAuth 2.0 server.} + +\item{access_token}{Access token can be obtained from running authorize() +interactively (token <-authorize(); token$credentials$access_token). This +allows it to be passed in using two secrets.} + +\item{refresh_token}{Refresh token can be obtained from running authorize() +interactively (token <-authorize(); token$credentials$refresh_token). This +allows it to be passed in using two secrets.} +} +\value{ +Character vector of object ID(s) +} +\description{ +Performs a HTTP GET method to request the IDs of every slide in a Google +Slides presentation. The ID of the first slide is always 'p'. +} +\examples{ +\dontrun{ +# First, obtain access token and store token for extract_object_id() to use +authorize(client_id = "MY_CLIENT_ID", client_secret = "MY_CLIENT_SECRET") +# Use stored token to talk to Google Slides API +extract_object_id(slide_url = "https://docs.google.com/presentation/d/1H5aF_ROKVxE-H + FHhoOy9vU2Y-y2M_PiV0q-JBL17Gss/edit?usp=sharing") +} +} diff --git a/man/download_gs_file.Rd b/man/get_gs_pptx.Rd similarity index 55% rename from man/download_gs_file.Rd rename to man/get_gs_pptx.Rd index bbed548..fc1c588 100644 --- a/man/download_gs_file.Rd +++ b/man/get_gs_pptx.Rd @@ -1,23 +1,20 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/gs_png.R -\name{download_gs_file} -\alias{download_gs_file} -\title{Download Google Slides File} +% Please edit documentation in R/notes_to_fig_alt.R +\name{get_gs_pptx} +\alias{get_gs_pptx} +\title{Download Google Slides pptx file} \usage{ -download_gs_file(id, out_type = "pptx") +get_gs_pptx(id) } \arguments{ \item{id}{Identifier of Google slides presentation, passed to \code{\link{get_slide_id}}} - -\item{out_type}{output type of file to download. Usually -`pdf` or `pptx`} } \value{ Downloaded file (in temporary directory) } \description{ -Download Google Slides File +Download Google Slides pptx file } \note{ This downloads presentations if they are public and also try to make diff --git a/man/get_object_id_notes.Rd b/man/get_object_id_notes.Rd new file mode 100644 index 0000000..c768a13 --- /dev/null +++ b/man/get_object_id_notes.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/notes_to_fig_alt.R +\name{get_object_id_notes} +\alias{get_object_id_notes} +\title{Retrieve Speaker Notes and their corresponding Object (Slide) IDs from a Google Slides presentation} +\usage{ +get_object_id_notes(slide_url) +} +\arguments{ +\item{slide_url}{URL whose 'General access' is set to 'Anyone with the link'} +} +\value{ +Data frame of Object IDs and Speaker notes. +} +\description{ +Google Slides API calls a presentation slide ID as an 'object ID'. +} +\examples{ +\dontrun{ + get_object_id_notes("https://docs.google.com/presentation/d/ + 1H5aF_ROKVxE-HFHhoOy9vU2Y-y2M_PiV0q-JBL17Gss/edit?usp=sharing") +} +} diff --git a/man/key_encrypt_creds_path.Rd b/man/key_encrypt_creds_path.Rd new file mode 100644 index 0000000..6661719 --- /dev/null +++ b/man/key_encrypt_creds_path.Rd @@ -0,0 +1,11 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/data.R +\name{key_encrypt_creds_path} +\alias{key_encrypt_creds_path} +\title{Get file path to an key encryption RDS} +\usage{ +key_encrypt_creds_path() +} +\description{ +Get file path to an key encryption RDS +} diff --git a/man/pptx_notes.Rd b/man/pptx_notes.Rd new file mode 100644 index 0000000..de34d42 --- /dev/null +++ b/man/pptx_notes.Rd @@ -0,0 +1,36 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/notes_to_fig_alt.R +\name{pptx_notes} +\alias{pptx_notes} +\alias{pptx_slide_text_df} +\alias{pptx_slide_note_df} +\alias{unzip_pptx} +\title{Get Notes from a PowerPoint (usually from Google Slides)} +\usage{ +pptx_notes(file, ...) + +pptx_slide_text_df(file, ...) + +pptx_slide_note_df(file, ...) + +unzip_pptx(file) +} +\arguments{ +\item{file}{Character. Path for `PPTX` file} + +\item{...}{additional arguments to pass to \code{\link{xml_notes}}, +particularly \code{xpath}} +} +\value{ +Either a character vector or `NULL` +} +\description{ +Get Notes from a PowerPoint (usually from Google Slides) +} +\examples{ +\dontrun{ +pptx_notes(ex_file) +pptx_slide_note_df(ex_file) +pptx_slide_text_df(ex_file) +} +} diff --git a/man/xml_notes.Rd b/man/xml_notes.Rd new file mode 100644 index 0000000..a059c7e --- /dev/null +++ b/man/xml_notes.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/notes_to_fig_alt.R +\name{xml_notes} +\alias{xml_notes} +\title{Get Notes from XML} +\usage{ +xml_notes(file, collapse_text = TRUE, xpath = "//a:r//a:t") +} +\arguments{ +\item{file}{XML file from a PPTX} + +\item{collapse_text}{should text be collapsed by spaces?} + +\item{xpath}{\code{xpath} to pass to [xml2::xml_find_all()]} +} +\value{ +A character vector +} +\description{ +Get Notes from XML +}