# The CS336 assignment repository ships tests that fail on purpose and an adapter file you have to fill in

> stanford-cs336's assignment1-basics is the student version of the first assignment from the language modeling from scratch course: a package skeleton, a test suite that raises NotImplementedError everywhere, an adapters file that connects your code to those tests, and a uv managed environment pinned to Python 3.12 through 3.13. The deliverable is the implementation, not this repository, and the README says so by deferring the actual assignment to a PDF handout.

**stanford-cs336/assignment1-basics** — Student version of Assignment 1 for Stanford CS336 - Language Modeling From Scratch

- Repository: https://github.com/stanford-cs336/assignment1-basics
- Website: https://cs336.stanford.edu
- Stars: 2,920 · Forks: 2,908
- Language: Python
- License: MIT
- Published: 2026-09-28 · Updated: 2026-09-28 · Language: en
- Canonical page: https://hysenlabs.com/projects/stanford-cs336-assignment1-basics

## The suite fails on day one, and adapters.py is the only seam

The test section explains the starting state directly: initially, all tests should fail with NotImplementedError. To connect your implementation to the tests, you complete the functions in the adapters file under the tests directory. That single design choice is what makes this repository a harness rather than a solution. The tests do not reach into your module directly; they go through an adapter layer that you fill in, so the suite can be written against an interface before any of the underlying code exists. Running them is one command:

```sh
uv run pytest
```

The pytest configuration in the manifest is tuned for watching a suite fail and change: log output is enabled at WARNING level and the addopts carry -s, so output is not captured and appears as it happens. That is a deliberate choice for a course where the feedback loop is the point, and it means a long running test will print rather than sit silent.

## uv manages the interpreter, the environment and the build

Environment management is the first thing the page addresses, and the stated reasons are reproducibility, portability and ease of use. Installing uv is left to the official page, with pip install uv and brew install uv named as alternatives. Once it is present, running anything in the repository is a single command:

```sh
uv run <python_file_path>
```

The environment is solved and activated automatically when necessary, which is why there is no virtual environment step and no requirements install step in the instructions. Two settings in the manifest make that explicit: the package is declared as a real package rather than a loose directory, and the Python preference is set to managed, which means uv supplies an interpreter instead of using whatever the system has. The build backend is uv's own, with the required version range pinned to a single minor series, and a lock file is committed, so the dependency set is reproducible rather than merely declared.

## The assignment itself is a PDF, and the README is only setup

The first line of the page points at a handout committed in the repository root, cs336_assignment1_basics.pdf, and says the full description of the assignment is there. Everything after that is mechanics: environment, tests, data. So the split is deliberate, with the specification in a document and the tooling in the readme, and anyone looking for the assignment text in the repository will not find it. The rest of the tree supports that shape. There is a package directory holding the code skeleton, the tests directory, the lock file, a changelog, an agents file and a Claude instructions file, and a shell script named make_submission.sh, which is how finished work gets handed in. The last commit to the default branch is dated 7 April 2026, and the single release published is a Spring 2025 archive from March 2026, so this is a course snapshot rather than a project with a release cadence.

## Python is capped below 3.14 and the package version is a year

The manifest is where two constraints show up that will bite first if you ignore them. The interpreter requirement is greater than or equal to 3.12 and less than 3.14, which is a window of two versions rather than an open floor, so an environment on 3.14 is out of scope and one on 3.11 is too old. Combined with the managed interpreter preference, that means the project expects uv to fetch a suitable Python rather than to accept the one already on the machine. The second detail is the version number: the package is version 26.0.0, which reads as a year rather than a release sequence. Paired with a single release called Spring 2025 Archive, the versioning is telling you that this artifact is a dated snapshot of a course, not a library that intends semantic versioning.

## Pytest, ruff, a type checker and Weights and Biases are install dependencies

The dependency list mixes what the code needs with what the course needs, and the second group is not optional. Alongside the tensor work, the manifest lists pytest with a version floor of 9.0, pytest-timeout, ruff with a floor of 0.15.8, a type checker at 0.0.26, psutil, tqdm, and wandb at 0.25 or newer. That means the experiment tracking library, the linter and the test runner are all installed with the project rather than added by you, which is convenient for a graded environment and surprising if you expected a lean dependency tree. The modeling side is PyTorch at a compatible release of the 2.11 series, with einops and einx both present as tensor libraries, jaxtyping for type hints across the torch, jax and numpy worlds even though jax itself is not a dependency, tiktoken for tokenization, and the regex module with a floor recent enough to date the manifest, chosen over the built in re.

