Midterm Review

Midterm Particulars

When
  • TBA - any 6-hour period through Friday April 3.
What can I use?
What can’t I use?
  • Anything else, e.g., book, computer, Thonny, other notes, etc.
  • Any other outside assistance. The Honor Code will apply to your taking of this exam.

What will the exam cover?

The exam will NOT include material that was in the book(s) but that we did not discuss in class, or use in our labs, or practice in the in-class exercises. The exam will NOT include material after 3/9/20 (no files, tuples, etc).

Types of questions

How do you suggest I prepare?

What do you suggest I put on my notes page?

Here are some (non-exhaustive) suggestions:

Review questions:

  1. The following function is supposed to prompt the user for numbers until they enter a blank line, then it tells the user how many of the numbers were less than zero. Unfortunately, the function has a few problems and doesn’t work correctly. Identify and fix the problems. Show answer.

    def neg_count():
        answer = input("Enter a number: ")
       
        below = 0
       
        while answer != "":
            if answer < 0:
                below += 1
       
        print("Below: " + below)
    

    Can be fixed as:

    # Fixed neg_count
    def neg_count():
        answer = input("Enter a number: ")
       
        below = 0
       
        while answer != "":
            # Need to convert string to float
            if float(answer) < 0:
                below += 1
    
            # Need to obtain subsequent inputs in each iteration of the loop
            answer = input("Enter a number:")
       
        # Need to convert below to string
        print("Below: " + str(below))
    
  2. Write a function called my_startswith that takes two strings as parameters and returns True if the first string starts with the second string. You may NOT use the built-in startswith method. You may assume that the second string is shorter than the first. Show answer.

    def my_startswith(s1, s2):
        n = len(s2)
        return s1[:n] == s2
    
  3. Rewrite each of the boolean expressions below more compactly. For example, rather than writing x and x we could just write x.

    1. Rewrite (Show answer):
      # x contains some bool value
      True and x
      

      Can be rewritten as:

      x
      
    2. Rewrite (Show answer):
      # x contains some bool value
      False or x
      

      Can be rewritten as:

      x
      
    3. Rewrite (Show answer):
      y > 0 and y < 10
      

      Can be rewritten as:

      0 < y < 10
      
    4. Rewrite (Show answer):
      (y > 0 and z == 1) or (y > 0 and z == 2)
      

      Can be rewritten as:

      y > 0 and (z == 1 or z == 2)
      
    5. Rewrite (Show answer):
      (y > 0 and y < 10) and (y > 0 and y < 20)
      

      Can be rewritten as:

      y > 0 and y < 10
      

      The expression y > 0 and y < 10 is a subset of y > 0 and y < 20 and so if that first expression is True, then the second expression must be True. Thus the overall expression will true if and only if the first expression is True.

    6. Rewrite (Show answer):
      (y > 0 and y < 10) and (y <= 0 or y >= 10)
      

      Can be rewritten as:

      False
      

      The expression y > 0 and y < 10 is the same as not (y <= 0 or y >= 10) and such both operands can’t be True at the same time, thus the overall expression must be False.

  4. Draw below what the following program would draw on the screen (Show answer):

    from turtle import *
       
    def draw_something(x, y, length):
        pu()
        goto(x, y)
        pd()
        goto(x + length, y)
       
    for i in range(10):
        draw_something(0, i*5, i*5)
       
    done()
    

    The above will draw horizontal lines of increasing length at increasing vertical coordinates.

  5. For each of the statements below state whether an error would occur OR state what would be printed out. Make sure to make it clear whether you have printed an integer, a float or a string.

    1. Evaluate (Show answer):
      print(2 + 5.5)
      
      >>> print(2+5.5)
      7.5
      
    2. Evaluate (Show answer):
      print(15 / 2)
      
      >>> print(15 / 2)
      7.5
      
    3. Evaluate (Show answer):
      print(float(15 // 2))
      
      >>> print(float(15 // 2))
      7.0
      
    4. Evaluate (Show answer):
      print(2 + '3')
      
      >>> print(2 + '3')
      TypeError: unsupported operand type(s) for +: 'int' and 'str'
      
    5. Evaluate (Show answer):
      print(str(2) + '3')
      
      >>> print(str(2) + '3')
      "23"
      
  6. Write a function called random_test that takes three integer parameters: max, threshold and num. The function should generate num random integers between 0 and max (inclusive) and return the number of these values that were less or equal to the threshold. Show answer.

    from random import randint
       
    def random_test(max, threshold, num):
        count = 0
        for i in range(num):
            r = random.randint(0, max)
            if r <= threshold:
                count += 1
        return count
    
  7. What would the following function return if we invoked it with 4 as the argument? Show answer.

    def mystery(x):
        count = 1
        total = 0
       
        while count <= x:
            total += count * count
       
        return total
    

    No return. count is never modified and so this is an infinite loop.

  8. What does the following expression evaluate to? Show answer.

    len(("Mississippi" + "!").upper().replace("ss","a"))
    

    12. The len argument evaluates as "Mississippi!".upper().replace("ss","a"). Since upper converts the string to MISSISSIPPI!, nothing is replaced. Thus we are evaluating len("MISSISSIPPI!"), which results in 12.

  9. Write a function named intersection that has two lists as parameters and prints out every item in the first list that is present in the second list. It should only print each item once, even if it appears in the second list multiple times. Do not use a set. For example: Show answer.

     >>> intersection(["a", "b"], ["a", "a", "c"])
     a
    

    The simplest approach uses the in operator on lists.

     def intersection(list1, list2):
         for item in list1:
             if item in list2:
                 print(item)
    
    

    If we do not use that operator, we can create the equivalent code with a nested for loop.

     def intersection(list1, list2):
         for item in list1:
             for match in list2:
                 if item == match:
                     print(item)
                     break
    

    Here we use the break statement to terminate the inner loop once we have a match so that we don’t print item multiple times. We have previously used break with while loops, it can also be used with for loops. In the context of nested loops, break only terminates the current loop (not all loops). Alternately we can use a helper function to only match an item in list2 once. For example:

     def match_once(item, list2):
         for match in list2:
             if item == match:
                 return True
         return False
    
     def intersection(list1, list2):
         for item in list1:
             if match_once(item, list2):
                 print(item)
    

    In match_once we return True immediately if there is a match (once we know the answer, no reason to continue the computation) and False only if there is no match (if we complete the loop there must not have been a match). Thus we will only print matching items once.