Computer Science 15-112, Fall 2011
Class Notes:  Final Exam Practice


These notes were prepared by CA's with the intention of helping students prepare for the final exam.  The CA's who wrote these notes have not seen or discussed the actual final exam, which may or may not actually cover the material in these notes.


Note:  The following questions are divided between free response and reasoning about code (with a few miscellaneous questions thrown in with the reasoning about code). Although there may not be quite as much free response on the final as the midterms, doing free response questions is still a great way to study, and there will almost certainly still be some! Reasoning about code is where students have struggled the most, so we tried to get a lot of practice content so you can polish up on that.

Though these problems are on the content covered on the final, studying only them is not a good way to prepare for the final. Note that the final will likely include other kinds of questions you've seen on quizzes and exams (True/False, multiple choice, and draw-what-the-code-draws). Also, content might not be represented below though it will still likely appear on the final. For example, there are no problems on the case studies or Tetris here; this is intentional, as it's very easy for you to 'write' your own by trying to reproduce functions from within the case studies, or understand better how the data structures work, but you still need to be able to do this!

The best way to solve these problems is to write solutions on paper first (as if you were in the exam), and then check your work using python, either by testing a function from Free Response, or by running the code given. You cannot type during the final, so practicing by typing the code is not recommended. Also, you may tackle these problems in any order you like, but for something more like a practice final (keeping in mind there will be some other shorter questions), try the following:

Exam 1: Free Response #2, Free Response #13,  Free Response #16, Free Response #17, Reasoning About Code #s 3-6

Exam 2: Free Response #3, Free Response #8, Free Response #18, Free Response #5, Reasoning About Code #s 7-19

Free Response:

1) [wmacrae] Write the function findAllSums(L) that takes a 1d list of numbers and returns a sorted list of all of the possible sums that can be made from (a possibly-empty subset of) the list. For example, findAllSums([1,2,-1]) gives [-1, 0, 1, 2, 3] and findAllSums([2,2,2]) gives [0, 2, 4, 6]. (This can be written recursively for recursion practice)

 

2) [wmacrae] Write the function findMedian(L) that takes a list of numbers and returns the median. If there are an odd number of elements, this is the middle elements, and if there are an even number, this is the average of the 'middle' two. findMedian([1,5,1,3,6,4]) should return 3.5.

 

3) [wmacrae] A palindrom number is a number that is the same when its digits are reversed. For example, 121 is a palindromeNumber. Write the function nthPalindromNum that returns the nth positive palindrome number. nthPalindromeNum(1) should return 1, and nthPalindromeNum(11) should return 22. (For an easier problem, read the next sentence. For a harder problem, write the function without using strings)

 

4) [wmacrae] Write the function reverseGet(d, v) that takes a dictionary and a value, and returns either a key that is mapped to the given value in the dictionary, or None if no such key exists. For example, reverseGet([{"Steelers": 14, "Browns": 3}], 14) would return "Steelers", and reverseGet([{"Steelers": 14, "Browns": 3}], 10) would return None.

 

5) [wmacrae] Write the function mode(L) that takes a list and returns the set of elements that occur the most number of times.

 

6) [mchoquet] Windows (and probably other operating systems as well) has a problem with long file names; once the number of characters in the path gets to be around 220, it starts failing in unusual ways. Sometimes it won't run, sometimes it won't copy, but either way it can be a problem for large-scale projects with deep file trees. You will solve the problem of finding overlong file names in two different ways:

 

a. Write the function findAllOverlongs(path,limit), which takes in a path, known to be a directory, and a positive integer limit, and recursively returns a list containing all the file and folder PATHS, starting from (and including) the source path, whose name lengths are strictly over the given size limit. Note that if a folder is too long, it and all its subfiles/folders should be in the result list.

 

b. Write the function findLimits(path,limit), which takes in a path, known to be a directory, and recursively finds each of the places where the file path length first goes over the limit. The difference? If a folder is over the limit, don't check any of its subfolders/files.

 

7) [mchoquet] You are given the specifications for a class called Node, designed to be used to implement a data structure called a binary tree. Binary trees are made of Nodes, where each node has a piece of data in it, as well as references to two other nodes (its left and right children). For an example, see the

diagram near the top of the page: http://en.wikipedia.org/wiki/Binary_tree

 

