Note
CS50 Lab will be decommissioned on July 1, 2023. A new-and-improved version will be built into Visual Studio Code for CS50 instead! Documentation coming soon.
CS50 is a programming environment at [lab.cs50.io](https://lab.cs50.io/) for scaffolded learning that enables
* teachers to create step-by-step programming lessons (labs), providing incremental feedback at each step, and
* students to progress from an empty file (or starter code) to working code, with hints and feedback along the way.
To create a lab as a teacher, all you need is a [GitHub](https://github.com/) account and a (public or private) [repository](https://help.github.com/articles/create-a-repo/). To log into and work on a lab as a student, all you need is the former. Neither use case requires familiarity with `git` itself though if or once comfortable with `git`, you can create labs even more quickly via a command line!
CS50 Lab is essentially an extension of [CS50 Sandbox](sandbox) that allows teachers to embed interactive instructions alongside a sandbox. As such, CS50 Lab is, also, essentially a lightweight version of [CS50 IDE](ide/index) with problems' specifications embedded in students' actual programming environments.
URLs of labs are of the form `https://lab.cs50.io/{owner}/{repo}/{branch}/{path}`, where
* `owner` is the lab's owner, a GitHub user or [organization](https://help.github.com/articles/about-organizations/), on [github.com](https://github.com/),
* `repo` is that owner's repository in which the lab's source can be found,
* `branch` is the branch on which the lab's source can be found in that repository, and
* `path` is the path to the lab's source on that branch.
The source for a lab like [lab.cs50.io/cs50/labs/2019/fall/mario/less/](https://lab.cs50.io/cs50/labs/2019/fall/mario/less/) can thus be found in [https://github.com/cs50/labs/tree/2019/fall/mario/less/](https://github.com/cs50/labs/tree/2019/fall/mario/less/), wherein
* `cs50` is the lab's owner (hey, that's us),
* `labs` is the lab's repository,
* `2019/fall` is the lab's branch,
* `mario/less` is the lab's path, and
* `tree` is just a GitHub-specific trick, sandwiched between `:repo` and `:branch`, via which you can browse that branch and path.
## Creation
To create a lab:
1. [Sign up](https://github.com/join) for a (free) GitHub account, if you don't have one already.
1. [Create a repository](https://github.com/new), if you don't have one (that you'd like to use) already.
1. [Create a file](https://blog.github.com/2012-12-05-creating-files-on-github/) in that repository called `.cs50.yml`, optionally [inside of one or more directories](https://github.com/KirstieJane/STEMMRoleModels/wiki/Creating-new-folders-in-GitHub-repository-via-the-browser), using GitHub's website. Or create (and push) the same using `git` itself. Configure `.cs50.yml` [per below](#cs50yml).
1. Optionally create another file in the same directory as `.cs50.yml` called `README.md`, configured [per below](#cs50yml). While technically optional, without this file your lab won't have instructions!
1. Optionally create in or [upload](https://blog.github.com/2016-02-18-upload-files-to-your-repositories/) to that directory (or any descendent thereof) any files you'd like to install in a student's environment (and automatically open in the text editor's tabs).
You can then (assuming no mistakes!) visit `https://lab.cs50.io/:owner/:repo/:branch/:path`, where each of those placeholders is [as above](#cs50-lab), to see your lab!
## Configuration
### `.cs50.yml`
To define a lab, it suffices to create a file called `.cs50.yml` in the root (or subdirectory) of a branch in a repository that contains, minimally, a top-level `lab50` key, the value of which is `true`:
```text
lab50: true
```
#### `window`
It turns out [the above](#cs50yml) is an abbreviation of (and equivalent to)
```text
lab50:
window:
- editor
- readme
- terminal
```
wherein
* `editor` signifies that the lab should have an embedded text editor,
* `readme` signifies that the lab has instructions (written in `README.md`), and
* `terminal` signifies that the lab should have an embedded terminal window.
A value of `terminal` (implicit or explicit) is required.
Also available as values for `window` are
* `browser`, which signifies that the lab should have an embedded browser, and
* `x`, which signifies that the lab should have an embedded X window,
but those two values are mutually exclusive.
It's worth noting that a lab without `readme` is functionally similar to [CS50 Sandbox](sandbox). Whereas sandboxes are intended to be temporary, labs are persistent: if a student logs into a lab and makes changes, those changes will persist indefinitely (unless the student resets the lab).
#### `files`
To install files in students' environments (e.g., `foo.c` and `foo.h`), add a key below `lab50` called `files` (as a sibling of `window`, if explicitly present):
```text
lab50:
files:
- !include foo.c
- !include foo.h
```
That `!include` is a (confusing) feature of [YAML](https://en.wikipedia.org/wiki/YAML); it indeed means "include," not "don't include," as a programmer might otherwise assume.
If those files exist (in the same directory as `.cs50.yml`), they will be copied into students' environments and opened automatically (if recognized as text files). If those files don't exist, they will be created as empty (and opened).
Files (e.g., `bar.c` and `bar.h`) can also be in subdirectories (of whatever directory `.cs50.yml` is in):
```text
lab50:
files:
- !include foo/bar.c
- !include foo/bar.h
```
Alternatively, you can specify subdirectories:
```text
lab50:
files:
- !include foo/
```
Globbing is also supported, but asterisks have special meaning in YAML, so take care to quote any strings that have wildcards:
```text
lab50:
files:
- !include "foo/*.c"
- !include "foo/*.h"
```
You can also exclude files, as with:
```text
lab50:
files:
- !exclude "*"
- !include "foo.*"
```
The value of `files` is an ordered list, top to bottom, so the above means that all files are excluded by default but `foo.*` is then included, thereby overriding their exclusion.
#### `cmd`
To specify a command to be run in the sandbox's terminal window (e.g., `python`), add a key below `lab50` called `cmd`:
```text
lab50:
cmd: python
```
The (implicit) default is:
```text
lab50:
cmd: bash
```
### `README.md`
A lab's instructions should be written in `README.md` (which must be in the same directory as `.cs50.yml`), using
[GitHub-flavored Markdown](https://guides.github.com/features/mastering-markdown/). Via CS50-specific "tags" can you add interactive features to those instructions. If present, each should appear on a line of its own but might very work in other contexts too (e.g., in ordered or unordered lists).
Your Markdown can also contain, if need, raw HTML, but not [these tags](https://github.github.com/gfm/#disallowed-raw-html-extension-).
Your Markdown can also contain [emoji](https://www.webfx.com/tools/emoji-cheat-sheet/).