Midterm Review Python Fundamentals - aljimenez28/champlain GitHub Wiki

Midterm Review - Python Fundamentals (GitHub Wiki Format)

This GitHub Wiki is a complete breakdown of each part of the midterm exam. For each part, you will find:

  • The original prompt
  • The final working solution
  • A note on how it connects to what you learned
  • A super simple explanation of how the code works
  • Example usage and output

Part 1: calculate_discounted_price

Original Prompt:

'''
Do not use AI! You can schedule to try again if you have a bad grade!
Basic Function: Write a function named exactly "calculate_discounted_price" which receives 2 parameters: price(float) and discount(float) in percentage, and returns the final price after applying the discount.
'''
def calculate_discounted_price(price, discount):
    # code here
    pass

Final Working Code:

# This function calculates a discounted price given the original price and discount percentage

def calculate_discounted_price(price, discount):
    return price - (price * discount / 100)  # Subtract the discount amount from the original price

print(calculate_discounted_price(100, 10))  # Output: 90.0
print(calculate_discounted_price(50, 50))   # Output: 25.0

Output:

90.0
25.0

What You Learned:

  • Python functions and return values
  • Math operations: *, /, -

How the Code Works (Simple): It multiplies the price by the percentage discount, then subtracts that value from the original price.


Part 2: divide_and_remainder

Original Prompt:

'''
Do not use AI! You can schedule to try again if you have a bad grade!
Write a function named exactly 'divide_and_remainder' and receive a parameter 'num' and a base 'b' and returns a tuple where: the first element is the result of integer division, and the second element is the remainder.
'''
def divide_and_remainder(num, b):
    # code here
    pass

Final Working Code:

# This function returns the result of integer division and the remainder as a tuple