The spec is as follows:

 

class Node:

            METHODS:

            def setLeftChild(newLeft):

                        sets the given Node to be this node's left child

           

            def setRightChild(newRight):

                        sets the given Node to be this node's right child

           

            def getLeftChild():

                        returns this node's left child

 

            def getRightChild():

                        returns this node's right child

 

            def getData():

                        returns the data stored in this node

 

            def copyNode():

                        returns a perfect, deep copy of this node

 

 

Given this information, write the following functions over trees, only using the functions provided above; do not directly access any variables in the class!

 

a.Write contains(node,data), which takes in a Node object and a piece of data, and recursively checks to see whether the data is held anywhere in that tree.

Hint: this node could have the data, or the left child's tree could contain it, or the right child's tree could contain it. Remember your base case!

 

b. (bonus) Write mirror(node), which takes in a node and returns a new Node, whose tree is a perfect mirror of the original tree. Note that this must be completely nondestructive; I recommend using <node>.copyNode(). Hint: it's easy to make a mirror of a node when it has no children; just copy it!

 

8) [mhranick] Write a function called findLargestSong(path) that looks through the files and folders in path and returns the largest file ending in ".mp3".

 

9) [wmacrae] The problem of finding secondary structures of RNA is often solved with recursive programs. We will write a simplified version of one under the assumption that energy is minimized by having the most base pairings. Write bestFold(rna), which takes in a string representing a strand of RNA and returns the greatest number of base pairings possible. The string representing RNA will be made up of the characters 'A', 'U', 'C', and 'G', and pairs must match As with Us or Cs with Gs. So, for example bestFold("GAACCGUU") should return 3, corresponding to the below configuration:

  C

C-G

U-A

A-U

G

Between pairings, extra RNA can be paired or unpaired (such as the C in the middle of the strand shown above), but we will disallow pseudoknots, in which RNA 'circles back' to a previous loop for a pairing, such as adding a pair between the unmatched C and the unmatched G in the above (many real programs exclude this to allow for a better recursive structure).

 

Here are some tips

- First write a function pair(x,y) that checks whether x can pair with y

- The most pairs will be achieved in one of four ways:

- 1. Pair the first and last nucleotides

- 2. Skip the first nucleotide and find pairings in the rest

- 3. Skip the last nucleotide and find pairings in the rest

- 4. Pick a nucleotide in the middle and pair it with the first. Then, you need to pair nucleotides between the first and the 'middle' one, and from the 'middle' one to the end

- For large strands you would want to add memoization

- For a longer description of how it actually works: https://users-cs.au.dk/cstorm/courses/AiBTaS_e09/papers/Eddy2004_RNA.pdf

 

10) [mschervi] Write the function primeLessThan, which takes an integer n and returns the largest prime less than n.

 

11) [mschervi] Write the method eat for the plant class below. This method should try to eat 1+height/5 nutrients from the garden. The plant's height should increase by 1 each time plant's nutrients reaches/exceeds a multiple of 10 if the plant cannot get any nutrients, it will die. You can write any helper methods you wish.

 

class Garden(object):

    def __init__(self, n):

        self.plants=[]

        self.nutrients = n

    def addPlant(self):

        self.plants += [Plant(self)]

    def addNutrients(self, n):

        self.nutrients += n

    def removeNutrients(self, n):

        if self.nutrients<n:

            x=self.nutrients

            self.nutrients=0

            return x

        self.nutrients -= n

        return n

    def getPlants(self):

        return self.plants

class Plant(object):

    def __init__(self, g):

        self.garden = g

        self.height=0

        self.nutrients=0

        self.live = True

    def isLive(self):

        return self.live

 

12) [mschervi] Write the function sustainability(n,p). This function should take 2 integers - n and p and return how many times all plants can eat in a garden with p plants and n initial nutrients in the garden, until one of them dies.Use the classes from above.

 

13) [dswen] Write the function listPythonFiles(path) that returns list of python files (files ending in .py)

 

14) [wmacrae] Write the function listDocFolders(path) that returns a list of all folders that contain a file ending in .doc (either immediately, or in some subfolder)

 

15) [saagars] Write a function redundantNames(path) that when given a directory returns the names of all directories and sub-directories and files within them that share the same name as the directory above them. Return a list of the names only, not the full paths. Don't worry about duplicates.

 

