CSCI 141 - Extra Exam Practice

In addition to daily Programs, the Extra Practice Problems, the Practica, and Exam 0, this page provides even more problems to help you practice and prepare for exams.

Past Exams

These are actual exams given in prior quarters. Each is annotated with the lecture number that the exam assumes knowledge of.

Exam 1 Exam 2 Exam 3 Final
Fall 2025 exam1.zip (L08) exam2.zip (L12) exam3.zip (L16) final.zip, prompts
Spring 2025 Exam1.zip (L06) Exam2.zip (L16) Exam3.zip (L16) Final.zip

Other Practice Problems

These problems are ordered under headings that indicate the lecture number that the problem assumes knowledge of. They do not have test programs.

L10

def next_square(n):
    """ Return the smallest perfect square greater than n.
    A perfect square is a number that is the square of an integer
    (i.e., an integer times itself). Precondition: n >= 0.
    Examples:
    next_square(3) => 4, (because 2*2=4, but 1*1 = 1, less than 3) 
    next_square(10) => 16 (because 4*4 = 16, but 3*3 = 9, less than 10)
    next_square(4) => 9 (must be strictly greater than n, so 3*3=9 is the next)
    next_square(0) => 1 (0*0 = 0, so 1*1 = 1 is the next perfect square)
    next_square(9000) => 9025 (= 95*95)
    """

L13

def safe_slice(string, start, end):
    """ A "safer" version of string slicing that checks for likely error cases
    at the expense of flexibility. Returns string[start:end] only if the
    the following conditions are met:
    - start and end are in the range from 0 to len(string), inclusive
    - start is strictly smaller than end
    Otherwise, returns None.
    Examples:
      safe_slice("012345", 0, 4) => "0123"
      safe_slice("012345", -1, 4) => None (start < 0)
      safe_slice("012345", 4, 6) => "45"
      safe_slice("012345", 4, 7) => None (end > len(string))
      safe_slice("012345", 4, 4) => None (start == end)
      safe_slice("012345", 4, 3) => None (start > end)
    """
def reverse_substring(string, start, end):
    """ Return string, but with string[start:end] replaced by its reverse.
    Precondition: 0 <= start <= end <= len(string).
    Examples:
        reverse_substring("0123456", 0, 3) => "2103456" (012 is reversed)
        reverse_substring("0123456", 4, 6) => "0123546" (45 is reversed)
        reverse_substring("0123456", 6, 7) => "0123456" (6 is reversed)
        reverse_substring("0123456", 0, 7) => "6543210" (whole string reversed)
        reverse_substring("1", 0, 0) => "1" (reverse an empty range)
        reverse_substring("", 0, 0) => "" (reverse nothing in an empty string)
    """

L14

def order_two(x, y):
    """ Return a 2-tuple containing x and y in sorted order, i.e., return
    (a, b) such that a is the smaller of x and y, and b is the larger. If x
    and y are equal, return x first.
    Precondition: x and y are values that can be compared with comparison
    operators.
    Examples:
        order_two(1, 2) => (1, 2)
        order_two(2, 1) => (1, 2)
        order_two(99, 101) => (99, 101)
        order_two("ac", "ab") => ("ab", "ac")
        order_two("a", "B") => ("B", "a") (because of lexicographic string ordering)
    """

L15

def tent(n):
    """ Returns a string representing a symmetric numerical sequence.
    The sequence starts from 1 and counts up to n. If n > 1, it then counts back
    down to 1. All numbers in the sequence are separated by hyphens (-).
    Precondition: n is a positive integer.
    Examples:
      tent(3) => "1-2-3-2-1"
      tent(1) => "1"
      tent(6) => "1-2-3-4-5-6-5-4-3-2-1"
    """
    s = ""
    if n == 1:
        return str(1)
    
    for i in range(1, n+1):
        s += str(i) + "-"
    for i in range(n-1, 1, -1):
        s += str(i) + "-"
    s += str(1)
    
    return s
def count_even(words):
    """ Return the number of strings in words that have even length.
    Precondition: words is a list of strings.
    Examples:
      count_even(["gjij"]) => 1
      count_even(["a", "bc", "def", "ghij"]) => 2
      count_even(["def"]) => 0
      count_even([""]) => 1
      count_even([]) => 0
    """
def reverse_all(string, substring):
    """ Return string, but with all instances of substring reversed.
    Examples:
        reverse_all("abcdef", "cd") => "abdcef"
        reverse_all("banana man", "an") => "bnanaa mna"
        reverse_all("amicus", "bus") => "amicus"
    """
def find_all(query, string): # 3 points
    """ Return a list of places in string where where the substring
    query appears. Each element of the returned list is an index
    of the beginning of the substring. Overlapping copies of the query
    are not considered. Pre: query's length is at least 1
    find_all('a', 'abab') => [0, 2]
    find_all('ab', 'abbab') => [0, 3]
    find_all('bb', 'bbb') => [0] (overlapping occurrences are not counted)
    find_all('z', 'the quick brown fox') => [] (none found)
    find_all('q', '') => [] (nothing found in the empty string)
    find_all('abcdef', 'abc') => [] (query is longer than the string)
    """