## The data step is two corpora and two gunzips

The last section of the page fetches the datasets, and the block is worth reading as written because the directory handling is manual:

``` sh
mkdir -p data
cd data

wget https://huggingface.co/datasets/roneneldan/TinyStories/resolve/main/TinyStoriesV2-GPT4-train.txt
wget https://huggingface.co/datasets/roneneldan/TinyStories/resolve/main/TinyStoriesV2-GPT4-valid.txt

wget https://huggingface.co/datasets/stanford-cs336/owt-sample/resolve/main/owt_train.txt.gz
gunzip owt_train.txt.gz
wget https://huggingface.co/datasets/stanford-cs336/owt-sample/resolve/main/owt_valid.txt.gz
gunzip owt_valid.txt.gz

cd ..
```

Two sources, both on a dataset host: the TinyStories validation and training splits as plain text, and an OpenWebText sample whose two files arrive compressed and are expanded in place. Note that the data directory is created and entered by hand rather than by the tool, and that nothing on the page says how much disk the sample needs or how the splits are meant to be used, which is one more thing the handout has to cover.

## Style is enforced by ruff with a 120 column line and four file level exemptions

The lint configuration is short and has an opinionated shape. The line length is 120, the pyupgrade rule set is switched on in addition to the defaults, one rule is disabled outright, and every __init__.py gets four codes ignored: module level imports that are not at the top, unused imports, star imports, and line length. The exempted codes are exactly the ones a package's __init__ files accumulate when they re-export a public API, so the configuration is a deliberate accommodation rather than sloppiness. The remaining tree tells you where a submission is assembled: a submission script at the root, a changelog, an agents file, a Claude instructions file, the package directory and the tests directory with its adapter file. Nothing about the layout is clever, which is the point, since the only variable the course is measuring is what you write inside it.

## Conclusion

Treat this repository as a harness rather than a library. It gives you an environment that resolves itself, a test suite that states the expected behaviour precisely, and one adapter file as the only place your code has to be wired in, which is a good deal more than most course repositories offer. Three things to know before you start. The tests fail until that adapter is complete, so a red suite on day one is the expected state rather than a broken checkout. Read the PDF handout in the repository root, because the README covers setup, tests and data only, and the assignment itself is not described anywhere else. And check the Python constraint before installing anything, since the project requires a version below 3.14 and asks uv to manage the interpreter rather than using the one on your system.

## FAQ

### Why do all the CS336 Assignment 1 tests fail when I first run them?

That is the intended starting state. The page says initially all tests should fail with NotImplementedError, and that to connect your implementation to the tests you complete the functions in tests/adapters.py. The suite talks to your code through that adapter layer rather than importing it directly.

### How do I run code in the CS336 assignment repository?

With uv run followed by the path to a Python file, and the environment is solved and activated automatically when needed. The tests are run the same way with uv run pytest, and dependencies are pinned in a committed uv.lock.

### Which Python versions does the CS336 Assignment 1 project support?

requires-python is greater than or equal to 3.12 and less than 3.14, and the tool configuration asks uv to manage the interpreter. The package version is 26.0.0, which reads as a dated course snapshot rather than a semantic release line.

### Where is the full description of the CS336 Assignment 1 work?

In the handout committed at the repository root as cs336_assignment1_basics.pdf. The readme covers only environment setup, running the tests and downloading the data, and points readers to raise an issue or a pull request if either the handout or the code has problems.

### What data does the CS336 Assignment 1 setup download?

Two corpora from a dataset host: the TinyStories training and validation text files, and an OpenWebText sample whose training and validation files arrive gzipped and are expanded with gunzip. The data directory is created and entered by hand with mkdir and cd before the downloads.

### Does the CS336 assignment depend on Weights and Biases?

Yes, wandb at 0.25 or newer is listed among the project dependencies, alongside pytest, pytest-timeout, ruff, a type checker, psutil and tqdm. The tracking library, the linter and the test runner are all installed with the project rather than added separately.

## Sources

- [License: MIT](https://github.com/stanford-cs336/assignment1-basics/blob/main/LICENSE)
- [Project website](https://cs336.stanford.edu)
- [README](https://github.com/stanford-cs336/assignment1-basics/blob/main/README.md)
- [Releases](https://github.com/stanford-cs336/assignment1-basics/releases)
- [stanford-cs336/assignment1-basics on GitHub](https://github.com/stanford-cs336/assignment1-basics)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/stanford-cs336-assignment1-basics