16) [xiaoboz] An interesting conjecture about properties of numbers is the Collatz Conjecture. It states: for any positive number, if it is even then divide it by two, otherwise multiply it by three and add one; continue applying this algorithm and the number eventually reduces to one. Write the function collatzSteps that given a number it calculates the number of steps before it reduces to one, using the proposed algorithm. E.g. collatzSteps(1) == 0 and collatzSteps(2) == 1

 

17) [xiaoboz] Using what you know about class variables and dictionaries, write a memoized function collatzSteps that is the class method of class Collatz.

 In other words, if I call Collatz.collatzSteps(10) first, then Collatz.collatzSteps(20) should return its answer after 1 reduction. You should do this without using the @memoized decorator. Make sure to also store intermediate values! In other words calling Collatz.collatzSteps(10) also allows Collatz.collatzSteps(5) to be solved immediately.

 

18) [askumar] Write a class FarmAnimal and subclasses Chicken and Cow. Any shared methods should only be written once. Your class should pass the asserts in the following code:

 

cow1 = Cow(3, "brown")

assert(type(cow1) == Cow)

assert(isinstance(cow1, FarmAnimal))

assert(cow1.getAge() == 3)

assert(cow1.getNumAnimals() == 1)

 

chicken1 = Chicken(4, "white")

assert(type(chicken1) == Chicken)

assert(isinstance(chicken1, FarmAnimal))

assert(chicken1.getFeatherColor() == "white")

assert(chicken1.getNumAnimals() == 2)

assert(chicken1.getChickens() == [chicken1])

 

cow2 = Cow(5, "black")

assert(cow2.coatColor == "black")

assert(cow2.getNumAnimals() == 3)

assert(cow2.getCows() == [cow1, cow2])

 

Reasoning about code (+ misc):

 

1) [wmacrae] Consider the following line of code:

math.degrees(math.radians(theta)) == theta

 

a. describe what the left hand side of the equality does

b. for many values of theta, this evaluates to False. Explain why.

c. what is a value of theta for which this evaluates to True? [technically, this may require knowledge beyond what you're expected for the final, but your intuition may prove valuable here!]

 

2) [wmacrae] Circle which structures below are immutable in python

1d list

set

dictionary

string

tuple

2d list

 

3) [wmacrae] Provide an integer x such that each of the following functions will return 5 when called with x as their only argument. [test your answers in python after!]

 

def a(x):

            if x < 0:

                        return 0

            p = x%10

            return x/(10**p)%10

 

def b(x):

            return x&(x/4)

 

def c(x):

            assert(type(x) == str)

            if len(x) == 1:

                        return int(x) + 10

            else:

                        return c(x[0]) - c(x[1:])

 

def d(x, i=0, n=3):

            if n==0:

                        return x[i]

            else:

                        return d(x, i=x[i] ,n=n-1)

 

def e(x):

            i = len(x)/2

            y = x[:i]

            z = x[i:]

            return (2*(len(y) - len(y.strip("a"))) +

                        (len(z) - len(z.strip("b")) == 1) * (len(z) == len(z.strip("a"))))

 

def f(x):

            if len(x) < 3: return "too short!"

            y = x

            for i in xrange(len(x)):

                        y[i] += i

            return int(sum(x) + sum(y))

 

class Square(object):

 

            totalArea = 0

           

            @classmethod

            def getTotalArea(cls):

                        return Square.totalArea

 

            def __init__(self, x):

                        self.side = x

                        Square.totalArea += self.area()

 

            def perimeter(self):

                        return 4*self.side

 

            def area(self):

                        return self.side*self.side

 

def g(x):

            Square.totalArea = 0

            for i in xrange(1,1000):

                        s = Square(i)

                        if s.perimeter() > x:

                                    break

            return Square.getTotalArea()

 

def h(x):

            r = len(x[0])

            c = 0

            n = 0

            b = True

            while b:

                        try:

                                    q = x[r][c]

                                    n += 1

                        except:

                                    b = False

                        finally:

                                    n += 1

                                    r += q

                                    c += q

            return n

 

def i(x):

            r = len(x[0])

            c = 0

            n = 0

            b = True

            while b:

                        try:

                                    q = x[r][c]

                                    n += 1

                        except:

                                    b = False

                        finally:

                                    n += 1

                                    r += q

                                    c += q

            return r

 

