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!
Related
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