1 of 4
Read a unittest failure down to the value your code returned, then fix the code from that line alone.
Your suite just printed this. Click the one line that tells you what your code actually returned.
text
Foundations· 2 of 3
Check your setup
What the toolchain is, how an exercise is graded, and how to read a unittest failure. Then an easy exercise whose only job is to break loudly now rather than confusingly in module 4.
15 minute read
Every exercise in this course runs the same way. Taking ten minutes to verify your local environment now prevents tooling issues in later modules. The introductory exercise verifies that Python, the editor, the test runner, and the mock client interact properly on your machine.
The minimal toolchain
The runtime requires three components:
- Python 3.10 or newer.
unittest, which ships in the Python standard library.mockllm, a single-file test mock with zero external dependencies, copied into each exercise workspace.
This design avoids external package managers, virtual environments, and API credentials, keeping tests self-contained and reproducible. The skills required to read unittest outputs translate directly to pytest and other test frameworks.
unittest tests the Python standard library itself. Its output format maps directly to the test reports generated by broader Python testing tools.
How grading works
When an exercise opens, the workspace copies scaffold.py to solution.py. The file solution.py stores your code and persists across editor restarts.
The test file test.py imports directly from solution.py:
from solution import (
count_words,
first_reply,
last_user_message,
role_counts,
summarise_messages,
)
The test runner tests both user solutions and reference solutions against the identical test suite. The build pipeline runs reference.py against test.py in continuous integration; if reference code fails any assertion, the lesson cannot build.
Because test.py imports functions by name, preserving function signatures is mandatory. Renaming count_words to word_count triggers an immediate ImportError:
ImportError: cannot import name 'count_words' from 'solution' (/.../solution.py)
Modify function bodies freely, but keep function names and parameter lists intact.
Reading a test failure
Consider a test failure caused by using content.split(" ") instead of content.split():
test_an_empty_string_is_zero (__main__.TestCountingWords.test_an_empty_string_is_zero) ... FAIL
test_collapses_runs_of_whitespace (__main__.TestCountingWords.test_collapses_runs_of_whitespace) ... FAIL
test_counts_words (__main__.TestCountingWords.test_counts_words) ... ok
======================================================================
FAIL: test_an_empty_string_is_zero (__main__.TestCountingWords.test_an_empty_string_is_zero)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/you/exercises/check-your-setup/test.py", line 34, in test_an_empty_string_is_zero
self.assertEqual(count_words(""), 0)
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
AssertionError: 1 != 0
----------------------------------------------------------------------
Ran 16 tests in 0.001s
FAILED (failures=3)
Read the traceback from the bottom:
FAILED (failures=3)indicates the total failure count.AssertionError: 1 != 0shows the mismatch. The left value is the output returned by your code; the right value is the expected output.- The lines above the assertion show the test file location and the specific call under test (
count_words("")). - The test name
test_an_empty_string_is_zerodescribes the specific behavior being checked.
Custom assertion messages provide additional context:
AssertionError: 1 != 0 : content is None on a turn that only calls a tool, so this has to return a number rather than raise
Text following the colon explains the rationale for the test case.
FAIL indicates an unmet assertion where code executed but returned an unexpected value. ERROR indicates an unhandled exception during test execution, pointing to an exception in solution.py. Resolve ERROR tracebacks first, as fixing exceptions often clears multiple assertion failures.
Running tests from the command line
Run tests from the terminal in the exercise directory:
python3 test.py # run all tests
python3 test.py TestCountingWords # run one test class
python3 test.py TestCountingWords.test_none_is_zero # run one specific test
Isolating a single test case speeds up debugging. When a single logic error fails multiple tests within a class, running the simplest failing test provides the cleanest debugging signal.
unittest executes test methods in alphabetical order. Rather than debugging whichever test appears first in the terminal output, select the test case with the minimal input, such as empty or zero-length arguments.
Troubleshooting Python versions
Verify your installed interpreter version:
python3 --version
If the command prints Python 3.10.x or newer, the setup is complete.
On Windows systems, use the Python launcher py:
py -3 --version
py -3 test.py
If your system has Python 3.9 or older, upgrade to 3.10 or higher. The exercises rely on standard library features introduced in 3.10, including union type annotations (str | None) and sys.stdlib_module_names.
On macOS, install Python via python.org or Homebrew to run alongside the default system interpreter.
Exercise specification
Implement five utility functions for processing chat message sequences:
count_words: count words in a message body.role_counts: tally message counts per role.last_user_message: locate the most recent message with roleuser.summarise_messages: generate a single-line summary string.first_reply: execute a single completion call viaMockClient.
Pay attention to edge cases:
str.split()without arguments collapses consecutive whitespace and returns an empty list for empty strings (""), whereasstr.split(" ")returns[""].- To find the last user message in multi-turn dialogues, iterate through the message list in reverse order.
Check your setup
What the toolchain is, how an exercise is graded, and how to read a unittest failure. Then an easy exercise whose only job is to break loudly now rather than confusingly in module 4.
15 minute read
Implement your solution in the editor on the right or work in your local IDE. All unit tests run against your code in real-time.
Exercise
check-your-setup
16 tests, graded on your machine in about a second. Stuck for 10 minutes? The desktop app will offer you the reference solution.