def j(x):

            return (type(x) == str) + x[0]

 

4) [mchoquet] Give three values of n such that f(n) below returns 16

 

def f(n):

            return 1<<f(n>>1) if n>0 else 0

 

5) [mchoquet] Give a value of a such that g(a) prints:

(3,2)

(1,5)

Then give a value of a such that, at the conclusion of the function g below, 

the largest value in d is 5

 

def g(a):

            d = {}

            for b in a:

                        if b not in d:

                                    d[b] = len(b)

                        else:

                                    print tuple(reversed(b))

 

6) [mchoquet] Give the big-O runtime and the big-O return value of the below function (when n is a positive integer).

 

def f(n):

            res,i = 0,0

            while (i<n):

                        j=1

                        while (j<n):

                                    res+=j

                                    j<<=1

                        i+=1

            return res

 

7) [mhranick] What will the below code print? What does mystery1 do?

 

d1 = { 0:0, 1:3, 2:7, 4:6, 5:3 }
def mystery1(d)
   s = 0
   c = 0
   for n in d:
       s += n*d[n]
       c += d[n]
   return 1.0*s/c

print mystery1(d1)

 

8) [mhranick] When does the below code return True?

 

def f(a, q, l, h):
   m = (l+h)/2
   if (l > h): return False
   if (a[m] < f):
       return f(a, f, m, h)
   elif (a[m] > f):
       return f(a, f, l, m)
   else:
       return True

 

9) [amsmith1 / cswanson] find a value for koz such that helloWorld(koz) returns "Koz_be_Great

 

def helloWorld(koz, result=""):

    if(koz == ""): return result

    result += koz[0] + koz[-1]

    return helloWorld(koz[1:-1], result)

 

10) [amsmith1 / cswanson] find a value for input1 so that umad(input1) returns 7

 

def umad(input1):

    if(input1 <= 0): return 1

    return ((input1 + 1) % 2) + umad(input1 / 2)

 

11) [amsmith1 / cswanson] Find a pair of values for a and b such that fool returns 1024

 

def foo1(a, b):

    if(a > 10): return 1

    if(b == False): return 1

    return (a * b.pop()) * foo1(a, not (b == []) and b)

 

12) [amsmith1 / cswanson] What will the below code print? What is a value of cat such that lolCatz(cat) will return 7? Describe what the function lolCatz does on a high level.

def lolCatz(cat, lol=1):

    if (cat <= 0): 

        return 0

    else:

        return (cat & lol) + lolCatz(cat >> 1, lol << 1)

print lolCatz(39)

 

13) [mschervi] Give values for s and c such that mysteryA(s,c) returns 4

def mysteryA(s,c):

    if(len(s) == 0):

        return -1

    if(len(s)==1):

        return 0 if s[0]==c else -1

    x=len(s)/2

    y=mysteryA(s[:x],c)

    z=mysteryA(s[x:],c)

    if(y>=0):

        return y

    if (z>=0):

        return x+z

    return -1

 

14) [mschervi] Give values for a and i such that mysteryB(a,i) returns [0,3,4]

def mysteryB(a,i):

    if (len(a)==0):

        return []

    if(i==0):

        return a[1:]

    if(i<0 or i >=len(a)):

        return a

    x=len(a)/2

    return mysteryB(a[:x], i)+mysteryB(a[x:], i-x)

 

15) [dswen] Consider the following code:

 

def main(l):
   a = []
   for i in xrange(len(l)):
       a.append(sorted(l[i][::-1]))
       for j in xrange(len(a[i])):
           if (j % (i+1) == 0):
               print a[i][-(j+1)],
       print

Give an example of an input l for which main(l) produces the following output.

3 2 1
5 4
6

 

16) [dswen] Consider the following code:

 

def f2(x):

   i = x/2
   while (x % i > 0):
       print x * i
       i -= 1

Give a value of x for which f2(x) prints the following.

210
189
168

 

17) [saagars] If the input of h is a list, what does the function h do? Be specific. Then, write contracts for the function f.

 

def f(a,b):

    if len(a) == 0:

        return b

    elif len(b) == 0:

        return a

    else:

        if a<b:

            return [a[0]] + f(a[1:],b)

        else:

            return [b[0]] + f(b[1:],a)

