CMU 15-112: Fundamentals of Programming and Computer Science
Quiz1


Notes:

Part 1: CTs

You may not run any code in Part 1. Once you move to Part 2, you may not return to Part 1.

CT1: Code Tracing [5pts]

Indicate what the following code prints. Place your answers (and nothing else) in the box below. Note that you may not run this code.

def ct1(b, k):
    m = g(k) if b else j(k)
    t = 0
    for n in range(m):
        t += n
    return t

def g(k): return 2*k
def h(k): return k**2
def j(k): return h(k) - g(k)

print(ct1(True, 3), ct1(False, 3))

CT2: Code Tracing [5pts]

Indicate what the following code prints. Place your answers (and nothing else) in the box below. Note that you may not run this code.

def ct2(d):
    result = ''
    count = 0
    for x in range(d, 100):
        if x%2 == 0:
            count += 1
            if count < 3:
                continue
            elif count == 5:
                break
        if x%3 > 0:
            result += str(x)
    return result
print(ct2(1))

CT3: Code Tracing [5pts]

Indicate what the following code prints. Place your answers (and nothing else) in the box below. Note that you may not run this code.

def ct3(s):
    t = s[:2]
    s += '2'
    for c in 'b34':
        t += str(int(s.find(c)))
        s = s.replace(c, '4')
    return f'{s[-2:]}.{t}'

print(ct3('a2b'))

Part 2: Free Response

Free Response: is/nth Neighborly() [30pts]

Note: to receive any credit, you cannot use strings on this problem.

Background: We will say that an integer n is "neighborly" (a coined term) if n >= 100 and each consecutive pair of digits in n differ by exactly 1.

For example, 5654 is neighborly because:

  • 5 and 6 differ by 1
  • 6 and 5 differ by 1
  • 5 and 4 differ by 1

