CMU 15-112: Fundamentals of Programming and Computer Science
Quiz 3 (35 minutes)

Quiz 3 frontmatter:

    (This quiz was given in the CS Academy quiz proctoring app on 7/26)

    Quick Reminders:

    During the quiz

    1. You may not ask questions during the quiz.
      • If you are unsure how to interpret a problem, take your best guess.
    2. You may not leave the quiz and return, and you may not interact with anyone else (remotely or in person) except for the TAs or faculty until the quiz is submitted.
    3. You must not leave the full-screen testing environment at any time. If anything except the testing environment is visible on your screen, it will trigger a security error, and you will be locked out of your quiz / you may receive a deduction or a zero. Additionally, we will investigate whether this could be a matter of academic integrity.
    4. All of these must be visible to your phone's camera at all times:
      • All of your screen, and any other screens nearby
      • Most of your desk
      • Your mouse and keyboard
      • Note: You must not block your screen with your head/arms/etc while taking the quiz
      • You must not have any other computer monitors on, and no other phones/tablets/calculators/notes/other resources should be accessible.
    5. If you are locked out due to a security error, exit the breakout room immediately to speak with the TA or faculty member on duty. At their discretion, they may unlock the quiz and allow you to continue.
    6. When you finish a question, press the submit button to lock in your answer. You will not be able to return and change your answers after pressing submit. Once the allotted time elapses, the quiz will auto-submit with your current progress. See above for more details

    You must use your phone to join the proctored Zoom meeting. If you cannot join Zoom on your phone:

    After the quiz

    1. If you submit your quiz before time is up, wait until everyone else finishes and your proctor gives you further instructions.
    2. Wait until your proctor dismisses you, and then please exit Zoom. You are done! Rejoin the lecture Zoom session on your laptop.

    For any tech fails (laptop or internet stops working, etc.):

1. True/False [3 points]

Write only the whole word "True" or "False" (and not just T or F).

The make_dataclass function returns a generic object, whereas SimpleNamespace returns a new class.

2. True/False [3 points]

Write only the whole word "True" or "False" (and not just T or F).

An object is an instance of a class, and can have properties and methods.

3. True/False [3 points]

Write only the whole word "True" or "False" (and not just T or F).

At the end of the following code, A and B are no longer aliases of the same list:

A = [1, 2, 3]
B = A
B = B + []

4. True/False [3 points]

Write only the whole word "True" or "False" (and not just T or F).

Destructive functions and methods must not return any value other than None.

5. True/False [3 points]

Write only the whole word "True" or "False" (and not just T or F).

Tuples are very similar to lists, except tuples cannot be destructively modified.

6. Code Tracing [15 points]

What does the following code print?

#Hint: Draw a box and arrow diagram!
import copy
def ct1(a):
    b = a
    c = copy.copy(a)
    b[0] = 42
    c[3] = 2 * c[3]
    b = b[:2] + ["hi"] + b[2:]
    a[-2] = 112
    print("a:", a)
    print("b:", b)
    print("c:", c)
z = ["jul", "26", 1, 100]
print("z:", z)

7. Reasoning over Code [10 points]

Find an argument for L that makes rc1(L) return True. Write your answer below.

def rc1(L):
    if (not isinstance(L, list)):
        return False
    A = []
    B = []
    while(L != []):
        B = [L.pop(0)] + B
    return A + B == list(range(2, 6))

8. Free Response 1: dataCleaner(L) [25 points]

Write the function dataCleaner(L) which takes a list of strings like ['aBc+123', 'Hey 3P0', 'R2-D2!'] and non-destructively returns a new list of strings where:

The list and its strings should otherwise be the same.

So, dataCleaner(['aBc+123', 'Hey 3P0', 'R2-D2!']) should return ['abc123', 'hey3p0', 'r2d2']
Look at the test cases for more examples! And remember to be non-destructive!
Hint: It is a *bad* idea to try converting the list to a string and splitting it up again later.
Hint: Use helper functions to make this easier to debug!

import copy

def dataCleaner(L):
    return 42

def testDataCleaner():
    print('Testing dataCleaner()...', end='')
    assert(dataCleaner(['aBc+123?']) == ['abc123'])
    assert(dataCleaner(['aBc+123', 'Hey 3P0', 'R2-D2!']) == ['abc123', 'hey3p0', 'r2d2'])
    assert(dataCleaner(['1 ', 'Hungry-', '?Axolotl??']) == ['1', 'hungry', 'axolotl'])
    assert(dataCleaner([" '\t\n'  ", '12"3"45', '(-,@#$%^)' , 'NICE']) == ['', '12345', '', 'nice'])
    assert(dataCleaner([]) == [])

    #Test for non-destructiveness
    L = ['aBc+123', 'Hey 3P0', 'R2-D2!']
    L2 = copy.copy(L)
    assert(dataCleaner(L) == ['abc123', 'hey3p0', 'r2d2'])
    assert(L == L2)

    #Remember, we may use more test cases! 
    #Don't hard-code or assume certain characters won't be used! 


9. Free Response: Clicky Grid Animation [35 points]

Write an animation with the following properties:

  1. A canvas contains a 9x9 grid with a 10-pixel margin.
    1. The grid should scale with the canvas, but assume the canvas is at least 400x400
    2. All cells are initially red with a black border.
  2. When a user clicks a red cell, that cell turns blue.
    1. Up to 5 cells can be blue at any time. Once a 6th cell turns blue, the oldest blue cell (the one that has been blue longest) becomes red again. (Hint: Remember Snake!)
    2. Clicking on a blue cell does nothing at all
  3. Every 5 seconds, the oldest blue cell turns red.
    1. Note: The timer should *not* reset when a new cell turns blue with a mouse press, even if the new cell results in an old cell becoming red.

Hint 1: Remember Snake!
Hint 2: Write getCell and getCellBounds!

As before, you can't run animation code, but we will grade with this in mind. As always, we give partial credit, even if you leave out a feature. (For example, you can still get partial credit if you leave getCellBounds or getCell blank, or if you don't use a margin, or if you don't remove the oldest blue cell, etc)

def almostEqual(d1, d2, epsilon=10**-7): #helper-fn
    return (abs(d2 - d1) < epsilon)

#(This works the same as the one you've seen before)
def roundHalfUp(d): #helper-fn
    sign = 1 if (d >= 0) else -1
    d = abs(d)
    n = int(d)
    if (d - n >= 0.5): n += 1
    return sign * n

from cmu_112_graphics import *

def appStarted(app):

def mousePressed(app, event):

def timerFired(app):

def getCellBounds(app, row, col):
  return (x0, y0, x1, y1)

def getCell(app, x, y):
  return (row, col)

def redrawAll(app, canvas):

runApp(width=400, height=400)