def g(a):

    return (a[:len(a)/2],a[len(a)/2:])

 

def h(a):

    if len(a) <= 1:

        return a

    else:

        (b,c) = g(a)

        return f(h(b),h(c))

 

18) [saagars] For what value of a will f(a) return [2,2,3,4,5,6,7]

 

def f(a, j=1, k=0):

    if len(a) <= j :

        return []

    else:

        t = j

        j += k

        k = t

        return [a[k]] + f(a,j,k)

 

19) [xiaoboz] What does the following code do?

 

def doubleRainbow(sky):

    sky&=0xFF

    sky=(sky|(sky>>4))&0xF

    sky=(sky|(sky>>2))&0x3

    sky=(sky|(sky>>1))&1

    return sky^1

 

20) [xiaoboz] What input values makes the following code output 9?

 

def nyanCats(rainbow):

    if(len(rainbow)<=2):

        return 0

    elif(rainbow[0] <= 1):

        return 10

    else:

        return len(rainbow)-nyanCats(rainbow[::rainbow[0]])+nyanCats(rainbow[::2])

 

21) [askumar] What does the following print?

 

def bar(x,y):

    s = ""

    if (len(x) < 2):

        return s

    for z in y:

        for y in x:

            if (s < y):

                s += z

    return s + bar(x[1:], y)

 

print bar("cat", "dog")

 

22) [askumar] What does the following print?

def unicorn(sparkle, magic):

    fairy = []

    if (sparkle == 0 or magic == 0):

        return [1]

    for star in unicorn(sparkle/2, magic-1):

        fairy += [star]

        if sparkle % star == 0:

            fairy += [sparkle]

        elif magic % star == 1:

            fairy += [magic]

    return fairy 

 

print unicorn(21, 3)

 

23) [askumar] Supply arguments a,b such that awesome(a,b) returns True.

 

def awesome(a, b):

    z = 0

    False = (bool)(0)

    for x in xrange(a**b):

        if (x % b == 0):

            True = False

            False = not True

        else:

            z += a

    return (False and z > a**b)


Practice Problems for Final Exam
15-112 Fall 2011
Charlie Swanson

1.      True/False. Circle either True or False for each statement.

TRUE or FALSE : To tell if a row was full in tetris, we simply checked that none of the values of the row were canvas.data.emptyColor

TRUE or FALSE : In our implementation of snake, the tail of the snake had the    largest value

TRUE or FALSE : a program that runs in O(n2) will take longer to run on all          inputs than one that runs in O(nlogn)

TRUE or FALSE : Anything that can be done with a for loop can also be done      with a while loop.

TRUE or FALSE : Recursion is awesome

TRUE or FALSE : [([0] * cols) for row in xrange(rows)] will create a valid

      (non-aliased) 2D list

TRUE or FALSE : good style will protect you from bugs

TRUE or FALSE : every class must have an __init__() function

TRUE or FALSE : in our implementation of wordSearch, we never actually           checked if it matched our word until wordSearch2 (the last wordSearch function)

TRUE or FALSE : an invariant can be used inside a loop to make sure it is             behaving properly

 

2.      Indicate what the following will print:

           

a = 0

for i in xrange(3, 8, 2):

    a += i%4

print a

 

def f(n, m):

    r = 0

    for i in xrange(m):

        r += i^m

    return r

print f(7, 8)

 

str = ""