Each of these numbers are not neighborly:

  • 43 (too small, since 43 < 100)
  • 100 (has consecutive 0's)
  • 343423 (has a gap from 4 to 2)
  • -101 (too small, since -101 < 100)

Here are the first several neighborly numbers:

  101, 121, 123, 210, 212, 232, 234, ...

With that in mind, and without using strings, write the function isNeighborly(n) that takes a possibly-negative integer n and returns True if it is neighborly and False otherwise.

Also, write the function nthNeighborly(n) that takes a non-negative integer n and returns the nth neighborly number, where nthNeighborly(0) returns 101.

def isNeighborly(n):
    pass

def nthNeighborly(n):
    pass

########################################################
# Test Function
########################################################
def testIsNeighborly():
    print('Testing isNeighborly()...', end='')
    assert(isNeighborly(5654) == True)
    assert(isNeighborly(43) == False) # too small (43 < 100)
    assert(isNeighborly(100) == False) # has consecutive 0's
    assert(isNeighborly(343423) == False) # gap from 4 to 2
    assert(isNeighborly(343432) == True)
    assert(isNeighborly(-101) == False) # no negatives (-101 < 100)
    assert(isNeighborly(101) == True)
    print('Passed!')

def testNthNeighborly():
    print('Testing nthNeighborly()...', end='')
    assert(nthNeighborly(0) == 101)
    assert(nthNeighborly(1) == 121)
    assert(nthNeighborly(2) == 123)
    assert(nthNeighborly(3) == 210)
    assert(nthNeighborly(4) == 212)
    assert(nthNeighborly(5) == 232)
    assert(nthNeighborly(6) == 234)
    print('Passed!')

testIsNeighborly()
testNthNeighborly()

Free Response: makeBanner() [30pts]

Write the function makeBanner(message, useAllCaps) that takes a nonempty possibly-multiline string "message" and a boolean "useAllCaps", and returns that message converted into a banner, which is also a string that:

  1. places a rectangle of asterisks around the message,
  2. centers each line of the message,
  3. adds a single space as a margin within the asterisks on each line, and
  4. converts the message to uppercase if useAllCaps is True

For example:


    message0 = '''\
a
ccc'''

    banner0 = '''\
*******
*  a  *
* ccc *
*******'''

    assert(makeBanner(message0, False) == banner0)

And here is that same example with useAllCaps=True:


    message0 = '''\
a
ccc'''

    banner0WithAllCaps = '''\
*******
*  A  *
* CCC *
*******'''

    assert(makeBanner(message0, True) == banner0WithAllCaps)

Note: if a line cannot be exactly centered, then leave the extra space after the line rather than before it.

In particular, consider how the line 'bb' is centered here:


    message1 = '''\
a
bb
ccc
eeeee'''

    banner1 = '''\
*********
*   a   *
*  bb   *
*  ccc  *
* eeeee *
*********'''

    assert(makeBanner(message1, False) == banner1)
def makeBanner(message, useAllCaps):
    pass

########################################################
# Test Function
########################################################
def testMakeBanner():
    print('Testing makeBanner()...', end='')
    message0 = '''\
a
ccc'''

    banner0 = '''\
*******
*  a  *
* ccc *
*******'''
    assert(makeBanner(message0, False) == banner0)

    message0 = '''\
a
ccc'''

    banner0WithAllCaps = '''\
*******
*  A  *
* CCC *
*******'''
    assert(makeBanner(message0, True) == banner0WithAllCaps)

    message1 = '''\
a
bb
ccc
eeeee'''

    banner1 = '''\
*********
*   a   *
*  bb   *
*  ccc  *
* eeeee *
*********'''
    assert(makeBanner(message1, False) == banner1)

    message2 = '''\
Here we go
Steelers'''

    banner2 = '''\
**************
* Here we go *
*  Steelers  *
**************'''
    assert(makeBanner(message2, False) == banner2)

    message3 = '''\
Here we go
Steelers!'''

    banner3 = '''\
**************
* HERE WE GO *
* STEELERS!  *
**************'''
    assert(makeBanner(message3, True) == banner3)
    print('Passed!')

testMakeBanner()

Free Response: showDigits() [25pts]

Write the functions onAppStart(app), onKeyPress(app, key), and redrawAll(app) to make an app that works like so:

  1. When first started, the app displays the message 'No digits' centered in the canvas.
  2. When the user presses a digit key, the 'No digits' message disappears and is replaced by that digit.
  3. When the user presses more digits, they are appended to the displayed number. So if the user presses '1' then '3', the number 13 is displayed.
  4. When the user presses 'backspace', the rightmost digit is removed from the displayed number. If this removed the last digit, then the message 'No digits' is displayed again. If the user presses 'backspace' when 'No digits' is displayed, this is ignored.
  5. When the user presses 's', as long as 'No digits' is not displayed, then the displayed number is squared. For example, if '12' is displayed, and the user presses 's', then '144' is displayed.
  6. All other key presses are ignored.

You may assume that the canvas is 400x400.

from cmu_graphics import *

def onAppStart(app):
    pass

def onKeyPress(app, key):
    pass

def redrawAll(app):
    pass

def main():
    runApp()

main()

Part 3: Bonus CT

BonusCT1: Code Tracing [2.5pts]

Indicate what the following code prints. Place your answers (and nothing else) in the box below. Note that you may not run this code.

import string

def bonusCt1():
    x = y = 0
    s = 3 * string.ascii_uppercase
    for c in s:
        x += ord(c) - ord('A')
        y += ord('N') - ord(c)
    return (x, y)

print(bonusCt1())

BonusCT2: Code Tracing [2.5pts]

Indicate what the following code prints. Place your answers (and nothing else) in the box below. Note that you may not run this code.

def bonusCt2(n):
    def f(n):
        c = 0
        while n > 0:
            c += n%2
            n //= 2
        return c
    k = f(n)
    while f(n) <= k:
        n += 1
    return (n, f(n))

print(bonusCt2(23))

carpe diem