Final Exam Practice


The final exam only includes one new concept: recursion! We will be adding practice recursive memory diagrams to the practice memory diagram page soon! You also should make sure you are more comfortable with nested data structures (e.g. lists of dicts), as that’s what we worked on with DataWrangling!

Otherwise, to practice, you should review the practice problems for the previous quizzes:

Additionally, you will be expected to do more advanced function writing for the final, so we’ve included more function writing practice problems below.

Questions

This review is not comprehensive of all content that will be on the final exam, but rather provides a few extra practice questions. Previous quizzes/practice questions are also valuable in reviewing for the final exam. Lecture videos are another valuable resource.

Solutions for each problem can be found at the bottom of this page. Keep in mind that there may be multiple solutions to each problem.

Function Writing

  1. Write a function called free_biscuits. Given a dictionary with str keys (representing basketball games) and list[int] values (representing points scored by players), free_biscuits should return a new dictionary of type dict[str, bool] that maps each game to a boolean value for free biscuits. (True if the points add up to 100+, False if otherwise)
    Example: free_biscuits({ “UNCvsDuke”: [38, 20, 42] , “UNCvsState”: [9, 51, 16, 23] }) should return { “UNCvsDuke”: True, “UNCvsState”: False }.

  2. Write a function called max_key. Given a dictionary with str keys and list[int] values, return a str with the name of the key whose list has the highest sum of values. Example: max_key({"a": [1,2,3], "b": [4,5,6]}) should return "b" because the sum of a’s elements is 1 + 2 + 3 = 6 and the sum of b’s elements is 4 + 5 + 6 = 15, and 15 > 6.

  3. Write a function called multiples. Given a list[int], multiples should return a list[bool] that tells whether each int value is a multiple of the previous value. For the first number in the list, you should wrap around the list and compare this int to the last number in the list. (Hint: x is a multiple of y if and only if x % y is 0.) Example: multiples([2, 3, 4, 8, 16, 2, 4, 2]) should return [True, False, False, True, True, False, True, False].

  4. Write a function called merge_lists. Given a list[str] and a list[int], merge_lists should return a dict[str, int] that maps each item in the first list to its corresponding item in the second (based on index). If the lists are not the same size, the function should return an empty dictionary.
    Example: merge_lists([“blue”, “yellow”, “red”], [5, 2, 4]) should return {"blue": 5, "yellow": 2, "red": 4}.

  5. Write a function called reverse_multiply. Given a list[int], reverse_multiply should return a list[int] with the values from the original list doubled and in reverse order.
    Example: reverse_multiply([1, 2, 3]) should return [6, 4, 2].

Solutions

Function Writing

    def free_biscuits(input: dict[str, list[int]]) -> dict[str, bool]:
        """Check each game to see if we get free biscuits."""
        result: dict[str, bool] = {}
        # loop over each key in my input dictionary
        for key in input:
            # for each element of the dictionary, sum up its values
            list_to_sum: list[int] = input[key]
            sum: int = 0
            # loop through list and add each value to sum
            for element in list_to_sum:
                sum += element
            # if sum >= 100, store in result under key "key" with value True
            if sum >= 100:
                result[key] = True
            else: # if not, store as False
                result[key] = False
        return result
    def max_key(input: dict[str, int]) -> str:
        # Create variables to store max key and max val sum
        max_key: str = ""
        max_val_sum: int = 0
        # Loop through each key of the dictionary
        for key in input:
            # Sum up the values of that key's corresponding list
            val_sum: int = 0
            for value in input[key]:
                val_sum += value
            # If the sum is the max so far, update the max_key and max_val_sum
            if val_sum > max_val_sum:
                max_val_sum = val_sum
                max_key = key 
        return max_key

One Solution:

    def multiples(input: list[int]) -> list[bool]:
        """Return a mapping of each element for whether or not it's a multiple of the previous element"""
        # initialize the output
        output: list[bool] = []
        # handle the "wrap around" case to check if the first element is a multiple of the last element
        if input[0] % input[len(input) - 1] == 0: # If first element is a multiple of last
            output.append(True) # Append True
        else:
            output.append(False) # Otherwise, append False
        # now, handle the rest of the list 
        # for idx values 1 to len(input) - 1...
        idx: int = 1
        while idx < len(input):
            # ...we want to see if val at idx is a multiple of val at idx-1
            if input[idx] % input[idx-1] == 0:
                output.append(True)
            else:
                output.append(False)
            idx += 1
        return output

Another Solution:

    def multiples(input: list[int]) -> list[bool]:
        """Return a mapping of each element for whether or not it's a multiple of the previous element"""
        # initialize the output
        output: list[bool] = []
        # handle the "wrap around" case to check if the first element is a multiple of the last element
        output.append(input[0] % input[len(input) - 1] == 0)
        # now, handle the rest of the list 
        # for idx values 1 to len(input) - 1...
        idx: int = 1
        while idx < len(input):
            # ...we want to see if val at idx is a multiple of val at idx-1
            output.append(input[idx] % input[idx-1] == 0)
            idx += 1
        return output
Contributor(s): David Karash, Megan Zhang, Alyssa Byrnes