for c in "hellotherehowareya":

    if ((ord(c)>= ord("a")) and

        (ord(c)<= ord("h")):

         str += c

print str[1:4]

 

blah = ":\"/\t-\nhi)"

for i in xrange(0, len(blah), 4):

    print blah[i],

 

 

def f(a, b = []):

    if len(a) == 0:

        return b

    else:

        return f(a[:-1], b+[a[-1]])

print f([1,2,3,4])

 

 

 

f = lambda a,b : a + b

print reduce(f, [1,2,3,4])

 

 

 

3.      Short answer: 

a.       in hw6, we had the method getWheels inside of the class Vehicle raise an exception. What was that exception, and why did it make sense for the class Vehicle to raise it?

b.      describe how we draw a star

c.       what does running python –i foo.py on the linux shell do? (assuming foo.py exists in the current directory). How is it useful?

d.      In our run() function in tKinter, what is the purpose of the lines

                                    class Struct(): pass

              canvas.data = Struct()

e.       Prove (using a truth table), that x ^ (not y) == not(x ^ y)

                        (here ^ is the logical operator exclusive or, meaning x or y, but not both)

4.      Free response:

            a. (I don’t think anything this long would be on the exam, but it’s a good exercise). Assuming the run function is already written, and that canvas.data.width and canvas.data.height are set to 500 and 500, write a program that initially displays two bubbles on the screen, one with radius 30, one with radius 15 (just circles is fine). The two bubbles should bounce around the screen whenever they get to the edge. You can start them wherever you want to, and moving in any direction, at any speed. When the two bubbles collide, they should join together (form a new bubble whose radius is the sum of their radii, and whose center is the average of their centers. Then, every 4 seconds (exactly, using time.time(), NOT timerFired), a new bubble should appear in the middle, moving in a random direction, with a random radius between 10 and 40, and behave the same way as the old bubbles. You must use a class Bubble(object). Write the functions redrawAll(), timerFired(), and init(), as well as the class Bubble, and any other methods you find useful, that would make it behave this way.


Practice Midterm II (15-110-S11)

Read all of the following information before starting the exam: 

·         This PRACTICE midterm is not meant to be a perfect representation of the upcoming midterm! This practice exam was not made to be all-inclusive. You are still responsible for knowing all material up to and including Homework 7: Tetris.

·         This exam will likely be longer than the actual midterm.

·         Read instructions carefully and show all work.

·         Short answer questions should be answered briefly, but completely.

·         For solutions, attend a CA-led review session, or contact your CA.

·         Most of the questions come from past exams and quizzes. Therefore it is possible for any of these questions or something of similar level to come up in your midterm 2.

·         Good luck!

Total Points: 180

 

Disclaimer: "At this point, I have not seen the exam paper yet. Therefore the difficulty level may vary but this practice should help you to identify which topics you need more focus on" - Andre

Code Tracing: Indicate what the following code will print / draw

  1. (5 points)

a = [4, 2, 6, 1, 5]

j = 0

for i in range (len(a)-1, -1, -2):

      a[j] += a[i]

      j += 1

      print a

 

  1. (5 points)

z = 251

s = "z" + str(z)

while (z > len(s)):

      z /= len(s)

      s += str(z)

      print z, ",", s

 

  1. (5 points)

def mystery(x, y, depth=0):

    print "   "*depth, "mystery(", x, ",", y, ")"

    if ((x < y) or (y <= 0)):

        pass # do nothing

    else:

        mystery(x/y, y-1, depth+1)

        mystery(x/5, y/2, depth+1)

 

mystery(13, 4)

 

  1. (5 points)

# Assuming that all of the other functions are written,

# canvas.data.width = 200, canvas.data.height = 150,

# and redrawAll() is called in init()

 

def redrawAll()

      k = 2

      h = canvas.data.height

w = canvas.data.width

px = []

py = []

      for x in range (0, w, 50):

            for y in range (h/k, h, h/k):

                  px += [x]

                  py += [y]

      canvas.create_polygon(px[0],py[0],px[2],py[2],px[3],py[3],\

fill="black",outline ="black",width=5)

 

 

 

Mystery Code: What do these functions do? State what each of the following functions does in general, in a few words of plain English. You must identify the general pattern and should not state line by line what each step of the function does.

 

  1. (5 points)

# Assume ls is a list

def mysteryA(ls):

    if len(ls) == 0:

        return [[]]

    else:

        r = []

        h = []

        for x in ls:

            if x not in h:

                ts = ls[:]

                ts.remove(x)

                for p in mysteryA(ts):

                    r.append([x]+p)

            h.append(x)

        return r

 

  1. (5 points)

# a and b are lists with single-digit integers as elements

def mysteryB(a, b):

    while (len(a) < len(b)):

        a.insert(0, 0)

    while (len(b) < len(a)):

        b.insert(0, 0)

    r = [0] * len(a)

    c = 0

    for i in range(len(a)):

        p = len(a) - 1 - i

        s = c + a[p] + b[p]

        r[p] = s % 10

        c = s / 10

    if (c > 0):

        r.insert(0, c)

    return r

 

  1. (5 points)

# s is a string

def mysteryC(s):

    x = 0

    for i in range(len(s)):

        c = s[i]

        if (c >= 'a' and c <= 'z'):

            x += 1

        elif (c >= 'A' and c <= 'Z'):

            x -= 1

    return (x >= 0)

 

 

  1. (5 points)

# n is a positive number

def mysteryD(n):

    assert (n > 0)

    x = 2

    a = 0

    for i in range (1, n+1):

        if ((i+1)/x == (i+1)%x):

            x *= 2

            a += 1

    return a

 

Code Writing

  1. (7 points) Write a function save(list2d) that takes in a 2d list of integers and save it into a text file on the desktop. Then write load(filename) that reads from the above-mentioned file and returns the original 2d list of integers. You may assume that all of the file I/O functions (e.g. getDesktopPath, fileExists, readTextFile, etc.) are written for you.

Note: load(filename) should not crash it the file does not exist. It should print "File Not Found" instead.

  

  1. (8 points) Write a function write(s, filename) that takes in a string s and a filename. This function should be similar to writeTextFile that is provided, however, write(s, filename) should not rewrite the file but adds the string s as a new line in the original file. If the file does not exist, then write(s, filename) should create a new file. You may assume that all of the file I/O functions (e.g. getDesktopPath, fileExists, readTextFile, etc.) are written for you.

Hint: You might want to utilize the writeTextFile function within write(s, filename)

Example:

Original File:

123

456

789

 

After write("abc", filename)

File:

123

456

789

abc

 

  1. (8 points) Write a function mixUpLines(filename) that takes a filename  crazily swaps its lines around and rewrites the original file. Each of the line number from the original file should be mapped to a unique line number in the new file (e.g. newLineIndex = (oldLineIndex * 2) % totalNumberOfLines). This way, the data is not lost but all of the lines will be mixed up. You are allowed to use the same formula to mix up the lines. You may assume that all of the file I/O functions (e.g. getDesktopPath, fileExists, readTextFile, etc.) are written for you.

Hint: Since you need to access each line in the file and then swap them around, how do you want to read the file?

 

  1. (8 points) Use Monte Carlo Method to simulate the concept of Gambler’s Ruin!

 

  1.  (10 points) Write a Python function that takes three positive integers – the number of dice, the number of sides per dice, and the targetValue – and uses Monte Carlo techniques to return the odds of getting all die with value = targetValue when rolling that many dice, each with the given number of sides per dice. For example, the function should be able to return the odd of getting 5, 5, 5 from a roll of 3 six-sided-die.

 

  1.  (8 points) Write a function uniqueLetterCount that takes a String and returns the number of unique letters, ignoring case, that occur in that String.  For example, "Wowee" contains the letters 'e', 'o', and 'w' (ignoring case), so uniqueLetterCount("Wowee") should return 3.  Ignore all non-letters.  The null string contains no unique letters.

 

  1.  (8 points) Assuming the usual run function with a 300x300 canvas. Write a program that animates a red ball bouncing up-and-down along the right edge of the window.  When the user presses ‘b’, the ball becomes blue (and stays blue from that point on). 

 

  1.  (8 points) Assuming the usual run function with a 300x300 canvas, write an animation that first displays a horizontal line of length 100 that is centered in the canvas, and a ball of radius 10 that is centered on the right endpoint of the line.  Each time the user presses the left arrow; the ball moves five pixel left, until the center of the ball reaches the left endpoint of the line, after which left presses are ignored.

 

  1. (15 points) Write a function findTreasure(myList) that traverses a list of integers simulating a treasure hunt. Begin searching for the treasure (the only element in the list with value -1) starting from the first element. The value of each element represents the index of next element to be visited. Your function will print one out of three messages:

 

1) if the treasure is found, print "Found treasure in X steps.", where X is the actual number of steps it took to find to the treasure;

2) if the first element in the list is the treasure, print "No steps were needed.";

