Lab 8: Midterm 2 Review
Due at 11:59pm on 10/21/2015.
Starter Files
Download lab08.zip. Inside the archive, you will find starter files for the questions in this lab, along with a copy of the OK autograder.
Submission
By the end of this lab, you should have submitted the lab with
python3 ok --submit
. You may submit more than once before the
deadline; only the final submission will be graded.
- To receive credit for this lab, you must complete questions 1, 2, and 3 in lab08.py and submit through OK.
Question 1: WWPP: Methods
Use OK to test your knowledge with the following "What Would Python Print?" questions:
python3 ok -q foobar -u
Hint: Remember for all WWPP questions, enter
Function
if you believe the answer is<function ...>
andError
if it errors.
>>> class Foo:
... def print_one(self):
... print('foo')
... def print_two():
... print('foofoo')
>>> f = Foo()
>>> f.print_one()
______foo
>>> f.print_two()
______Error
>>> Foo.print_two()
______foofoo
>>> class Bar(Foo):
... def print_one(self):
... print('bar')
>>> b = Bar()
>>> b.print_one()
______bar
>>> Bar.print_two()
______foofoo
>>> Bar.print_one = lambda x: print('new bar')
>>> b.print_one()
______new bar
Question 2: WWPP: Attributes
Use OK to test your knowledge with the following "What Would Python Print?" questions:
python3 ok -q attributes -u
Hint: Remember for all WWPP questions, enter
Function
if you believe the answer is<function ...>
andError
if it errors.
>>> class Foo:
... a = 10
... def __init__(self, a):
... self.a = a
>>> class Bar(Foo):
... b = 1
>>> a = Foo(5)
>>> b = Bar(2)
>>> a.a
______5
>>> b.a
______2
>>> Foo.a
______10
>>> Bar.b
______1
>>> Bar.a
______10
>>> b.b
______1
>>> Foo.c = 15
>>> Foo.c
______15
>>> a.c
______15
>>> b.c
______15
>>> Bar.c
______15
>>> b.b = 3
>>> b.b
______3
>>> Bar.b
______1
Question 3: Advanced Counter
Complete the definition of make_advanced_counter_maker
,
which creates a function that creates counters. These counters can not
only update their personal count, but a shared count for all
counters. They can also reset either count.
def make_advanced_counter_maker():
"""Makes a function that makes counters that understands the
messages "count", "global-count", "reset", and "global-reset".
See the examples below:
>>> make_counter = make_advanced_counter_maker()
>>> tom_counter = make_counter()
>>> tom_counter('count')
1
>>> tom_counter('count')
2
>>> tom_counter('global-count')
1
>>> jon_counter = make_counter()
>>> jon_counter('global-count')
2
>>> jon_counter('count')
1
>>> jon_counter('reset')
>>> jon_counter('count')
1
>>> tom_counter('count')
3
>>> jon_counter('global-count')
3
>>> jon_counter('global-reset')
>>> tom_counter('global-count')
1
"""
"*** YOUR CODE HERE ***"
global_count = 0
def make_counter():
count = 0
def counter(msg):
nonlocal global_count, count
if msg == 'count':
count += 1
return count
elif msg == 'reset':
count = 0
elif msg == 'global-count':
global_count += 1
return global_count
elif msg == 'global-reset':
global_count = 0
return counter
return make_counter
Use OK to test your code:
python3 ok -q make_advanced_counter_maker
Question 4: Find Intersection
Implement intersection
, which takes two linked lists, xs
and ys
, and finds
the Link
at which the two linked list begin to intersect (or overlap).
Remember that all Link
s end with Link.empty
, so there will always be some
overlap.
For the two linked lists below, z1
should be the start of the linked list that
you return. Note that you should be comparing with identity, rather than
equality; an intersection means that some part of the Link
is shared between
xs
and ys
, not just that they have the same elements.
Try to aim for θ(n)
runtime (where n
is the sum of the lengths of xs
and
ys
), and even θ(1)
additional space.
xs: x1 -> x2 -> z1 -> z2 -> z3 -> ...
^
|
ys: y1 ---+
def intersection(xs, ys):
"""
>>> a = Link(1)
>>> intersection(a, Link.empty) is Link.empty
True
>>> b = a
>>> intersection(a, b).first # intersection begins at a
1
>>> looks_like_a = Link(1)
>>> intersection(a, looks_like_a) is Link.empty # no intersection! (identity vs value)
True
>>> b = Link(1, Link(2, Link(3, a)))
>>> a.first = 5
>>> intersection(a, b).first # intersection begins at a
5
>>> c = Link(3, b)
>>> intersection(b, c).first # intersection begins at b
1
>>> intersection(c, b).first # intersection begins at b
1
>>> intersection(a, c).first # intersection begins at a
5
"""
"*** YOUR CODE HERE ***"
if xs is Link.empty or ys is Link.empty:
return Link.empty
# make xs and ys the same size
if len(xs) < len(ys):
return intersection(xs, ys.rest)
elif len(xs) > len(ys):
return intersection(xs.rest, ys)
# comparison
while xs is not ys:
xs, ys = xs.rest, ys.rest
return xs
Use OK to test your code:
python3 ok -q intersection
Question 5: Trade
In the integer market, each participant has a list of positive integers to trade. When two participants meet, they trade the smallest non-empty prefix of their list of integers. A prefix is a slice that starts at index 0.
Write a function trade
that exchanges the first m
elements of list first
with the first n
elements of list second
, such that the sums of those
elements are equal, and the sum is as small as possible. If no such prefix
exists, return the string 'No deal!'
and do not change either list. Otherwise
change both lists and return 'Deal!'
. A partial implementation is provided.
def trade(first, second):
"""Exchange the smallest prefixes of first and second that have equal sum.
>>> a = [1, 1, 3, 2, 1, 1, 4]
>>> b = [4, 3, 2, 7]
>>> trade(a, b) # Trades 1+1+3+2=7 for 4+3=7
'Deal!'
>>> a
[4, 3, 1, 1, 4]
>>> b
[1, 1, 3, 2, 2, 7]
>>> c = [3, 3, 2, 4, 1]
>>> trade(b, c)
'No deal!'
>>> b
[1, 1, 3, 2, 2, 7]
>>> c
[3, 3, 2, 4, 1]
>>> trade(a, c)
'Deal!'
>>> a
[3, 3, 2, 1, 4]
>>> b
[1, 1, 3, 2, 2, 7]
>>> c
[4, 3, 1, 4, 1]
"""
m, n = 1, 1
"*** YOUR CODE HERE ***"
equal_prefix = lambda: sum(first[:m]) == sum(second[:n])
while m < len(first) and n < len(second) and not equal_prefix():
if sum(first[:m]) < sum(second[:n]):
m += 1
else:
n += 1
if False: # change this line!
if equal_prefix(): first[:m], second[:n] = second[:n], first[:m]
return 'Deal!'
else:
return 'No deal!'
Use OK to test your code:
python3 ok -q trade
Question 6: Boom (Orders of Growth)
What is the order of growth in time for the following function boom? Use big-θ notation.
def boom(n):
sum = 0
a, b = 1, 1
while a <= n*n:
while b <= n*n:
sum += (a*b)
b += 1
b = 0
a += 1
return sum
θ(n4)
Use OK to test your code:
python3 ok -q boom -u