Final Exam Study Guide
The final exam for this course is comprehensive: it covers all of the material we have discussed this semester, a list of which can be found on the Course Schedule. You are encouraged to use all of the following material to prepare yourself for the final exam:
- the previous study guides (1, 2, 3, 4, 5, 6)
- your returned quizzes and labs
- the course textbook
- quizzes from the other sections
- this study guide
Exam Composition
The final exam will consist of eight multi-part questions, each of which will cover a topic that we have discussed in class. As a general rule, any topic on which we have had a lab assignment is an example of a topic about which a question may be asked (recursion, classes and objects, loops, etc.). Questions may also be asked regarding material given significant attention during lecture (e.g. algorithmic complexity). You will not be asked questions about material which was not covered either in lecture or lab. We expect that this exam will take most students between 1½ to 2 hours; the exam is scheduled in a 3 hour time slot.
During the exam, you may be expected to
- Read Python code to predict its behavior
- Find mistakes in Python code and describe how to correct them
- Write Python code in significant amounts without the use of a computer (e.g. a program spanning a few functions)
- Know the types to which various Python expressions will evaluate
- Draw stack diagrams demonstrating your understanding of a program’s execution
- Answer conceptual questions regarding CS21 material (e.g. definition of prominent vocabulary words such as “recursion”)
The quizzes administered during class give examples of all of these tasks.
Practice Questions
In addition to the previous study guides, labs, and quizzes, the following is a collection of practice questions which should help you prepare for the exam.
Types
Determine the value to which each of the following expressions evaluates. Then, give the Python type of that value.
5
5 + 2
5 / 2
5.0 / 2.0
5 == 2
5 >= 2
"five" + "two"
"five" * 2
"five%d" % 2
str(5)
range(2,5)
len(range(2,5))
Functions
Write both iterative and recursive functions to perform the following tasks:
- Add the numbers from
1
up to some parametern
and return the result - Add
1
to every element in a list (returning a new list with the new values) - Reverse the ordering of characters in a string
- For three parameters
s
,old
, andnew
, replace all occurrences of the characterold
ins
with the characternew
Classes and Objects
Consider the following code:
class Turtle(object):
def __init__(self, name):
self.name = name
self.diet = "lettuce"
def __str__(self):
return "A turtle named %s that eats %s" % (self.name, self.diet)
def get_diet(self):
return self.diet
def set_diet(self, diet):
self.diet = diet
def can_eat(self, food):
return food == self.diet
def main():
turtle = Turtle("Sanjana")
print turtle
print turtle.can_eat("lettuce")
main()
Given the above, answer the following questions:
- What will the above program print when it is executed?
- In the
__init__
method, onlyself
andname
are given as parameters butself.diet
is named in the method body in addition toself.name
. Why is this okay? - When
turtle.can_eat
is called inmain
, it is given only one argument. The methodcan_eat
has two parameters:self
andfood
. What are the values assigned to each of these parameters? Why is it okay for there to be an extra parameter in thecan_eat
method? - How can we change the above program so that the third line of
main
printsFalse
? - How can we change the above program so that the second line of
main
prints the messageA turtle named Turtlestopheles that eats the anguished screams of lettuce of ages past!
?
Now, write a class called TurtleFarm
which keeps track of zero or more turtles. It should have the following methods:
- A constructor, which takes no arguments but prepares the
TurtleFarm
to hold several turtles. - An
add_turtle
method which accepts aTurtle
object to add to the farm. - A
farm_size
method determining how manyTurtle
s are in the farm. - A
feeding_time
method which takes a list of food. It returnsTrue
if there is some food for everyTurtle
(that is, if there is a string in the list for eachTurtle
describing the food it can eat) andFalse
if there is not. The list of food does not need to be in any particular order.
Complexity
What is the complexity of each of the following algorithms on a list of size n? (Note: the links below lead to Wikipedia pages which contain the answer. Try to guess answers for all of these before clicking the links.)
Consider the following code:
def make_special_list(n):
lst = []
for i in range(n):
for j in range(n):
for k in range(n):
lst.append(i+j+k)
return
What is the complexity of this method in terms of n?
Searching and Sorting
Consider the following list:
[ 'a' , 'c' , 'd' , 'e' , 'h' , 'i' , 'j' , 'm' , 'o' , 'q' , 'r' , 't' , 'v' , 'x' , 'z' ]
(index) 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
Show how a binary search would proceed on this list by giving the values of L
, R
, and M
determined at each step.
The bubble sort algorithm consists of two loops: an inner loop (which compares and may swap a single pair of elements) and an outer loop. Given the list [3,6,1,2,8,2,4,5]
, show how bubble sort will change that list after each iteration of the outer loop.
Tracing and Debugging
For each of the following two programs, draw a stack trace for the moment that the program reaches the comment # HERE
.
def f(x):
if x > 0:
# HERE
print "Positive!"
return x * 2
else:
print "Not positive!"
return x + 5
def main():
x = -3
x = f(x)
x = f(x)
x = f(x)
main()
class TicketDispenser(object):
def __init__(self):
self.counter = 0
def next_ticket(self):
# HERE
return self.counter + 1
def main():
dispenser = TicketDispenser()
for n in range(5):
print dispenser.next_ticket()
main()
Suppose the second program was intended to print the numbers of the first 5 tickets in the ticket dispenser (which should be 1, 2, 3, 4, and 5). There is a bug in this program. Identify it and explain how to correct it.
Writing Programs
Write a program which determines what a student’s course letter grade will be depending on how well they do on their final exam. You will ask the user for the name of a file which contains 3 lines. Those lines are:
- A comma-separated list of the weights that quizzes, labs, and the final will have in the course (e.g.
30,40,25
– we’re pretending that there’s no participation grade) - A comma-separated list of quiz grades (e.g.
95,85,80,96,92,94
) - A comma-separated list of lab grades (e.g.
100,100,95,94,96,98,82,74,96,92
)
From this information, you should:
- Print out the average for the quiz and lab grades
- Print out the course average grade based on the grade the student receives from the final exam, in increments of 5 from 60 to 100
Given the above data, your program might output
Final exam score: 60 Course grade: 83.1
Final exam score: 65 Course grade: 84.4
Final exam score: 70 Course grade: 85.7
Final exam score: 75 Course grade: 87.0
Final exam score: 80 Course grade: 88.4
Final exam score: 85 Course grade: 89.7
Final exam score: 90 Course grade: 91.0
Final exam score: 95 Course grade: 92.3
Final exam score: 100 Course grade: 93.6
You should write at least three functions (including your main
function).
Remember: try to write this program without the aid of the Python interpreter! You will be expected to write a similar program on paper during the exam.
Linked Lists
Consider the linked list code we used in the most recent lecture (found here). Add to that code the following methods:
- A method which counts the number of times a given value appears in the list (similar to the Python list’s
count
method). - A method which removes all instances of a given value from the list.
- A method which creates a duplicate copy of the list (so that if the first list changes, the second list does not).