0% found this document useful (0 votes)
9 views12 pages

2021 Fall Final

Uploaded by

vr2vfp9ry4
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views12 pages

2021 Fall Final

Uploaded by

vr2vfp9ry4
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 12

Last Name: First: Netid:

CS 1110 Final, December 12th, 2021

This 150-minute exam has 8 questions worth a total of 100 points. Scan the whole test before
starting. Budget your time wisely. Use the back of the pages if you need more space. You may tear
the pages apart; we have a stapler at the front of the room.

It is a violation of the Academic Integrity Code to look at any exam other than your
own, look at any reference material, or otherwise give or receive unauthorized help.

You will be expected to write Python code on this exam. We recommend that you draw vertical
lines to make your indentation clear, as follows:

def foo():
if something:
do something
do more things
do something last

Unless you are explicitly directed otherwise, you may use anything you have learned in this course.
You may use the backside of each page for extra room for your answers. However, if you do this,
please indicate clearly on the page of the associated problem.

Question Points Score


1 2
2 14
3 9
4 14
5 10
6 22
7 12
8 17
Total: 100

The Important First Question:


1. [2 points] Write your last name, first name, and netid at the top of each page.
Last Name: First: Netid:

References
String Operations

Expression Description

len(s) Returns: Number of characters in s; it can be 0.


a in s Returns: True if the substring a is in s; False otherwise.
s.find(s1) Returns: Index of FIRST occurrence of s1 in s (-1 if s1 is not in s).
s.count(s1) Returns: Number of (non-overlapping) occurrences of s1 in s.
s.islower() Returns: True if s is has at least one letter and all letters are lower case;
it returns False otherwise (e.g. 'a123' is True but '123' is False).
s.isupper() Returns: True if s is has at least one letter and all letters are upper case;
it returns False otherwise (e.g. 'A123' is True but '123' is False).
s.lower() Returns: A copy of s but with all letters converted to lower case
(so 'A1b' becomes 'a1b').
s.upper() Returns: A copy of s but with all letters converted to upper case
(so 'A1b' becomes 'A1B').
s.isalpha() Returns: True if s is not empty and its elements are all letters; it returns
False otherwise.
s.isdigit() Returns: True if s is not empty and its elements are all numbers; it returns
False otherwise.
s.isalnum() Returns: True if s is not empty and its elements are all letters or numbers;
it returns False otherwise.

List Operations

Expression Description

len(x) Returns: Number of elements in list x; it can be 0.


y in x Returns: True if y is in list x; False otherwise.
x.index(y) Returns: Index of FIRST occurrence of y in x (error if y is not in x).
x.count(y) Returns: the number of times y appears in list x.
x.append(y) Adds y to the end of list x.
x.insert(i,y) Inserts y at position i in x. Elements after i are shifted to the right.
x.remove(y) Removes first item from the list equal to y. (error if y is not in x).

Dictionary Operations

Expression Description

len(d) Returns: number of keys in dictionary d; it can be 0.


y in d Returns: True if y is a key in dictionary d; False otherwise.
d[k] = v Assigns value v to the key k in dictionary d.
del d[k] Deletes the key k (and its value) from the dictionary d.
d.clear() Removes all keys (and values) from the dictionary d.

Page 2
Last Name: First: Netid:

2. [14 points total] Testing and Exceptions


(a) [5 points] Below is the specification of a function. Do not implement it. In the space
below, provide at least five different test cases to verify that this function is working
correctly. For each test case provide: (1) the function input, (2) the expected output, and
(3) an explanation of what makes this test significantly different.
def repeat(s,n):
"""Returns a copy of s concatentated together n times.
Example: repeat('a',4) returns 'aaaa'
Precondition: s is a string, n > 0 an int"""

(b) [9 points] Consider the functions listed below. Note that ValueError and AssertionError
are both subclasses of Exception but neither is a subclass of the other. On the next page,
we want you to write down the text printed out (e.g. the traces) for each function call.

1 def first(n): 11 def second(n):


2 x=0 12 y=5
3 try: 13 try:
4 print('Try first') 14 print('Try second')
5 x = second(n) 15 y = third(n)
6 except Exception: 16 except ValueError:
7 print('Except first') 17 print('Except second')
8 x = x+2 18 y = y-2
9 print('End first at '+str(x)) 19 print('End second at '+str(y))
10 return x 20 return y

21 def third(n):
22 print('Start third')
23 if n == 0:
24 print('Third at n == 0')
25 raise ValueError('Value error')
26 elif n == 1:
27 print('Third at n == 1')
28 assert False, 'Assertion error'
29 print('End third at '+str(n))
30 return n

Page 3
Last Name: First: Netid:

i. first(0) iii. first(2)

ii. first(1)

3. [9 points total] Short Answer


(a) [3 points] Name the four categories of Python variables seen in class.

(b) [2 points] What is the difference between a function and a method?

