Lab #9

Before Kattis

Warning

Before you do ANYTHING, take out a scrap piece of paper. If I do not see your paper at the end of the lab, you will get 0 on this lab.

1

Using print statements, fix this code…

def count_numbers_up_to(n):
    '''
    This function adds up all the numbers from 0 - n exclusively.
    Eg. 5 -> 0 + 1 + 2 + 3 + 4 -> 10

    :param n: The number we are counting to. Note we do not count n
    :return: The sum of the numbers
    '''

    total = 0
    c = 0
    while c < n:
        c += 1
        total += c

    return total

2

Using pencil and paper, fix this code…

def find_max_index(aList):
    '''
    This function takes a list and returns the INDEX of where the largest
    element is inside the list. If there are multiple copies of the max,
    it will return only the index of the first occurrence

    :param aList: A list of integers
    :return: The index where the first max number is
    '''
    curMax = aList[0]
    curMaxIndex = 0
    c = 0
    while c < len(aList):
        if aList[c] > curMax:
            curMax = aList[c]
            curMaxIndex += 1

        c +=1

    return curMaxIndex

3

Using delta debugging (comment out all code, and then start un-commenting the code one-ish line at a time), fix this code… HINT: You’re going to want to combine this strategy with the print strategy.

def ones_in_corners(n):
    '''
    Creates an nxn matrix full of 0s, except the corners of the matrix
    will have 1s in it.
    eg. ones_in_corners(3) would give us
    1 0 1
    0 0 0
    1 0 1


    :param n: the size of the square matrix
    :return:
    '''

    # setup a single row of n ' ' (space) chars
    row = ['0'] * n

    # now we will make the mat have n rows
    mat = [row] * n

    # the following four lines make it so only
    # the corners of the matrix has 1s
    mat[0][0] = '1'
    mat[0][n-1] ='1'
    mat[n-1][0] = '1'
    mat[n-1][n-1] = '1'
    return mat

4 Using a debugger

To get our hands dirty, let’s start by re-fixing one of the above problems with a debugger.

Obviously you should know where the problem is given that you fixed this above, but still go through this exercise.

 1def find_max_index(aList):
 2    '''
 3    This function takes a list and returns the INDEX of where the largest
 4    element is inside the list. If there are multiple copies of the max,
 5    it will return only the index of the first occurrence
 6
 7    :param aList: A list of integers
 8    :return: The index where the first max number is
 9    '''
10    curMax = aList[0]
11    curMaxIndex = 0
12    c = 0
13    while c < len(aList):
14        if aList[c] > curMax:
15            curMax = aList[c]
16            curMaxIndex += 1
17
18        c +=1
19
20    return curMaxIndex
21
22print(find_max_index([5,2,8,9,5,4,3]))
  1. Copy this into PyCharm.

  2. Set a break point on line 13 NOTE, THIS WILL PROBABLY BE A DIFFERENT LINE NUMBER WHEN YOU COPY IT

  3. Start the debugger.

  4. Add a watch for the condition on line 13 (c < len(aList))

  5. Add a watch for the condition on like 14 (aList[c] > curMax)

  6. Now you will press the step into button. Take your time with this, for real. If you don’t, you’re using the debugger wrong and it won’t actually be helpful. This is where the magic happens. The trick is to (a) do not skip a step, (b) do not make any assumptions, (c) critically think about what should happen if the code was correct, and compare your hypothesis to what is actually happening, (d) oh, and TAKE YOUR TIME.

_images/stepInto.png
  1. I know you know where the problem is, so just spay special attention to what your hypothesis for curMaxIndex should be when curMax is set to 8, and how the code actually reacts.

5 Use whatever you want now

I’m just going to throw a bunch of buggy code your way. Fix it however you want.

 1def make_a_string_from_list(a):
 2    '''
 3    Take a list, and convert it to a string version of the contents of the list
 4    eg.
 5    a = [1,2,'a','b']
 6    return '12ab'
 7
 8    :param a: the list we want turned into a string
 9    :return: a string version of the list
10    '''
11
12    # always have to start with an
13    # empty string when string building
14    s = ''
15    for thing in a:
16        s = str(a) + s
17
18    return s
19
20# maStr should be '12ab'
21maStr = make_a_string_from_list([1,2,'a','b'])
22print(maStr)
 1def grocery_bill(a, b):
 2    prices = {'apple': 0.40, 'banana': 0.50}
 3    my_purchase = {'apple': a, 'banana': a}
 4    grocery_bill = 0
 5    for fruit in my_purchase:
 6        grocery_bill = prices[fruit] * my_purchase[fruit]
 7    return 'I owe the grocer ' + str(grocery_bill)
 8
 9# Should be 2.90
