Practice
Every exercise lives inside its lesson, where it has full context. This page helps you find one by topic, difficulty, or type.
Add a return_book method to LibraryBook
Write a method that reverses borrow()'s state change, then trace borrowing, returning, and borrowing again.
Choose the minimal model for three library questions
Decide the minimal model needed for three different questions about a library's books.
Classify a Thermostat's public and internal members
Sort a class's methods and attributes into public interface vs. implementation detail.
Classify three bugs
Sort three short examples into syntax error, runtime error, or logic error.
Classify three class pairs as is-a or has-a
Decide whether three pairs of classes relate by inheritance or composition, and sketch the direction.
Classify three functions by growth rate
Sort three functions into constant, linear, or quadratic based on their loop structure.
Decide class vs. plain function for three scenarios
Apply the state-and-behavior test to decide whether three scenarios justify a class or a plain function.
Decide most_vowels's empty-list behavior on purpose
Predict what an unspecified edge case does by accident, then make the decision explicit in code.
Decompose an email-checking problem
Split a vague problem into three or four subproblems, each with one job.
Decompose the undecomposed receipt program
Compare a monolithic version of the receipt calculation to the decomposed one, then rewrite it as functions.
Diagnose a quadratic slowdown in a growing report
Predict why a quadratic duplicate-checker got dramatically slower as input grew, then swap in the linear version.
Evaluate four expressions by hand
Apply operator precedence and parentheses to evaluate four short arithmetic expressions.
Fix a backwards is-a diagram
Predict why a Manager/Employee diagram is drawn backwards, then redraw it correctly.
Fix a binary search on unsorted usernames
Predict why binary_search reports a present username as missing on unsorted data, then fix it.
Fix a graph traversal that never tracks visited nodes
Predict why a traversal with no visited tracking loops forever on a cyclic graph, then fix it.
Fix a node silently dropped from a chain
Predict why a node disappears from traversal after an insertion, then fix the missing reference.
Fix a running total that never escapes its function
Predict why a return value that's never captured leaves a NameError outside the function, then fix it.
Fix a ticket queue that serves the newest first
Predict why pop() serves tickets in the wrong order, then fix it with pop(0).
Fix average() and write tests for it
Fix a logic error in an averaging function, then write assertions including an edge case.
Fix is_even so its result can be used
Predict why a function that prints instead of returning breaks a caller's if statement, then fix it.
Fix the broken swap
Predict why a two-line swap fails, then fix it using a third variable.
Fix the crashing loyalty-points lookup
Predict why a dictionary lookup raises KeyError for a new customer, then fix it with .get().
Fix the discount-then-tax calculation
Predict why a missing parenthesis causes tax to be computed on the wrong amount, then fix it.
Fix the infinite while loop
Predict why a while loop never stops, then add the missing line that fixes it.
Fix the receipt total
Predict whether a checkout calculation raises a TypeError, then fix it.
Fix the temperature labeler
Predict why separate if statements misclassify a temperature, then rewrite them as one elif chain.
Identify a tree's root, leaves, and a parent
Given a small three-level tree built from node dictionaries, identify its root, leaves, and one node's parent.
Improve total() and re-verify it
Replace a manual summing loop with sum(), then confirm the original assertion still passes.
Isolate which of three changes broke a test
Predict why three simultaneous changes make a failing test hard to diagnose, then reapply them one at a time.
Match five scenarios to the structures that fit
Apply the four-question framework to pick the best structure for five different scenarios.
Name the types
For five given values, write down each one's type before checking.
Pick a list or a dictionary for three scenarios
Decide whether a list or dictionary fits three data scenarios, and explain why.
Replace a direct _balance edit with deposit()
Predict why bypassing deposit() is risky even when it currently works, then fix the code.
Replace a forgotten isinstance branch with polymorphism
Predict why a new Director class silently gets the wrong bonus, then refactor to a polymorphic bonus() method.
Replace a manually-searched username list with a set
Predict why a list-based membership check gets slower as it grows, then replace it with a set.
Replace a misused inheritance with composition
Predict why PremiumMember inheriting from Discount misrepresents the relationship, then refactor to composition.
Replace direct attribute access with borrow()
Predict the risk of bypassing an object's interface, then rewrite the code to use it.
Rewrite Member to compose Account instead of duplicating it
Predict the risk of reimplementing balance logic directly, then refactor Member to delegate to a composed Account.
Simplify DiscountCalculator into a plain function
Predict why a stateless class adds no value here, then rewrite it as a plain function.
Specify a highest-score problem fully
Write down inputs, outputs, constraints, and edge cases for a "find the highest score" problem.
Speed up order-ID membership checks with a set
Predict why a growing list makes membership checks slower, then rewrite using a set.
Stop get_sorted from mutating the caller's list
Predict why sorting a list parameter changes the caller's original, then fix it with .copy().
Trace a bonus() loop across three subclasses
Trace what each of three Employee subclasses returns from a shared bonus() call in a loop.
Trace a counting algorithm, including an empty list
Trace pseudocode that counts matching values, for both a normal list and the empty-list edge case.
Trace a linked chain being built node by node
Trace the chain of next references after each line links a new node in.
Trace a member's balance through three fines
Trace the composed Account's balance as pay_fine delegates to it three times, including a refused withdrawal.
Trace a running total through a for loop
Trace total after each pass of a for loop that subtracts amounts from a list.
Trace a set built from duplicate words
Trace a set's contents as four .add() calls run, including a repeated value.
Trace a total by hand
Trace three assignments, including one where a variable appears on both sides.
Trace an account through deposits and withdrawals
Trace _balance through a sequence of deposit and withdraw calls, including one that must be checked against the current balance.
Trace inherited vs. overridden area()
Trace a base Shape's area() against a Square subclass's overridden version.
Trace linear and binary search side by side
Trace both search strategies looking for the same target and compare how many comparisons each takes.
Trace shared list references vs. independent numbers
Trace how a mutated shared list is visible through both names, contrasted with independent number variables.
Trace the cinema pricing rules
For four ages, work out which branch of an if/elif/else chain runs.
Trace three calls to area()
Trace how width and height map to a return value across three function calls.
Trace three pops from a stack
Trace what each pop() call removes and returns from a stack of three numbers.
Trace two independent LibraryBook instances
Trace is_on_loan for two separate book instances as borrow() is called on each.
Trace which names are visible where
Decide whether each print line succeeds or raises a NameError, for a program mixing global and local names.
Translate count_negatives from pseudocode
Turn traced pseudocode into a working Python function, then trace the function itself to confirm it.
Trim an over-modeled average function
Predict why tracking names and a highest scorer is unnecessary for a simple average, then simplify the function.