(c) [4 points] Name four sorting algorithms we covered in class, and the running time of each
(e.g. n, n log n, or n2 ).

Page 4
Last Name: First: Netid:

4. [14 points] Iteration


The Python package numpy has a lot of tools for manipulating matrices (what you may call a
table), which are 2-dimensional lists of numbers. One of the things that numpy can do is to
reshape a matrix. When you reshape a matrix with m rows and n columns, you turn it into a
matrix with s rows and t columns, where mn = st. For example, we can call reshape twice to
turn a 2x4 matrix into a 4x2 matrix, and then into a 1x8 matrix as follows:
 
  1 2
1 2 3 4 3 4  
=⇒   =⇒ 1 2 3 4 5 6 7 8
5 6 7 8 reshape(a,4,2) 5 6 reshape(a,1,8)
7 8

Note that 1x8 matrix is not a 1-dimensional list. It is a nested list containing one list (the
row) of eight elements. Similarly, an 8x1 matrix is a nested list of eight one-element lists.
When you reshape the matrix, you process the elements in normal row-major order. So top row
first, left-to-right. With this in mind, implement the function below according to its specifica-
tion. You are allowed to use any form of iteration (for-loop or while-loop) that you want.
Hint: This function is a lot simpler if you first create a 1-dimensional list with the elements in
the proper order. Then use this new list to make your matrix.

def reshape(table,r,c):
"""Returns a copy of the table reshaped to have r rows and c cols

Example: reshape([[0,1,2],[3,4,5]],3,2) returns [[0,1],[2,3],[4,5]]

Precondition: table is a nonempty 2d list of numbers. r and c are ints with


r*c equal to the total number of elements in the table"""

Page 5
Last Name: First: Netid:

5. [10 points] Recursion


Implement the function below using recursion according to its specification. You may not use
any loops in your answer (for or while). You also may not use any list methods (though
slicing and adding lists is okay). Answers that violate this rule will receive no credit.
def insert(nums,x):
"""Returns a copy of nums, putting x into the correct, ordered position.

List nums is sorted (e.g. the elements are in order). The function puts
puts x into nums at the right position so it is still ordered. If x is
already in nums, this function still inserts a copy of x.

Example: insert([0,2,4,5],3) returns [0,2,3,4,5]


insert([1,2,3,7],-1) returns [-1,1,2,3,7]
insert([1,2,2,7],2) returns [1,2,2,2,7]
insert([],4) returns [4]

Precondition: nums is a sorted (possibly empty) list of ints; x is an int"""

6. [22 points] Classes and Subclasses


For this question, you will use the classes of Assignment 7 to Hello visible
make a GTextField. Shown to the right, this is a text label with
a blinking cursor. The idea is that the cursor represents where
text will appear when typed. However, you will not worry about Hello not visible
typing or adding text. You will only focus on the blinking cursor.

Page 6
Last Name: First: Netid:

The cursor itself will be a solid black GRectangle. As a reminder, the GRectangle class comes
with the following (mutable) attributes.
Attribute Invariant Description
x float x-coordinate of the center of the rectangle.
y float y-coordinate of the center of the rectangle.
left float < x x-coordinate of the left edge of the rectangle.
right float > x x-coordinate of the right edge of the rectangle.
top float > y y-coordinate of the top edge of the rectangle.
bottom float < y y-coordinate of the bottom edge of the rectangle.
width float > 0 The width along the horizontal axis.
height float > 0 The height along the vertical axis.
fillcolor str The interior color (represented as the name, e.g. 'blue').

There are other attributes, but they can be ignored for this problem. Recall that when you
create a GRectangle, you use keyword arguments to specify the attributes, and all arguments
are optional (e.g. GRectangle(fillcolor='red')).
The class GLabel is a subclass of GRectangle and has additional attributes. You can ignore
all the font attributes for this problem. We will assume the default font. Instead, you
only need to use the attribute text, which is a string. In addition, the version of GLabel we
are using has the following methods.
Method Precondition Description
l.descent() None Returns: The y-coord of the lowest character position.
l.ascent() None Returns: The y-coord of the highest character position.
l.leftside(p) an index of l.text Returns: The x-coord left of character at position p.
l.rightside(p) an index of l.text Returns: The x-coord right of character at position p.
To greatly simplify this problem, we are going to
assume that text is an immutable attribute of the leftside(0) ascent()
GLabel, meaning it does not change after you set it
in the constructor call. Otherwise, it will be very hard
to satisfy all of the invariants (because they depend on
Hello
the length of text). We will also assume all the text
descent() rightside(4)
fits on one line (e.g. newlines are ignored). Once the
rightside(1) leftside(2)
attribute text is set, you can call the methods above
to get the position of the characters in the label.
You will note that this diagram includes some spacing between the actual characters and the
values returned, such as with l.descent(). This is natural – it is the way that fonts work.
With this in mind, implement GTextField as outlined on the next two pages. This is a subclass
of GLabel that has a single GRectangle as an attribute (for the cursor). We have provided the
specifications for the methods __init__, update, and draw. You should also add getters and
setters (where appropriate) for the new attributes. Those setters must have preconditions to
enforce the attribute invariants. Furthermore, all methods (not just the setters) must enforce
the preconditions for any value other than self. Finally, all type-based preconditions should
be enforced with isinstance and not type.
You do not need setters and/or getters for the attributes inherited from GRectangle or GLabel.
Those can be left as is. Remember that attribute text is immutable.