3) if there is a bad clue (a clue indexing a non existing element), print "Bad clue!".

 

For example, given  myList = [2, -1, 1], your function will print "Found treasure in 2 steps".  This is because you always start with the first element, myList[0], which has value 2.  This means that the next element to go to is myList[2].  myList[2] has value 1 which means that the next element to be visited is myList[1].  Finally, we realize that myList[1] has value -1 (we have found the treasure!) . It took two clues (or steps) to find the treasure.  Other examples:

 

myList = [3, -1, 1, 5, 5, 2]

Found treasure in 4 steps.

 

myList = [2, -1, 10]

Bad clue!

 

myList = [-1]

No steps were needed.

 

 

  1. (5 points) Write a recursive function isReverse(s1, s2) that takes two strings and returns True if s1 is the reverse of s2, and False otherwise.

 

  1. (10 points) Assuming that fallingPieceIsLegal(), init(), run() canvas.data.board, canvas.data.fallingPiece, canvas.data.fallingPieceRow, canvas.data.fallingPieceCol, and canvas.data.emptyColor are defined for you, write rotateFallingPiece().

 

Hint: Do not forget to shift the center accordingly

 

  1. (10 points) Given canvas.data.snakeBoard and all of the other snake functions are defined, write placeFood() and removeTail().

 

