Second Largest Test

The questions below are due on Sunday July 20, 2025; 10:00:00 PM.
 
You are not logged in.

Please Log In for full access to the web site.
Note that this link will take you to an external site (https://shimmer.mit.edu) to authenticate, and then you will be redirected back to this page.

Larry was so impressed with your implementation of second_largest that he and his friends also tried to implement their own versions of the function. However, because there was no autograder to submit to, they are unsure if their functions are correct. Larry has asked you to create a program that could verify whether an implementation of the second_largest function was correct.

To accomplish this, implement the function test, which takes a single function as input. If the provided function is incorrect, your test function should raise a runtime error (either an AssertionError or some other kind of error that indicates a bug within the provided function). If the provided function is correct, your function should return True.

You may assume that the input function followed the instructions (so you don't need to check whether sorted, min, or max were used). The test function should determinine whether the input function can return the expected output given a valid input (without mutating the input list). You may find it helpful to refer to the Dictionary Map remap_test function as an example.

When you are ready, submit your .py file that contains the test function below. The autograder will run various correct and broken versions of second_largest through your test function and see if it gets the correct result. Unlike the autograder for most problems, you will not see the code that is running, but the test cases will provide an explanation message. You are encouraged to make or re-use your own second_largest function implementations to help test your test function.

Try Now:

If you are having trouble answering this question, consider taking a peek at the hints below:

Here is a template file to start with:

def second_largest_1(num_list):
    # a correct implementation
    if len(num_list) == 0 or len(num_list) == 1:
        return None

    if num_list[0] > num_list[1]:
        largest = num_list[0]
        second = num_list[1]
    else:
        largest = num_list[1]
        second = num_list[0]

    for i in range(2, len(num_list)):
        if num_list[i] > largest:
            second = largest
            largest = num_list[i]
        elif num_list[i] > second:
            second = num_list[i]
    return second

def second_largest_2(num_list):
    # a broken implementation -- there are many bugs!
    largest = -1000
    second = -1000
    if len(num_list) <= 2:
        return None

    for num in num_list:
        if num >= largest:
            second = largest
            largest = num
        else:
            break
    return second

def test(second_largest):
    assert second_largest([2,6,7,5,3,4]) == 6
    assert second_largest([7,6,7]) == 7
    # TODO: add some more test cases!
    return True

if __name__ == "__main__":
    print(f'{test(second_largest_1)=}')
    # this should print "test(second_largest_1)=True"
    print(f'{test(second_largest_2)=}') # this should raise an error

When designing test cases, it is helpful to think about both the possible input space and the possible output space of a correct solution.

The possible input space includes all lists of numbers, which can vary both in terms of the length of the list and the numbers themselves (positive, negative, large, small). The possible output space includes None, and any number. In order to make sure we get the correct output, we create varied inputs that cover a range of possibilities, which may include:

  • Lists of length 0 and 1 (to make sure we can get None in those cases)
  • Lists of length 2 and 3 (to make sure we didn't mess up the boundary condition)
  • Lists of only really large negative numbers (to make sure we are not hard coding a particular negative value)
  • Lists of numbers where the second largest number is unique (and where it is not unique!)
  • Because some solutions may try to look at the first two or last two numbers separately outside the loop, we should vary where we put the largest and second largest number in terms of position in the input list.
  • Another important requirement is that we do not mutate the input list. How can we check for that? (hint: look at the test function for remap from the previous problem).

  No file selected

Next Exercise: Electricity (Part 2: Files)

Back to exercises