def divide_and_remainder(num, b):
    return (num // b, num % b)  # // gets the quotient, % gets the remainder

print(divide_and_remainder(10, 3))  # Output: (3, 1)
print(divide_and_remainder(10, 2))  # Output: (5, 0)

Output:

(3, 1)
(5, 0)

What You Learned:

  • Integer division (//) and modulus (%)
  • Returning tuples

How the Code Works (Simple): num // b calculates how many times b fits into num. num % b gives the leftover. Both are returned as a tuple.


Part 3: lucas

Original Prompt:

'''
Do not use AI! You can schedule to try again if you have a bad grade!
Lucas Sequence: Write a function 'lucas' which receives an integer 'n' and returns the n-th element of the Lucas sequence (like Fibonacci but starts with 2, 1).
'''
def lucas(n):
    # code here
    pass

Final Working Code:

# This function calculates the n-th value in the Lucas sequence

def lucas(n):
    a = 2  # First number in Lucas sequence
    b = 1  # Second number in Lucas sequence
    for _ in range(n):
        a, b = b, a + b  # Move to next pair in the sequence
    return a

print(lucas(0))  # Output: 2
print(lucas(1))  # Output: 1
print(lucas(2))  # Output: 3
print(lucas(5))  # Output: 11

Output:

2
1
3
11

What You Learned:

  • Loops and variables
  • Lucas is like Fibonacci but starts with 2, 1

How the Code Works (Simple): Starts with a = 2, b = 1. In a loop, each next number is made by adding the previous two. After n steps, return the current a.


Part 4: last2

Original Prompt:

'''
Do not use AI! You can schedule to try again if you have a bad grade!
Write a function named exactly "last2" which receives a list and returns the second-to-last element, or None if the list is too short.
'''
def last2(lst):
    # code here
    pass

Final Working Code:

# This function returns the second-to-last element of a list, or None if too short

def last2(lst):
    if len(lst) < 2:
        return None  # Not enough items
    return lst[-2]  # Second from the end

print(last2(['red', 'blue', 'green', 'yellow']))  # Output: green
print(last2([0, 1]))                              # Output: 0
print(last2([0]))                                 # Output: None

Output:

green
0
None

What You Learned:

  • Lists and indexing
  • Conditional statements

How the Code Works (Simple): It checks if the list has fewer than two items. If not, it returns the second-to-last item using -2 index.


Part 5: median

Original Prompt:

'''
Do not use AI! You can schedule to try again if you have a bad grade!
Write a function named "median" that returns the median value from a list of numbers.
'''
def median(numbers):
    # code here
    pass

Final Working Code:

# This function returns the median of a list

def median(numbers):
    nums = sorted(numbers)  # Sort the numbers
    n = len(nums)
    mid = n // 2
    if n % 2 == 1:
        return nums[mid]  # Odd: return middle
    else:
        return (nums[mid - 1] + nums[mid]) / 2  # Even: average the two middle

print(median([1, 2, 3, 4, 5]))     # Output: 3
print(median([1, 2, 3, 4, 5, 6]))  # Output: 3.5

Output:

3
3.5

What You Learned:

  • Sorting, indexing
  • Even vs odd number of items

How the Code Works (Simple): It sorts the list. If the length is odd, return the middle number. If even, average the two middle numbers.


Part 6: manage_playlist

Original Prompt:

'''
Do not use AI! You can schedule to try again if you have a bad grade!
Write a function 'manage_playlist' which takes a list, a song to add, and a song to search. Add the new song, and return index of the searched one (or None).
'''
def manage_playlist(playlist, new_song, search_song):
    # code here
    pass

Final Working Code:

# This function adds a new song to a playlist and finds the index of a given song

def manage_playlist(playlist, new_song, search_song):
    playlist.append(new_song)  # Add new song to playlist
    if search_song in playlist:
        return playlist.index(search_song)  # Return index of search song
    else:
        return None

playlist = ['Dream On', 'Bohemian Rhapsody', 'Stairway to Heaven']
print(manage_playlist(playlist, 'Hotel California', 'Bohemian Rhapsody'))  # Output: 1
print(playlist)

playlist = ['Imagine', 'Confortably Numb']
print(manage_playlist(playlist, 'Wish You Were Here', 'Wish You Were Here'))  # Output: 2
print(playlist)

Output:

1
['Dream On', 'Bohemian Rhapsody', 'Stairway to Heaven', 'Hotel California']
2
['Imagine', 'Confortably Numb', 'Wish You Were Here']

What You Learned:

  • Modifying lists with .append()
  • Checking membership and index

How the Code Works (Simple): Adds the new song to the playlist. Then checks if search_song exists in the updated playlist. If it does, return its index.


Part 7: split_full_name

Original Prompt:

'''
Do not use AI! You can schedule to try again if you have a bad grade!
Write a function named 'split_full_name' which receives a parameter 'full_name' with 2 or more surnames and returns a tuple with the last name and the first name. If there's only one word, return it as last name and empty string for first.
'''
def split_full_name(full_name):
    # code here
    pass

Final Working Code:

# This function returns a tuple (last_name, first_name) from a full name string

def split_full_name(full_name):
    parts = full_name.split()  # Split the name into parts by spaces
    if len(parts) == 1:
        return (parts[0], '')  # If only one name, return it as last name with empty first name
    return (parts[-1], parts[0])  # Return last word and first word as a tuple

print(split_full_name("John Doe"))             # Output: ('Doe', 'John')
print(split_full_name("John Doe Smith"))       # Output: ('Smith', 'John')
print(split_full_name("John"))                 # Output: ('John', '')
print(split_full_name("John Doe Smith Lee"))   # Output: ('Lee', 'John')

Output:

('Doe', 'John')
('Smith', 'John')
('John', '')
('Lee', 'John')

What You Learned:

  • Strings and .split()
  • Returning tuples

How the Code Works (Simple): It splits the name into words. Returns the last word as last name and first word as first name. If only one word, return it with an empty string.


Part 8: countdown

Original Prompt:

'''
Do not use AI! You can schedule to try again if you have a bad grade!
Write a function named 'countdown' which receives a parameter 'n' and returns a list counting down from n to 0.
'''
def countdown(n):
    # code here
    pass

Final Working Code:

# This function returns a list that counts down from n to 0

def countdown(n):
    if n < 0:
        return []  # Return empty list for negative input
    return list(range(n, -1, -1))  # Count down from n to 0

print(countdown(5))    # Output: [5, 4, 3, 2, 1, 0]
print(countdown(0))    # Output: [0]
print(countdown(-1))   # Output: []
print(countdown(10))   # Output: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

Output:

[5, 4, 3, 2, 1, 0]
[0]
[]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

What You Learned:

  • range() and lists
  • Using steps to count backward

How the Code Works (Simple): If n is less than 0, return an empty list. Otherwise, create a list that counts from n down to 0 using range(n, -1, -1).


Part 9: above_main_diagonal

Original Prompt:

'''
Do not use AI! You can schedule to try again if you have a bad grade!
Write a function 'above_main_diagonal' that takes a square matrix and returns the sum of values above the main diagonal.
'''
def above_main_diagonal(matrix):
    # code here
    pass

Final Working Code:

# This function sums values above the main diagonal in a square matrix

def above_main_diagonal(matrix):
    total = 0
    for i in range(len(matrix)):
        for j in range(len(matrix[i])):
            if i < j:  # Above the diagonal means row index < column index
                total += matrix[i][j]
    return total

matrix = [[1, 1, 1],
          [1, 1, 1],
          [1, 1, 1]]
print(above_main_diagonal(matrix))  # Output: 3

matrix = [[1,  2,  3,  4],
          [5,  6,  7,  8],
          [9, 10, 11, 12],
          [13,14, 15, 16]]
print(above_main_diagonal(matrix))  # Output: 36

Output:

3
36

What You Learned:

  • Nested loops and 2D lists
  • Matrix indexing and comparison

How the Code Works (Simple): Loops through every position. If row index is smaller than column index, it adds that number to the total.


Part 10: spiral_matrix (Bonus)

Original Prompt:

'''
Do not use AI! You can schedule to try again if you have a bad grade!
This is a bonus question: Write a function 'spiral_matrix' that returns a n x n matrix filled in spiral order from 1 to n*n.
'''
def spiral_matrix(n):
    matrix = [[0 for i in range(n)] for j in range(n)]
    # code here
    pass

Final Working Code:

# This function builds an n x n spiral matrix of numbers from 1 to n*n

def spiral_matrix(n):
    matrix = [[0 for i in range(n)] for j in range(n)]
    left = 0
    right = n - 1
    top = 0
    bottom = n - 1
    num = 1  # Start filling from 1

    while left <= right and top <= bottom:
        for i in range(left, right + 1):  # Fill top row
            matrix[top][i] = num
            num += 1
        top += 1

        for i in range(top, bottom + 1):  # Fill right column
            matrix[i][right] = num
            num += 1
        right -= 1

        for i in range(right, left - 1, -1):  # Fill bottom row
            matrix[bottom][i] = num
            num += 1
        bottom -= 1

        for i in range(bottom, top - 1, -1):  # Fill left column
            matrix[i][left] = num
            num += 1
        left += 1

    return matrix

print(spiral_matrix(3))

Output:

[1, 2, 3], [8, 9, 4], [7, 6, 5](/aljimenez28/champlain/wiki/1,-2,-3],-[8,-9,-4],-[7,-6,-5)

What You Learned:

  • Nested loops and conditionals
  • Matrix manipulation

How the Code Works (Simple): The loop fills the outer layer of the matrix in a spiral (top row, right column, bottom row, left column) and keeps going inward until the whole matrix is filled.


Let this wiki be your cheat sheet and guide. If you understand these ten parts, you're golden. 🎯