Short Answers and Miscellaneous Questions

 

  1. (6 points) Assuming the usual run function, the following animation is supposed to display a rectangle that alternates between green and yellow, with the animation pausing or unpausing each time the user presses "p".  The pause feature is broken, unfortunately, so as it is now, the program pauses on "p" but never unpauses.  For this problem, you will fix this bug in two separate ways.

 

def keyPressed(event):
    canvas = event.widget.canvas
    if (event.char == "p"):
        canvas.data["paused"] = not canvas.data["paused"]

 


def timerFired(canvas):
    redrawAll(canvas)
    if (canvas.data.paused == False):
        canvas.data["counter"] += 1
        delay = 250 # milliseconds
        canvas.after(delay, timerFired, canvas)

def redrawAll(canvas):
    canvas.delete(ALL)
    color = "green"
    if (canvas.data.counter % 2 == 0):
        color = "yellow"
    canvas.create_rectangle(100, 100, 200, 200, fill=color)

 

def init(canvas):
    canvas.data.counter = 0
    canvas.data.paused = False

 

a.       Fix the pause bug by changing the timerFired function (and nothing else). You may make edits to the following code:

def timerFired(canvas):
    redrawAll(canvas)
    if (canvas.data.paused == False):
        canvas.data["counter"] += 1
        delay = 250 # milliseconds
        canvas.after(delay, timerFired, canvas)

 

b.      Fix the pause bug by changing the keyPressed function (and nothing else). You may make edits to the following code:

def keyPressed(event):
    canvas = event.widget.canvas
    if (event.char == "p"):
        canvas.data["paused"] = not canvas.data["paused"]

 

  1. (4 points) The following function is supposed to find the smallest digit in the given integer parameter, but it contains one bug on one line. Circle the bug and provide the correct line of code.

 

   def smallestDigit(n):
      n = abs(n)
      smallest = 0
      while (n > 0):
         digit = n%10
         if (digit < smallest):
            smallest = digit
         n /= 10
      return smallest

 

  1. (6 points) The following is a correct function that solves the "Towers of Hanoi" game. Break this code by changing one single character of it. With your change, the program is still syntactically correct, but it will never terminate (if you run it on a computer with unlimited memory, so the program will not crash because of a stack overflow). Will your modified program ever print any partial results? Explain.

 

def hanoi(n, source, target, temp):
      if n == 1:
         print "Move", source, "to", target
      else:
         hanoi(n-1, source, temp, target)
         hanoi(1, source, target, temp)
         hanoi(n-1, temp, target, source)

 

  1. (5 points) Briefly explain how wordSearch functions are used to determine the winner in Tic-Tac-Toe / Connect 4.

  

  1. (2 points) Strings are immutable in Python.  Very briefly, what does this mean?

 

  1. (2 points) What must be true in order for binary search to work properly over a list?

 

  1. (4 points) Very briefly, and in English (not Python!), explain how selection sort and merge sort work.

 

  1. (3 points) In just a few words, how do we represent the 8 possible directions in 2d board search?

 

  1. (2 points) In our Snake implementation, say our timerFired tries to set the headRow and headCol to a board location that contains the value -1.  From the user’s perspective, what just happened?

 

  1. (2 points)  Briefly explain what a short-circuit-evaluation means.
     

carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem   -   carpe diem