Quiz 4 -- Grading Scheme and Comments

Full marks: 30, mean 21.25, median 25, standard deviation 8.6

Overall Comments:

This quiz wasn't too bad. The mean was slightly lower than in Quiz 3, but then the concepts are also more difficult than those covered in Quiz 3.

As usual, if you have any questions about the quiz, or need help with any of the concepts, please come talk to me!

Question 1

This question caused more problems than I anticipated. Common mistakes in the first part (drawing the frame) were:

  1. Setting number from main() and num from mystery() to point to the same value (36), which is correct, but then changing the value to 41. Remember, if we change the value itself, this means that a function is capable of changing the value of an integer variable in main(), which we know is not possible in Python. The correct answer should be to make the two variables point to the same value to begin with, then we make a new value 41 on the heap, and move the arrow from num to point to the value 41. number in main() still points to 36.
  2. Making a new copy of the list L on the heap. Remember that when a list is passed to a function, the variable in the function points back to the same list on the heap. Therefore, L in main() and ls in mystery() point to the same list! That's how functions can modify items in list that are passed to them.
  3. Neglecting to change the values in the list. Quite a number of people forgot this, actually. I count this as just carelessness.
  4. Then there are people who forgot the global frame, the main frame, the variable i, etc etc.

Part b: many people wrote down that the output would be

41
[21, 12, 3, 7, 2]

The second part (the list) is correct. Actually, what mystery() does is to "flip" negative items in the list so that we have a list with all positive numbers.

However, where does the 41 come from? Sure, mystery() returns the value of num, which is 41, but we don't print it out, nor do we assign it to anything. Therefore, that return value is just unused. The value that is printed out is stored in number. Since number was assigned a value of 36, and never got another value reassigned to it, 36 should be printed out.

Part c: Most people got this right. Answer is 41. The only mistakes were that some people wrote down 40. Remember that the length of a list is the number of items in it. Which is one more than the index of the last item.

Part d: I think everybody got this. Clearly it's an integer.

Question 2

This one is very easy, if you don't over-think and confuse yourself:

def reverse(string):
    new_string = ""
    for i in range(len(string)):
        new_string = string[i] + new_string
    return new_string

If you prefer a backwards approach:

def reverse(string):
    new_string = ""
    for i in range(len(string)-1, -1, -1):
        new_string = new_string + string[i] 
    return new_string

Either one is correct. The thing to note is that characters with smaller indices should be towards the end of the new string.

Alternatively, this is the Python-esque way:

def reverse(string):
    new_string = ""
    for char in string:
        new_string = char + new_string
    return new_string

Some common mistakes:

  1. Some people forgot that Python does not let us modify individual letters in a string! Therefore, you cannot do something like string[i] = string[len(string)-1-i].
  2. I am seeing some confusion with the reverse ranges. Remember that the syntax is range(begin, end, step). And the range will stop before end. Therefore, if you want the last value of i to be 0, then your end value has to be -1.

Question 3

This one was also very easy, especially if you looked at the hint (you can use the function reverse() from Question 2. Even if you got stuck in Question 2, you can still use the function as if it existed! That's the beauty of code reuse.

def isPalindrome(string):
    if string == reverse(string):
       return True
    return False

Some people went and compared the characters back to front, which is fine (and most of those answers were correct). You're just making life harder for yourself :-)

Question 4

Most people got this one:

def getAllInRange(L, high, low):
    for i in range(len(L)):
        if L[i] < low or L[i] > high:
            L[i] = -1

That's it. You do not need to return L. Remember that a list can be modified in a function. I did not take off any points even if you did (and many people did), but it only works this time because I didn't ask you to return anything else. If you had other information that you needed to return (e.g. number of items you had to set to -1), then you'd have been in trouble.

Some people did a:

for item in L:
    if item < low or item > high:
        item = -1

Now that's not correct. What happens if you do that is that Python makes a new integer variable called item. This variable initially points to the integer stored inside the list. However, when we set the value of item to -1, Python moves item's arrow to point to a new value, -1. It does not change the value inside the list. (Draw out the function stack and you'll see what I mean.)

I also saw this: if low <= L[i] <= high -- now we cannot do that in Python. We have to use two independent comparisons and link them together with a boolean operator (or or and).