# ex15PhillConrad.py Examples to use for ex15, CS5NM # Code for "new_check_expect", "check_exception", and # examples of various kinds of functions. import sys # new_check_expect checks whether a fruitful (non-void) # function produces the expected result # # consumes: # check: a string containing the function call we want to test # expect: the value we are expecting (typically a literal value) # msg: True if we should print output, False if we should not # default is True) # produces: # True if test passes, False otherwise # side effect: # prints a message indicating whether the test passed or failed def new_check_expect(check,expect,msg=True): if msg: print "Testing " + check + " :", try: actual = eval(check) result = (actual == expect) if msg: if result: print " Passed!" else: print " Failed! Expected: " + str(expect) + " Got: " + str(actual) return result except: if msg: print " ERROR: Unable to evaluate test: " + str(sys.exc_info()[0]) # check_exception is used when we want to test whether a function # returns the correct "exception" under certain circumstances # # consumes: # check: an expression to test, as a string # expectedException: the exception you should get in response # msg: whether or not to print results as a side effect # produces: # boolean: True is the test comes out as expected, i.e. you get the # exception that you think you are going to get # side effect: # if msg is True, then print messages about what happened to the console def check_exception(check,expectedException,msg=True): if msg: print "Testing " + check + " :", try: evalResult = eval(check) gotException = False except: actualException = sys.exc_info()[1] gotException = True gotExpectedException = (str(actualException) == expectedException) if gotException and gotExpectedException: if msg: print " Passed!" return True elif not gotException: if msg: print " Failed! I expected an exception, but instead I got the result: " + \ str(evalResult) return False else: # must be true that (not gotExpectedException) if msg: print " Failed! I expected this Exception: " + \ expectedException + " but instead I got this exception: " + \ str(actualException) return False # noDups is a function that takes a list of items, and # returns a copy of that list with no consecutive duplicates # consumes: a list of items # produces: the same list with any consecutive duplicates removed # example: noDups([2,3,3,3,4,4,5,6,6,2,2,1,5,3,3,2] # produces: [2,3,4,5,6,2,1,5,3,2] def noDups(lst): # return -1 stub if (len(lst)==0): return lst # not [], because then it doesn't work on tuples or strings elif len(lst)==1: return lst else: # now we now that the list has at least two elements if lst[0] == lst[1]: return noDups(lst[1:]) # remove first element if its a duplicate else: return lst[0:1] + noDups(lst[1:]) # we could use: # return [lst[0]] + noDups(lst[1:]) # but that only works on lists, not strings or tuples # we cannot use: # lst[0] + noDups(lst[1:]) because + isn't defined for adding # an item to a sequence (like a list, tuple or string), # only for combining two sequences into one. new_check_expect("noDups([])",[]) new_check_expect("noDups([1])",[1]) new_check_expect("noDups([2,2])",[2]) new_check_expect("noDups([1,2,3])",[1,2,3]) new_check_expect("noDups([1,1,2,2,3,3])",[1,2,3]) new_check_expect("noDups([3,3,2,1,1,4,5,5,6,7,7,7,8])", [3,2,1,4,5,6,7,8]) # noDups works on lists of strings too: new_check_expect("noDups(['a','a','b','d','f','f','g'])", ['a','b','d','f','g']) new_check_expect("noDups(['adam','adam','bravo','adam','frank','frank'])", ['adam','bravo','adam','frank']) # and it works on strings: new_check_expect("noDups('aabdffg')", 'abdfg') new_check_expect("noDups(['aabdffg'])", ['aabdffg']) new_check_expect("noDups('')",'') # and on tuples: new_check_expect("noDups((23,1,1,45,6,6,6,7,1,1))", (23,1,45,6,7,1)) # isVowel checks whether a given letter is a vowel. For purposes of this # function, treat y as always a vowel, w never as a vowel. # consumes: a string containing a single letter # produces: True, if the letter is a vowel, otherwise False # exceptions: if the value of the parameter is not a single letter string, # raise Exception('isVowel only takes single letter strings') def isVowel(letter): return "stub" # this is a stub for testing the test cases # @@@ REPLACE THE STUB WITH A CORRECT FUNCTION SO THAT THE TEST CASES PASS # @@@ HINTS: # @@@ (1) This one doesn't need to be recursive # @@@ (2) For an example of raising an exception, see lecture notes # @@@ from 11/24, including the function "smallest" from # @@@ http://www.cs.ucsb.edu/~pconrad/cs5nm/08F/code/11.24/newCheckExpect.py # @@@ (3) You need to check both the type and the length new_check_expect("isVowel('a')",True) new_check_expect("isVowel('e')",True) new_check_expect("isVowel('i')",True) new_check_expect("isVowel('o')",True) new_check_expect("isVowel('u')",True) new_check_expect("isVowel('y')",True) new_check_expect("isVowel('A')",True) new_check_expect("isVowel('E')",True) new_check_expect("isVowel('I')",True) new_check_expect("isVowel('O')",True) new_check_expect("isVowel('U')",True) new_check_expect("isVowel('Y')",True) new_check_expect("isVowel('b')",False) new_check_expect("isVowel('c')",False) new_check_expect("isVowel('d')",False) new_check_expect("isVowel('f')",False) new_check_expect("isVowel('m')",False) new_check_expect("isVowel('z')",False) new_check_expect("isVowel('G')",False) new_check_expect("isVowel('K')",False) new_check_expect("isVowel('J')",False) new_check_expect("isVowel('W')",False) new_check_expect("isVowel('X')",False) new_check_expect("isVowel('P')",False) new_check_expect("isVowel('.')",False) new_check_expect("isVowel('!')",False) new_check_expect("isVowel(',')",False) new_check_expect("isVowel(' ')",False) check_exception("isVowel('')",'isVowel only takes single letter strings') check_exception("isVowel('aa')",'isVowel only takes single letter strings') check_exception("isVowel('ab')",'isVowel only takes single letter strings') check_exception("isVowel('ba')",'isVowel only takes single letter strings') check_exception("isVowel(0)",'isVowel only takes single letter strings') check_exception("isVowel(['a'])",'isVowel only takes single letter strings') # countVowels counts the number of vowels in a word. # consumes: a string # produces: an integer # exceptions: if the input is not a string, # raise Exception('countVowels only takes strings') # Note: the empty string is legal, and should produce the answer 0 def countVowels(word): return "stub" # a stub for testing the tests # @@@ REPLACE THE STUB WITH A CORRECT FUNCTION SO THAT THE TEST CASES PASS # @@@ HINTS: # @@@ (1) Use recursion. The pattern is "counting items in a list", so # @@@ look at functions like countOdd() or countEven(). new_check_expect('countVowels("")',0) new_check_expect('countVowels("pwn")',0) new_check_expect('countVowels("pwned")',1) new_check_expect('countVowels("We")',1) new_check_expect('countVowels("hold")',1) new_check_expect('countVowels("these")',2) new_check_expect('countVowels("truths")',1) new_check_expect('countVowels("to")',1) new_check_expect('countVowels("be")',1) new_check_expect('countVowels("self")',1) new_check_expect('countVowels("evident")',3) new_check_expect('countVowels("Go Gauchos")',4) check_exception('countVowels(0)','countVowels only takes strings') check_exception('countVowels(["a"])','countVowels only takes strings') # allVowelsA is a function that changes all vowels to A. # This function is a building block for a function that will count # syllables by counting vowels. For that purpose, all vowels are equivalent. # But, we want to remove consecutive duplicate vowels. Converting all # vowels to the same vowel is a first step. # consumes: a string # produces: another string, with all vowels changed to the letter a # examples: # allVowelsA("by") produces "ba" # allVowelsA("alien") produces "alaan" # allVowelsA("boot") produces "baat" # allVowelsA("fruition") produces "fraataan" # exceptions: if the input is not a string, # raise Exception('allVowelsA only takes strings') # Note: empty string is legal, and should return empty string def allVowelsA(word): return -1 # stub value # @@@ FINISH THIS FUNCTION! # @@@ Hint: this is a function that transforms one kind of sequence # @@@ into another. For an example, look at the example we did in lecture # @@@ where we transformed a sequence of numeric grades into a sequence # @@@ of letter grades. # @@@ Recursion is an appropriate problem solving strategy here. new_check_expect('allVowelsA("")',"") new_check_expect('allVowelsA("pwn")',"pwn") new_check_expect('allVowelsA("pwned")',"pwnad") new_check_expect('allVowelsA("pone")',"pana") new_check_expect('allVowelsA("We")',"Wa") new_check_expect('allVowelsA("hold")',"hald") new_check_expect('allVowelsA("these")',"thasa") new_check_expect('allVowelsA("be")',"ba") new_check_expect('allVowelsA("self")',"salf") new_check_expect('allVowelsA("pone")',"pana") new_check_expect('allVowelsA("defenestrate")',"dafanastrata") new_check_expect('allVowelsA("independence")',"andapandanca") new_check_expect('allVowelsA("people")',"paapla") new_check_expect('allVowelsA("fruition")',"fraataan") check_exception("allVowelsA(0)",'allVowelsA only takes strings') check_exception("allVowelsA(['a'])",'allVowelsA only takes strings') # syllableHelper is a function that is a building block for a function # that counts syllables. It transforms a word by doing two things: # (1) changing all vowels to the letter a # (2) removing all consecutive duplicates # consumes: a string # produces: another string, with all vowels changed to the letter a, # and consecutive duplicates removed # examples: # syllableHelper("by") produces "ba" # syllableHelper("alien") produces "alan" # syllableHelper("boot") produces "bat" # syllableHelper("fruition") produces "fratan" # examples: # syllableHelper("by") produces "ba" # syllableHelper("alien") produces "alaan" # syllableHelper("boot") produces "baat" # syllableHelper("fruition") produces "fraataan" # exceptions: if the input is not a string, # raise Exception('syllableHelper only takes strings') # Note: empty string is legal, and should return empty string def syllableHelper(word): return -1 # stub value # @@@ FINISH THIS FUNCTION! # @@@ Hint: this is a function that transforms one kind of sequence # @@@ into another. For an example, look at the example we did in lecture # @@@ where we transformed a sequence of numeric grades into a sequence # @@@ of letter grades. # @@@ Recursion is an appropriate problem solving strategy here. new_check_expect('syllableHelper("")',"") new_check_expect('syllableHelper("Guards")',"Gards") new_check_expect('syllableHelper("people")',"papla") new_check_expect('syllableHelper("fruition")',"fratan") new_check_expect('syllableHelper("Gauchos")',"Gachas") new_check_expect('syllableHelper("by")',"ba") new_check_expect('syllableHelper("buy")',"ba") new_check_expect('syllableHelper("low")',"law") new_check_expect('syllableHelper("Audry")',"adra") check_exception("syllableHelper(0)",'syllableHelper only takes strings') check_exception("syllableHelper(['a'])",'syllableHelper only takes strings') # removeSilentE is an example of a "heuristic". A heuristic is an approach to # a problem that is not perfect, not guaranteed to succeed, but is still # useful. # We want to remove silent e from the ends of words in English. We'll use this approach: # (1) Let "howMany" be the number of 'a's in the word after it has been # processed by the syllableHelper function. # (2) If the original word now ends in 'e', but howMany is >= 2, # then, return the original word without the 'e' in place. # (3) Otherwise, return the word unchanged. # These rules work for many words, such as "rule", "take", and "defenestrate"--we'll remove the silent # 'e' from these words. The rule also works for 'be', 'we', 'the', where the final e should # NOT be removed. Some words where this rule fails are "castle", "chronicle", "muscle" # The idea of a heuristic is that exceptions like these # are rare, so the rule is still pretty good. Problem solving is often a matter of # starting with a "pretty good heuristic", and sucessively refining it. (Can you think of an # improved rule that handles the words "castle", "chronicle" and "muscle" as well?) # # consumes: a string # produces: the same string, but with silent e removed, according to the rules above. # exceptions: if the input is not a string, # raise Exception('removeSilentE only takes strings') # Note: the empty string is legal, and should produce the answer '' (empty string) def removeSilentE(word): return -1 # a stub for testing the tests new_check_expect('removeSilentE("")',"") new_check_expect('removeSilentE("pwn")',"pwn") new_check_expect('removeSilentE("pwned")',"pwned") new_check_expect('removeSilentE("pone")',"pon") new_check_expect('removeSilentE("We")',"We") new_check_expect('removeSilentE("hold")',"hold") new_check_expect('removeSilentE("these")',"thes") new_check_expect('removeSilentE("be")',"be") new_check_expect('removeSilentE("self")',"self") new_check_expect('removeSilentE("pone")',"pon") new_check_expect('removeSilentE("defenestrate")',"defenestrat") new_check_expect('removeSilentE("independence")',"independenc") # tests where our heuristic does the wrong thing. If you can come up with a better # heuristic---one that passes the tests above, but passes these tests when we replace the # non-silent e's below (i.e. removeSilentE('castle') produces 'castle', then you are a star! new_check_expect('removeSilentE("castle")',"castl") new_check_expect('removeSilentE("muscle")',"muscl") new_check_expect('removeSilentE("chronicle")',"chronicl") new_check_expect('removeSilentE("people")',"peopl") check_exception("removeSilentE(0)",'removeSilentE only takes strings') check_exception("removeSilentE(['a'])",'removeSilentE only takes strings') # removeEdWhenNotASyllable is another example of a "heuristic". # In order to be able to count syllables, we want to # remove ed from the ends of words in English such as "owned","phoned", # "rehearsed" and "goverened" when it doesn't add an extra syllable. # We don't want to remove it from # words like "wed","cred", "bed", "tried" # We'll use a similar approach to removeSilentE: # (1) Let "howMany" be the number of 'a's in the word after it has been # processed by the syllableHelper function. # (2) If the original word now ends in 'ed', but howMany is >= 2, # then, return the original word without the 'ed' in place. # (3) Otherwise, return the word unchanged. # Words where this heuristic fails are "busted", "instituted", "enbed" # consumes: a string # produces: the same string, but with silent ed removed, according to the rules above. # exceptions: if the input is not a string, # raise Exception('removeEdWhenNotASyllable only takes strings') # Note: the empty string is legal, and should produce the answer '' (empty string) def removeEdWhenNotASyllable(word): return -1 # a stub for testing the tests new_check_expect("removeEdWhenNotASyllable('')","") new_check_expect("removeEdWhenNotASyllable('pwn')","pwn") new_check_expect("removeEdWhenNotASyllable('pwned')","pwned") new_check_expect("removeEdWhenNotASyllable('pone')","pone") new_check_expect("removeEdWhenNotASyllable('poned')","pon") new_check_expect("removeEdWhenNotASyllable('established')","establish") new_check_expect("removeEdWhenNotASyllable('by')","by") new_check_expect("removeEdWhenNotASyllable('consent')","consent") new_check_expect("removeEdWhenNotASyllable('governed')","govern") new_check_expect("removeEdWhenNotASyllable('wed')","wed") new_check_expect("removeEdWhenNotASyllable('bed')","bed") # Tests that show where the heuristic fails (removing ed when we would rather keep it) new_check_expect('removeEdWhenNotASyllable("embed")',"emb") new_check_expect('removeEdWhenNotASyllable("created")',"creat") new_check_expect('removeEdWhenNotASyllable("busted")',"bust") new_check_expect('removeEdWhenNotASyllable("instituted")',"institut") new_check_expect('removeEdWhenNotASyllable("connected")',"connect") new_check_expect("removeEdWhenNotASyllable('tried')","tried") check_exception("removeEdWhenNotASyllable(0)",'removeEdWhenNotASyllable only takes strings') check_exception("removeEdWhenNotASyllable(['a'])",'removeEdWhenNotASyllable only takes strings') # countSyllables is a final example of a heuristic # The theory is that the number of vowels in a word is a good indicator of the number of syllables # in the word, if we (a) remove silent e, (b) remove final ed when it doesn't create a new syllable # and (c) remove duplicate consecutive vowels in words like "boat", "patient", "pursuit" and "gaucho" # # This works for most words. Convince yourself by trying it in your head on all the words in # this sentence. Then, try it on the first paragraph or two of the declaration of independence, # found here: # # This heuristic does fail for some words. Here are some examples: # "alien", "likely", "States". # # Here's our approach: Write the code to do this. # (1) removeSilentE, removeEdWhenNotASyllable, and then all consecutive duplicate letters # (2) count the remaining vowels # # Note that this approach also removes duplicate consonants, but we don't care, since we are only # counting vowels. (If we changed our heuristic, that might change also). # # consumes: a string # produces: an integer, our best guess at the number of syllables # exceptions: if the input is not a string, # raise Exception('countSyllables only takes strings') # Note: the empty string is legal, and should produce the answer 0 def countSyllables(word): return "stub" # a stub for testing the tests new_check_expect('countSyllables("")',0) new_check_expect('countSyllables("pwn")',0) new_check_expect('countSyllables("pwned")',1) new_check_expect('countSyllables("pone")',1) new_check_expect('countSyllables("poned")',1) new_check_expect('countSyllables("established")',3) new_check_expect('countSyllables("by")',1) new_check_expect('countSyllables("consent")',2) new_check_expect('countSyllables("governed")',2) new_check_expect('countSyllables("wed")',1) new_check_expect('countSyllables("bed")',1) new_check_expect('countSyllables("tried")',1) # Examples where the heuristic fails to produce the correct answer new_check_expect('countSyllables("embed")',1) # really its 2 new_check_expect('countSyllables("created")',1) # really its 3 new_check_expect('countSyllables("busted")',1) # really its 2 new_check_expect('countSyllables("instituted")',3) # really its 4 new_check_expect('countSyllables("alien")',2) # really its 3 new_check_expect('countSyllables("likely")',3) # really its 2 new_check_expect('countSyllables("States")',2) # really its 1 check_exception("countSyllables(0)",'countSyllables only takes strings') check_exception("countSyllables(['a'])",'countSyllables only takes strings')