Useless and useful little R function – Typing speed benchmark

[This article was first published on R – TomazTsql, and kindly contributed to R-bloggers]. (You can report problems with content on this page here)


Want to share your content on R-blogger? click here if you have a blog, or here if you don’t.

Have you ever wondered how fast and accurate your typing is?

For this example, we will introduce some random pangrams, code examples, and random strings sorted by difficulty.

Besides the list of sample strings, we also have some helper functions – calculating WPM, accuracy and handling input and results for the user:

calculate_wpm <- function(text, time_seconds) {

  char_count <- nchar(text)
  word_count <- char_count / 5
  time_minutes <- time_seconds / 60
  wpm <- word_count / time_minutes
  
  return(round(wpm, 1))
}



calculate_accuracy <- function(original, typed) {
  
  orig_chars <- strsplit(original, "")[[1]]
  typed_chars <- strsplit(typed, "")[[1]]
  orig_len <- length(orig_chars)
  typed_len <- length(typed_chars)
  if (typed_len == 0) {
    return(0)
  }

  compare_len <- min(orig_len, typed_len)
  matches <- sum(orig_chars[1:compare_len] == typed_chars[1:compare_len])
  
  length_penalty <- abs(orig_len - typed_len)
  accuracy <- (matches / orig_len) * 100
  penalty_pct <- (length_penalty / orig_len) * 100
  accuracy <- max(0, accuracy - penalty_pct)
  
  return(round(accuracy, 1))
}


get_random_phrase <- function(mode = "pangram", difficulty = "medium") {
  
  valid_modes <- c("pangram", "rstats", "code", "chaos")
  if (!mode %in% valid_modes) {
    warning(paste("Invalid mode; use one of these modes:", 
                  paste(valid_modes, collapse = ", ")))
    mode <- "pangram"
  }

  valid_difficulties <- c("easy", "medium", "hard")
  if (!difficulty %in% valid_difficulties) {
    warning(paste("Invalid difficulty; use one of these difficulties:",
                  paste(valid_difficulties, collapse = ", ")))
    difficulty <- "medium"
  }
  
  phrase_pool <- phrases_db[[mode]][[difficulty]]
  phrase <- sample(phrase_pool, 1)
  
  return(phrase)
}


##### Diplay results
display_results <- function(wpm, accuracy, time_seconds) {
  
  cat("\n")
  cat(rep("\U00002550", 48), "\n", sep = "")
  cat("                      RESULTS\n")
  cat(rep("\U00002550", 48), "\n", sep = "")
  
  cat("\n")
  
  cat(sprintf("  Time:        %.2f seconds\n", time_seconds))
  cat(sprintf("  WPM:         %.1f \n", wpm))
  cat(sprintf("  Accuracy:    %.1f%% \n", accuracy))

  
  cat("\n")
  cat(rep("\U00002550", 48), "\n", sep = "")

}


show_error_details <- function(original, typed) {
  
  orig_chars <- strsplit(original, "")[[1]]
  typed_chars <- strsplit(typed, "")[[1]]
  
  max_len <- max(length(orig_chars), length(typed_chars))
  if (length(orig_chars) < max_len) {
    orig_chars <- c(orig_chars, rep("_", max_len - length(orig_chars)))
  }
  if (length(typed_chars) < max_len) {
    typed_chars <- c(typed_chars, rep("_", max_len - length(typed_chars)))
  }
  
  errors <- which(orig_chars != typed_chars)
  if (length(errors) == 0) {
    cat("\n  Perfetoooo! \n")
    return(invisible(NULL))
  }
  
  cat("\n  Errors:\n")
  cat("  --------------\n")
  show_errors <- head(errors, 5)
  for (pos in show_errors) {
    expected <- if (orig_chars[pos] == " ") "[space]" else orig_chars[pos]
    got <- if (typed_chars[pos] == " ") "[space]" else 
      if (typed_chars[pos] == "_") "[missing]" else typed_chars[pos]
    cat(sprintf("  Position %d: expected '%s', got '%s'\n", pos, expected, got))
  }
  
  if (length(errors) > 5) {
    cat(sprintf("  ... and %d more errors\n", length(errors) - 5))
  }
}



### Function itself

TypingTest <- function(mode = "code", 
                       difficulty = "easy",
                       show_errors = TRUE) {
  
  # Display header
  cat("\n")
  cat("\U00002554", rep("\U00002550", 52), "\U00002557\n", sep = "")
  cat("\U00002551           R TYPING SPEED TEST                      \U00002551\n")
  cat("\U00002551           Mode: ", sprintf("%-10s", mode), " | Difficulty: ", 
      sprintf("%-8s", difficulty), "\U00002551\n", sep = "")
  cat("\U0000255A", rep("\U00002550", 52), "\U0000255D\n", sep = "")
  cat("\n")
  
  phrase <- get_random_phrase(mode, difficulty)
  cat("Type the following:\n\n")
  cat("  \"", phrase, "\"\n\n", sep = "")
  cat("Press ENTER when ready to start...")
  invisible(readline())
  
  cat("\n----------------------------------------------------------\n")
  cat("  \"", phrase, "\"\n", sep = "")
  cat("----------------------------------------------------------\n\n")
  
  start_time <- Sys.time()
  typed <- readline(prompt = "> ")
  end_time <- Sys.time()
  time_seconds <- as.numeric(difftime(end_time, start_time, units = "secs"))
  wpm <- calculate_wpm(phrase, time_seconds)
  accuracy <- calculate_accuracy(phrase, typed)
  
  display_results(
    wpm = wpm,
    accuracy = accuracy,
    time_seconds = time_seconds
  )
  
  if (show_errors && accuracy < 100) {
    show_error_details(phrase, typed)
  }
  
  cat("\nPlay again? (y/n): ")
  play_again <- tolower(readline())
  
  if (play_again == "y" || play_again == "yes") {
    return(TypingTest(mode = mode, difficulty = difficulty,  show_errors = show_errors))
  }
  
}


In the end, all we need to do is run the function itself:

Results displayed:

As always, the complete code is available on GitHub in the Useless_R_function repository. An example of a file in this repository is here (file name: TypingSpeed_tester.R.R). Check the repository for future updates.

Happy R-coding and stay healthy!



Berita Terkini

Berita Terbaru

Daftar Terbaru

News

Jasa Impor China

Berita Terbaru

Flash News

RuangJP

Pemilu

Berita Terkini

Prediksi Bola

Technology

Otomotif

Berita Terbaru

Teknologi

Berita terkini

Berita Pemilu

Berita Teknologi

Hiburan

master Slote

Berita Terkini

Pendidikan

Resep

Jasa Backlink

Slot gacor terpercaya

Anime Batch

Leave a Reply

Your email address will not be published. Required fields are marked *