10print(grocery_bill(1, 5))

set_up_game is tricky because it’s hard to even discover that there is a problem. Test this a lot to see if you can find the error.

 1def set_up_game(size):
 2    '''
 3    Sets up the game board based to be the size we want.
 4    It will be size x size. Eg. 3x3 if size is 3
 5    Will be a list of lists
 6    [[' ', ' ', ' '],
 7    [' ', ' ', ' '],
 8    [' ', ' ', ' ']]
 9
10    :param size: The size of the world. Will be size x size.
11    :return: The list of lists representing the game world.
12    '''
13    a = [' '] * size
14    b = [a] * size
15    return b
 1def give_me_5_words():
 2    '''
 3    This function will ask the user for 5 words.
 4    It will print out the full word they entered
 5    And also add the full word to a list that will be returned
 6
 7    :return: The list of the 5 words they entered
 8    '''
 9
10    a = []
11    for _ in range(5):
12        word = input('Gimmie: ')
13        a.append(word[0])
14        print('You gave me the word: ' + a[0])
15        return a
16
17'''
18Should work like this in:
19Gimmie: ab
20You gave me the word: ab
21Gimmie: bc
22You gave me the word: bc
23Gimmie: cd
24You gave me the word: cd
25Gimmie: ef
26You gave me the word: ef
27Gimmie: gh
28You gave me the word: gh
29['ab', 'bc', 'cd', 'ef', 'gh']
30'''
31print(give_me_5_words())
 1def message(text, plain, encryp):
 2    '''
 3    Perform a simple encription.
 4    Eg.
 5    plaintext  =  list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')
 6    encryptedtext=list('DEFGHIJKLMNOPQRSTUVWXYZABC')
 7    message("This is a test", plaintext, encryptedtext)
 8    should result in:
 9        THIS IS A TEST
10        has been encrypted to:
11        WKLV LV D WHVW
12
13    :param text: The message to encript
14    :param plain: The alphabet that the text exists in
15    :param encryp: The alphabet that we want o encript to. order matters.
16    :return:
17    '''
18
19    text = text.upper()
20    dictionary = dict(zip(plain, encryp))
21    newmessage = ''
22    i = 0
23    for char in text:
24        try:
25            newmessage += dictionary[i]
26        except:
27            newmessage += ' '
28        i = i + 1
29    print(text, '\nhas been encrypted to:')
30    print(newmessage)
31
32plaintext = list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')
33encryptedtext = list('DEFGHIJKLMNOPQRSTUVWXYZABC')
34message("This is a test", plaintext, encryptedtext)

This one is very buggy :(

 1import random
 2
 3guesses_made = 0
 4
 5name = input('Hello! What is your name?\n')
 6
 7number = random.randint(1, 20)
 8print('Well, {0}, I am thinking of a number between 1 and 20. You get 6 guesses.'.format(name))
 9
10while guesses_made < 6:
11
12    guess = int(input('Take a guess: '))
13
14    guesses_made += 0
15
16    if guess < number:
17        print('Your guess is too low.')
18
19    if guess < number:
20        print('Your guess is too high.')
21
22    if guess = number:
23        break
24
25if guess == number:
26    print('Good job, {0}! You guessed my number in {1} guesses!'.format(name, guesses_made))
27else:
28    print('Nope. The number I was thinking of was {0}'.format(number))

Kattis Problems

I’m willing to bet that in previous weeks you were working on Kattis problems that you couldn’t quite debug. You may have been close, or way off, but the problem was you were stuck wondering how best to fix your code. Now that you’re equipped with the debugger, go back and work on them! Seriously, GO BACK! But make use of this debugger. Whenever you can, USE THE DEBUGGER. Stuck on Kattis? DEBUGGER! Stuck on assignment? DEBUGGER! Stuck in life? DEBUGGER?

If you’re done everything I have listed so far, try some of the easy Kattis problems on the website that I didn’t assign.

LeetCode Problems

If you have somehow finished everything so far, go check out LeetCode. Sort the problems by Acceptance (click the table header) and start seeing if you can solve some of these problems.

ENSURE WE HAVE RECORDED YOUR COMPLETION. FAILURE TO DO SO WILL RESULT IN A GRADE OF 0!

Warning

If you are in the online section, you must submit the .py (python scripts), not the .ipynb (notebook files). To get the python scripts from Colab, simply select File and in te dropdown menue, hit Download .py.