Name:
Andrew ID:
Collaborated with:

This lab is to be completed in class. You can collaborate with your classmates, but you must identify their names above, and you must submit your own lab as an Rmd file on Blackboard, by 11:59pm on the day of the lab.

There are Homework 7 questions dispersed throughout. These must be written up in a separate Rmd document, together with all Homework 7 questions from other labs. Your homework writeup must start as this one: by listing your name, Andrew ID, and who you collaborated with. You must submit your own homework as a knit HTML file on Blackboard, by 6pm on Sunday October 23. This document contains 15 of the 30 total points for Homework 7.

Browsing practice

add.up.inv.powers = function(n, verbose=FALSE) {
  x = 0
  for (i in 1:n) {
    x = x + i^(1/i)
    if (verbose) roman.cat(i)
  }
  if (verbose) cat("\n")
  return(x)
}

roman.cat = function(num) {
  roman.num = as.roman(num)
  roman.str = as.character(roman.num)
  cat(roman.str, "... ")
}

add.up.inv.powers(n=3, verb=FALSE)
## [1] 3.856463
add.up.inv.powers(n=5, verb=FALSE)
## [1] 6.650406
add.up.inv.powers(n=10, verb=FALSE)
## [1] 13.15116
# Your code goes here
# Your code goes here
# Your code goes here

Browsing for bugs

fibonacci = function(n) {
  my.fib = c(1,1)
  for (i in 2:(n-1)) my.fib[i+1] = my.fib[i] + my.fib[i-1]  
  return(my.fib[i])
}

fibonacci(1) # Should be 1
## Error in my.fib[i + 1] = my.fib[i] + my.fib[i - 1]: replacement has length zero
fibonacci(2) # Should be 1
## Error in my.fib[i + 1] = my.fib[i] + my.fib[i - 1]: replacement has length zero
fibonacci(3) # Should be 2
## [1] 1
fibonacci(5) # Should be 5
## [1] 3
fibonacci(9) # Should be 34
## [1] 21

Hw7 Q2 (5 points). Use browser() to find and fix bugs in the functions sentence.flipper() and word.flipper() below. The first function is supposed to take a sentence, i.e., a single string composed of words separated by spaces, and flip each of the words (meaning reverse the order of their characters); the second function is used by the first, to take a single word and flip it (reverse the order of the characters). Describe what bugs you found, how you found them, and what you did to fix them. Once this is done, your function should be producing outputs on the test cases below that match those described in the comments.

sentence.flipper = function(str) {
  str.words = strsplit(str, split=" ")  
  rev.words = lapply(str, word.flipper)  
  str.flipped = paste(rev.words, collapse=" ")
  return(str.flipped)
}

word.flipper = function(str) {
  chars = strsplit(str, split="")
  chars.flipped = rev(chars)
  str.flipped = paste(chars.flipped, collapse="")
  return(str.flipped)
}

# Should be "eht kciuq nworb xof depmuj revo eht yzal god"
sentence.flipper("the quick brown fox jumped over the lazy dog") 
## [1] "c(\"t\", \"h\", \"e\", \" \", \"q\", \"u\", \"i\", \"c\", \"k\", \" \", \"b\", \"r\", \"o\", \"w\", \"n\", \" \", \"f\", \"o\", \"x\", \" \", \"j\", \"u\", \"m\", \"p\", \"e\", \"d\", \" \", \"o\", \"v\", \"e\", \"r\", \" \", \"t\", \"h\", \"e\", \" \", \"l\", \"a\", \"z\", \"y\", \" \", \"d\", \"o\", \"g\")"
# Should be "ot eb ro on ot eb taht si eht noitseuq"
sentence.flipper("to be or no to be that is the question") 
## [1] "c(\"t\", \"o\", \" \", \"b\", \"e\", \" \", \"o\", \"r\", \" \", \"n\", \"o\", \" \", \"t\", \"o\", \" \", \"b\", \"e\", \" \", \"t\", \"h\", \"a\", \"t\", \" \", \"i\", \"s\", \" \", \"t\", \"h\", \"e\", \" \", \"q\", \"u\", \"e\", \"s\", \"t\", \"i\", \"o\", \"n\")"

Hw7 Q4 (5 points). Extend the function sentence.flipper() so that it is vectorized, i.e., if the input str is a vector of strings, then this function should return a vector where each element is a string that is flipped in accordance with the description above. (Hint: there is certainly more than one way to modify sentence.flipper() so that it works over vectors. But look out for a simple strategy—you already know that sentence.flipper() works over single strings, so be mindful of the strategies you learned last week, to apply a function over each element of a vector!) Once this is done, your function should be producing outputs on the test cases below that match those described in the comments.

sentence.flipper = function(str.vec) {
  # Your code goes here
  return(str.vec) # Temp return value, replace as needed
}

# Should be "olleh ssenkrad ym dlo dneirf", 
#           "ev'i emoc ot kaeps htiw uoy niaga"
sentence.flipper(c("hello darkness my old friend",
                   "i've come to speak with you again"))
## [1] "hello darkness my old friend"      "i've come to speak with you again"
# Should be "reven annog evig uoy pu",
#           "reven annog tel uoy nwod",
#           "reven annog nur dnuora dna tresed uoy"
sentence.flipper(c("never gonna give you up",
                   "never gonna let you down",
                   "never gonna run around and desert you"))
## [1] "never gonna give you up"              
## [2] "never gonna let you down"             
## [3] "never gonna run around and desert you"

Hw7 Q5 (5 points). Fill out the function sentence.scrambler() defined below, similar to sentence.flipper(), but where the former randomly scrambles the order of characters in each word, instead of deterministically reversing them. The function sentence.scrambler() should be vectorized, just like the current version of sentence.flipper(). (Hint: you can use browser() at any point if you run into bugs in your development, or simply to see how your function is handling certain test inputs. Also, the differences between sentence.flipper() and sentence.scrambler() should be pretty minor; really, you just need to replace word.flipper() by a suitable function.) Once done, run sentence.scrambler() on the test string below to display the output, and ensure that is passes the check below, as well (this check ensures that the character counts of sentences before and after scrambling are the same).

sentence.scrambler = function(str.vec) {  
  # Your code goes here
  return(str.vec) # Temp return value, replace as needed
}

test.str.vec =  c("I have no theorems, well",
  "I do have theorems, but none of them are named Fienberg's Theorem",
  "Even if there were a Fienberg's Theorem, it probably wouldn't be important",
  "What's important is the attitude, for what statistics is",
  "and how it's recognized by other people outside of our field")
sentence.scrambler(test.str.vec)
## [1] "I have no theorems, well"                                                  
## [2] "I do have theorems, but none of them are named Fienberg's Theorem"         
## [3] "Even if there were a Fienberg's Theorem, it probably wouldn't be important"
## [4] "What's important is the attitude, for what statistics is"                  
## [5] "and how it's recognized by other people outside of our field"
# Code to check character counts before and after. (Good to make sure that you 
# understanding this code! If not, ask questions during lab or office hours)
char.tab = function(str) { table(strsplit(str,split="")) }
char.tabs.before = lapply(test.str.vec, char.tab)
char.tabs.after = lapply(sentence.scrambler(test.str.vec), char.tab)
names(char.tabs.before) = names(char.tabs.after) = NULL # Get rid of names
identical(char.tabs.before, char.tabs.after) # This should return TRUE
## [1] TRUE