# Customize the code environment

> A Code Exercise (VS Code) starts each new bash terminal in /workspace. If /workspace/.curacourse/bashrc exists, that terminal sources it. Use it for aliases, environment variables, and…

Source: https://www.curacourse.com/help/customize-a-code-exercise-shell-and-python-environment

## At a glance

A **Code Exercise** (VS Code) starts each new bash terminal in `/workspace`. If `/workspace/.curacourse/bashrc` exists, that terminal sources it. Use it for aliases, environment variables, and to activate a Python virtual environment.

The file name is `bashrc` with no leading dot. It lives in a folder named `.curacourse`.

This applies to every Code Exercise image (Python, Node.js, Flutter, and the others). The virtual-environment steps are for the **Python** image only. They do not change the in-lesson **Code Editor** activity, which runs in a separate sandbox.

## Prerequisites

- A **Code Exercise** open in the editor, with the VS Code panel on the side.
- For the Python section, the exercise image is **Python** (VS Code with CPython).

Put these files in the instructor workspace before learners open the exercise. A learner receives a copy of your files the first time their workspace is created. Files you add later are not copied into a workspace that already exists. A learner can still add the same files in their own copy; that change stays on their copy.

## Add .curacourse/bashrc

In the VS Code terminal:

```
mkdir -p /workspace/.curacourse
```

Create `/workspace/.curacourse/bashrc`. In the Explorer that is a folder named `.curacourse` at the workspace root, and a file inside it named `bashrc`.

A minimal file:

```
# Course shell setup. Do not source /etc/profile.d/cc-prompt.sh
# or this file from inside itself.
alias ll='ls -alF'
```

Open a **new** terminal to load it. An already-open terminal keeps the old shell until you close it. Check the file before you rely on it:

```
bash -n /workspace/.curacourse/bashrc
```

No output means the syntax is fine.

### What belongs in the file

- Aliases and shell functions
- `export` for environment variables the course needs
- Activating a virtual environment under `/workspace` (see below)

Leave out any line that sources `/etc/profile.d/cc-prompt.sh` or `/workspace/.curacourse/bashrc`. The terminal already sources your file, and sourcing it again loops.

Keep course shell setup in `/workspace/.curacourse/bashrc`. Edits to `~/.bashrc` live on the machine image: they are dropped when the machine is recreated and are not copied to learners.

## Python: use a virtual environment in the workspace

The Python image already provides `python` and `python3` (the same interpreter), `pip`, and `venv`. These packages are installed for that system Python:

- numpy
- pandas
- matplotlib
- seaborn
- scipy
- flask
- requests
- beautifulsoup4
- pytest

VS Code uses that system interpreter by default (`/usr/bin/python3`) and does not create a virtual environment for you.

Install course-specific packages into a virtual environment at `/workspace/.venv`, and list them in `/workspace/requirements.txt`.

Packages installed with `pip` into the system Python live outside `/workspace`. They disappear when the machine is recreated, and they are not copied to learners. A virtual environment inside `/workspace` stays with the exercise files.

### requirements.txt

Create `/workspace/requirements.txt` with one package per line. Pin a version after you have tested it (`package==1.2.3`) so every learner installs the same release:

```
# Packages beyond the image defaults.
# Pin a version you have tested: package==1.2.3
pillow
python-dotenv
```

You can leave numpy, pandas, and the other image packages off this list when the virtual environment can see them (next section).

### Create the environment and install

Run this in the VS Code terminal from the workspace root. Run it in the instructor workspace before learners open the exercise if you want their first copy to include the installed packages. Keep `requirements.txt` either way, so the environment can be rebuilt.

```
cd /workspace
python3 -m venv --system-site-packages .venv
. .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
```

`--system-site-packages` lets this environment import the image packages (numpy, pandas, and the rest) without installing them again. `pip install` inside the environment can still install a newer copy of one of those packages when `requirements.txt` asks for it.

Leave off `--system-site-packages` when the exercise should not see the image packages. Then list every package the course needs in `requirements.txt`, including numpy or pandas if learners import them.

Confirm the terminal is using the environment:

```
which python
python -c 'import sys; print(sys.prefix)'
```

Both should point at `/workspace/.venv`.

### Point VS Code at the environment

Command Palette → **Python: Select Interpreter** → `/workspace/.venv/bin/python`.

To make that the default for new terminals and for learners, add `/workspace/.vscode/settings.json`:

```
{
  "python.defaultInterpreterPath": "/workspace/.venv/bin/python"
}
```

### Activate it from .curacourse/bashrc

New terminals do not activate `.venv` on their own. Append this to `/workspace/.curacourse/bashrc`:

```
if [ -f /workspace/.venv/bin/activate ]; then
  . /workspace/.venv/bin/activate
fi
```

Open a new terminal. The prompt should show `(.venv)`.

Optional: create the environment on first use when you ship `requirements.txt` and not a prebuilt `.venv`. The first terminal needs network access and can take a minute.

```
if [ ! -x /workspace/.venv/bin/python ] && [ -f /workspace/requirements.txt ]; then
  python3 -m venv --system-site-packages /workspace/.venv
  /workspace/.venv/bin/python -m pip install --upgrade pip
  /workspace/.venv/bin/python -m pip install -r /workspace/requirements.txt
fi

if [ -f /workspace/.venv/bin/activate ]; then
  . /workspace/.venv/bin/activate
fi
```

## What is saved

| **Path** | **Kept when the machine restarts** | **Copied to a new learner** |
| --- | --- | --- |
| `/workspace/.curacourse/bashrc` | Yes | Yes, the first time their workspace is created |
| `/workspace/requirements.txt` | Yes | Yes, the first time their workspace is created |
| `/workspace/.venv` | Yes | Yes, if it already exists on your copy |
| `/workspace/.vscode/settings.json` | Yes | Yes, the first time their workspace is created |
| `~/.bashrc`, or `pip install` outside `/workspace` | No | No |

## If the terminal looks wrong

- The prompt has no `(.venv)`. Open a new terminal. Check that `/workspace/.venv/bin/activate` exists and that `.curacourse/bashrc` sources it.
- `python` is still `/usr/bin/python3`. The virtual environment is not active. Run `. /workspace/.venv/bin/activate`, or fix the `bashrc` file and open a new terminal.
- Import errors for a course package. Run `python -m pip install -r /workspace/requirements.txt` while the environment is active.
- Import errors for numpy or pandas inside `.venv`. Recreate it with `--system-site-packages`, or add those packages to `requirements.txt`.
- A new terminal prints an error and stops your setup. Run `bash -n /workspace/.curacourse/bashrc` and fix the reported line. Remove any line that sources `cc-prompt.sh` or `.curacourse/bashrc`.

