Redirect Chapter 3: Python Drills: Practice Programs | AI Fundamentals
← Back to Tutorials Chapter 3

Python Drills: Practice Programs

Repetition builds fluency. This chapter is a set of short, self-contained programs that exercise lists, tuples, and dictionaries. For each one, read the goal, try to solve it yourself first, then compare with the solution and the idea behind it. Each snippet is intentionally small so you can run it in seconds.

Arithmetic Warm-Ups

Celsius to Fahrenheit conversion

The formula converts a Celsius reading into its Fahrenheit equivalent by multiplying by 9/5 and adding 32.

celsius = 25.0
fahrenheit = celsius * 9 / 5 + 32
print(fahrenheit)   # 77.0

Area of a rectangle

Multiply length by width. Notice how a small reusable function makes the same math callable many times.

def rect_area(length, width):
    return length * width

print(rect_area(5, 4))   # 20

Distance covered by a vehicle

Distance equals speed multiplied by time. Keep the units consistent: kilometres per hour times hours.

speed_kmh = 60
time_h = 2.5
distance_km = speed_kmh * time_h
print(distance_km)   # 150.0

Number of rounds of a lift

If a lift carries a maximum load per trip, the number of trips equals the total load divided by the capacity, rounded up to the next whole trip. The math.ceil helper handles the rounding.

import math
total_weight = 950
capacity = 300
trips = math.ceil(total_weight / capacity)
print(trips)   # 4

Line equation (slope / intercept)

Given two points, the slope is the rise over the run, and the intercept is found by plugging one point into y = mx + b.

def line_from_points(p1, p2):
    x1, y1 = p1
    x2, y2 = p2
    m = (y2 - y1) / (x2 - x1)
    b = y1 - m * x1
    return m, b

m, b = line_from_points((1, 2), (3, 6))
print(m, b)   # 2.0 0.0
Reading the output: the line is y = 2.0x + 0.0. Two distinct points always define a unique straight line, which is why this same idea reappears in linear regression later in the book.

List Challenges

Sum of list elements

Add every number in a list. The built-in sum is the idiomatic choice.

nums = [4, 8, 15, 16]
print(sum(nums))   # 43

Largest element in a list

Track a running maximum, or use the built-in max.

nums = [3, 9, 2, 11, 5]
largest = nums[0]
for n in nums[1:]:
    if n > largest:
        largest = n
print(largest)   # 11

Removing duplicates from a list

A set keeps only unique values; converting back to a list drops the repeats while preserving a set of distinct items.

data = [1, 2, 2, 3, 3, 3]
unique = list(set(data))
print(unique)   # order may vary

Checking if all list elements are unique

If the set has the same length as the list, nothing was duplicated.

def all_unique(items):
    return len(items) == len(set(items))

print(all_unique([1, 2, 3]))   # True
print(all_unique([1, 2, 2]))   # False

Reversing a list

Slice notation with a step of -1 produces a reversed copy without modifying the original.

nums = [1, 2, 3, 4]
print(nums[::-1])   # [4, 3, 2, 1]

Counting odd and even elements

A single pass can tally both categories using the modulo operator.

nums = [1, 2, 3, 4, 5, 6]
even = sum(1 for n in nums if n % 2 == 0)
odd = len(nums) - even
print(even, odd)   # 3 3

Checking if a list is a subset of another

Set comparison answers this directly: every element of the first set is also in the second.

a = {2, 3}
b = {1, 2, 3, 4}
print(a.issubset(b))   # True

Maximum difference between two consecutive elements

Slide along the list comparing each neighbour pair and keep the largest gap. zip pairs adjacent items neatly.

nums = [1, 7, 3, 12]
gaps = [abs(x - y) for x, y in zip(nums, nums[1:])]
print(max(gaps))   # 9

Merging two sorted lists

Concatenate and sort is simple; walking both lists with two pointers is the classic efficient merge.

def merge(a, b):
    out = []
    i = j = 0
    while i < len(a) and j < len(b):
        if a[i] <= b[j]:
            out.append(a[i]); i += 1
        else:
            out.append(b[j]); j += 1
    out.extend(a[i:])
    out.extend(b[j:])
    return out

print(merge([1, 3, 5], [2, 4, 6]))   # [1, 2, 3, 4, 5, 6]

Rotating a list

Rotation shifts elements so the front moves to the back. Slice the list into two pieces and rejoin them in the new order.

def rotate(items, k):
    k = k % len(items)
    return items[k:] + items[:k]

print(rotate([1, 2, 3, 4, 5], 2))   # [3, 4, 5, 1, 2]
Watch out: rotation amount larger than the list length wraps around. The k % len(items) guard handles that edge case before slicing.

Dictionary and Tuple Challenges

Merging two lists into a dictionary

Pair each key with its matching value using zip.

keys = ["name", "age"]
values = ["Mira", 24]
merged = dict(zip(keys, values))
print(merged)   # {'name': 'Mira', 'age': 24}

Merging multiple dictionaries

Use update in a loop, or chain the modern union operator that joins them left to right.

a = {"x": 1}
b = {"y": 2}
c = {"z": 3}
combined = {}
for d in (a, b, c):
    combined.update(d)
print(combined)   # {'x': 1, 'y': 2, 'z': 3}

Merging dictionaries with common keys

When keys repeat, decide how to combine values. Here duplicate keys have their values added instead of overwritten.

a = {"apples": 3, "mangoes": 2}
b = {"apples": 4, "grapes": 5}
total = {}
for d in (a, b):
    for key, val in d.items():
        total[key] = total.get(key, 0) + val
print(total)   # {'apples': 7, 'mangoes': 2, 'grapes': 5}

Words frequency in a sentence

Split the text into words and count how often each appears. collections.Counter does the whole tally in one line.

from collections import Counter
sentence = "the cat and the dog"
counts = Counter(sentence.split())
print(counts)   # Counter({'the': 2, 'cat': 1, 'and': 1, 'dog': 1})

Palindromic tuple check

A tuple is palindromic if it reads the same forwards and backwards, which a reversed comparison detects directly.

def is_palindrome_tuple(t):
    return t == t[::-1]

print(is_palindrome_tuple((1, 2, 1)))   # True
print(is_palindrome_tuple((1, 2, 3)))   # False

Merging dictionaries with common keys (alternate)

For simple key conflicts, the union operator keeps the value from the right-hand dictionary, which is useful when later data should win.

a = {"name": "Leo", "score": 70}
b = {"score": 85, "city": "Pune"}
combined = a | b
print(combined)   # {'name': 'Leo', 'score': 85, 'city': 'Pune'}
Exercise: Pick any five drills above and rewrite each one using a different technique (for example, replace a built-in like sum with an explicit loop, or swap a loop for a list comprehension). Confirm every version produces the same output. Then write one new program of your own that combines at least three of the ideas, such as finding the most frequent word in a paragraph after removing duplicates.