Page 7
Last Name: First: Netid:

class GTextField(GLabel):
"""A class representing a label with a flashing cursor

The cursor is drawn as a rectangle that is 2 pixels wide, and whose top
is ascent() and bottom is descent(). If p is the current position, the
horizontal coordinates of the cursor are defined as follows:
* if p is 0, the right edge of the cursor is leftside(0)
* if p is len(text), the left edge of the cursor is rightside(p-1)
* otherwise the cursor is centered between leftside(p) and rightside(p-1)
The cursor is only drawn if the visible attribute is True. The visible
switches between True and False every BLINK_RATE animation frames.

Attribute BLINK_RATE: A CLASS ATTRIBUTE set to the integer 20"""


# MUTABLE ATTRIBUTE:
# _position: the cursor position; an int between 0 and len(text) (inclusive)
# NOTE: Changing this value moves the cursor (see above)
# IMMUTABLE ATTRIBUTE:
# _visible: whether to show the cursor; a boolean
# INACCESSIBLE ATTRIBUTES (NO GETTERS OR SETTERS):
# _cursor: the cursor; a GRectangle whose position/size is as explained above
# _blinkdown: frame counter for blinking; an int >= 0 and <= BLINK_RATE

# CLASS ATTRIBUTE. NO GETTERS OR SETTERS.

# DEFINE GETTERS/SETTERS AS APPROPRIATE. SPECIFICATIONS NOT NEEDED.

Page 8
Last Name: First: Netid:

# Class GTextField (CONTINUED).

def __init__ # Fill in


"""Initializes a text field with the given parameters.

The cursor starts off visible and at position len(text) (after the last
character). This method sets the frame counter for blinking to BLINK_RATE.

Parameter left: left edge of the field; a float


Parameter bottom: bottom edge of the field; a float
Parameter width: width of the field; a float > 0
Parameter height: height of the field; a float > 0
Parameter text: the text to display; a string
The argument text is OPTIONAL with default value 'Hello'."""

def update # Fill in


"""Updates the blinking cursor

Subtracts one from the blinking frame counter. If the result is 0, it


it resets the counter to BLINK_RATE and swaps the visibility attribute."""

def draw # Fill in


"""Draws this object to the given view.

The cursor is only drawn when it is visible"""


Parameter view: the view to draw to, which is a GView object"""

Page 9
Last Name: First: Netid:

7. [12 points] Generators


Implement the generator shown below. You can use any Python you have learned in class.
However, note the precondition. The value input is iterable, but it is not necessarily a sequence.
So it cannot be sliced and it has no length.
def pairify(input):
"""Generates a sequence of adjacent pairs (as tuples) from input

If there is one element left over when the generator is finished,


then it yields a pair with second element None. If input is empty
this generator outputs nothing (and hence crashes).

Example: pairify([1,2,3,4]) yields (1,2), and then (3,4)


pairify([1,2,3]) yields (1,2), and then (3,None)

Precondition: input is any iterable of numbers"""

8. [17 points] Call Frames


Consider the coroutine corot and the function fold_up shown below

1 def corot(alist,size): 9 def fold_up(alist):


2 """Generates folded segs of alist""" 10 """Modifies alist to add first, last"""
3 last = 0 11 alist[0] = alist[0]+alist[-1]
4 while last < len(alist): 12
5 cut = alist[last:last+size] 13 # Code to be executed
6 fold_up(cut) 14 a = corot([1,2,3,4],1)
7 last = last+size 15 b = next(a)
8 size = (yield cut) 16 c = a.send(2)

At the top of the next page, we have provided the contents of global space and the heap
after executing the assignment statement to b on line 15 above. We want you to diagram the
assignment statement on the next line, line 16. You should draw a new diagram every time
a call frame is added or erased, or an instruction counter changes. There are a total of nine
diagrams to draw, not including the initial diagram we have provided. You may write unchanged
in any of the three spaces if the space does not change at that step.

Page 10
Last Name: First: Netid:

Call Frames Global Space The Heap


id1 id2 id3
a id1 coroutine list list
b id3 corot([1,2,3,4],1) 0 1 0 2
1 2
2 3
3 4

Page 11
Last Name: First: Netid:

Call Frames Global Space The Heap


5

Page 12

You might also like